diff options
author | apatrick@google.com <apatrick@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-25 00:01:32 +0000 |
---|---|---|
committer | apatrick@google.com <apatrick@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-25 00:01:32 +0000 |
commit | 96449d2cf2f37ffcab09ad8e15d9d6f3534271cb (patch) | |
tree | 7d603b2bc43bea75362248d27e54c5ce51017fdf /gpu | |
parent | fd50fb2b7e19a6589270a02a28fb4dea5b6f38d3 (diff) | |
download | chromium_src-96449d2cf2f37ffcab09ad8e15d9d6f3534271cb.zip chromium_src-96449d2cf2f37ffcab09ad8e15d9d6f3534271cb.tar.gz chromium_src-96449d2cf2f37ffcab09ad8e15d9d6f3534271cb.tar.bz2 |
Landing the GPU process and command buffer code again, this time with a DEPS file with the necessary include rules.
TEST=none
BUG=none
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@33006 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
118 files changed, 34530 insertions, 0 deletions
diff --git a/gpu/DEPS b/gpu/DEPS new file mode 100644 index 0000000..992eb71 --- /dev/null +++ b/gpu/DEPS @@ -0,0 +1,4 @@ +include_rules = [ + "+webkit/glue/plugins", + "+third_party/npapi", +] diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py new file mode 100644 index 0000000..04f9a7b --- /dev/null +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -0,0 +1,2577 @@ +#!/usr/bin/python +# +# Copyright (c) 2006-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. + +"""code generator for GL command buffers.""" + +import os +import os.path +import sys +import re +from optparse import OptionParser + +_SIZE_OF_UINT32 = 4 +_SIZE_OF_COMMAND_HEADER = 4 +_FIRST_SPECIFIC_COMMAND_ID = 1024 + +_LICENSE = """ +// Copyright (c) 2006-2008 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 string is copied directly out of the gl2.h file from GLES2.0 +# the reasons it is copied out instead of parsed directly are +# +# 1) Because order is important. The command IDs need to stay constant forever +# so if you add a new command it needs to be added to the bottom of the list. +# +# 2) So we can add more commands easily that are unrelated to GLES2.0 but still +# needed for GLES2.0 command buffers. +# +# Edits: +# +# *) Any argument that is a resourceID has been changed to GLresourceID. +# (not pointer arguments) +# +_GL_FUNCTIONS = """ +GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture); +GL_APICALL void GL_APIENTRY glAttachShader (GLResourceId program, GLResourceId shader); +GL_APICALL void GL_APIENTRY glBindAttribLocation (GLResourceId program, GLuint index, const char* name); +GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLResourceId buffer); +GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLResourceId framebuffer); +GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLResourceId renderbuffer); +GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLResourceId texture); +GL_APICALL void GL_APIENTRY glBlendColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +GL_APICALL void GL_APIENTRY glBlendEquation ( GLenum mode ); +GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha); +GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); +GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void* data, GLenum usage); +GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void* data); +GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target); +GL_APICALL void GL_APIENTRY glClear (GLbitfield mask); +GL_APICALL void GL_APIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +GL_APICALL void GL_APIENTRY glClearDepthf (GLclampf depth); +GL_APICALL void GL_APIENTRY glClearStencil (GLint s); +GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +GL_APICALL void GL_APIENTRY glCompileShader (GLResourceId shader); +GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data); +GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL GLuint GL_APIENTRY glCreateProgram (void); +GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type); +GL_APICALL void GL_APIENTRY glCullFace (GLenum mode); +GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint* buffers); +GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint* framebuffers); +GL_APICALL void GL_APIENTRY glDeleteProgram (GLResourceId program); +GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint* renderbuffers); +GL_APICALL void GL_APIENTRY glDeleteShader (GLResourceId shader); +GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint* textures); +GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func); +GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag); +GL_APICALL void GL_APIENTRY glDepthRangef (GLclampf zNear, GLclampf zFar); +GL_APICALL void GL_APIENTRY glDetachShader (GLResourceId program, GLResourceId shader); +GL_APICALL void GL_APIENTRY glDisable (GLenum cap); +GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); +GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void* indices); +GL_APICALL void GL_APIENTRY glEnable (GLenum cap); +GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glFinish (void); +GL_APICALL void GL_APIENTRY glFlush (void); +GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLResourceId renderbuffer); +GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLResourceId texture, GLint level); +GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode); +GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint* buffers); +GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target); +GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint* framebuffers); +GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint* renderbuffers); +GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint* textures); +GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLResourceId program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name); +GL_APICALL void GL_APIENTRY glGetActiveUniform (GLResourceId program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name); +GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLResourceId program, GLsizei maxcount, GLsizei* count, GLuint* shaders); +GL_APICALL int GL_APIENTRY glGetAttribLocation (GLResourceId program, const char* name); +GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean* params); +GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint* params); +GL_APICALL GLenum GL_APIENTRY glGetError (void); +GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetProgramiv (GLResourceId program, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLResourceId program, GLsizei bufsize, GLsizei* length, char* infolog); +GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetShaderiv (GLResourceId shader, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLResourceId shader, GLsizei bufsize, GLsizei* length, char* infolog); +GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision); +GL_APICALL void GL_APIENTRY glGetShaderSource (GLResourceId shader, GLsizei bufsize, GLsizei* length, char* source); +GL_APICALL const GLubyte* GL_APIENTRY glGetString (GLenum name); +GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetUniformfv (GLResourceId program, GLint location, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetUniformiv (GLResourceId program, GLint location, GLint* params); +GL_APICALL int GL_APIENTRY glGetUniformLocation (GLResourceId program, const char* name); +GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void** pointer); +GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode); +GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLResourceId buffer); +GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap); +GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLResourceId framebuffer); +GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLResourceId program); +GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLResourceId renderbuffer); +GL_APICALL GLboolean GL_APIENTRY glIsShader (GLResourceId shader); +GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLResourceId texture); +GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width); +GL_APICALL void GL_APIENTRY glLinkProgram (GLResourceId program); +GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units); +GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels); +GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void); +GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glSampleCoverage (GLclampf value, GLboolean invert); +GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei n, const GLResourceId* shaders, GLenum binaryformat, const void* binary, GLsizei length); +GL_APICALL void GL_APIENTRY glShaderSource (GLResourceId shader, GLsizei count, const char** string, const GLint* length); +GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); +GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum fail, GLenum zfail, GLenum zpass); +GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels); +GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); +GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat* params); +GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint* params); +GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels); +GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat x); +GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint x); +GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint x, GLint y); +GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint x, GLint y, GLint z); +GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint x, GLint y, GLint z, GLint w); +GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUseProgram (GLResourceId program); +GL_APICALL void GL_APIENTRY glValidateProgram (GLResourceId program); +GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint indx, GLfloat x); +GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint indx, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint indx, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr); +GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); +// Non-GL commands. +GL_APICALL void GL_APIENTRY glSwapBuffers (void); +""" + +# This table specifies types and other special data for the commands that +# will be generated. +# +# type: defines which handler will be used to generate code. +# DecoderFunc: defines which function to call in the decoder to execute the +# corresponding GL command. If not specified the GL command will +# be called directly. +# cmd_args: The arguments to use for the command. This overrides generating +# them based on the GL function arguments. +# immediate: Whether or not to generate an immediate command for the GL +# function. The default is if there is exactly 1 pointer argument +# in the GL function an immediate command is generated. +# needs_size: If true a data_size field is added to the command. +# data_type: The type of data the command uses. For PUTn or PUT types. +# count: The number of units per element. For PUTn or PUT types. + +_FUNCTION_INFO = { + 'BindAttribLocation': {'type': 'GLchar'}, + 'BindBuffer': {'DecoderFunc': 'DoBindBuffer'}, + 'BindFramebuffer': {'DecoderFunc': 'glBindFramebufferEXT'}, + 'BindRenderbuffer': {'DecoderFunc': 'glBindRenderbufferEXT'}, + 'BufferData': {'type': 'Data'}, + 'BufferSubData': {'type': 'Data'}, + 'CheckFramebufferStatus': {'DecoderFunc': 'glCheckFramebufferStatusEXT'}, + 'ClearDepthf': {'DecoderFunc': 'glClearDepth'}, + 'CompressedTexImage2D': {'type': 'Data'}, + 'CompressedTexSubImage2D': {'type': 'Data'}, + 'CreateProgram': {'type': 'Create'}, + 'CreateShader': {'type': 'Create'}, + 'DeleteBuffers': {'type': 'DELn'}, + 'DeleteFramebuffers': {'type': 'DELn'}, + 'DeleteProgram': {'DecoderFunc': 'DoDeleteProgram'}, + 'DeleteRenderbuffers': {'type': 'DELn'}, + 'DeleteShader': {'DecoderFunc': 'DoDeleteShader'}, + 'DeleteTextures': {'type': 'DELn'}, + 'DepthRangef': {'DecoderFunc': 'glDepthRange'}, + 'DrawElements': { + 'type': 'Manual', + 'cmd_args': 'GLenum mode, GLsizei count, GLenum type, GLuint index_offset', + }, + 'FramebufferRenderbuffer': {'DecoderFunc': 'glFramebufferRenderbufferEXT'}, + 'FramebufferTexture2D': {'DecoderFunc': 'glFramebufferTexture2DEXT'}, + 'GenerateMipmap': {'DecoderFunc': 'glGenerateMipmapEXT'}, + 'GenBuffers': {'type': 'GENn'}, + 'GenFramebuffers': {'type': 'GENn'}, + 'GenRenderbuffers': {'type': 'GENn'}, + 'GenTextures': {'type': 'GENn'}, + 'GetActiveAttrib': {'type': 'Custom'}, + 'GetActiveUniform': {'type': 'Custom'}, + 'GetAttachedShaders': {'type': 'Custom'}, + 'GetAttribLocation': {'type': 'GetGLchar'}, + 'GetBooleanv': {'type': 'GETn'}, + 'GetBufferParameteriv': {'type': 'GETn'}, + 'GetError': {'type': 'Is'}, + 'GetFloatv': {'type': 'GETn'}, + 'GetFramebufferAttachmentParameteriv': { + 'type': 'GETn', + 'DecoderFunc': 'glGetFramebufferAttachmentParameterivEXT', + }, + 'GetIntegerv': {'type': 'GETn'}, + 'GetProgramiv': {'type': 'GETn'}, + 'GetProgramInfoLog': {'type': 'STRn'}, + 'GetRenderbufferParameteriv': { + 'type': 'GETn', + 'DecoderFunc': 'glGetRenderbufferParameterivEXT', + }, + 'GetShaderiv': {'type': 'GETn'}, + 'GetShaderInfoLog': {'type': 'STRn'}, + 'GetShaderPrecisionFormat': {'type': 'Custom'}, + 'GetShaderSource': {'type': 'STRn'}, + 'GetTexParameterfv': {'type': 'GETn'}, + 'GetTexParameteriv': {'type': 'GETn'}, + 'GetUniformfv': {'type': 'Custom', 'immediate': False}, + 'GetUniformiv': {'type': 'Custom', 'immediate': False}, + 'GetUniformLocation': {'type': 'GetGLchar'}, + 'GetVertexAttribfv': {'type': 'GETn'}, + 'GetVertexAttribiv': {'type': 'GETn'}, + 'GetVertexAttribPointerv': {'type': 'Custom', 'immediate': False}, + 'IsBuffer': {'type': 'Is'}, + 'IsEnabled': {'type': 'Is'}, + 'IsFramebuffer': {'type': 'Is', 'DecoderFunc': 'glIsFramebufferEXT'}, + 'IsProgram': {'type': 'Is'}, + 'IsRenderbuffer': {'type': 'Is', 'DecoderFunc': 'glIsRenderbufferEXT'}, + 'IsShader': {'type': 'Is'}, + 'IsTexture': {'type': 'Is'}, + 'PixelStorei': {'type': 'Custom'}, + 'RenderbufferStorage': {'DecoderFunc': 'glRenderbufferStorageEXT'}, + 'ReadPixels': {'type': 'Custom', 'immediate': False}, + 'ReleaseShaderCompiler': {'type': 'Noop'}, + 'ShaderBinary': {'type': 'Noop'}, + 'ShaderSource': { + 'type': 'Manual', + 'immediate': True, + 'needs_size': True, + 'cmd_args': + 'GLuint shader, GLsizei count, const char* data', + }, + 'TexImage2D': {'type': 'Data'}, + 'TexParameterfv': {'type': 'PUT', 'data_type': 'GLfloat', 'count': 1}, + 'TexParameteriv': {'type': 'PUT', 'data_type': 'GLint', 'count': 1}, + 'TexSubImage2D': {'type': 'Data'}, + 'Uniform1fv': {'type': 'PUTn', 'data_type': 'GLfloat', 'count': 1}, + 'Uniform1iv': {'type': 'PUTn', 'data_type': 'GLint', 'count': 1}, + 'Uniform2fv': {'type': 'PUTn', 'data_type': 'GLfloat', 'count': 2}, + 'Uniform2iv': {'type': 'PUTn', 'data_type': 'GLint', 'count': 2}, + 'Uniform3fv': {'type': 'PUTn', 'data_type': 'GLfloat', 'count': 3}, + 'Uniform3iv': {'type': 'PUTn', 'data_type': 'GLint', 'count': 3}, + 'Uniform4fv': {'type': 'PUTn', 'data_type': 'GLfloat', 'count': 4}, + 'Uniform4iv': {'type': 'PUTn', 'data_type': 'GLint', 'count': 4}, + 'UniformMatrix2fv': {'type': 'PUTn', 'data_type': 'GLfloat', 'count': 4}, + 'UniformMatrix3fv': {'type': 'PUTn', 'data_type': 'GLfloat', 'count': 9}, + 'UniformMatrix4fv': {'type': 'PUTn', 'data_type': 'GLfloat', 'count': 16}, + 'VertexAttrib1fv': {'type': 'PUT', 'data_type': 'GLfloat', 'count': 1}, + 'VertexAttrib2fv': {'type': 'PUT', 'data_type': 'GLfloat', 'count': 2}, + 'VertexAttrib3fv': {'type': 'PUT', 'data_type': 'GLfloat', 'count': 3}, + 'VertexAttrib4fv': {'type': 'PUT', 'data_type': 'GLfloat', 'count': 4}, + 'VertexAttribPointer': { + 'type': 'Manual', + 'cmd_args': 'GLuint indx, GLint size, GLenum type, GLboolean normalized, ' + 'GLsizei stride, GLuint offset', + }, + 'SwapBuffers': {'DecoderFunc': 'DoSwapBuffers'}, +} + + +class CWriter(object): + """Writes to a file formatting it for Google's style guidelines.""" + + def __init__(self, filename): + self.filename = filename + self.file = open(filename, "w") + + def Write(self, string): + """Writes a string to a file spliting if it's > 80 characters.""" + lines = string.splitlines() + num_lines = len(lines) + for ii in range(0, num_lines): + self.__WriteLine(lines[ii], ii < (num_lines - 1) or string[-1] == '\n') + + def __FindSplit(self, string): + """Finds a place to split a string.""" + splitter = string.find('=') + if splitter >= 0 and not string[splitter + 1] == '=': + return splitter + parts = string.split('(') + if len(parts) > 1: + splitter = len(parts[0]) + for ii in range(1, len(parts)): + if not parts[ii - 1][-3:] == "if ": + return splitter + splitter += len(parts[ii]) + 1 + done = False + end = len(string) + last_splitter = -1 + while not done: + splitter = string[0:end].rfind(',') + if splitter < 0: + return last_splitter + elif splitter >= 80: + end = splitter + else: + return splitter + + def __WriteLine(self, line, ends_with_eol): + """Given a signle line, writes it to a file, splitting if it's > 80 chars""" + if len(line) >= 80: + i = self.__FindSplit(line) + if i > 0: + line1 = line[0:i + 1] + self.file.write(line1 + '\n') + match = re.match("( +)", line1) + indent = "" + if match: + indent = match.group(1) + splitter = line[i] + if not splitter == ',': + indent = " " + indent + self.__WriteLine(indent + line[i + 1:].lstrip(), True) + return + self.file.write(line) + if ends_with_eol: + self.file.write('\n') + + def Close(self): + """Close the file.""" + self.file.close() + + +class TypeHandler(object): + """This class emits code for a particular type of function.""" + + def __init__(self): + pass + + def InitFunction(self, func): + """Add or adjust anything type specific for this function.""" + if func.GetInfo('needs_size'): + func.AddCmdArg(CmdArg('data_size', 'uint32')) + + def AddImmediateFunction(self, generator, func): + """Adds an immediate version of a function.""" + # Generate an immediate command if there is only 1 pointer arg. + immediate = func.GetInfo('immediate') # can be True, False or None + if immediate == True or immediate == None: + if func.num_pointer_args == 1 or immediate: + generator.AddFunction(ImmediateFunction(func)) + + def WriteHandlerImplementation(self, func, file): + """Writes the handler implementation for this command.""" + file.Write(" parse_error::ParseError result =\n") + file.Write(" Validate%s(this, arg_count%s);\n" % + (func.name, func.MakeOriginalArgString("", True))) + file.Write(" if (result != parse_error::kParseNoError) {\n") + file.Write(" return result;\n") + file.Write(" }\n") + file.Write(" %s(%s);\n" % + (func.GetGLFunctionName(), func.MakeOriginalArgString(""))) + + def WriteCmdSizeTest(self, func, file): + """Writes the size test for a command.""" + file.Write(" EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT\n") + + def WriteFormatTest(self, func, file): + """Writes a format test for a command.""" + file.Write("TEST(GLES2FormatTest, %s) {\n" % func.name) + file.Write(" %s cmd = { 0, };\n" % func.name) + file.Write(" void* next_cmd = cmd.Set(\n") + file.Write(" &cmd") + args = func.GetCmdArgs() + value = 11 + for arg in args: + file.Write(",\n static_cast<%s>(%d)" % (arg.type, value)) + value += 1 + file.Write(");\n") + value = 11 + file.Write(" EXPECT_EQ(%s::kCmdId, cmd.header.command);\n" % func.name) + func.type_handler.WriteCmdSizeTest(func, file) + for arg in args: + file.Write(" EXPECT_EQ(static_cast<%s>(%d), cmd.%s);\n" % + (arg.type, value, arg.name)) + value += 1 + file.Write("}\n") + file.Write("\n") + + def WriteImmediateFormatTest(self, func, file): + """Writes a format test for an immediate version of a command.""" + file.Write("TEST(GLES2FormatTest, %s) {\n" % func.name) + file.Write(" int8 buf[256] = { 0, };\n") + file.Write(" %s& cmd = *static_cast<%s*>(static_cast<void*>(&buf));\n" % + (func.name, func.name)) + file.Write(" void* next_cmd = cmd.Set(\n") + file.Write(" &cmd") + args = func.GetCmdArgs() + value = 11 + for arg in args: + file.Write(",\n static_cast<%s>(%d)" % (arg.type, value)) + value += 1 + file.Write(");\n") + value = 11 + file.Write(" EXPECT_EQ(%s::kCmdId, cmd.header.command);\n" % func.name) + func.type_handler.WriteImmediateCmdSizeTest(func, file) + for arg in args: + file.Write(" EXPECT_EQ(static_cast<%s>(%d), cmd.%s);\n" % + (arg.type, value, arg.name)) + value += 1 + file.Write("}\n") + file.Write("\n") + + def WriteImmediateCmdSizeTest(self, func, file): + """Writes a size test for an immediate version of a command.""" + file.Write(" // TODO(gman): Compute correct size.\n") + file.Write(" EXPECT_EQ(sizeof(cmd), cmd.header.size * 4);\n") + + def WriteImmediateHandlerImplementation (self, func, file): + """Writes the handler impl for the immediate version of a command.""" + file.Write(" // Immediate version.\n") + file.Write(" parse_error::ParseError result =\n") + file.Write(" Validate%s(this, arg_count%s);\n" % + (func.name, func.MakeOriginalArgString("", True))) + file.Write(" if (result != parse_error::kParseNoError) {\n") + file.Write(" return result;\n") + file.Write(" }\n") + file.Write(" %s(%s);\n" % + (func.GetGLFunctionName(), func.MakeOriginalArgString(""))) + + def WriteServiceImplementation(self, func, file): + """Writes the service implementation for a command.""" + file.Write( + "parse_error::ParseError GLES2DecoderImpl::Handle%s(\n" % func.name) + file.Write( + " unsigned int arg_count, const gles2::%s& c) {\n" % func.name) + for arg in func.GetOriginalArgs(): + arg.WriteGetCode(file) + func.WriteHandlerImplementation(file) + file.Write(" return parse_error::kParseNoError;\n") + file.Write("}\n") + file.Write("\n") + + def WriteImmediateServiceImplementation(self, func, file): + """Writes the service implementation for an immediate version of command.""" + file.Write( + "parse_error::ParseError GLES2DecoderImpl::Handle%s(\n" % func.name) + file.Write( + " unsigned int arg_count, const gles2::%s& c) {\n" % func.name) + for arg in func.GetOriginalArgs(): + arg.WriteGetCode(file) + func.WriteHandlerImplementation(file) + file.Write(" return parse_error::kParseNoError;\n") + file.Write("}\n") + file.Write("\n") + + def WriteImmediateValidationCode(self, func, file): + """Writes the validation code for an immediate version of a command.""" + pass + + def WriteGLES2ImplementationHeader(self, func, file): + """Writes the GLES2 Implemention declaration.""" + if func.can_auto_generate: + file.Write("%s %s(%s) {\n" % + (func.return_type, func.original_name, + func.MakeTypedOriginalArgString(""))) + file.Write(" helper_->%s(%s);\n" % + (func.name, func.MakeOriginalArgString(""))) + file.Write("}\n") + file.Write("\n") + else: + file.Write("%s %s(%s);\n" % + (func.return_type, func.original_name, + func.MakeTypedOriginalArgString(""))) + file.Write("\n") + + def WriteGLES2ImplementationImpl(self, func, file): + """Writes the GLES2 Implemention definition.""" + if not func.can_auto_generate: + file.Write("%s GLES2Implementation::%s(%s) {\n" % + (func.return_type, func.original_name, + func.MakeTypedOriginalArgString(""))) + if not func.return_type == "void": + file.Write(" return 0;\n") + file.Write("}\n") + file.Write("\n") + + def WriteImmediateCmdComputeSize(self, func, file): + """Writes the size computation code for the immediate version of a cmd.""" + file.Write(" static uint32 ComputeSize(uint32 size_in_bytes) {\n") + file.Write(" return static_cast<uint32>(\n") + file.Write(" sizeof(ValueType) + // NOLINT\n") + file.Write(" RoundSizeToMultipleOfEntries(size_in_bytes));\n") + file.Write(" }\n") + file.Write("\n") + + def WriteImmediateCmdSetHeader(self, func, file): + """Writes the SetHeader function for the immediate version of a cmd.""" + file.Write(" void SetHeader(uint32 size_in_bytes) {\n") + file.Write(" header.SetCmdByTotalSize<ValueType>(size_in_bytes);\n") + file.Write(" }\n") + file.Write("\n") + + def WriteImmediateCmdInit(self, func, file): + """Writes the Init function for the immediate version of a command.""" + file.Write(" void Init(%s) {\n" % func.MakeTypedCmdArgString("_")) + file.Write(" SetHeader(0); // TODO(gman): pass in correct size\n") + args = func.GetCmdArgs() + for arg in args: + file.Write(" %s = _%s;\n" % (arg.name, arg.name)) + file.Write(" }\n") + file.Write("\n") + + def WriteImmediateCmdSet(self, func, file): + """Writes the Set function for the immediate version of a command.""" + copy_args = func.MakeCmdArgString("_", False) + file.Write(" void* Set(void* cmd%s) {\n" % + func.MakeTypedCmdArgString("_", True)) + file.Write(" // TODO(gman): compute correct size.\n") + file.Write(" const uint32 size = ComputeSize(0);\n") + file.Write(" static_cast<ValueType*>(cmd)->Init(%s);\n" % copy_args) + file.Write(" return NextImmediateCmdAddressTotalSize<ValueType>(" + "cmd, size);\n") + file.Write(" }\n") + file.Write("\n") + + def WriteImmediateCmdHelper(self, func, file): + """Writes the cmd helper definition for the immediate version of a cmd.""" + args = func.MakeCmdArgString("") + file.Write(" void %s(%s) {\n" % + (func.name, func.MakeTypedCmdArgString(""))) + file.Write(" const uint32 s = 0; // TODO(gman): compute correct size\n") + file.Write(" gles2::%s& c = " + "GetImmediateCmdSpaceTotalSize<gles2::%s>(s);\n" % + (func.name, func.name)) + file.Write(" c.Init(%s);\n" % args) + file.Write(" }\n\n") + + +class CustomHandler(TypeHandler): + """Handler for commands that are auto-generated but require minor tweaks.""" + + def __init__(self): + TypeHandler.__init__(self) + + def WriteServiceImplementation(self, func, file): + """Overrriden from TypeHandler.""" + pass + + def WriteImmediateCmdGetTotalSize(self, func, file): + """Overrriden from TypeHandler.""" + file.Write(" uint32 total_size = 0; // TODO(gman): get correct size.") + + def WriteImmediateCmdInit(self, func, file): + """Overrriden from TypeHandler.""" + file.Write(" void Init(%s) {\n" % func.MakeTypedCmdArgString("_")) + self.WriteImmediateCmdGetTotalSize(func, file) + file.Write(" SetHeader(total_size);\n") + args = func.GetCmdArgs() + for arg in args: + file.Write(" %s = _%s;\n" % (arg.name, arg.name)) + file.Write(" }\n") + file.Write("\n") + + def WriteImmediateCmdSet(self, func, file): + """Overrriden from TypeHandler.""" + copy_args = func.MakeCmdArgString("_", False) + file.Write(" void* Set(void* cmd%s) {\n" % + func.MakeTypedCmdArgString("_", True)) + self.WriteImmediateCmdGetTotalSize(func, file) + file.Write(" static_cast<ValueType*>(cmd)->Init(%s);\n" % copy_args) + file.Write(" return NextImmediateCmdAddressTotalSize<ValueType>(" + "cmd, total_size);\n") + file.Write(" }\n") + file.Write("\n") + + +class TodoHandler(CustomHandler): + """Handle for commands that are not yet implemented.""" + + def WriteImmediateFormatTest(self, func, file): + """Overrriden from TypeHandler.""" + pass + + +class ManualHandler(CustomHandler): + """Handler for commands that must be written by hand.""" + + def __init__(self): + CustomHandler.__init__(self) + + def WriteServiceImplementation(self, func, file): + """Overrriden from TypeHandler.""" + pass + + def WriteImmediateServiceImplementation(self, func, file): + """Overrriden from TypeHandler.""" + pass + + def WriteImmediateFormatTest(self, func, file): + """Overrriden from TypeHandler.""" + file.Write("// TODO(gman): Implement test for %s\n" % func.name) + + def WriteGLES2ImplementationHeader(self, func, file): + """Overrriden from TypeHandler.""" + file.Write("%s %s(%s);\n" % + (func.return_type, func.original_name, + func.MakeTypedOriginalArgString(""))) + file.Write("\n") + + def WriteGLES2ImplementationImpl(self, func, file): + """Overrriden from TypeHandler.""" + pass + + def WriteImmediateCmdGetTotalSize(self, func, file): + """Overrriden from TypeHandler.""" + # TODO(gman): Move this data to _FUNCTION_INFO? + if func.name == 'ShaderSourceImmediate': + file.Write(" uint32 total_size = ComputeSize(_data_size);\n") + else: + CustomHandler.WriteImmediateCmdGetTotalSize(self, func, file) + + +class DataHandler(CustomHandler): + """Handler for glBufferData, glBufferSubData, glTexImage2D, glTexSubImage2D, + glCompressedTexImage2D, glCompressedTexImageSub2D.""" + def __init__(self): + CustomHandler.__init__(self) + + def WriteServiceImplementation(self, func, file): + """Overrriden from TypeHandler.""" + file.Write( + "parse_error::ParseError GLES2DecoderImpl::Handle%s(\n" % func.name) + file.Write( + " unsigned int arg_count, const gles2::%s& c) {\n" % func.name) + for arg in func.GetCmdArgs(): + arg.WriteGetCode(file) + + # TODO(gman): Move this data to _FUNCTION_INFO? + if func.name == 'BufferData': + file.Write(" uint32 data_size = size;\n") + elif func.name == 'BufferSubData': + file.Write(" uint32 data_size = size;\n") + elif func.name == 'CompressedTexImage2D': + file.Write(" uint32 data_size = imageSize;\n") + elif func.name == 'CompressedTexSubImage2D': + file.Write(" uint32 data_size = imageSize;\n") + elif func.name == 'TexImage2D': + file.Write(" uint32 pixels_size = GLES2Util::ComputeImageDataSize(\n") + file.Write(" width, height, format, type, unpack_alignment_);\n") + elif func.name == 'TexSubImage2D': + file.Write(" uint32 pixels_size = GLES2Util::ComputeImageDataSize(\n") + file.Write(" width, height, format, type, unpack_alignment_);\n") + else: + file.Write(" uint32 data_size = 0; // TODO(gman): get correct size!\n") + + for arg in func.GetOriginalArgs(): + arg.WriteGetAddress(file) + func.WriteHandlerImplementation(file) + file.Write(" return parse_error::kParseNoError;\n") + file.Write("}\n") + file.Write("\n") + + def WriteImmediateCmdGetTotalSize(self, func, file): + """Overrriden from TypeHandler.""" + # TODO(gman): Move this data to _FUNCTION_INFO? + if func.name == 'BufferDataImmediate': + file.Write(" uint32 total_size = ComputeSize(_size);\n") + elif func.name == 'BufferSubDataImmediate': + file.Write(" uint32 total_size = ComputeSize(_size);\n") + elif func.name == 'CompressedTexImage2DImmediate': + file.Write(" uint32 total_size = ComputeSize(_imageSize);\n") + elif func.name == 'CompressedTexSubImage2DImmediate': + file.Write(" uint32 total_size = ComputeSize(_imageSize);\n") + elif func.name == 'TexImage2DImmediate': + file.Write( + " uint32 total_size = 0; // TODO(gman): get correct size\n") + elif func.name == 'TexSubImage2DImmediate': + file.Write( + " uint32 total_size = 0; // TODO(gman): get correct size\n") + + def WriteImmediateCmdSizeTest(self, func, file): + """Overrriden from TypeHandler.""" + # TODO(gman): Move this data to _FUNCTION_INFO? + if func.name == 'BufferDataImmediate': + file.Write(" uint32 total_size = cmd.ComputeSize(cmd.size);\n") + elif func.name == 'BufferSubDataImmediate': + file.Write(" uint32 total_size = cmd.ComputeSize(cmd.size);\n") + elif func.name == 'CompressedTexImage2DImmediate': + file.Write(" uint32 total_size = cmd.ComputeSize(cmd.imageSize);\n") + elif func.name == 'CompressedTexSubImage2DImmediate': + file.Write(" uint32 total_size = cmd.ComputeSize(cmd.imageSize);\n") + elif func.name == 'TexImage2DImmediate': + file.Write( + " uint32 total_size = 0; // TODO(gman): get correct size\n") + elif func.name == 'TexSubImage2DImmediate': + file.Write( + " uint32 total_size = 0; // TODO(gman): get correct size\n") + file.Write(" EXPECT_EQ(sizeof(cmd), total_size);\n") + + def WriteImmediateFormatTest(self, func, file): + """Overrriden from TypeHandler.""" + # TODO(gman): Remove this exception. + file.Write("// TODO(gman): Implement test for %s\n" % func.name) + return + + def WriteGLES2ImplementationImpl(self, func, file): + """Overrriden from TypeHandler.""" + pass + + +class GENnHandler(TypeHandler): + """Handler for glGen___ type functions.""" + + def __init__(self): + TypeHandler.__init__(self) + + def InitFunction(self, func): + """Overrriden from TypeHandler.""" + pass + + def WriteHandlerImplementation (self, func, file): + """Overrriden from TypeHandler.""" + file.Write(" parse_error::ParseError result =\n") + file.Write(" Validate%s(this, arg_count%s);\n" % + (func.name, func.MakeOriginalArgString("", True))) + file.Write(" if (result != parse_error::kParseNoError) {\n") + file.Write(" return result;\n") + file.Write(" }\n") + file.Write(" GenGLObjects<GL%sHelper>(n, %s);\n" % + (func.name, func.GetLastOriginalArg().name)) + + def WriteImmediateHandlerImplementation(self, func, file): + """Overrriden from TypeHandler.""" + file.Write(" parse_error::ParseError result =\n") + file.Write(" Validate%s(this, arg_count%s);\n" % + (func.name, func.MakeOriginalArgString("", True))) + file.Write(" if (result != parse_error::kParseNoError) {\n") + file.Write(" return result;\n") + file.Write(" }\n") + file.Write(" GenGLObjects<GL%sHelper>(n, %s);\n" % + (func.original_name, func.GetLastOriginalArg().name)) + + def WriteGLES2ImplementationHeader(self, func, file): + """Overrriden from TypeHandler.""" + file.Write("%s %s(%s) {\n" % + (func.return_type, func.original_name, + func.MakeTypedOriginalArgString(""))) + file.Write(" MakeIds(%s);\n" % func.MakeOriginalArgString("")) + file.Write(" helper_->%sImmediate(%s);\n" % + (func.name, func.MakeOriginalArgString(""))) + file.Write("}\n") + file.Write("\n") + + def WriteGLES2ImplementationImpl(self, func, file): + """Overrriden from TypeHandler.""" + pass + + def WriteImmediateCmdComputeSize(self, func, file): + """Overrriden from TypeHandler.""" + file.Write(" static uint32 ComputeDataSize(GLsizei n) {\n") + file.Write( + " return static_cast<uint32>(sizeof(GLuint) * n); // NOLINT\n") + file.Write(" }\n") + file.Write("\n") + file.Write(" static uint32 ComputeSize(GLsizei n) {\n") + file.Write(" return static_cast<uint32>(\n") + file.Write(" sizeof(ValueType) + ComputeDataSize(n)); // NOLINT\n") + file.Write(" }\n") + file.Write("\n") + + def WriteImmediateCmdSetHeader(self, func, file): + """Overrriden from TypeHandler.""" + file.Write(" void SetHeader(GLsizei n) {\n") + file.Write(" header.SetCmdByTotalSize<ValueType>(ComputeSize(n));\n") + file.Write(" }\n") + file.Write("\n") + + def WriteImmediateCmdInit(self, func, file): + """Overrriden from TypeHandler.""" + last_arg = func.GetLastOriginalArg() + file.Write(" void Init(%s, %s _%s) {\n" % + (func.MakeTypedCmdArgString("_"), + last_arg.type, last_arg.name)) + file.Write(" SetHeader(_n);\n") + args = func.GetCmdArgs() + for arg in args: + file.Write(" %s = _%s;\n" % (arg.name, arg.name)) + file.Write(" memcpy(ImmediateDataAddress(this),\n") + file.Write(" _%s, ComputeDataSize(_n));\n" % last_arg.name) + file.Write(" }\n") + file.Write("\n") + + def WriteImmediateCmdSet(self, func, file): + """Overrriden from TypeHandler.""" + last_arg = func.GetLastOriginalArg() + copy_args = func.MakeCmdArgString("_", False) + file.Write(" void* Set(void* cmd%s, %s _%s) {\n" % + (func.MakeTypedCmdArgString("_", True), + last_arg.type, last_arg.name)) + file.Write(" static_cast<ValueType*>(cmd)->Init(%s, _%s);\n" % + (copy_args, last_arg.name)) + file.Write(" const uint32 size = ComputeSize(_n);\n") + file.Write(" return NextImmediateCmdAddressTotalSize<ValueType>(" + "cmd, size);\n") + file.Write(" }\n") + file.Write("\n") + + def WriteImmediateCmdHelper(self, func, file): + """Overrriden from TypeHandler.""" + args = func.MakeOriginalArgString("") + file.Write(" void %s(%s) {\n" % + (func.name, func.MakeTypedOriginalArgString(""))) + file.Write(" const uint32 size = gles2::%s::ComputeSize(n);\n" % + func.name) + file.Write(" gles2::%s& c = " + "GetImmediateCmdSpaceTotalSize<gles2::%s>(size);\n" % + (func.name, func.name)) + file.Write(" c.Init(%s);\n" % args) + file.Write(" }\n\n") + + def WriteImmediateFormatTest(self, func, file): + """Overrriden from TypeHandler.""" + file.Write("TEST(GLES2FormatTest, %s) {\n" % func.name) + file.Write(" static GLuint ids[] = { 12, 23, 34, };\n") + file.Write(" int8 buf[256] = { 0, };\n") + file.Write(" %s& cmd = *static_cast<%s*>(static_cast<void*>(&buf));\n" % + (func.name, func.name)) + file.Write(" void* next_cmd = cmd.Set(\n") + file.Write(" &cmd") + args = func.GetCmdArgs() + value = 11 + for arg in args: + file.Write(",\n static_cast<%s>(%d)" % (arg.type, value)) + value += 1 + file.Write(",\n ids);\n") + args = func.GetCmdArgs() + value = 11 + file.Write(" EXPECT_EQ(%s::kCmdId, cmd.header.command);\n" % func.name) + file.Write(" EXPECT_EQ(sizeof(cmd) +\n") + file.Write(" RoundSizeToMultipleOfEntries(cmd.n * 4),\n") + file.Write(" cmd.header.size * 4); // NOLINT\n") + for arg in args: + file.Write(" EXPECT_EQ(static_cast<%s>(%d), cmd.%s);\n" % + (arg.type, value, arg.name)) + value += 1 + file.Write(" // TODO(gman): Check that ids were inserted;\n") + file.Write("}\n") + file.Write("\n") + + +class CreateHandler(TypeHandler): + """Handler for glCreate___ type functions.""" + + def __init__(self): + TypeHandler.__init__(self) + + def InitFunction(self, func): + """Overrriden from TypeHandler.""" + func.AddCmdArg(CmdArg("client_id", 'uint32')) + + def WriteHandlerImplementation (self, func, file): + """Overrriden from TypeHandler.""" + file.Write(" uint32 client_id = c.client_id;\n") + file.Write(" parse_error::ParseError result =\n") + file.Write(" Validate%s(this, arg_count%s);\n" % + (func.name, func.MakeOriginalArgString("", True))) + file.Write(" if (result != parse_error::kParseNoError) {\n") + file.Write(" return result;\n") + file.Write(" }\n") + file.Write(" %sHelper(%s);\n" % + (func.name, func.MakeCmdArgString(""))) + + def WriteGLES2ImplementationHeader(self, func, file): + """Overrriden from TypeHandler.""" + file.Write("%s %s(%s) {\n" % + (func.return_type, func.original_name, + func.MakeTypedOriginalArgString(""))) + file.Write(" GLuint client_id;\n") + file.Write(" MakeIds(1, &client_id);\n") + file.Write(" helper_->%s(%s);\n" % + (func.name, func.MakeCmdArgString(""))) + file.Write(" return client_id;\n") + file.Write("}\n") + file.Write("\n") + + def WriteGLES2ImplementationImpl(self, func, file): + """Overrriden from TypeHandler.""" + pass + + +class DELnHandler(TypeHandler): + """Handler for glDelete___ type functions.""" + + def __init__(self): + TypeHandler.__init__(self) + + def WriteHandlerImplementation (self, func, file): + """Overrriden from TypeHandler.""" + file.Write(" parse_error::ParseError result =\n") + file.Write(" Validate%s(this, arg_count%s);\n" % + (func.name, func.MakeOriginalArgString("", True))) + file.Write(" if (result != parse_error::kParseNoError) {\n") + file.Write(" return result;\n") + file.Write(" }\n") + file.Write(" DeleteGLObjects<GL%sHelper>(n, %s);\n" % + (func.name, func.GetLastOriginalArg().name)) + + def WriteImmediateHandlerImplementation (self, func, file): + """Overrriden from TypeHandler.""" + file.Write(" parse_error::ParseError result =\n") + file.Write(" Validate%s(this, arg_count%s);\n" % + (func.name, func.MakeOriginalArgString("", True))) + file.Write(" if (result != parse_error::kParseNoError) {\n") + file.Write(" return result;\n") + file.Write(" }\n") + file.Write(" DeleteGLObjects<GL%sHelper>(n, %s);\n" % + (func.original_name, func.GetLastOriginalArg().name)) + + def WriteGLES2ImplementationHeader(self, func, file): + """Overrriden from TypeHandler.""" + file.Write("%s %s(%s) {\n" % + (func.return_type, func.original_name, + func.MakeTypedOriginalArgString(""))) + file.Write(" FreeIds(%s);\n" % func.MakeOriginalArgString("")) + file.Write(" helper_->%sImmediate(%s);\n" % + (func.name, func.MakeOriginalArgString(""))) + file.Write("}\n") + file.Write("\n") + + def WriteGLES2ImplementationImpl(self, func, file): + """Overrriden from TypeHandler.""" + pass + + def WriteImmediateCmdComputeSize(self, func, file): + """Overrriden from TypeHandler.""" + file.Write(" static uint32 ComputeDataSize(GLsizei n) {\n") + file.Write( + " return static_cast<uint32>(sizeof(GLuint) * n); // NOLINT\n") + file.Write(" }\n") + file.Write("\n") + file.Write(" static uint32 ComputeSize(GLsizei n) {\n") + file.Write(" return static_cast<uint32>(\n") + file.Write(" sizeof(ValueType) + ComputeDataSize(n)); // NOLINT\n") + file.Write(" }\n") + file.Write("\n") + + def WriteImmediateCmdSetHeader(self, func, file): + """Overrriden from TypeHandler.""" + file.Write(" void SetHeader(GLsizei n) {\n") + file.Write(" header.SetCmdByTotalSize<ValueType>(ComputeSize(n));\n") + file.Write(" }\n") + file.Write("\n") + + def WriteImmediateCmdInit(self, func, file): + """Overrriden from TypeHandler.""" + last_arg = func.GetLastOriginalArg() + file.Write(" void Init(%s, %s _%s) {\n" % + (func.MakeTypedCmdArgString("_"), + last_arg.type, last_arg.name)) + file.Write(" SetHeader(_n);\n") + args = func.GetCmdArgs() + for arg in args: + file.Write(" %s = _%s;\n" % (arg.name, arg.name)) + file.Write(" memcpy(ImmediateDataAddress(this),\n") + file.Write(" _%s, ComputeDataSize(_n));\n" % last_arg.name) + file.Write(" }\n") + file.Write("\n") + + def WriteImmediateCmdSet(self, func, file): + """Overrriden from TypeHandler.""" + last_arg = func.GetLastOriginalArg() + copy_args = func.MakeCmdArgString("_", False) + file.Write(" void* Set(void* cmd%s, %s _%s) {\n" % + (func.MakeTypedCmdArgString("_", True), + last_arg.type, last_arg.name)) + file.Write(" static_cast<ValueType*>(cmd)->Init(%s, _%s);\n" % + (copy_args, last_arg.name)) + file.Write(" const uint32 size = ComputeSize(_n);\n") + file.Write(" return NextImmediateCmdAddressTotalSize<ValueType>(" + "cmd, size);\n") + file.Write(" }\n") + file.Write("\n") + + def WriteImmediateCmdHelper(self, func, file): + """Overrriden from TypeHandler.""" + args = func.MakeOriginalArgString("") + file.Write(" void %s(%s) {\n" % + (func.name, func.MakeTypedOriginalArgString(""))) + file.Write(" const uint32 size = gles2::%s::ComputeSize(n);\n" % + func.name) + file.Write(" gles2::%s& c = " + "GetImmediateCmdSpaceTotalSize<gles2::%s>(size);\n" % + (func.name, func.name)) + file.Write(" c.Init(%s);\n" % args) + file.Write(" }\n\n") + + def WriteImmediateFormatTest(self, func, file): + """Overrriden from TypeHandler.""" + file.Write("TEST(GLES2FormatTest, %s) {\n" % func.name) + file.Write(" static GLuint ids[] = { 12, 23, 34, };\n") + file.Write(" int8 buf[256] = { 0, };\n") + file.Write(" %s& cmd = *static_cast<%s*>(static_cast<void*>(&buf));\n" % + (func.name, func.name)) + file.Write(" void* next_cmd = cmd.Set(\n") + file.Write(" &cmd") + args = func.GetCmdArgs() + value = 11 + for arg in args: + file.Write(",\n static_cast<%s>(%d)" % (arg.type, value)) + value += 1 + file.Write(",\n ids);\n") + args = func.GetCmdArgs() + value = 11 + file.Write(" EXPECT_EQ(%s::kCmdId, cmd.header.command);\n" % func.name) + file.Write(" EXPECT_EQ(sizeof(cmd) +\n") + file.Write(" RoundSizeToMultipleOfEntries(cmd.n * 4),\n") + file.Write(" cmd.header.size * 4); // NOLINT\n") + for arg in args: + file.Write(" EXPECT_EQ(static_cast<%s>(%d), cmd.%s);\n" % + (arg.type, value, arg.name)) + value += 1 + file.Write(" // TODO(gman): Check that ids were inserted;\n") + file.Write("}\n") + file.Write("\n") + + +class GETnHandler(TypeHandler): + """Handler for GETn for glGetBooleanv, glGetFloatv, ... type functions.""" + + def __init__(self): + TypeHandler.__init__(self) + + def AddImmediateFunction(self, generator, func): + """Overrriden from TypeHandler.""" + pass + + def WriteServiceImplementation(self, func, file): + """Overrriden from TypeHandler.""" + file.Write( + "parse_error::ParseError GLES2DecoderImpl::Handle%s(\n" % func.name) + file.Write( + " unsigned int arg_count, const gles2::%s& c) {\n" % func.name) + last_arg = func.GetLastOriginalArg() + + all_but_last_args = func.GetOriginalArgs()[:-1] + for arg in all_but_last_args: + arg.WriteGetCode(file) + + file.Write(" %s params;\n" % last_arg.type) + file.Write(" GLsizei num_values = util_.GLGetNumValuesReturned(pname);\n") + file.Write(" uint32 params_size = num_values * sizeof(*params);\n") + file.Write(" params = GetSharedMemoryAs<%s>(\n" % last_arg.type) + file.Write(" c.params_shm_id, c.params_shm_offset, params_size);\n") + func.WriteHandlerImplementation(file) + file.Write(" return parse_error::kParseNoError;\n") + file.Write("}\n") + file.Write("\n") + + def WriteGLES2ImplementationHeader(self, func, file): + """Overrriden from TypeHandler.""" + file.Write("%s %s(%s) {\n" % + (func.return_type, func.original_name, + func.MakeTypedOriginalArgString(""))) + all_but_last_args = func.GetOriginalArgs()[:-1] + arg_string = ( + ", ".join(["%s" % arg.name for arg in all_but_last_args])) + file.Write(" helper_->%s(%s, shared_memory_.GetId(), 0);\n" % + (func.name, arg_string)) + file.Write(" int32 token = helper_->InsertToken();\n") + file.Write(" helper_->WaitForToken(token);\n") + file.Write(" GLsizei num_values = util_.GLGetNumValuesReturned(pname);\n") + file.Write(" memcpy(params, shared_memory_.GetAddress(0),\n") + file.Write(" num_values * sizeof(*params));\n") + file.Write("}\n") + file.Write("\n") + + def WriteGLES2ImplementationImpl(self, func, file): + """Overrriden from TypeHandler.""" + pass + + +class PUTHandler(TypeHandler): + """Handler for glTexParameter_v, glVertexAttrib_v functions.""" + + def __init__(self): + TypeHandler.__init__(self) + + def WriteImmediateValidationCode(self, func, file): + """Overrriden from TypeHandler.""" + file.Write(" if (!CheckImmediateDataSize<%s>(" + "arg_count, 1, sizeof(%s), %d)) {\n" % + (func.name, func.info.data_type, func.info.count)) + file.Write(" return parse_error::kParseOutOfBounds;\n") + file.Write(" }\n") + + def WriteGLES2ImplementationHeader(self, func, file): + """Overrriden from TypeHandler.""" + file.Write("%s %s(%s) {\n" % + (func.return_type, func.original_name, + func.MakeTypedOriginalArgString(""))) + file.Write(" helper_->%sImmediate(%s);\n" % + (func.name, func.MakeOriginalArgString(""))) + file.Write("}\n") + file.Write("\n") + + def WriteGLES2ImplementationImpl(self, func, file): + """Overrriden from TypeHandler.""" + pass + + def WriteImmediateCmdComputeSize(self, func, file): + """Overrriden from TypeHandler.""" + file.Write(" static uint32 ComputeDataSize() {\n") + file.Write(" return static_cast<uint32>(\n") + file.Write(" sizeof(%s) * %d); // NOLINT\n" % + (func.info.data_type, func.info.count)) + file.Write(" }\n") + file.Write("\n") + file.Write(" static uint32 ComputeSize() {\n") + file.Write(" return static_cast<uint32>(\n") + file.Write( + " sizeof(ValueType) + ComputeDataSize()); // NOLINT\n") + file.Write(" }\n") + file.Write("\n") + + def WriteImmediateCmdSetHeader(self, func, file): + """Overrriden from TypeHandler.""" + file.Write(" void SetHeader() {\n") + file.Write( + " header.SetCmdByTotalSize<ValueType>(ComputeSize());\n") + file.Write(" }\n") + file.Write("\n") + + def WriteImmediateCmdInit(self, func, file): + """Overrriden from TypeHandler.""" + last_arg = func.GetLastOriginalArg() + file.Write(" void Init(%s, %s _%s) {\n" % + (func.MakeTypedCmdArgString("_"), + last_arg.type, last_arg.name)) + file.Write(" SetHeader();\n") + args = func.GetCmdArgs() + for arg in args: + file.Write(" %s = _%s;\n" % (arg.name, arg.name)) + file.Write(" memcpy(ImmediateDataAddress(this),\n") + file.Write(" _%s, ComputeDataSize());\n" % last_arg.name) + file.Write(" }\n") + file.Write("\n") + + def WriteImmediateCmdSet(self, func, file): + """Overrriden from TypeHandler.""" + last_arg = func.GetLastOriginalArg() + copy_args = func.MakeCmdArgString("_", False) + file.Write(" void* Set(void* cmd%s, %s _%s) {\n" % + (func.MakeTypedCmdArgString("_", True), + last_arg.type, last_arg.name)) + file.Write(" static_cast<ValueType*>(cmd)->Init(%s, _%s);\n" % + (copy_args, last_arg.name)) + file.Write(" const uint32 size = ComputeSize();\n") + file.Write(" return NextImmediateCmdAddressTotalSize<ValueType>(" + "cmd, size);\n") + file.Write(" }\n") + file.Write("\n") + + def WriteImmediateCmdHelper(self, func, file): + """Overrriden from TypeHandler.""" + args = func.MakeOriginalArgString("") + file.Write(" void %s(%s) {\n" % + (func.name, func.MakeTypedOriginalArgString(""))) + file.Write(" const uint32 size = gles2::%s::ComputeSize();\n" % + func.name) + file.Write(" gles2::%s& c = " + "GetImmediateCmdSpaceTotalSize<gles2::%s>(size);\n" % + (func.name, func.name)) + file.Write(" c.Init(%s);\n" % args) + file.Write(" }\n\n") + + def WriteImmediateFormatTest(self, func, file): + """Overrriden from TypeHandler.""" + file.Write("TEST(GLES2FormatTest, %s) {\n" % func.name) + file.Write(" const int kSomeBaseValueToTestWith = 51;\n") + file.Write(" static %s data[] = {\n" % func.info.data_type) + for v in range(0, func.info.count): + file.Write(" static_cast<%s>(kSomeBaseValueToTestWith + %d),\n" % + (func.info.data_type, v)) + file.Write(" };\n") + file.Write(" int8 buf[256] = { 0, };\n") + file.Write(" %s& cmd = *static_cast<%s*>(static_cast<void*>(&buf));\n" % + (func.name, func.name)) + file.Write(" void* next_cmd = cmd.Set(\n") + file.Write(" &cmd") + args = func.GetCmdArgs() + value = 11 + for arg in args: + file.Write(",\n static_cast<%s>(%d)" % (arg.type, value)) + value += 1 + file.Write(",\n data);\n") + args = func.GetCmdArgs() + value = 11 + file.Write(" EXPECT_EQ(%s::kCmdId, cmd.header.command);\n" % func.name) + file.Write(" EXPECT_EQ(sizeof(cmd) +\n") + file.Write(" RoundSizeToMultipleOfEntries(sizeof(data)),\n") + file.Write(" cmd.header.size * 4); // NOLINT\n") + for arg in args: + file.Write(" EXPECT_EQ(static_cast<%s>(%d), cmd.%s);\n" % + (arg.type, value, arg.name)) + value += 1 + file.Write(" // TODO(gman): Check that data was inserted;\n") + file.Write("}\n") + file.Write("\n") + + +class PUTnHandler(TypeHandler): + """Handler for PUTn 'glUniform__v' type functions.""" + + def __init__(self): + TypeHandler.__init__(self) + + def WriteImmediateValidationCode(self, func, file): + """Overrriden from TypeHandler.""" + file.Write(" if (!CheckImmediateDataSize<%s>(" + "arg_count, count, sizeof(%s), %d)) {\n" % + (func.name, func.info.data_type, func.info.count)) + file.Write(" return parse_error::kParseOutOfBounds;\n") + file.Write(" }\n") + + def WriteGLES2ImplementationHeader(self, func, file): + """Overrriden from TypeHandler.""" + file.Write("%s %s(%s) {\n" % + (func.return_type, func.original_name, + func.MakeTypedOriginalArgString(""))) + file.Write(" helper_->%sImmediate(%s);\n" % + (func.name, func.MakeOriginalArgString(""))) + file.Write("}\n") + file.Write("\n") + + def WriteGLES2ImplementationImpl(self, func, file): + """Overrriden from TypeHandler.""" + pass + + def WriteImmediateCmdComputeSize(self, func, file): + """Overrriden from TypeHandler.""" + file.Write(" static uint32 ComputeDataSize(GLsizei count) {\n") + file.Write(" return static_cast<uint32>(\n") + file.Write(" sizeof(%s) * %d * count); // NOLINT\n" % + (func.info.data_type, func.info.count)) + file.Write(" }\n") + file.Write("\n") + file.Write(" static uint32 ComputeSize(GLsizei count) {\n") + file.Write(" return static_cast<uint32>(\n") + file.Write( + " sizeof(ValueType) + ComputeDataSize(count)); // NOLINT\n") + file.Write(" }\n") + file.Write("\n") + + def WriteImmediateCmdSetHeader(self, func, file): + """Overrriden from TypeHandler.""" + file.Write(" void SetHeader(GLsizei count) {\n") + file.Write( + " header.SetCmdByTotalSize<ValueType>(ComputeSize(count));\n") + file.Write(" }\n") + file.Write("\n") + + def WriteImmediateCmdInit(self, func, file): + """Overrriden from TypeHandler.""" + last_arg = func.GetLastOriginalArg() + file.Write(" void Init(%s, %s _%s) {\n" % + (func.MakeTypedCmdArgString("_"), + last_arg.type, last_arg.name)) + file.Write(" SetHeader(_count);\n") + args = func.GetCmdArgs() + for arg in args: + file.Write(" %s = _%s;\n" % (arg.name, arg.name)) + file.Write(" memcpy(ImmediateDataAddress(this),\n") + file.Write(" _%s, ComputeDataSize(_count));\n" % last_arg.name) + file.Write(" }\n") + file.Write("\n") + + def WriteImmediateCmdSet(self, func, file): + """Overrriden from TypeHandler.""" + last_arg = func.GetLastOriginalArg() + copy_args = func.MakeCmdArgString("_", False) + file.Write(" void* Set(void* cmd%s, %s _%s) {\n" % + (func.MakeTypedCmdArgString("_", True), + last_arg.type, last_arg.name)) + file.Write(" static_cast<ValueType*>(cmd)->Init(%s, _%s);\n" % + (copy_args, last_arg.name)) + file.Write(" const uint32 size = ComputeSize(_count);\n") + file.Write(" return NextImmediateCmdAddressTotalSize<ValueType>(" + "cmd, size);\n") + file.Write(" }\n") + file.Write("\n") + + def WriteImmediateCmdHelper(self, func, file): + """Overrriden from TypeHandler.""" + args = func.MakeOriginalArgString("") + file.Write(" void %s(%s) {\n" % + (func.name, func.MakeTypedOriginalArgString(""))) + file.Write(" const uint32 size = gles2::%s::ComputeSize(count);\n" % + func.name) + file.Write(" gles2::%s& c = " + "GetImmediateCmdSpaceTotalSize<gles2::%s>(size);\n" % + (func.name, func.name)) + file.Write(" c.Init(%s);\n" % args) + file.Write(" }\n\n") + + def WriteImmediateFormatTest(self, func, file): + """Overrriden from TypeHandler.""" + file.Write("TEST(GLES2FormatTest, %s) {\n" % func.name) + file.Write(" const int kSomeBaseValueToTestWith = 51;\n") + file.Write(" static %s data[] = {\n" % func.info.data_type) + for v in range(0, func.info.count * 2): + file.Write(" static_cast<%s>(kSomeBaseValueToTestWith + %d),\n" % + (func.info.data_type, v)) + file.Write(" };\n") + file.Write(" int8 buf[256] = { 0, };\n") + file.Write(" %s& cmd = *static_cast<%s*>(static_cast<void*>(&buf));\n" % + (func.name, func.name)) + file.Write(" void* next_cmd = cmd.Set(\n") + file.Write(" &cmd") + args = func.GetCmdArgs() + value = 1 + for arg in args: + file.Write(",\n static_cast<%s>(%d)" % (arg.type, value)) + value += 1 + file.Write(",\n data);\n") + args = func.GetCmdArgs() + value = 1 + file.Write(" EXPECT_EQ(%s::kCmdId, cmd.header.command);\n" % func.name) + file.Write(" EXPECT_EQ(sizeof(cmd) +\n") + file.Write(" RoundSizeToMultipleOfEntries(sizeof(data)),\n") + file.Write(" cmd.header.size * 4); // NOLINT\n") + for arg in args: + file.Write(" EXPECT_EQ(static_cast<%s>(%d), cmd.%s);\n" % + (arg.type, value, arg.name)) + value += 1 + file.Write(" // TODO(gman): Check that data was inserted;\n") + file.Write("}\n") + file.Write("\n") + + +class GLcharHandler(TypeHandler): + """Handler for functions that pass a single string .""" + + def __init__(self): + TypeHandler.__init__(self) + + def InitFunction(self, func): + """Overrriden from TypeHandler.""" + func.AddCmdArg(CmdArg('data_size', 'uint32')) + + def WriteServiceImplementation(self, func, file): + """Overrriden from TypeHandler.""" + file.Write( + "parse_error::ParseError GLES2DecoderImpl::Handle%s(\n" % func.name) + file.Write( + " unsigned int arg_count, const gles2::%s& c) {\n" % func.name) + last_arg = func.GetLastOriginalArg() + + all_but_last_arg = func.GetOriginalArgs()[:-1] + for arg in all_but_last_arg: + arg.WriteGetCode(file) + + file.Write(" uint32 name_size = c.data_size;\n") + file.Write(" const char* name = GetSharedMemoryAs<%s>(\n" % + last_arg.type) + file.Write(" c.%s_shm_id, c.%s_shm_offset, name_size);\n" % + (last_arg.name, last_arg.name)) + file.Write(" parse_error::ParseError result =\n") + file.Write(" Validate%s(this, arg_count%s);\n" % + (func.name, func.MakeOriginalArgString("", True))) + file.Write(" if (result != parse_error::kParseNoError) {\n") + file.Write(" return result;\n") + file.Write(" }\n") + arg_string = ", ".join(["%s" % arg.name for arg in all_but_last_arg]) + file.Write(" String name_str(name, name_size);\n") + file.Write(" %s(%s, name_str.c_str());\n" % + (func.GetGLFunctionName(), arg_string)) + file.Write(" return parse_error::kParseNoError;\n") + file.Write("}\n") + file.Write("\n") + + def WriteImmediateServiceImplementation(self, func, file): + """Overrriden from TypeHandler.""" + file.Write( + "parse_error::ParseError GLES2DecoderImpl::Handle%s(\n" % func.name) + file.Write( + " unsigned int arg_count, const gles2::%s& c) {\n" % func.name) + last_arg = func.GetLastOriginalArg() + + all_but_last_arg = func.GetOriginalArgs()[:-1] + for arg in all_but_last_arg: + arg.WriteGetCode(file) + + file.Write(" uint32 name_size = c.data_size;\n") + file.Write( + " const char* name = GetImmediateDataAs<const char*>(c);\n") + file.Write(" // TODO(gman): Make sure validate checks arg_count\n") + file.Write(" // covers data_size.\n") + file.Write(" parse_error::ParseError result =\n") + file.Write(" Validate%s(this, arg_count%s);\n" % + (func.name, func.MakeOriginalArgString("", True))) + file.Write(" if (result != parse_error::kParseNoError) {\n") + file.Write(" return result;\n") + file.Write(" }\n") + arg_string = ", ".join(["%s" % arg.name for arg in all_but_last_arg]) + file.Write(" String name_str(name, name_size);\n") + file.Write(" %s(%s, name_str.c_str());\n" % + (func.GetGLFunctionName(), arg_string)) + file.Write(" return parse_error::kParseNoError;\n") + file.Write("}\n") + file.Write("\n") + + def WriteGLES2ImplementationHeader(self, func, file): + """Overrriden from TypeHandler.""" + file.Write("%s %s(%s) {\n" % + (func.return_type, func.original_name, + func.MakeTypedOriginalArgString(""))) + file.Write(" // TODO(gman): This needs to change to use SendString.\n") + file.Write(" helper_->%sImmediate(%s);\n" % + (func.name, func.MakeOriginalArgString(""))) + file.Write("}\n") + file.Write("\n") + + def WriteGLES2ImplementationImpl(self, func, file): + """Overrriden from TypeHandler.""" + pass + + def WriteImmediateCmdComputeSize(self, func, file): + """Overrriden from TypeHandler.""" + file.Write(" static uint32 ComputeDataSize(const char* s) {\n") + file.Write(" return strlen(s);\n") + file.Write(" }\n") + file.Write("\n") + file.Write(" static uint32 ComputeSize(const char* s) {\n") + file.Write(" return static_cast<uint32>(\n") + file.Write(" sizeof(ValueType) + ComputeDataSize(s)); // NOLINT\n") + file.Write(" }\n") + file.Write("\n") + + def WriteImmediateCmdSetHeader(self, func, file): + """Overrriden from TypeHandler.""" + file.Write(" void SetHeader(const char* s) {\n") + file.Write(" header.SetCmdByTotalSize<ValueType>(ComputeSize(s));\n") + file.Write(" }\n") + file.Write("\n") + + def WriteImmediateCmdInit(self, func, file): + """Overrriden from TypeHandler.""" + last_arg = func.GetLastOriginalArg() + file.Write(" void Init(%s) {\n" % func.MakeTypedOriginalArgString("_")) + file.Write(" SetHeader(_%s);\n" % last_arg.name) + args = func.GetCmdArgs()[:-1] + for arg in args: + file.Write(" %s = _%s;\n" % (arg.name, arg.name)) + file.Write(" data_size = strlen(_%s);\n" % last_arg.name) + file.Write(" memcpy(ImmediateDataAddress(this), _%s, data_size);\n" % + last_arg.name) + file.Write(" }\n") + file.Write("\n") + + def WriteImmediateCmdSet(self, func, file): + """Overrriden from TypeHandler.""" + last_arg = func.GetLastOriginalArg() + file.Write(" void* Set(void* cmd%s) {\n" % + func.MakeTypedOriginalArgString("_", True)) + file.Write(" static_cast<ValueType*>(cmd)->Init(%s);\n" % + func.MakeOriginalArgString("_")) + file.Write(" const uint32 size = ComputeSize(_%s);\n" % last_arg.name) + file.Write(" return NextImmediateCmdAddressTotalSize<ValueType>(" + "cmd, size);\n") + file.Write(" }\n") + file.Write("\n") + + def WriteImmediateCmdHelper(self, func, file): + """Overrriden from TypeHandler.""" + args = func.MakeOriginalArgString("") + last_arg = func.GetLastOriginalArg() + file.Write(" void %s(%s) {\n" % + (func.name, func.MakeTypedOriginalArgString(""))) + file.Write(" const uint32 size = gles2::%s::ComputeSize(%s);\n" % + (func.name, last_arg.name)) + file.Write(" gles2::%s& c = GetImmediateCmdSpaceTotalSize<gles2::%s>(" + "size);\n" % + (func.name, func.name)) + file.Write(" c.Init(%s);\n" % args) + file.Write(" }\n\n") + + def WriteImmediateFormatTest(self, func, file): + """Overrriden from TypeHandler.""" + file.Write("TEST(GLES2FormatTest, %s) {\n" % func.name) + file.Write(" int8 buf[256] = { 0, };\n") + file.Write(" %s& cmd = *static_cast<%s*>(static_cast<void*>(&buf));\n" % + (func.name, func.name)) + file.Write(" static const char* const test_str = \"test string\";\n") + file.Write(" void* next_cmd = cmd.Set(\n") + file.Write(" &cmd") + all_but_last_arg = func.GetCmdArgs()[:-1] + value = 11 + for arg in all_but_last_arg: + file.Write(",\n static_cast<%s>(%d)" % (arg.type, value)) + value += 1 + file.Write(",\n test_str);\n") + value = 11 + file.Write(" EXPECT_EQ(%s::kCmdId, cmd.header.command);\n" % func.name) + file.Write(" EXPECT_EQ(sizeof(cmd) + // NOLINT\n") + file.Write(" RoundSizeToMultipleOfEntries(strlen(test_str)),\n") + file.Write(" cmd.header.size * 4);\n") + for arg in all_but_last_arg: + file.Write(" EXPECT_EQ(static_cast<%s>(%d), cmd.%s);\n" % + (arg.type, value, arg.name)) + value += 1 + file.Write(" // TODO(gman): check that string got copied.\n") + file.Write("}\n") + file.Write("\n") + +class GetGLcharHandler(GLcharHandler): + """Handler for glGetAttibLoc, glGetUniformLoc.""" + + def __init__(self): + GLcharHandler.__init__(self) + + def WriteServiceImplementation(self, func, file): + """Overrriden from TypeHandler.""" + file.Write( + "parse_error::ParseError GLES2DecoderImpl::Handle%s(\n" % func.name) + file.Write( + " unsigned int arg_count, const gles2::%s& c) {\n" % func.name) + last_arg = func.GetLastOriginalArg() + + all_but_last_arg = func.GetOriginalArgs()[:-1] + for arg in all_but_last_arg: + arg.WriteGetCode(file) + + file.Write(" uint32 name_size = c.data_size;\n") + file.Write(" const char* name = GetSharedMemoryAs<%s>(\n" % + last_arg.type) + file.Write(" c.%s_shm_id, c.%s_shm_offset, name_size);\n" % + (last_arg.name, last_arg.name)) + file.Write(" parse_error::ParseError result =\n") + file.Write(" Validate%s(this, arg_count%s);\n" % + (func.name, func.MakeOriginalArgString("", True))) + file.Write(" if (result != parse_error::kParseNoError) {\n") + file.Write(" return result;\n") + file.Write(" }\n") + arg_string = ", ".join(["%s" % arg.name for arg in all_but_last_arg]) + file.Write(" String name_str(name, name_size);\n") + file.Write(" GLint location = %s(%s, name_str.c_str());\n" % + (func.GetGLFunctionName(), arg_string)) + file.Write(" DCHECK(false); // TODO: return result.\n") + file.Write(" return parse_error::kParseNoError;\n") + file.Write("}\n") + file.Write("\n") + + def WriteImmediateServiceImplementation(self, func, file): + """Overrriden from TypeHandler.""" + file.Write( + "parse_error::ParseError GLES2DecoderImpl::Handle%s(\n" % func.name) + file.Write( + " unsigned int arg_count, const gles2::%s& c) {\n" % func.name) + last_arg = func.GetLastOriginalArg() + + all_but_last_arg = func.GetOriginalArgs()[:-1] + for arg in all_but_last_arg: + arg.WriteGetCode(file) + + file.Write(" uint32 name_size = c.data_size;\n") + file.Write( + " const char* name = GetImmediateDataAs<const char*>(c);\n") + file.Write(" // TODO(gman): Make sure validate checks arg_count\n") + file.Write(" // covers data_size.\n") + file.Write(" parse_error::ParseError result =\n") + file.Write(" Validate%s(this, arg_count%s);\n" % + (func.name, func.MakeOriginalArgString("", True))) + file.Write(" if (result != parse_error::kParseNoError) {\n") + file.Write(" return result;\n") + file.Write(" }\n") + arg_string = ", ".join(["%s" % arg.name for arg in all_but_last_arg]) + file.Write(" String name_str(name, name_size);\n") + file.Write(" GLint location = %s(%s, name_str.c_str());\n" % + (func.GetGLFunctionName(), arg_string)) + file.Write(" DCHECK(false); // TODO: return result.\n") + file.Write(" return parse_error::kParseNoError;\n") + file.Write("}\n") + file.Write("\n") + + def WriteGLES2ImplementationHeader(self, func, file): + """Overrriden from TypeHandler.""" + file.Write("%s %s(%s) {\n" % + (func.return_type, func.original_name, + func.MakeTypedOriginalArgString(""))) + file.Write(" // TODO(gman): This needs to change to use SendString.\n") + file.Write(" GLint* result = shared_memory_.GetAddressAs<GLint*>(0);\n") + file.Write(" DCHECK(false); // pass in shared memory\n") + file.Write(" helper_->%sImmediate(%s);\n" % + (func.name, func.MakeOriginalArgString(""))) + file.Write(" int32 token = helper_->InsertToken();\n") + file.Write(" helper_->WaitForToken(token);\n") + file.Write(" return *result;\n") + file.Write("}\n") + file.Write("\n") + + def WriteGLES2ImplementationImpl(self, func, file): + """Overrriden from TypeHandler.""" + pass + + def WriteImmediateCmdComputeSize(self, func, file): + """Overrriden from TypeHandler.""" + file.Write(" static uint32 ComputeDataSize(const char* s) {\n") + file.Write(" return strlen(s);\n") + file.Write(" }\n") + file.Write("\n") + file.Write(" static uint32 ComputeSize(const char* s) {\n") + file.Write(" return static_cast<uint32>(\n") + file.Write(" sizeof(ValueType) + ComputeDataSize(s)); // NOLINT\n") + file.Write(" }\n") + file.Write("\n") + + def WriteImmediateCmdSetHeader(self, func, file): + """Overrriden from TypeHandler.""" + file.Write(" void SetHeader(const char* s) {\n") + file.Write(" header.SetCmdByTotalSize<ValueType>(ComputeSize(s));\n") + file.Write(" }\n") + file.Write("\n") + + def WriteImmediateCmdInit(self, func, file): + """Overrriden from TypeHandler.""" + last_arg = func.GetLastOriginalArg() + file.Write(" void Init(%s) {\n" % func.MakeTypedOriginalArgString("_")) + file.Write(" SetHeader(_%s);\n" % last_arg.name) + args = func.GetCmdArgs()[:-1] + for arg in args: + file.Write(" %s = _%s;\n" % (arg.name, arg.name)) + file.Write(" data_size = strlen(_%s);\n" % last_arg.name) + file.Write(" memcpy(ImmediateDataAddress(this), _%s, data_size);\n" % + last_arg.name) + file.Write(" }\n") + file.Write("\n") + + def WriteImmediateCmdSet(self, func, file): + """Overrriden from TypeHandler.""" + last_arg = func.GetLastOriginalArg() + file.Write(" void* Set(void* cmd%s) {\n" % + func.MakeTypedOriginalArgString("_", True)) + file.Write(" static_cast<ValueType*>(cmd)->Init(%s);\n" % + func.MakeOriginalArgString("_")) + file.Write(" const uint32 size = ComputeSize(_%s);\n" % last_arg.name) + file.Write(" return NextImmediateCmdAddressTotalSize<ValueType>(" + "cmd, size);\n") + file.Write(" }\n") + file.Write("\n") + + def WriteImmediateCmdHelper(self, func, file): + """Overrriden from TypeHandler.""" + args = func.MakeOriginalArgString("") + last_arg = func.GetLastOriginalArg() + file.Write(" void %s(%s) {\n" % + (func.name, func.MakeTypedOriginalArgString(""))) + file.Write(" const uint32 size = gles2::%s::ComputeSize(%s);\n" % + (func.name, last_arg.name)) + file.Write(" gles2::%s& c = GetImmediateCmdSpaceTotalSize<gles2::%s>(" + "size);\n" % + (func.name, func.name)) + file.Write(" c.Init(%s);\n" % args) + file.Write(" }\n\n") + + def WriteImmediateFormatTest(self, func, file): + """Overrriden from TypeHandler.""" + file.Write("TEST(GLES2FormatTest, %s) {\n" % func.name) + file.Write(" int8 buf[256] = { 0, };\n") + file.Write(" %s& cmd = *static_cast<%s*>(static_cast<void*>(&buf));\n" % + (func.name, func.name)) + file.Write(" static const char* const test_str = \"test string\";\n") + file.Write(" void* next_cmd = cmd.Set(\n") + file.Write(" &cmd") + all_but_last_arg = func.GetCmdArgs()[:-1] + value = 11 + for arg in all_but_last_arg: + file.Write(",\n static_cast<%s>(%d)" % (arg.type, value)) + value += 1 + file.Write(",\n test_str);\n") + value = 11 + file.Write(" EXPECT_EQ(%s::kCmdId, cmd.header.command);\n" % func.name) + file.Write(" EXPECT_EQ(sizeof(cmd) + // NOLINT\n") + file.Write(" RoundSizeToMultipleOfEntries(strlen(test_str)),\n") + file.Write(" cmd.header.size * 4);\n") + for arg in all_but_last_arg: + file.Write(" EXPECT_EQ(static_cast<%s>(%d), cmd.%s);\n" % + (arg.type, value, arg.name)) + value += 1 + file.Write(" // TODO(gman): check that string got copied.\n") + file.Write("}\n") + file.Write("\n") + + +class IsHandler(TypeHandler): + """Handler for glIs____ type and glGetError functions.""" + + def __init__(self): + TypeHandler.__init__(self) + + def InitFunction(self, func): + """Overrriden from TypeHandler.""" + func.AddCmdArg(CmdArg("result_shm_id", 'uint32')) + func.AddCmdArg(CmdArg("result_shm_offset", 'uint32')) + + def WriteServiceImplementation(self, func, file): + """Overrriden from TypeHandler.""" + file.Write( + "parse_error::ParseError GLES2DecoderImpl::Handle%s(\n" % func.name) + file.Write( + " unsigned int arg_count, const gles2::%s& c) {\n" % func.name) + args = func.GetOriginalArgs() + for arg in args: + arg.WriteGetCode(file) + + file.Write(" %s* result_dst = GetSharedMemoryAs<%s*>(\n" % + (func.return_type, func.return_type)) + file.Write( + " c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));\n") + file.Write(" parse_error::ParseError result =\n") + file.Write(" Validate%s(this, arg_count%s);\n" % + (func.name, func.MakeOriginalArgString("", True))) + file.Write(" if (result != parse_error::kParseNoError) {\n") + file.Write(" return result;\n") + file.Write(" }\n") + file.Write(" *result_dst = %s(%s);\n" % + (func.GetGLFunctionName(), func.MakeOriginalArgString(""))) + file.Write(" return parse_error::kParseNoError;\n") + file.Write("}\n") + file.Write("\n") + + def WriteGLES2ImplementationHeader(self, func, file): + """Overrriden from TypeHandler.""" + file.Write("%s %s(%s) {\n" % + (func.return_type, func.original_name, + func.MakeTypedOriginalArgString(""))) + arg_string = func.MakeOriginalArgString("") + comma = "" + if len(arg_string) > 0: + comma = ", " + file.Write(" helper_->%s(%s%sshared_memory_.GetId(), 0);\n" % + (func.name, arg_string, comma)) + file.Write(" int32 token = helper_->InsertToken();\n") + file.Write(" helper_->WaitForToken(token);\n") + file.Write(" return *shared_memory_.GetAddressAs<%s*>(0);\n" % + func.return_type) + file.Write("}\n") + file.Write("\n") + + def WriteGLES2ImplementationImpl(self, func, file): + """Overrriden from TypeHandler.""" + pass + + +class STRnHandler(TypeHandler): + """Handler for GetProgramInfoLog, GetShaderInfoLog and GetShaderSource.""" + + def __init__(self): + TypeHandler.__init__(self) + + def WriteGLES2ImplementationHeader(self, func, file): + """Overrriden from TypeHandler.""" + file.Write("// TODO(gman): Implement this\n") + TypeHandler.WriteGLES2ImplementationHeader(self, func, file) + + +class FunctionInfo(object): + """Holds info about a function.""" + + def __init__(self, info, type_handler): + for key in info: + setattr(self, key, info[key]) + self.type_handler = type_handler + if not 'type' in info: + self.type = '' + + +class CmdArg(object): + """A class used to represent arguments at the command buffer level.""" + cmd_type_map_ = { + 'GLfloat': 'float', + 'GLclampf': 'float', + } + + def __init__(self, name, type): + self.name = name + self.type = type + + if type in self.cmd_type_map_: + self.cmd_type = self.cmd_type_map_[type] + else: + self.cmd_type = 'uint32' + + def WriteGetCode(self, file): + file.Write(" %s %s = static_cast<%s>(c.%s);\n" % + (self.type, self.name, self.type, self.name)) + + +class Argument(object): + """A class that represents a function argument.""" + + def __init__(self, name, type): + self.name = name + self.type = type + + def AddCmdArgs(self, args): + """Adds command arguments for this argument to the given list.""" + return args.append(CmdArg(self.name, self.type)) + + def WriteGetCode(self, file): + """Writes the code to get an argument from a command structure.""" + file.Write(" %s %s = static_cast<%s>(c.%s);\n" % + (self.type, self.name, self.type, self.name)) + + def WriteValidationCode(self, file): + """Writes the validation code for an argument.""" + pass + + def WriteGetAddress(self, file): + """Writes the code to get the address this argument refers to.""" + pass + + def GetImmediateVersion(self): + """Gets the immediate version of this argument.""" + return self + + +class ImmediatePointerArgument(Argument): + """A class that represents an immediate argument to a function. + + An immediate argument is one where the data follows the command. + """ + + def __init__(self, name, type): + Argument.__init__(self, name, type) + + def AddCmdArgs(self, args): + """Overridden from Argument.""" + pass + + def WriteGetCode(self, file): + """Overridden from Argument.""" + file.Write( + " %s %s = GetImmediateDataAs<%s>(c);\n" % + (self.type, self.name, self.type)) + + def WriteValidationCode(self, file): + """Overridden from Argument.""" + file.Write(" if (%s == NULL) {\n" % self.name) + file.Write(" return parse_error::kParseOutOfBounds;\n") + file.Write(" }\n") + + def GetImmediateVersion(self): + """Overridden from Argument.""" + return None + + +class PointerArgument(Argument): + """A class that represents a pointer argument to a function.""" + + def __init__(self, name, type): + Argument.__init__(self, name, type) + + def AddCmdArgs(self, args): + """Overridden from Argument.""" + args.append(CmdArg("%s_shm_id" % self.name, 'uint32')) + args.append(CmdArg("%s_shm_offset" % self.name, 'uint32')) + + def WriteGetCode(self, file): + """Overridden from Argument.""" + file.Write( + " %s %s = GetSharedMemoryAs<%s>(\n" % + (self.type, self.name, self.type)) + file.Write( + " c.%s_shm_id, c.%s_shm_offset, 0 /* TODO(gman): size */);\n" % + (self.name, self.name)) + + def WriteGetAddress(self, file): + """Overridden from Argument.""" + file.Write( + " %s %s = GetSharedMemoryAs<%s>(\n" % + (self.type, self.name, self.type)) + file.Write( + " %s_shm_id, %s_shm_offset, %s_size);\n" % + (self.name, self.name, self.name)) + + def WriteValidationCode(self, file): + """Overridden from Argument.""" + file.Write(" if (%s == NULL) {\n" % self.name) + file.Write(" return parse_error::kParseOutOfBounds;\n") + file.Write(" }\n") + + def GetImmediateVersion(self): + """Overridden from Argument.""" + return ImmediatePointerArgument(self.name, self.type) + + +class ResourceIdArgument(Argument): + """A class that represents a resource id argument to a function.""" + + def __init__(self, name, type): + type = type.replace("GLResourceId", "GLuint") + Argument.__init__(self, name, type) + + def WriteGetCode(self, file): + """Overridden from Argument.""" + file.Write(" %s %s;\n" % (self.type, self.name)) + file.Write(" if (!id_map_.GetServiceId(c.%s, &%s)) {\n" % + (self.name, self.name)) + file.Write(" SetGLError(GL_INVALID_VALUE);\n") + file.Write(" return parse_error::kParseNoError;\n") + file.Write(" }\n") + + +class Function(object): + """A class that represents a function.""" + + def __init__(self, name, info, return_type, original_args, args_for_cmds, + cmd_args, num_pointer_args): + self.name = name + self.original_name = name + self.info = info + self.type_handler = info.type_handler + self.return_type = return_type + self.original_args = original_args + self.num_pointer_args = num_pointer_args + self.can_auto_generate = num_pointer_args == 0 and return_type == "void" + self.cmd_args = cmd_args + self.args_for_cmds = args_for_cmds + self.type_handler.InitFunction(self) + + def IsType(self, type_name): + """Returns true if function is a certain type.""" + return self.info.type == type_name + + def GetInfo(self, name): + """Returns a value from the function info for this function.""" + if hasattr(self.info, name): + return getattr(self.info, name) + return None + + def GetGLFunctionName(self): + """Gets the function to call to execute GL for this command.""" + if self.GetInfo('DecoderFunc'): + return self.GetInfo('DecoderFunc') + return "gl%s" % self.original_name + + def AddCmdArg(self, arg): + """Adds a cmd argument to this function.""" + self.cmd_args.append(arg) + + def GetCmdArgs(self): + """Gets the command args for this function.""" + return self.cmd_args + + def GetOriginalArgs(self): + """Gets the original arguments to this function.""" + return self.original_args + + def GetLastOriginalArg(self): + """Gets the last original argument to this function.""" + return self.original_args[len(self.original_args) - 1] + + def __GetArgList(self, arg_string, add_comma): + """Adds a comma if arg_string is not empty and add_comma is true.""" + comma = "" + if add_comma and len(arg_string): + comma = ", " + return "%s%s" % (comma, arg_string) + + def MakeTypedOriginalArgString(self, prefix, add_comma = False): + """Gets a list of arguments as they arg in GL.""" + args = self.GetOriginalArgs() + arg_string = ", ".join( + ["%s %s%s" % (arg.type, prefix, arg.name) for arg in args]) + return self.__GetArgList(arg_string, add_comma) + + def MakeOriginalArgString(self, prefix, add_comma = False): + """Gets the list of arguments as they are in GL.""" + args = self.GetOriginalArgs() + arg_string = ", ".join( + ["%s%s" % (prefix, arg.name) for arg in args]) + return self.__GetArgList(arg_string, add_comma) + + def MakeTypedCmdArgString(self, prefix, add_comma = False): + """Gets a typed list of arguments as they need to be for command buffers.""" + args = self.GetCmdArgs() + arg_string = ", ".join( + ["%s %s%s" % (arg.type, prefix, arg.name) for arg in args]) + return self.__GetArgList(arg_string, add_comma) + + def MakeCmdArgString(self, prefix, add_comma = False): + """Gets the list of arguments as they need to be for command buffers.""" + args = self.GetCmdArgs() + arg_string = ", ".join( + ["%s%s" % (prefix, arg.name) for arg in args]) + return self.__GetArgList(arg_string, add_comma) + + def WriteHandlerImplementation(self, file): + """Writes the handler implementation for this command.""" + self.type_handler.WriteHandlerImplementation(self, file) + + def WriteValidationCode(self, file): + """Writes the validation code for a command.""" + pass + + def WriteCmdArgFlag(self, file): + """Writes the cmd kArgFlags constant.""" + file.Write(" static const cmd::ArgFlags kArgFlags = cmd::kFixed;\n") + + def WriteCmdComputeSize(self, file): + """Writes the ComputeSize function for the command.""" + file.Write(" static uint32 ComputeSize() {\n") + file.Write( + " return static_cast<uint32>(sizeof(ValueType)); // NOLINT\n") + file.Write(" }\n") + file.Write("\n") + + def WriteCmdSetHeader(self, file): + """Writes the cmd's SetHeader function.""" + file.Write(" void SetHeader() {\n") + file.Write(" header.SetCmd<ValueType>();\n") + file.Write(" }\n") + file.Write("\n") + + def WriteCmdInit(self, file): + """Writes the cmd's Init function.""" + file.Write(" void Init(%s) {\n" % self.MakeTypedCmdArgString("_")) + file.Write(" SetHeader();\n") + args = self.GetCmdArgs() + for arg in args: + file.Write(" %s = _%s;\n" % (arg.name, arg.name)) + file.Write(" }\n") + file.Write("\n") + + def WriteCmdSet(self, file): + """Writes the cmd's Set function.""" + copy_args = self.MakeCmdArgString("_", False) + file.Write(" void* Set(void* cmd%s) {\n" % + self.MakeTypedCmdArgString("_", True)) + file.Write(" static_cast<ValueType*>(cmd)->Init(%s);\n" % copy_args) + file.Write(" return NextCmdAddress<ValueType>(cmd);\n") + file.Write(" }\n") + file.Write("\n") + + def WriteStruct(self, file): + """Writes a structure that matched the arguments to the function.""" + file.Write("struct %s {\n" % self.name) + file.Write(" typedef %s ValueType;\n" % self.name) + file.Write(" static const CommandId kCmdId = k%s;\n" % self.name) + self.WriteCmdArgFlag(file) + file.Write("\n") + + self.WriteCmdComputeSize(file) + self.WriteCmdSetHeader(file) + self.WriteCmdInit(file) + self.WriteCmdSet(file) + + file.Write(" command_buffer::CommandHeader header;\n") + args = self.GetCmdArgs() + for arg in args: + file.Write(" %s %s;\n" % (arg.cmd_type, arg.name)) + file.Write("};\n") + file.Write("\n") + + size = len(args) * _SIZE_OF_UINT32 + _SIZE_OF_COMMAND_HEADER + file.Write("COMPILE_ASSERT(sizeof(%s) == %d,\n" % (self.name, size)) + file.Write(" Sizeof_%s_is_not_%d);\n" % (self.name, size)) + file.Write("COMPILE_ASSERT(offsetof(%s, header) == 0,\n" % self.name) + file.Write(" OffsetOf_%s_header_not_0);\n" % self.name) + offset = _SIZE_OF_COMMAND_HEADER + for arg in args: + file.Write("COMPILE_ASSERT(offsetof(%s, %s) == %d,\n" % + (self.name, arg.name, offset)) + file.Write(" OffsetOf_%s_%s_not_%d);\n" % + (self.name, arg.name, offset)) + offset += _SIZE_OF_UINT32 + file.Write("\n") + + def WriteCmdHelper(self, file): + """Writes the cmd's helper.""" + args = self.MakeCmdArgString("") + file.Write(" void %s(%s) {\n" % + (self.name, self.MakeTypedCmdArgString(""))) + file.Write(" gles2::%s& c = GetCmdSpace<gles2::%s>();\n" % + (self.name, self.name)) + file.Write(" c.Init(%s);\n" % args) + file.Write(" }\n\n") + + def WriteServiceImplementation(self, file): + """Writes the service implementation for a command.""" + self.type_handler.WriteServiceImplementation(self, file) + + def WriteGLES2ImplementationHeader(self, file): + """Writes the GLES2 Implemention declaration.""" + self.type_handler.WriteGLES2ImplementationHeader(self, file) + + def WriteGLES2ImplementationImpl(self, file): + """Writes the GLES2 Implemention definition.""" + self.type_handler.WriteGLES2ImplementationImpl(self, file) + + def WriteFormatTest(self, file): + """Writes the cmd's format test.""" + self.type_handler.WriteFormatTest(self, file) + + +class ImmediateFunction(Function): + """A class that represnets an immediate function command.""" + + def __init__(self, func): + new_args = [] + for arg in func.GetOriginalArgs(): + new_arg = arg.GetImmediateVersion() + if new_arg: + new_args.append(new_arg) + + cmd_args = [] + new_args_for_cmds = [] + for arg in func.args_for_cmds: + new_arg = arg.GetImmediateVersion() + if new_arg: + new_args_for_cmds.append(new_arg) + new_arg.AddCmdArgs(cmd_args) + + Function.__init__( + self, + "%sImmediate" % func.name, + func.info, + func.return_type, + new_args, + new_args_for_cmds, + cmd_args, + 0) + self.original_name = func.name + + def WriteServiceImplementation(self, file): + """Overridden from Function""" + self.type_handler.WriteImmediateServiceImplementation(self, file) + + def WriteHandlerImplementation(self, file): + """Overridden from Function""" + self.type_handler.WriteImmediateHandlerImplementation(self, file) + + def WriteValidationCode(self, file): + """Overridden from Function""" + self.type_handler.WriteImmediateValidationCode(self, file) + + def WriteCmdArgFlag(self, file): + """Overridden from Function""" + file.Write(" static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;\n") + + def WriteCmdComputeSize(self, file): + """Overridden from Function""" + self.type_handler.WriteImmediateCmdComputeSize(self, file) + + def WriteCmdSetHeader(self, file): + """Overridden from Function""" + self.type_handler.WriteImmediateCmdSetHeader(self, file) + + def WriteCmdInit(self, file): + """Overridden from Function""" + self.type_handler.WriteImmediateCmdInit(self, file) + + def WriteCmdSet(self, file): + """Overridden from Function""" + self.type_handler.WriteImmediateCmdSet(self, file) + + def WriteCmdHelper(self, file): + """Overridden from Function""" + self.type_handler.WriteImmediateCmdHelper(self, file) + + def WriteFormatTest(self, file): + """Overridden from Function""" + self.type_handler.WriteImmediateFormatTest(self, file) + + +class GLGenerator(object): + """A class to generate GL command buffers.""" + + _function_re = re.compile(r'GL_APICALL(.*?)GL_APIENTRY (.*?) \((.*?)\);') + _non_alnum_re = re.compile(r'[^a-zA-Z0-9]') + + def __init__(self, verbose): + self.original_functions = [] + self.functions = [] + self.verbose = verbose + self._function_info = {} + self._empty_type_handler = TypeHandler() + self._empty_function_info = FunctionInfo({}, self._empty_type_handler) + + self._type_handlers = { + 'Create': CreateHandler(), + 'Custom': CustomHandler(), + 'Data': DataHandler(), + 'DELn': DELnHandler(), + 'GENn': GENnHandler(), + 'GETn': GETnHandler(), + 'GetGLchar': GetGLcharHandler(), + 'GLchar': GLcharHandler(), + 'Is': IsHandler(), + 'Manual': ManualHandler(), + 'PUT': PUTHandler(), + 'PUTn': PUTnHandler(), + 'STRn': STRnHandler(), + 'Todo': TodoHandler(), + } + + for func_name in _FUNCTION_INFO: + info = _FUNCTION_INFO[func_name] + type = '' + if 'type' in info: + type = info['type'] + self._function_info[func_name] = FunctionInfo(info, + self.GetTypeHandler(type)) + + def AddFunction(self, func): + """Adds a function.""" + self.functions.append(func) + + def GetTypeHandler(self, name): + """Gets a type info for the given type.""" + if name in self._type_handlers: + return self._type_handlers[name] + return self._empty_type_handler + + def GetFunctionInfo(self, name): + """Gets a type info for the given function name.""" + if name in self._function_info: + return self._function_info[name] + return self._empty_function_info + + def Log(self, msg): + """Prints something if verbose is true.""" + if self.verbose: + print msg + + def WriteHeader(self, file): + """Writes header to file""" + file.Write( + "// This file is auto-generated. DO NOT EDIT!\n" + "\n") + + def WriteLicense(self, file): + """Writes the license.""" + file.Write(_LICENSE) + + def WriteNamespaceOpen(self, file): + """Writes the code for the namespace.""" + file.Write("namespace command_buffer {\n") + file.Write("namespace gles2 {\n") + file.Write("\n") + + def WriteNamespaceClose(self, file): + """Writes the code to close the namespace.""" + file.Write("} // namespace gles2\n") + file.Write("} // namespace command_buffer\n") + file.Write("\n") + + def MakeGuard(self, filename): + """Creates a header guard id.""" + base = os.path.dirname(os.path.dirname(os.path.dirname( + os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))) + hpath = os.path.abspath(filename)[len(base) + 1:] + return self._non_alnum_re.sub('_', hpath).upper() + + def ParseArgs(self, arg_string): + """Parses a function arg string.""" + args = [] + num_pointer_args = 0 + parts = arg_string.split(',') + for arg in parts: + arg_parts = arg.split() + if len(arg_parts) == 1 and arg_parts[0] == 'void': + pass + # Is this a pointer argument? + elif arg.find('*') >= 0: + num_pointer_args += 1 + args.append(PointerArgument( + arg_parts[-1], + " ".join(arg_parts[0:-1]))) + # Is this a resource argument? Must come after pointer check. + elif arg_parts[0] == 'GLResourceId': + args.append(ResourceIdArgument( + arg_parts[-1], + " ".join(arg_parts[0:-1]))) + else: + args.append(Argument( + arg_parts[-1], + " ".join(arg_parts[0:-1]))) + return (args, num_pointer_args) + + def ParseGLH(self, filename): + """Parses the GL2.h file and extracts the functions""" + for line in _GL_FUNCTIONS.splitlines(): + match = self._function_re.match(line) + if match: + func_name = match.group(2)[2:] + func_info = self.GetFunctionInfo(func_name) + if func_info.type != 'Noop': + return_type = match.group(1).strip() + arg_string = match.group(3) + (args, num_pointer_args) = self.ParseArgs(arg_string) + args_for_cmds = args + if hasattr(func_info, 'cmd_args'): + (args_for_cmds, num_pointer_args) = ( + self.ParseArgs(getattr(func_info, 'cmd_args'))) + cmd_args = [] + for arg in args_for_cmds: + arg.AddCmdArgs(cmd_args) + f = Function(func_name, func_info, return_type, args, args_for_cmds, + cmd_args, num_pointer_args) + self.original_functions.append(f) + self.AddFunction(f) + f.type_handler.AddImmediateFunction(self, f) + + self.Log("Auto Generated Functions : %d" % + len([f for f in self.functions if f.can_auto_generate or + (not f.IsType('') and not f.IsType('Custom') and + not f.IsType('Todo'))])) + + funcs = [f for f in self.functions if not f.can_auto_generate and + (f.IsType('') or f.IsType('Custom') or f.IsType('Todo'))] + self.Log("Non Auto Generated Functions: %d" % len(funcs)) + + for f in funcs: + self.Log(" %-10s %-20s gl%s" % (f.info.type, f.return_type, f.name)) + + def WriteCommandIds(self, filename): + """Writes the command buffer format""" + file = CWriter(filename) + self.WriteHeader(file) + file.Write("#define GLES2_COMMAND_LIST(OP) \\\n") + command_id = _FIRST_SPECIFIC_COMMAND_ID + for func in self.functions: + file.Write(" %-60s /* %d */ \\\n" % ("OP(%s)" % func.name, command_id)) + command_id += 1 + file.Write("\n") + + file.Write("enum CommandId {\n") + file.Write(" kStartPoint = cmd::kLastCommonId, " + "// All GLES2 commands start after this.\n") + file.Write("#define GLES2_CMD_OP(name) k ## name,\n") + file.Write(" GLES2_COMMAND_LIST(GLES2_CMD_OP)\n") + file.Write("#undef GLES2_CMD_OP\n") + file.Write(" kNumCommands\n") + file.Write("};\n") + file.Write("\n") + file.Close() + + def WriteFormat(self, filename): + """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() + + def WriteFormatTest(self, filename): + """Writes the command buffer format test.""" + file = CWriter(filename) + self.WriteHeader(file) + file.Write("// This file contains unit tests for gles2 commmands\n") + file.Write("// It is included by gles2_cmd_format_test.cc\n") + file.Write("\n") + + for func in self.functions: + func.WriteFormatTest(file) + + file.Close() + + def WriteCommandIdTest(self, filename): + """Writes the command id test.""" + file = CWriter(filename) + self.WriteLicense(file) + file.Write("// This file contains unit tests for gles2 commmand ids\n") + file.Write("\n") + file.Write("#include \"tests/common/win/testing_common.h\"\n") + file.Write("#include \"gpu/command_buffer/common/gles2_cmd_format.h\"\n") + file.Write("\n") + + self.WriteNamespaceOpen(file) + + file.Write("// *** These IDs MUST NOT CHANGE!!! ***\n") + file.Write("// Changing them will break all client programs.\n") + file.Write("TEST(GLES2CommandIdTest, CommandIdsMatch) {\n") + command_id = 1024 + for func in self.functions: + file.Write(" COMPILE_ASSERT(%s::kCmdId == %d,\n" % + (func.name, command_id)) + file.Write(" GLES2_%s_kCmdId_mismatch);\n" % func.name) + command_id += 1 + + file.Write("}\n") + + self.WriteNamespaceClose(file) + + file.Close() + + def WriteCmdHelperHeader(self, filename): + """Writes the gles2 command helper.""" + file = CWriter(filename) + + for func in self.functions: + func.WriteCmdHelper(file) + + file.Close() + + def WriteServiceImplementation(self, filename): + """Writes the service decorder implementation.""" + file = CWriter(filename) + self.WriteHeader(file) + file.Write("// It is included by gles2_cmd_decoder.cc\n") + file.Write("\n") + + for func in self.functions: + func.WriteServiceImplementation(file) + + file.Close() + + def WriteServiceValidation(self, filename): + file = CWriter(filename) + self.WriteLicense(file) + file.Write("\n") + self.WriteNamespaceOpen(file) + file.Write("namespace {\n") + file.Write("\n") + for func in self.functions: + file.Write("parse_error::ParseError Validate%s(\n" % func.name) + file.Write(" GLES2Decoder* decoder, unsigned int arg_count%s) {\n" % + func.MakeTypedOriginalArgString("", True)) + for arg in func.GetOriginalArgs(): + arg.WriteValidationCode(file) + func.WriteValidationCode(file) + file.Write(" return parse_error::kParseNoError;\n") + file.Write("}\n") + file.Write("} // anonymous namespace\n") + self.WriteNamespaceClose(file) + file.Close() + + def WriteGLES2CLibImplementation(self, filename): + """Writes the GLES2 c lib implementation.""" + file = CWriter(filename) + self.WriteHeader(file) + file.Write("\n") + file.Write("// These functions emluate GLES2 over command buffers.\n") + file.Write("\n") + file.Write("\n") + + for func in self.original_functions: + file.Write("%s GLES2%s(%s) {\n" % + (func.return_type, func.name, + func.MakeTypedOriginalArgString(""))) + return_string = "return " + if func.return_type == "void": + return_string = "" + file.Write(" %sgles2::GetGLContext()->%s(%s);\n" % + (return_string, func.original_name, + func.MakeOriginalArgString(""))) + file.Write("}\n") + + file.Write("\n") + + file.Close() + + def WriteGLES2ImplementationHeader(self, filename): + """Writes the GLES2 helper header.""" + file = CWriter(filename) + self.WriteHeader(file) + file.Write( + "// This file is included by gles2_implementation.h to declare the\n") + file.Write("// GL api functions.\n") + for func in self.original_functions: + func.WriteGLES2ImplementationHeader(file) + file.Close() + + def WriteGLES2ImplementationImpl(self, filename): + """Writes the gles2 helper implementation.""" + file = CWriter(filename) + self.WriteLicense(file) + file.Write("\n") + file.Write("// A class to emluate GLES2 over command buffers.\n") + file.Write("\n") + file.Write( + "#include \"gpu/command_buffer/client/gles2_implementation.h\"\n") + file.Write("\n") + self.WriteNamespaceOpen(file) + for func in self.original_functions: + func.WriteGLES2ImplementationImpl(file) + file.Write("\n") + + self.WriteNamespaceClose(file) + file.Close() + + +def main(argv): + """This is the main function.""" + parser = OptionParser() + parser.add_option( + "-g", "--generate-implementation-templates", action="store_true", + help="generates files that are generally hand edited..") + parser.add_option( + "--generate-command-id-tests", action="store_true", + help="generate tests for commands ids. Commands MUST not change ID!") + parser.add_option( + "-v", "--verbose", action="store_true", + help="prints more output.") + + (options, args) = parser.parse_args(args=argv) + + gen = GLGenerator(options.verbose) + gen.ParseGLH("common/GLES2/gl2.h") + gen.WriteCommandIds("common/gles2_cmd_ids_autogen.h") + gen.WriteFormat("common/gles2_cmd_format_autogen.h") + gen.WriteFormatTest("common/gles2_cmd_format_test_autogen.h") + gen.WriteGLES2ImplementationHeader("client/gles2_implementation_autogen.h") + gen.WriteGLES2CLibImplementation("client/gles2_c_lib_autogen.h") + gen.WriteCmdHelperHeader("client/gles2_cmd_helper_autogen.h") + gen.WriteServiceImplementation("service/gles2_cmd_decoder_autogen.h") + + if options.generate_implementation_templates: + gen.WriteGLES2ImplementationImpl("client/gles2_implementation_gen.h") + gen.WriteServiceValidation("service/gles2_cmd_decoder_validate.h") + + if options.generate_command_id_tests: + gen.WriteCommandIdTest("common/gles2_cmd_id_test.cc") + + +if __name__ == '__main__': + main(sys.argv[1:]) + diff --git a/gpu/command_buffer/client/cmd_buffer_helper.cc b/gpu/command_buffer/client/cmd_buffer_helper.cc new file mode 100644 index 0000000..e8f6fef --- /dev/null +++ b/gpu/command_buffer/client/cmd_buffer_helper.cc @@ -0,0 +1,195 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the implementation of the command buffer helper class. + +#include "gpu/command_buffer/client/cmd_buffer_helper.h" +#include "gpu/command_buffer/common/command_buffer.h" +#include "gpu/np_utils/np_utils.h" + +namespace command_buffer { + +using command_buffer::CommandBuffer; +using np_utils::NPBrowser; +using np_utils::NPInvoke; +using np_utils::NPObjectPointer; + +CommandBufferHelper::CommandBufferHelper(CommandBuffer* command_buffer) + : command_buffer_(command_buffer), + entries_(NULL), + entry_count_(0), + token_(0), + last_token_read_(-1), + get_(0), + put_(0) { +} + +bool CommandBufferHelper::Initialize() { + ring_buffer_ = command_buffer_->GetRingBuffer(); + if (!ring_buffer_) + return false; + + // Map the ring buffer into this process. + if (!ring_buffer_->Map(ring_buffer_->max_size())) + return false; + + entries_ = static_cast<CommandBufferEntry*>(ring_buffer_->memory()); + entry_count_ = command_buffer_->GetSize(); + get_ = command_buffer_->GetGetOffset(); + put_ = command_buffer_->GetPutOffset(); + last_token_read_ = command_buffer_->GetToken(); + + return true; +} + +CommandBufferHelper::~CommandBufferHelper() { +} + +bool CommandBufferHelper::Flush() { + get_ = command_buffer_->SyncOffsets(put_); + return !command_buffer_->GetErrorStatus(); +} + +// Calls Flush() and then waits until the buffer is empty. Break early if the +// error is set. +bool CommandBufferHelper::Finish() { + do { + // Do not loop forever if the flush fails, meaning the command buffer reader + // has shutdown). + if (!Flush()) + return false; + } while (put_ != get_); + + return true; +} + +// Inserts a new token into the command stream. It uses an increasing value +// scheme so that we don't lose tokens (a token has passed if the current token +// value is higher than that token). Calls Finish() if the token value wraps, +// which will be rare. +int32 CommandBufferHelper::InsertToken() { + // Increment token as 31-bit integer. Negative values are used to signal an + // error. + token_ = (token_ + 1) & 0x7FFFFFFF; + CommandBufferEntry args; + args.value_uint32 = token_; + const uint32 kSetToken = 1; // TODO(gman): add a common set of commands. + AddCommand(kSetToken, 1, &args); + if (token_ == 0) { + // we wrapped + Finish(); + last_token_read_ = command_buffer_->GetToken(); + DCHECK_EQ(token_, last_token_read_); + } + return token_; +} + +// Waits until the current token value is greater or equal to the value passed +// in argument. +void CommandBufferHelper::WaitForToken(int32 token) { + // Return immediately if corresponding InsertToken failed. + if (token < 0) + return; + if (last_token_read_ >= token) return; // fast path. + if (token > token_) return; // we wrapped + Flush(); + last_token_read_ = command_buffer_->GetToken(); + while (last_token_read_ < token) { + if (get_ == put_) { + LOG(FATAL) << "Empty command buffer while waiting on a token."; + return; + } + // Do not loop forever if the flush fails, meaning the command buffer reader + // has shutdown. + if (!Flush()) + return; + last_token_read_ = command_buffer_->GetToken(); + } +} + +// Waits for available entries, basically waiting until get >= put + count + 1. +// It actually waits for contiguous entries, so it may need to wrap the buffer +// around, adding noops. Thus this function may change the value of put_. +// The function will return early if an error occurs, in which case the +// available space may not be available. +void CommandBufferHelper::WaitForAvailableEntries(int32 count) { + CHECK(count < entry_count_); + if (put_ + count > entry_count_) { + // There's not enough room between the current put and the end of the + // buffer, so we need to wrap. We will add noops all the way to the end, + // but we need to make sure get wraps first, actually that get is 1 or + // more (since put will wrap to 0 after we add the noops). + DCHECK_LE(1, put_); + Flush(); + while (get_ > put_ || get_ == 0) { + // Do not loop forever if the flush fails, meaning the command buffer + // reader has shutdown. + if (!Flush()) + return; + } + // Add the noops. By convention, a noop is a command 0 with no args. + // TODO(apatrick): A noop can have a size. It would be better to add a + // single noop with a variable size. Watch out for size limit on + // individual commands. + CommandHeader header; + header.size = 1; + header.command = 0; + while (put_ < entry_count_) { + entries_[put_++].value_header = header; + } + put_ = 0; + } + // If we have enough room, return immediatly. + if (count <= AvailableEntries()) return; + // Otherwise flush, and wait until we do have enough room. + Flush(); + while (AvailableEntries() < count) { + // Do not loop forever if the flush fails, meaning the command buffer reader + // has shutdown. + if (!Flush()) + return; + } +} + +CommandBufferEntry* CommandBufferHelper::GetSpace(uint32 entries) { + WaitForAvailableEntries(entries); + CommandBufferEntry* space = &entries_[put_]; + put_ += entries; + return space; +} + +parse_error::ParseError CommandBufferHelper::GetParseError() { + int32 parse_error = command_buffer_->ResetParseError(); + return static_cast<parse_error::ParseError>(parse_error); +} + +} // namespace command_buffer diff --git a/gpu/command_buffer/client/cmd_buffer_helper.h b/gpu/command_buffer/client/cmd_buffer_helper.h new file mode 100644 index 0000000..7cac568 --- /dev/null +++ b/gpu/command_buffer/client/cmd_buffer_helper.h @@ -0,0 +1,216 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the command buffer helper class. + +#ifndef GPU_COMMAND_BUFFER_CLIENT_CROSS_CMD_BUFFER_HELPER_H_ +#define GPU_COMMAND_BUFFER_CLIENT_CROSS_CMD_BUFFER_HELPER_H_ + +#include "gpu/command_buffer/common/logging.h" +#include "gpu/command_buffer/common/constants.h" +#include "gpu/command_buffer/common/cmd_buffer_common.h" +#include "gpu/command_buffer/common/command_buffer.h" + +namespace command_buffer { + +// Command buffer helper class. This class simplifies ring buffer management: +// it will allocate the buffer, give it to the buffer interface, and let the +// user add commands to it, while taking care of the synchronization (put and +// get). It also provides a way to ensure commands have been executed, through +// the token mechanism: +// +// helper.AddCommand(...); +// helper.AddCommand(...); +// int32 token = helper.InsertToken(); +// helper.AddCommand(...); +// helper.AddCommand(...); +// [...] +// +// helper.WaitForToken(token); // this doesn't return until the first two +// // commands have been executed. +class CommandBufferHelper { + public: + explicit CommandBufferHelper(command_buffer::CommandBuffer* command_buffer); + virtual ~CommandBufferHelper(); + + bool Initialize(); + + // Flushes the commands, setting the put pointer to let the buffer interface + // know that new commands have been added. After a flush returns, the command + // buffer service is aware of all pending commands and it is guaranteed to + // have made some progress in processing them. Returns whether the flush was + // successful. The flush will fail if the command buffer service has + // disconnected. + bool Flush(); + + // Waits until all the commands have been executed. Returns whether it + // was successful. The function will fail if the command buffer service has + // disconnected. + bool Finish(); + + // Waits until a given number of available entries are available. + // Parameters: + // count: number of entries needed. This value must be at most + // the size of the buffer minus one. + void WaitForAvailableEntries(int32 count); + + // Adds a command data to the command buffer. This may wait until sufficient + // space is available. + // Parameters: + // entries: The command entries to add. + // count: The number of entries. + void AddCommandData(const CommandBufferEntry* entries, int32 count) { + WaitForAvailableEntries(count); + for (; count > 0; --count) { + entries_[put_++] = *entries++; + } + DCHECK_LE(put_, entry_count_); + if (put_ == entry_count_) put_ = 0; + } + + // A typed version of AddCommandData. + template <typename T> + void AddTypedCmdData(const T& cmd) { + AddCommandData(reinterpret_cast<const CommandBufferEntry*>(&cmd), + ComputeNumEntries(sizeof(cmd))); + } + + // Adds a command to the command buffer. This may wait until sufficient space + // is available. + // Parameters: + // command: the command index. + // arg_count: the number of arguments for the command. + // args: the arguments for the command (these are copied before the + // function returns). + void AddCommand(int32 command, + int32 arg_count, + const CommandBufferEntry *args) { + CommandHeader header; + header.size = arg_count + 1; + header.command = command; + WaitForAvailableEntries(header.size); + entries_[put_++].value_header = header; + for (int i = 0; i < arg_count; ++i) { + entries_[put_++] = args[i]; + } + DCHECK_LE(put_, entry_count_); + if (put_ == entry_count_) put_ = 0; + } + + // Inserts a new token into the command buffer. This token either has a value + // different from previously inserted tokens, or ensures that previously + // inserted tokens with that value have already passed through the command + // stream. + // Returns: + // the value of the new token or -1 if the command buffer reader has + // shutdown. + int32 InsertToken(); + + // Waits until the token of a particular value has passed through the command + // stream (i.e. commands inserted before that token have been executed). + // NOTE: This will call Flush if it needs to block. + // Parameters: + // the value of the token to wait for. + void WaitForToken(int32 token); + + // Waits for a certain amount of space to be available. Returns address + // of space. + CommandBufferEntry* GetSpace(uint32 entries); + + // Typed version of GetSpace. Gets enough room for the given type and returns + // a reference to it. + template <typename T> + T& GetCmdSpace() { + COMPILE_ASSERT(T::kArgFlags == cmd::kFixed, Cmd_kArgFlags_not_kFixed); + uint32 space_needed = ComputeNumEntries(sizeof(T)); + void* data = GetSpace(space_needed); + return *reinterpret_cast<T*>(data); + } + + // Typed version of GetSpace for immediate commands. + template <typename T> + T& GetImmediateCmdSpace(size_t data_space) { + COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); + uint32 space_needed = ComputeNumEntries(sizeof(T) + data_space); + void* data = GetSpace(space_needed); + return *reinterpret_cast<T*>(data); + } + + // Typed version of GetSpace for immediate commands. + template <typename T> + T& GetImmediateCmdSpaceTotalSize(size_t total_space) { + COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); + uint32 space_needed = ComputeNumEntries(total_space); + void* data = GetSpace(space_needed); + return *reinterpret_cast<T*>(data); + } + + parse_error::ParseError GetParseError(); + + // Common Commands + void Noop(uint32 skip_count) { + cmd::Noop& cmd = GetImmediateCmdSpace<cmd::Noop>( + skip_count * sizeof(CommandBufferEntry)); + cmd.Init(skip_count); + } + + void SetToken(uint32 token) { + cmd::SetToken& cmd = GetCmdSpace<cmd::SetToken>(); + cmd.Init(token); + } + + + private: + // Waits until get changes, updating the value of get_. + void WaitForGetChange(); + + // Returns the number of available entries (they may not be contiguous). + int32 AvailableEntries() { + return (get_ - put_ - 1 + entry_count_) % entry_count_; + } + + command_buffer::CommandBuffer* command_buffer_; + ::base::SharedMemory* ring_buffer_; + CommandBufferEntry *entries_; + int32 entry_count_; + int32 token_; + int32 last_token_read_; + int32 get_; + int32 put_; + + friend class CommandBufferHelperTest; + DISALLOW_COPY_AND_ASSIGN(CommandBufferHelper); +}; + +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_CLIENT_CROSS_CMD_BUFFER_HELPER_H_ diff --git a/gpu/command_buffer/client/cmd_buffer_helper_test.cc b/gpu/command_buffer/client/cmd_buffer_helper_test.cc new file mode 100644 index 0000000..4e2b31b --- /dev/null +++ b/gpu/command_buffer/client/cmd_buffer_helper_test.cc @@ -0,0 +1,303 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// Tests for the Command Buffer Helper. + +#include "base/at_exit.h" +#include "base/message_loop.h" +#include "gpu/command_buffer/client/cmd_buffer_helper.h" +#include "gpu/command_buffer/service/mocks.h" +#include "gpu/command_buffer/service/command_buffer_service.h" +#include "gpu/command_buffer/service/gpu_processor.h" +#include "gpu/np_utils/np_object_pointer.h" +#include "gpu/np_utils/np_browser_stub.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace command_buffer { + +using command_buffer::CommandBufferService; +using command_buffer::GPUProcessor; +using np_utils::NPCreateObject; +using np_utils::NPObjectPointer; +using testing::Return; +using testing::Mock; +using testing::Truly; +using testing::Sequence; +using testing::DoAll; +using testing::Invoke; +using testing::_; + +const int32 kNumCommandEntries = 10; +const int32 kCommandBufferSizeBytes = kNumCommandEntries * sizeof(int32); + +// Test fixture for CommandBufferHelper test - Creates a CommandBufferHelper, +// using a CommandBufferEngine with a mock AsyncAPIInterface for its interface +// (calling it directly, not through the RPC mechanism). +class CommandBufferHelperTest : public testing::Test { + protected: + virtual void SetUp() { + api_mock_.reset(new AsyncAPIMock); + // ignore noops in the mock - we don't want to inspect the internals of the + // helper. + EXPECT_CALL(*api_mock_, DoCommand(0, 0, _)) + .WillRepeatedly(Return(parse_error::kParseNoError)); + + ::base::SharedMemory* ring_buffer = new ::base::SharedMemory; + ring_buffer->Create(std::wstring(), false, false, kCommandBufferSizeBytes); + ring_buffer->Map(1024); + + command_buffer_.reset(new CommandBufferService); + command_buffer_->Initialize(ring_buffer); + + parser_ = new command_buffer::CommandParser(ring_buffer->memory(), + kCommandBufferSizeBytes, + 0, + kCommandBufferSizeBytes, + 0, + api_mock_.get()); + + scoped_refptr<GPUProcessor> gpu_processor(new GPUProcessor( + command_buffer_.get(), NULL, parser_, 1)); + command_buffer_->SetPutOffsetChangeCallback(NewCallback( + gpu_processor.get(), &GPUProcessor::ProcessCommands)); + + api_mock_->set_engine(gpu_processor.get()); + + helper_.reset(new CommandBufferHelper(command_buffer_.get())); + helper_->Initialize(); + } + + virtual void TearDown() { + // If the GPUProcessor posts any tasks, this forces them to run. + MessageLoop::current()->RunAllPending(); + helper_.release(); + } + + // Adds a command to the buffer through the helper, while adding it as an + // expected call on the API mock. + void AddCommandWithExpect(parse_error::ParseError _return, + unsigned int command, + unsigned int arg_count, + CommandBufferEntry *args) { + helper_->AddCommand(command, arg_count, args); + EXPECT_CALL(*api_mock_, DoCommand(command, arg_count, + Truly(AsyncAPIMock::IsArgs(arg_count, args)))) + .InSequence(sequence_) + .WillOnce(Return(_return)); + } + + // Checks that the buffer from put to put+size is free in the parser. + void CheckFreeSpace(CommandBufferOffset put, unsigned int size) { + CommandBufferOffset parser_put = parser_->put(); + CommandBufferOffset parser_get = parser_->get(); + CommandBufferOffset limit = put + size; + if (parser_get > parser_put) { + // "busy" buffer wraps, so "free" buffer is between put (inclusive) and + // get (exclusive). + EXPECT_LE(parser_put, put); + EXPECT_GT(parser_get, limit); + } else { + // "busy" buffer does not wrap, so the "free" buffer is the top side (from + // put to the limit) and the bottom side (from 0 to get). + if (put >= parser_put) { + // we're on the top side, check we are below the limit. + EXPECT_GE(kNumCommandEntries, limit); + } else { + // we're on the bottom side, check we are below get. + EXPECT_GT(parser_get, limit); + } + } + } + + CommandBufferOffset get_helper_put() { return helper_->put_; } + + base::AtExitManager at_exit_manager_; + MessageLoop message_loop_; + np_utils::StubNPBrowser browser_; + scoped_ptr<AsyncAPIMock> api_mock_; + scoped_ptr<CommandBufferService> command_buffer_; + command_buffer::CommandParser* parser_; + scoped_ptr<CommandBufferHelper> helper_; + Sequence sequence_; +}; + +// Checks that commands in the buffer are properly executed, and that the +// status/error stay valid. +TEST_F(CommandBufferHelperTest, TestCommandProcessing) { + // Check initial state of the engine - it should have been configured by the + // helper. + EXPECT_TRUE(parser_ != NULL); + EXPECT_FALSE(command_buffer_->GetErrorStatus()); + EXPECT_EQ(parse_error::kParseNoError, command_buffer_->ResetParseError()); + EXPECT_EQ(0u, command_buffer_->GetGetOffset()); + + // Add 3 commands through the helper + AddCommandWithExpect(parse_error::kParseNoError, 1, 0, NULL); + + CommandBufferEntry args1[2]; + args1[0].value_uint32 = 3; + args1[1].value_float = 4.f; + AddCommandWithExpect(parse_error::kParseNoError, 2, 2, args1); + + CommandBufferEntry args2[2]; + args2[0].value_uint32 = 5; + args2[1].value_float = 6.f; + AddCommandWithExpect(parse_error::kParseNoError, 3, 2, args2); + + helper_->Flush(); + // Check that the engine has work to do now. + EXPECT_FALSE(parser_->IsEmpty()); + + // Wait until it's done. + helper_->Finish(); + // Check that the engine has no more work to do. + EXPECT_TRUE(parser_->IsEmpty()); + + // Check that the commands did happen. + Mock::VerifyAndClearExpectations(api_mock_.get()); + + // Check the error status. + EXPECT_FALSE(command_buffer_->GetErrorStatus()); + EXPECT_EQ(parse_error::kParseNoError, command_buffer_->ResetParseError()); +} + +// Checks that commands in the buffer are properly executed when wrapping the +// buffer, and that the status/error stay valid. +TEST_F(CommandBufferHelperTest, TestCommandWrapping) { + // Add 5 commands of size 3 through the helper to make sure we do wrap. + CommandBufferEntry args1[2]; + args1[0].value_uint32 = 3; + args1[1].value_float = 4.f; + + for (unsigned int i = 0; i < 5; ++i) { + AddCommandWithExpect(parse_error::kParseNoError, i + 1, 2, args1); + } + + helper_->Finish(); + // Check that the commands did happen. + Mock::VerifyAndClearExpectations(api_mock_.get()); + + // Check the error status. + EXPECT_FALSE(command_buffer_->GetErrorStatus()); + EXPECT_EQ(parse_error::kParseNoError, command_buffer_->ResetParseError()); +} + + +// Checks that commands in the buffer are properly executed, even if they +// generate a recoverable error. Check that the error status is properly set, +// and reset when queried. +TEST_F(CommandBufferHelperTest, TestRecoverableError) { + CommandBufferEntry args[2]; + args[0].value_uint32 = 3; + args[1].value_float = 4.f; + + // Create a command buffer with 3 commands, 2 of them generating errors + AddCommandWithExpect(parse_error::kParseNoError, 1, 2, args); + AddCommandWithExpect(parse_error::kParseUnknownCommand, 2, 2, args); + AddCommandWithExpect(parse_error::kParseInvalidArguments, 3, 2, + args); + + helper_->Finish(); + // Check that the commands did happen. + Mock::VerifyAndClearExpectations(api_mock_.get()); + + // Check that the error status was set to the first error. + EXPECT_EQ(parse_error::kParseUnknownCommand, + command_buffer_->ResetParseError()); + // Check that the error status was reset after the query. + EXPECT_EQ(parse_error::kParseNoError, command_buffer_->ResetParseError()); +} + +// Checks that asking for available entries work, and that the parser +// effectively won't use that space. +TEST_F(CommandBufferHelperTest, TestAvailableEntries) { + CommandBufferEntry args[2]; + args[0].value_uint32 = 3; + args[1].value_float = 4.f; + + // Add 2 commands through the helper - 8 entries + AddCommandWithExpect(parse_error::kParseNoError, 1, 0, NULL); + AddCommandWithExpect(parse_error::kParseNoError, 2, 0, NULL); + AddCommandWithExpect(parse_error::kParseNoError, 3, 2, args); + AddCommandWithExpect(parse_error::kParseNoError, 4, 2, args); + + // Ask for 5 entries. + helper_->WaitForAvailableEntries(5); + + CommandBufferOffset put = get_helper_put(); + CheckFreeSpace(put, 5); + + // Add more commands. + AddCommandWithExpect(parse_error::kParseNoError, 5, 2, args); + + // Wait until everything is done done. + helper_->Finish(); + + // Check that the commands did happen. + Mock::VerifyAndClearExpectations(api_mock_.get()); + + // Check the error status. + EXPECT_FALSE(command_buffer_->GetErrorStatus()); + EXPECT_EQ(parse_error::kParseNoError, command_buffer_->ResetParseError()); +} + +// Checks that the InsertToken/WaitForToken work. +TEST_F(CommandBufferHelperTest, TestToken) { + CommandBufferEntry args[2]; + args[0].value_uint32 = 3; + args[1].value_float = 4.f; + + // Add a first command. + AddCommandWithExpect(parse_error::kParseNoError, 3, 2, args); + // keep track of the buffer position. + CommandBufferOffset command1_put = get_helper_put(); + int32 token = helper_->InsertToken(); + + EXPECT_CALL(*api_mock_.get(), DoCommand(cmd::kSetToken, 1, _)) + .WillOnce(DoAll(Invoke(api_mock_.get(), &AsyncAPIMock::SetToken), + Return(parse_error::kParseNoError))); + // Add another command. + AddCommandWithExpect(parse_error::kParseNoError, 4, 2, args); + helper_->WaitForToken(token); + // check that the get pointer is beyond the first command. + EXPECT_LE(command1_put, command_buffer_->GetGetOffset()); + helper_->Finish(); + + // Check that the commands did happen. + Mock::VerifyAndClearExpectations(api_mock_.get()); + + // Check the error status. + EXPECT_FALSE(command_buffer_->GetErrorStatus()); + EXPECT_EQ(parse_error::kParseNoError, command_buffer_->ResetParseError()); +} + +} // namespace command_buffer diff --git a/gpu/command_buffer/client/fenced_allocator.cc b/gpu/command_buffer/client/fenced_allocator.cc new file mode 100644 index 0000000..810feb5 --- /dev/null +++ b/gpu/command_buffer/client/fenced_allocator.cc @@ -0,0 +1,214 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the implementation of the FencedAllocator class. + +#include "gpu/command_buffer/client/fenced_allocator.h" +#include <algorithm> +#include "gpu/command_buffer/client/cmd_buffer_helper.h" + +namespace command_buffer { + +#ifndef COMPILER_MSVC +const FencedAllocator::Offset FencedAllocator::kInvalidOffset; +#endif + +FencedAllocator::~FencedAllocator() { + // Free blocks pending tokens. + for (unsigned int i = 0; i < blocks_.size(); ++i) { + if (blocks_[i].state == FREE_PENDING_TOKEN) { + i = WaitForTokenAndFreeBlock(i); + } + } + DCHECK_EQ(blocks_.size(), 1u); + DCHECK_EQ(blocks_[0].state, FREE); +} + +// Looks for a non-allocated block that is big enough. Search in the FREE +// blocks first (for direct usage), first-fit, then in the FREE_PENDING_TOKEN +// blocks, waiting for them. The current implementation isn't smart about +// optimizing what to wait for, just looks inside the block in order (first-fit +// as well). +FencedAllocator::Offset FencedAllocator::Alloc(unsigned int size) { + // Similarly to malloc, an allocation of 0 allocates at least 1 byte, to + // return different pointers every time. + if (size == 0) size = 1; + + // Try first to allocate in a free block. + for (unsigned int i = 0; i < blocks_.size(); ++i) { + Block &block = blocks_[i]; + if (block.state == FREE && block.size >= size) { + return AllocInBlock(i, size); + } + } + + // No free block is available. Look for blocks pending tokens, and wait for + // them to be re-usable. + for (unsigned int i = 0; i < blocks_.size(); ++i) { + if (blocks_[i].state != FREE_PENDING_TOKEN) + continue; + i = WaitForTokenAndFreeBlock(i); + if (blocks_[i].size >= size) + return AllocInBlock(i, size); + } + return kInvalidOffset; +} + +// Looks for the corresponding block, mark it FREE, and collapse it if +// necessary. +void FencedAllocator::Free(FencedAllocator::Offset offset) { + BlockIndex index = GetBlockByOffset(offset); + DCHECK_NE(blocks_[index].state, FREE); + blocks_[index].state = FREE; + CollapseFreeBlock(index); +} + +// Looks for the corresponding block, mark it FREE_PENDING_TOKEN. +void FencedAllocator::FreePendingToken(FencedAllocator::Offset offset, + unsigned int token) { + BlockIndex index = GetBlockByOffset(offset); + Block &block = blocks_[index]; + block.state = FREE_PENDING_TOKEN; + block.token = token; +} + +// Gets the max of the size of the blocks marked as free. +unsigned int FencedAllocator::GetLargestFreeSize() { + unsigned int max_size = 0; + for (unsigned int i = 0; i < blocks_.size(); ++i) { + Block &block = blocks_[i]; + if (block.state == FREE) + max_size = std::max(max_size, block.size); + } + return max_size; +} + +// Gets the size of the largest segment of blocks that are either FREE or +// FREE_PENDING_TOKEN. +unsigned int FencedAllocator::GetLargestFreeOrPendingSize() { + unsigned int max_size = 0; + unsigned int current_size = 0; + for (unsigned int i = 0; i < blocks_.size(); ++i) { + Block &block = blocks_[i]; + if (block.state == IN_USE) { + max_size = std::max(max_size, current_size); + current_size = 0; + } else { + DCHECK(block.state == FREE || block.state == FREE_PENDING_TOKEN); + current_size += block.size; + } + } + return std::max(max_size, current_size); +} + +// Makes sure that: +// - there is at least one block. +// - there are no contiguous FREE blocks (they should have been collapsed). +// - the successive offsets match the block sizes, and they are in order. +bool FencedAllocator::CheckConsistency() { + if (blocks_.size() < 1) return false; + for (unsigned int i = 0; i < blocks_.size() - 1; ++i) { + Block ¤t = blocks_[i]; + Block &next = blocks_[i + 1]; + // This test is NOT included in the next one, because offset is unsigned. + if (next.offset <= current.offset) + return false; + if (next.offset != current.offset + current.size) + return false; + if (current.state == FREE && next.state == FREE) + return false; + } + return true; +} + +// Collapse the block to the next one, then to the previous one. Provided the +// structure is consistent, those are the only blocks eligible for collapse. +FencedAllocator::BlockIndex FencedAllocator::CollapseFreeBlock( + BlockIndex index) { + if (index + 1 < blocks_.size()) { + Block &next = blocks_[index + 1]; + if (next.state == FREE) { + blocks_[index].size += next.size; + blocks_.erase(blocks_.begin() + index + 1); + } + } + if (index > 0) { + Block &prev = blocks_[index - 1]; + if (prev.state == FREE) { + prev.size += blocks_[index].size; + blocks_.erase(blocks_.begin() + index); + --index; + } + } + return index; +} + +// Waits for the block's token, then mark the block as free, then collapse it. +FencedAllocator::BlockIndex FencedAllocator::WaitForTokenAndFreeBlock( + BlockIndex index) { + Block &block = blocks_[index]; + DCHECK_EQ(block.state, FREE_PENDING_TOKEN); + helper_->WaitForToken(block.token); + block.state = FREE; + return CollapseFreeBlock(index); +} + +// If the block is exactly the requested size, simply mark it IN_USE, otherwise +// split it and mark the first one (of the requested size) IN_USE. +FencedAllocator::Offset FencedAllocator::AllocInBlock(BlockIndex index, + unsigned int size) { + Block &block = blocks_[index]; + DCHECK_GE(block.size, size); + DCHECK_EQ(block.state, FREE); + Offset offset = block.offset; + if (block.size == size) { + block.state = IN_USE; + return offset; + } + Block newblock = { FREE, offset + size, block.size - size, kUnusedToken}; + block.state = IN_USE; + block.size = size; + // this is the last thing being done because it may invalidate block; + blocks_.insert(blocks_.begin() + index + 1, newblock); + return offset; +} + +// The blocks are in offset order, so we can do a binary search. +FencedAllocator::BlockIndex FencedAllocator::GetBlockByOffset(Offset offset) { + Block templ = { IN_USE, offset, 0, kUnusedToken }; + Container::iterator it = std::lower_bound(blocks_.begin(), blocks_.end(), + templ, OffsetCmp()); + DCHECK(it != blocks_.end() && it->offset == offset); + return it-blocks_.begin(); +} + +} // namespace command_buffer diff --git a/gpu/command_buffer/client/fenced_allocator.h b/gpu/command_buffer/client/fenced_allocator.h new file mode 100644 index 0000000..72bba33 --- /dev/null +++ b/gpu/command_buffer/client/fenced_allocator.h @@ -0,0 +1,266 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the definition of the FencedAllocator class. + +#ifndef GPU_COMMAND_BUFFER_CLIENT_CROSS_FENCED_ALLOCATOR_H_ +#define GPU_COMMAND_BUFFER_CLIENT_CROSS_FENCED_ALLOCATOR_H_ + +#include <vector> +#include "base/basictypes.h" +#include "gpu/command_buffer/common/logging.h" + +namespace command_buffer { +class CommandBufferHelper; + +// FencedAllocator provides a mechanism to manage allocations within a fixed +// block of memory (storing the book-keeping externally). Furthermore this +// class allows to free data "pending" the passage of a command buffer token, +// that is, the memory won't be reused until the command buffer has processed +// that token. +// +// NOTE: Although this class is intended to be used in the command buffer +// environment which is multi-process, this class isn't "thread safe", because +// it isn't meant to be shared across modules. It is thread-compatible though +// (see http://www.corp.google.com/eng/doc/cpp_primer.html#thread_safety). +class FencedAllocator { + public: + typedef unsigned int Offset; + // Invalid offset, returned by Alloc in case of failure. + static const Offset kInvalidOffset = 0xffffffffU; + + // Creates a FencedAllocator. Note that the size of the buffer is passed, but + // not its base address: everything is handled as offsets into the buffer. + FencedAllocator(unsigned int size, + CommandBufferHelper *helper) + : helper_(helper) { + Block block = { FREE, 0, size, kUnusedToken }; + blocks_.push_back(block); + } + + ~FencedAllocator(); + + // Allocates a block of memory. If the buffer is out of directly available + // memory, this function may wait until memory that was freed "pending a + // token" can be re-used. + // + // Parameters: + // size: the size of the memory block to allocate. + // + // Returns: + // the offset of the allocated memory block, or kInvalidOffset if out of + // memory. + Offset Alloc(unsigned int size); + + // Frees a block of memory. + // + // Parameters: + // offset: the offset of the memory block to free. + void Free(Offset offset); + + // Frees a block of memory, pending the passage of a token. That memory won't + // be re-allocated until the token has passed through the command stream. + // + // Parameters: + // offset: the offset of the memory block to free. + // token: the token value to wait for before re-using the memory. + void FreePendingToken(Offset offset, unsigned int token); + + // Gets the size of the largest free block that is available without waiting. + unsigned int GetLargestFreeSize(); + + // Gets the size of the largest free block that can be allocated if the + // caller can wait. Allocating a block of this size will succeed, but may + // block. + unsigned int GetLargestFreeOrPendingSize(); + + // Checks for consistency inside the book-keeping structures. Used for + // testing. + bool CheckConsistency(); + + private: + // Status of a block of memory, for book-keeping. + enum State { + IN_USE, + FREE, + FREE_PENDING_TOKEN + }; + + // Book-keeping sturcture that describes a block of memory. + struct Block { + State state; + Offset offset; + unsigned int size; + unsigned int token; // token to wait for in the FREE_PENDING_TOKEN case. + }; + + // Comparison functor for memory block sorting. + class OffsetCmp { + public: + bool operator() (const Block &left, const Block &right) { + return left.offset < right.offset; + } + }; + + typedef std::vector<Block> Container; + typedef unsigned int BlockIndex; + + static const unsigned int kUnusedToken = 0; + + // Gets the index of a memory block, given its offset. + BlockIndex GetBlockByOffset(Offset offset); + + // Collapse a free block with its neighbours if they are free. Returns the + // index of the collapsed block. + // NOTE: this will invalidate block indices. + BlockIndex CollapseFreeBlock(BlockIndex index); + + // Waits for a FREE_PENDING_TOKEN block to be usable, and free it. Returns + // the new index of that block (since it may have been collapsed). + // NOTE: this will invalidate block indices. + BlockIndex WaitForTokenAndFreeBlock(BlockIndex index); + + // Allocates a block of memory inside a given block, splitting it in two + // (unless that block is of the exact requested size). + // NOTE: this will invalidate block indices. + // Returns the offset of the allocated block (NOTE: this is different from + // the other functions that return a block index). + Offset AllocInBlock(BlockIndex index, unsigned int size); + + command_buffer::CommandBufferHelper *helper_; + Container blocks_; + + DISALLOW_IMPLICIT_CONSTRUCTORS(FencedAllocator); +}; + +// This class functions just like FencedAllocator, but its API uses pointers +// instead of offsets. +class FencedAllocatorWrapper { + public: + FencedAllocatorWrapper(unsigned int size, + CommandBufferHelper *helper, + void *base) + : allocator_(size, helper), + base_(base) { } + + // Allocates a block of memory. If the buffer is out of directly available + // memory, this function may wait until memory that was freed "pending a + // token" can be re-used. + // + // Parameters: + // size: the size of the memory block to allocate. + // + // Returns: + // the pointer to the allocated memory block, or NULL if out of + // memory. + void *Alloc(unsigned int size) { + FencedAllocator::Offset offset = allocator_.Alloc(size); + return GetPointer(offset); + } + + // Allocates a block of memory. If the buffer is out of directly available + // memory, this function may wait until memory that was freed "pending a + // token" can be re-used. + // This is a type-safe version of Alloc, returning a typed pointer. + // + // Parameters: + // count: the number of elements to allocate. + // + // Returns: + // the pointer to the allocated memory block, or NULL if out of + // memory. + template <typename T> T *AllocTyped(unsigned int count) { + return static_cast<T *>(Alloc(count * sizeof(T))); + } + + // Frees a block of memory. + // + // Parameters: + // pointer: the pointer to the memory block to free. + void Free(void *pointer) { + DCHECK(pointer); + allocator_.Free(GetOffset(pointer)); + } + + // Frees a block of memory, pending the passage of a token. That memory won't + // be re-allocated until the token has passed through the command stream. + // + // Parameters: + // pointer: the pointer to the memory block to free. + // token: the token value to wait for before re-using the memory. + void FreePendingToken(void *pointer, unsigned int token) { + DCHECK(pointer); + allocator_.FreePendingToken(GetOffset(pointer), token); + } + + // Gets a pointer to a memory block given the base memory and the offset. + // It translates FencedAllocator::kInvalidOffset to NULL. + void *GetPointer(FencedAllocator::Offset offset) { + return (offset == FencedAllocator::kInvalidOffset) ? + NULL : static_cast<char *>(base_) + offset; + } + + // Gets the offset to a memory block given the base memory and the address. + // It translates NULL to FencedAllocator::kInvalidOffset. + FencedAllocator::Offset GetOffset(void *pointer) { + return pointer ? static_cast<char *>(pointer) - static_cast<char *>(base_) : + FencedAllocator::kInvalidOffset; + } + + // Gets the size of the largest free block that is available without waiting. + unsigned int GetLargestFreeSize() { + return allocator_.GetLargestFreeSize(); + } + + // Gets the size of the largest free block that can be allocated if the + // caller can wait. + unsigned int GetLargestFreeOrPendingSize() { + return allocator_.GetLargestFreeOrPendingSize(); + } + + // Checks for consistency inside the book-keeping structures. Used for + // testing. + bool CheckConsistency() { + return allocator_.CheckConsistency(); + } + + FencedAllocator &allocator() { return allocator_; } + + private: + FencedAllocator allocator_; + void *base_; + DISALLOW_IMPLICIT_CONSTRUCTORS(FencedAllocatorWrapper); +}; + +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_CLIENT_CROSS_FENCED_ALLOCATOR_H_ diff --git a/gpu/command_buffer/client/fenced_allocator_test.cc b/gpu/command_buffer/client/fenced_allocator_test.cc new file mode 100644 index 0000000..dcb75bc --- /dev/null +++ b/gpu/command_buffer/client/fenced_allocator_test.cc @@ -0,0 +1,501 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the tests for the FencedAllocator class. + +#include "base/at_exit.h" +#include "base/message_loop.h" +#include "gpu/command_buffer/client/cmd_buffer_helper.h" +#include "gpu/command_buffer/client/fenced_allocator.h" +#include "gpu/command_buffer/service/cmd_buffer_engine.h" +#include "gpu/command_buffer/service/mocks.h" +#include "gpu/command_buffer/service/command_buffer_service.h" +#include "gpu/command_buffer/service/gpu_processor.h" +#include "gpu/np_utils/np_browser_stub.h" +#include "gpu/np_utils/np_object_pointer.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace command_buffer { + +using command_buffer::CommandBufferService; +using command_buffer::GPUProcessor; +using np_utils::NPCreateObject; +using np_utils::NPObjectPointer; +using testing::Return; +using testing::Mock; +using testing::Truly; +using testing::Sequence; +using testing::DoAll; +using testing::Invoke; +using testing::_; + +class BaseFencedAllocatorTest : public testing::Test { + protected: + static const unsigned int kBufferSize = 1024; + + virtual void SetUp() { + api_mock_.reset(new AsyncAPIMock); + // ignore noops in the mock - we don't want to inspect the internals of the + // helper. + EXPECT_CALL(*api_mock_, DoCommand(cmd::kNoop, 0, _)) + .WillRepeatedly(Return(parse_error::kParseNoError)); + // Forward the SetToken calls to the engine + EXPECT_CALL(*api_mock_.get(), DoCommand(cmd::kSetToken, 1, _)) + .WillRepeatedly(DoAll(Invoke(api_mock_.get(), &AsyncAPIMock::SetToken), + Return(parse_error::kParseNoError))); + + ::base::SharedMemory* ring_buffer = new ::base::SharedMemory; + ring_buffer->Create(std::wstring(), false, false, 1024); + ring_buffer->Map(1024); + + command_buffer_.reset(new CommandBufferService); + command_buffer_->Initialize(ring_buffer); + + parser_ = new command_buffer::CommandParser(ring_buffer->memory(), + kBufferSize, + 0, + kBufferSize, + 0, + api_mock_.get()); + + scoped_refptr<GPUProcessor> gpu_processor(new GPUProcessor( + command_buffer_.get(), NULL, parser_, INT_MAX)); + command_buffer_->SetPutOffsetChangeCallback(NewCallback( + gpu_processor.get(), &GPUProcessor::ProcessCommands)); + + api_mock_->set_engine(gpu_processor.get()); + + helper_.reset(new CommandBufferHelper(command_buffer_.get())); + helper_->Initialize(); + } + + virtual void TearDown() { + helper_.release(); + } + + base::AtExitManager at_exit_manager_; + MessageLoop message_loop_; + np_utils::StubNPBrowser browser_; + scoped_ptr<AsyncAPIMock> api_mock_; + scoped_ptr<CommandBufferService> command_buffer_; + command_buffer::CommandParser* parser_; + scoped_ptr<CommandBufferHelper> helper_; +}; + +#ifndef COMPILER_MSVC +const unsigned int BaseFencedAllocatorTest::kBufferSize; +#endif + +// Test fixture for FencedAllocator test - Creates a FencedAllocator, using a +// CommandBufferHelper with a mock AsyncAPIInterface for its interface (calling +// it directly, not through the RPC mechanism), making sure Noops are ignored +// and SetToken are properly forwarded to the engine. +class FencedAllocatorTest : public BaseFencedAllocatorTest { + protected: + virtual void SetUp() { + BaseFencedAllocatorTest::SetUp(); + allocator_.reset(new FencedAllocator(kBufferSize, helper_.get())); + } + + virtual void TearDown() { + // If the GPUProcessor posts any tasks, this forces them to run. + MessageLoop::current()->RunAllPending(); + + EXPECT_TRUE(allocator_->CheckConsistency()); + allocator_.release(); + + BaseFencedAllocatorTest::TearDown(); + } + + scoped_ptr<FencedAllocator> allocator_; +}; + +// Checks basic alloc and free. +TEST_F(FencedAllocatorTest, TestBasic) { + allocator_->CheckConsistency(); + + const unsigned int kSize = 16; + FencedAllocator::Offset offset = allocator_->Alloc(kSize); + EXPECT_NE(FencedAllocator::kInvalidOffset, offset); + EXPECT_GE(kBufferSize, offset+kSize); + EXPECT_TRUE(allocator_->CheckConsistency()); + + allocator_->Free(offset); + EXPECT_TRUE(allocator_->CheckConsistency()); +} + +// Checks out-of-memory condition. +TEST_F(FencedAllocatorTest, TestOutOfMemory) { + EXPECT_TRUE(allocator_->CheckConsistency()); + + const unsigned int kSize = 16; + const unsigned int kAllocCount = kBufferSize / kSize; + CHECK(kAllocCount * kSize == kBufferSize); + + // Allocate several buffers to fill in the memory. + FencedAllocator::Offset offsets[kAllocCount]; + for (unsigned int i = 0; i < kAllocCount; ++i) { + offsets[i] = allocator_->Alloc(kSize); + EXPECT_NE(FencedAllocator::kInvalidOffset, offsets[i]); + EXPECT_GE(kBufferSize, offsets[i]+kSize); + EXPECT_TRUE(allocator_->CheckConsistency()); + } + + // This allocation should fail. + FencedAllocator::Offset offset_failed = allocator_->Alloc(kSize); + EXPECT_EQ(FencedAllocator::kInvalidOffset, offset_failed); + EXPECT_TRUE(allocator_->CheckConsistency()); + + // Free one successful allocation, reallocate with half the size + allocator_->Free(offsets[0]); + EXPECT_TRUE(allocator_->CheckConsistency()); + offsets[0] = allocator_->Alloc(kSize/2); + EXPECT_NE(FencedAllocator::kInvalidOffset, offsets[0]); + EXPECT_GE(kBufferSize, offsets[0]+kSize); + EXPECT_TRUE(allocator_->CheckConsistency()); + + // This allocation should fail as well. + offset_failed = allocator_->Alloc(kSize); + EXPECT_EQ(FencedAllocator::kInvalidOffset, offset_failed); + EXPECT_TRUE(allocator_->CheckConsistency()); + + // Free up everything. + for (unsigned int i = 0; i < kAllocCount; ++i) { + allocator_->Free(offsets[i]); + EXPECT_TRUE(allocator_->CheckConsistency()); + } +} + +// Checks the free-pending-token mechanism. +TEST_F(FencedAllocatorTest, TestFreePendingToken) { + EXPECT_TRUE(allocator_->CheckConsistency()); + + const unsigned int kSize = 16; + const unsigned int kAllocCount = kBufferSize / kSize; + CHECK(kAllocCount * kSize == kBufferSize); + + // Allocate several buffers to fill in the memory. + FencedAllocator::Offset offsets[kAllocCount]; + for (unsigned int i = 0; i < kAllocCount; ++i) { + offsets[i] = allocator_->Alloc(kSize); + EXPECT_NE(FencedAllocator::kInvalidOffset, offsets[i]); + EXPECT_GE(kBufferSize, offsets[i]+kSize); + EXPECT_TRUE(allocator_->CheckConsistency()); + } + + // This allocation should fail. + FencedAllocator::Offset offset_failed = allocator_->Alloc(kSize); + EXPECT_EQ(FencedAllocator::kInvalidOffset, offset_failed); + EXPECT_TRUE(allocator_->CheckConsistency()); + + // Free one successful allocation, pending fence. + int32 token = helper_.get()->InsertToken(); + allocator_->FreePendingToken(offsets[0], token); + EXPECT_TRUE(allocator_->CheckConsistency()); + + // The way we hooked up the helper and engine, it won't process commands + // until it has to wait for something. Which means the token shouldn't have + // passed yet at this point. + EXPECT_GT(token, command_buffer_->GetToken()); + + // This allocation will need to reclaim the space freed above, so that should + // process the commands until the token is passed. + offsets[0] = allocator_->Alloc(kSize); + EXPECT_NE(FencedAllocator::kInvalidOffset, offsets[0]); + EXPECT_GE(kBufferSize, offsets[0]+kSize); + EXPECT_TRUE(allocator_->CheckConsistency()); + // Check that the token has indeed passed. + EXPECT_LE(token, command_buffer_->GetToken()); + + // Free up everything. + for (unsigned int i = 0; i < kAllocCount; ++i) { + allocator_->Free(offsets[i]); + EXPECT_TRUE(allocator_->CheckConsistency()); + } +} + +// Tests GetLargestFreeSize +TEST_F(FencedAllocatorTest, TestGetLargestFreeSize) { + EXPECT_TRUE(allocator_->CheckConsistency()); + EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeSize()); + + FencedAllocator::Offset offset = allocator_->Alloc(kBufferSize); + ASSERT_NE(FencedAllocator::kInvalidOffset, offset); + EXPECT_EQ(0u, allocator_->GetLargestFreeSize()); + allocator_->Free(offset); + EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeSize()); + + const unsigned int kSize = 16; + offset = allocator_->Alloc(kSize); + ASSERT_NE(FencedAllocator::kInvalidOffset, offset); + // The following checks that the buffer is allocated "smartly" - which is + // dependent on the implementation. But both first-fit or best-fit would + // ensure that. + EXPECT_EQ(kBufferSize - kSize, allocator_->GetLargestFreeSize()); + + // Allocate 2 more buffers (now 3), and then free the first two. This is to + // ensure a hole. Note that this is dependent on the first-fit current + // implementation. + FencedAllocator::Offset offset1 = allocator_->Alloc(kSize); + ASSERT_NE(FencedAllocator::kInvalidOffset, offset1); + FencedAllocator::Offset offset2 = allocator_->Alloc(kSize); + ASSERT_NE(FencedAllocator::kInvalidOffset, offset2); + allocator_->Free(offset); + allocator_->Free(offset1); + EXPECT_EQ(kBufferSize - 3 * kSize, allocator_->GetLargestFreeSize()); + + offset = allocator_->Alloc(kBufferSize - 3 * kSize); + ASSERT_NE(FencedAllocator::kInvalidOffset, offset); + EXPECT_EQ(2 * kSize, allocator_->GetLargestFreeSize()); + + offset1 = allocator_->Alloc(2 * kSize); + ASSERT_NE(FencedAllocator::kInvalidOffset, offset1); + EXPECT_EQ(0u, allocator_->GetLargestFreeSize()); + + allocator_->Free(offset); + allocator_->Free(offset1); + allocator_->Free(offset2); +} + +// Tests GetLargestFreeOrPendingSize +TEST_F(FencedAllocatorTest, TestGetLargestFreeOrPendingSize) { + EXPECT_TRUE(allocator_->CheckConsistency()); + EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeOrPendingSize()); + + FencedAllocator::Offset offset = allocator_->Alloc(kBufferSize); + ASSERT_NE(FencedAllocator::kInvalidOffset, offset); + EXPECT_EQ(0u, allocator_->GetLargestFreeOrPendingSize()); + allocator_->Free(offset); + EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeOrPendingSize()); + + const unsigned int kSize = 16; + offset = allocator_->Alloc(kSize); + ASSERT_NE(FencedAllocator::kInvalidOffset, offset); + // The following checks that the buffer is allocates "smartly" - which is + // dependent on the implementation. But both first-fit or best-fit would + // ensure that. + EXPECT_EQ(kBufferSize - kSize, allocator_->GetLargestFreeOrPendingSize()); + + // Allocate 2 more buffers (now 3), and then free the first two. This is to + // ensure a hole. Note that this is dependent on the first-fit current + // implementation. + FencedAllocator::Offset offset1 = allocator_->Alloc(kSize); + ASSERT_NE(FencedAllocator::kInvalidOffset, offset1); + FencedAllocator::Offset offset2 = allocator_->Alloc(kSize); + ASSERT_NE(FencedAllocator::kInvalidOffset, offset2); + allocator_->Free(offset); + allocator_->Free(offset1); + EXPECT_EQ(kBufferSize - 3 * kSize, + allocator_->GetLargestFreeOrPendingSize()); + + // Free the last one, pending a token. + int32 token = helper_.get()->InsertToken(); + allocator_->FreePendingToken(offset2, token); + + // Now all the buffers have been freed... + EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeOrPendingSize()); + // .. but one is still waiting for the token. + EXPECT_EQ(kBufferSize - 3 * kSize, + allocator_->GetLargestFreeSize()); + + // The way we hooked up the helper and engine, it won't process commands + // until it has to wait for something. Which means the token shouldn't have + // passed yet at this point. + EXPECT_GT(token, command_buffer_->GetToken()); + // This allocation will need to reclaim the space freed above, so that should + // process the commands until the token is passed, but it will succeed. + offset = allocator_->Alloc(kBufferSize); + ASSERT_NE(FencedAllocator::kInvalidOffset, offset); + // Check that the token has indeed passed. + EXPECT_LE(token, command_buffer_->GetToken()); + allocator_->Free(offset); + + // Everything now has been freed... + EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeOrPendingSize()); + // ... for real. + EXPECT_EQ(kBufferSize, allocator_->GetLargestFreeSize()); +} + +// Test fixture for FencedAllocatorWrapper test - Creates a +// FencedAllocatorWrapper, using a CommandBufferHelper with a mock +// AsyncAPIInterface for its interface (calling it directly, not through the +// RPC mechanism), making sure Noops are ignored and SetToken are properly +// forwarded to the engine. +class FencedAllocatorWrapperTest : public BaseFencedAllocatorTest { + protected: + virtual void SetUp() { + BaseFencedAllocatorTest::SetUp(); + + // Though allocating this buffer isn't strictly necessary, it makes + // allocations point to valid addresses, so they could be used for + // something. + buffer_.reset(new char[kBufferSize]); + allocator_.reset(new FencedAllocatorWrapper(kBufferSize, helper_.get(), + buffer_.get())); + } + + virtual void TearDown() { + // If the GPUProcessor posts any tasks, this forces them to run. + MessageLoop::current()->RunAllPending(); + + EXPECT_TRUE(allocator_->CheckConsistency()); + allocator_.release(); + buffer_.release(); + + BaseFencedAllocatorTest::TearDown(); + } + + scoped_ptr<FencedAllocatorWrapper> allocator_; + scoped_array<char> buffer_; +}; + +// Checks basic alloc and free. +TEST_F(FencedAllocatorWrapperTest, TestBasic) { + allocator_->CheckConsistency(); + + const unsigned int kSize = 16; + void *pointer = allocator_->Alloc(kSize); + ASSERT_TRUE(pointer); + EXPECT_LE(buffer_.get(), static_cast<char *>(pointer)); + EXPECT_GE(kBufferSize, static_cast<char *>(pointer) - buffer_.get() + kSize); + EXPECT_TRUE(allocator_->CheckConsistency()); + + allocator_->Free(pointer); + EXPECT_TRUE(allocator_->CheckConsistency()); + + char *pointer_char = allocator_->AllocTyped<char>(kSize); + ASSERT_TRUE(pointer_char); + EXPECT_LE(buffer_.get(), pointer_char); + EXPECT_GE(buffer_.get() + kBufferSize, pointer_char + kSize); + allocator_->Free(pointer_char); + EXPECT_TRUE(allocator_->CheckConsistency()); + + unsigned int *pointer_uint = allocator_->AllocTyped<unsigned int>(kSize); + ASSERT_TRUE(pointer_uint); + EXPECT_LE(buffer_.get(), reinterpret_cast<char *>(pointer_uint)); + EXPECT_GE(buffer_.get() + kBufferSize, + reinterpret_cast<char *>(pointer_uint + kSize)); + + // Check that it did allocate kSize * sizeof(unsigned int). We can't tell + // directly, except from the remaining size. + EXPECT_EQ(kBufferSize - kSize * sizeof(*pointer_uint), + allocator_->GetLargestFreeSize()); + allocator_->Free(pointer_uint); +} + +// Checks out-of-memory condition. +TEST_F(FencedAllocatorWrapperTest, TestOutOfMemory) { + allocator_->CheckConsistency(); + + const unsigned int kSize = 16; + const unsigned int kAllocCount = kBufferSize / kSize; + CHECK(kAllocCount * kSize == kBufferSize); + + // Allocate several buffers to fill in the memory. + void *pointers[kAllocCount]; + for (unsigned int i = 0; i < kAllocCount; ++i) { + pointers[i] = allocator_->Alloc(kSize); + EXPECT_TRUE(pointers[i]); + EXPECT_TRUE(allocator_->CheckConsistency()); + } + + // This allocation should fail. + void *pointer_failed = allocator_->Alloc(kSize); + EXPECT_FALSE(pointer_failed); + EXPECT_TRUE(allocator_->CheckConsistency()); + + // Free one successful allocation, reallocate with half the size + allocator_->Free(pointers[0]); + EXPECT_TRUE(allocator_->CheckConsistency()); + pointers[0] = allocator_->Alloc(kSize/2); + EXPECT_TRUE(pointers[0]); + EXPECT_TRUE(allocator_->CheckConsistency()); + + // This allocation should fail as well. + pointer_failed = allocator_->Alloc(kSize); + EXPECT_FALSE(pointer_failed); + EXPECT_TRUE(allocator_->CheckConsistency()); + + // Free up everything. + for (unsigned int i = 0; i < kAllocCount; ++i) { + allocator_->Free(pointers[i]); + EXPECT_TRUE(allocator_->CheckConsistency()); + } +} + +// Checks the free-pending-token mechanism. +TEST_F(FencedAllocatorWrapperTest, TestFreePendingToken) { + allocator_->CheckConsistency(); + + const unsigned int kSize = 16; + const unsigned int kAllocCount = kBufferSize / kSize; + CHECK(kAllocCount * kSize == kBufferSize); + + // Allocate several buffers to fill in the memory. + void *pointers[kAllocCount]; + for (unsigned int i = 0; i < kAllocCount; ++i) { + pointers[i] = allocator_->Alloc(kSize); + EXPECT_TRUE(pointers[i]); + EXPECT_TRUE(allocator_->CheckConsistency()); + } + + // This allocation should fail. + void *pointer_failed = allocator_->Alloc(kSize); + EXPECT_FALSE(pointer_failed); + EXPECT_TRUE(allocator_->CheckConsistency()); + + // Free one successful allocation, pending fence. + int32 token = helper_.get()->InsertToken(); + allocator_->FreePendingToken(pointers[0], token); + EXPECT_TRUE(allocator_->CheckConsistency()); + + // The way we hooked up the helper and engine, it won't process commands + // until it has to wait for something. Which means the token shouldn't have + // passed yet at this point. + EXPECT_GT(token, command_buffer_->GetToken()); + + // This allocation will need to reclaim the space freed above, so that should + // process the commands until the token is passed. + pointers[0] = allocator_->Alloc(kSize); + EXPECT_TRUE(pointers[0]); + EXPECT_TRUE(allocator_->CheckConsistency()); + // Check that the token has indeed passed. + EXPECT_LE(token, command_buffer_->GetToken()); + + // Free up everything. + for (unsigned int i = 0; i < kAllocCount; ++i) { + allocator_->Free(pointers[i]); + EXPECT_TRUE(allocator_->CheckConsistency()); + } +} + +} // namespace command_buffer diff --git a/gpu/command_buffer/client/gles2_c_lib.cc b/gpu/command_buffer/client/gles2_c_lib.cc new file mode 100644 index 0000000..d311a5d --- /dev/null +++ b/gpu/command_buffer/client/gles2_c_lib.cc @@ -0,0 +1,16 @@ +// Copyright (c) 2006-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. + +// These functions emluate GLES2 over command buffers for C. + +#include "gpu/command_buffer/client/gles2_lib.h" + +extern "C" { +// Include the auto-generated part of this file. We split this because it means +// we can easily edit the non-auto generated parts right here in this file +// instead of having to edit some template or the code generator. +#include "gpu/command_buffer/client/gles2_c_lib_autogen.h" +} // extern "C" + + diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h new file mode 100644 index 0000000..c03a350 --- /dev/null +++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h @@ -0,0 +1,504 @@ +// This file is auto-generated. DO NOT EDIT! + + +// These functions emluate GLES2 over command buffers. + + +void GLES2ActiveTexture(GLenum texture) { + gles2::GetGLContext()->ActiveTexture(texture); +} +void GLES2AttachShader(GLuint program, GLuint shader) { + gles2::GetGLContext()->AttachShader(program, shader); +} +void GLES2BindAttribLocation(GLuint program, GLuint index, const char* name) { + gles2::GetGLContext()->BindAttribLocation(program, index, name); +} +void GLES2BindBuffer(GLenum target, GLuint buffer) { + gles2::GetGLContext()->BindBuffer(target, buffer); +} +void GLES2BindFramebuffer(GLenum target, GLuint framebuffer) { + gles2::GetGLContext()->BindFramebuffer(target, framebuffer); +} +void GLES2BindRenderbuffer(GLenum target, GLuint renderbuffer) { + gles2::GetGLContext()->BindRenderbuffer(target, renderbuffer); +} +void GLES2BindTexture(GLenum target, GLuint texture) { + gles2::GetGLContext()->BindTexture(target, texture); +} +void GLES2BlendColor( + GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { + gles2::GetGLContext()->BlendColor(red, green, blue, alpha); +} +void GLES2BlendEquation(GLenum mode) { + gles2::GetGLContext()->BlendEquation(mode); +} +void GLES2BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) { + gles2::GetGLContext()->BlendEquationSeparate(modeRGB, modeAlpha); +} +void GLES2BlendFunc(GLenum sfactor, GLenum dfactor) { + gles2::GetGLContext()->BlendFunc(sfactor, dfactor); +} +void GLES2BlendFuncSeparate( + GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) { + gles2::GetGLContext()->BlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); +} +void GLES2BufferData( + GLenum target, GLsizeiptr size, const void* data, GLenum usage) { + gles2::GetGLContext()->BufferData(target, size, data, usage); +} +void GLES2BufferSubData( + GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { + gles2::GetGLContext()->BufferSubData(target, offset, size, data); +} +GLenum GLES2CheckFramebufferStatus(GLenum target) { + return gles2::GetGLContext()->CheckFramebufferStatus(target); +} +void GLES2Clear(GLbitfield mask) { + gles2::GetGLContext()->Clear(mask); +} +void GLES2ClearColor( + GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { + gles2::GetGLContext()->ClearColor(red, green, blue, alpha); +} +void GLES2ClearDepthf(GLclampf depth) { + gles2::GetGLContext()->ClearDepthf(depth); +} +void GLES2ClearStencil(GLint s) { + gles2::GetGLContext()->ClearStencil(s); +} +void GLES2ColorMask( + GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { + gles2::GetGLContext()->ColorMask(red, green, blue, alpha); +} +void GLES2CompileShader(GLuint shader) { + gles2::GetGLContext()->CompileShader(shader); +} +void GLES2CompressedTexImage2D( + GLenum target, GLint level, GLenum internalformat, GLsizei width, + GLsizei height, GLint border, GLsizei imageSize, const void* data) { + gles2::GetGLContext( + )->CompressedTexImage2D( + target, level, internalformat, width, height, border, imageSize, + data); +} +void GLES2CompressedTexSubImage2D( + GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, GLsizei imageSize, const void* data) { + gles2::GetGLContext( + )->CompressedTexSubImage2D( + target, level, xoffset, yoffset, width, height, format, imageSize, + data); +} +void GLES2CopyTexImage2D( + GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, + GLsizei width, GLsizei height, GLint border) { + gles2::GetGLContext( + )->CopyTexImage2D( + target, level, internalformat, x, y, width, height, border); +} +void GLES2CopyTexSubImage2D( + GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, + GLsizei width, GLsizei height) { + gles2::GetGLContext( + )->CopyTexSubImage2D( + target, level, xoffset, yoffset, x, y, width, height); +} +GLuint GLES2CreateProgram() { + return gles2::GetGLContext()->CreateProgram(); +} +GLuint GLES2CreateShader(GLenum type) { + return gles2::GetGLContext()->CreateShader(type); +} +void GLES2CullFace(GLenum mode) { + gles2::GetGLContext()->CullFace(mode); +} +void GLES2DeleteBuffers(GLsizei n, const GLuint* buffers) { + gles2::GetGLContext()->DeleteBuffers(n, buffers); +} +void GLES2DeleteFramebuffers(GLsizei n, const GLuint* framebuffers) { + gles2::GetGLContext()->DeleteFramebuffers(n, framebuffers); +} +void GLES2DeleteProgram(GLuint program) { + gles2::GetGLContext()->DeleteProgram(program); +} +void GLES2DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) { + gles2::GetGLContext()->DeleteRenderbuffers(n, renderbuffers); +} +void GLES2DeleteShader(GLuint shader) { + gles2::GetGLContext()->DeleteShader(shader); +} +void GLES2DeleteTextures(GLsizei n, const GLuint* textures) { + gles2::GetGLContext()->DeleteTextures(n, textures); +} +void GLES2DepthFunc(GLenum func) { + gles2::GetGLContext()->DepthFunc(func); +} +void GLES2DepthMask(GLboolean flag) { + gles2::GetGLContext()->DepthMask(flag); +} +void GLES2DepthRangef(GLclampf zNear, GLclampf zFar) { + gles2::GetGLContext()->DepthRangef(zNear, zFar); +} +void GLES2DetachShader(GLuint program, GLuint shader) { + gles2::GetGLContext()->DetachShader(program, shader); +} +void GLES2Disable(GLenum cap) { + gles2::GetGLContext()->Disable(cap); +} +void GLES2DisableVertexAttribArray(GLuint index) { + gles2::GetGLContext()->DisableVertexAttribArray(index); +} +void GLES2DrawArrays(GLenum mode, GLint first, GLsizei count) { + gles2::GetGLContext()->DrawArrays(mode, first, count); +} +void GLES2DrawElements( + GLenum mode, GLsizei count, GLenum type, const void* indices) { + gles2::GetGLContext()->DrawElements(mode, count, type, indices); +} +void GLES2Enable(GLenum cap) { + gles2::GetGLContext()->Enable(cap); +} +void GLES2EnableVertexAttribArray(GLuint index) { + gles2::GetGLContext()->EnableVertexAttribArray(index); +} +void GLES2Finish() { + gles2::GetGLContext()->Finish(); +} +void GLES2Flush() { + gles2::GetGLContext()->Flush(); +} +void GLES2FramebufferRenderbuffer( + GLenum target, GLenum attachment, GLenum renderbuffertarget, + GLuint renderbuffer) { + gles2::GetGLContext( + )->FramebufferRenderbuffer( + target, attachment, renderbuffertarget, renderbuffer); +} +void GLES2FramebufferTexture2D( + GLenum target, GLenum attachment, GLenum textarget, GLuint texture, + GLint level) { + gles2::GetGLContext( + )->FramebufferTexture2D(target, attachment, textarget, texture, level); +} +void GLES2FrontFace(GLenum mode) { + gles2::GetGLContext()->FrontFace(mode); +} +void GLES2GenBuffers(GLsizei n, GLuint* buffers) { + gles2::GetGLContext()->GenBuffers(n, buffers); +} +void GLES2GenerateMipmap(GLenum target) { + gles2::GetGLContext()->GenerateMipmap(target); +} +void GLES2GenFramebuffers(GLsizei n, GLuint* framebuffers) { + gles2::GetGLContext()->GenFramebuffers(n, framebuffers); +} +void GLES2GenRenderbuffers(GLsizei n, GLuint* renderbuffers) { + gles2::GetGLContext()->GenRenderbuffers(n, renderbuffers); +} +void GLES2GenTextures(GLsizei n, GLuint* textures) { + gles2::GetGLContext()->GenTextures(n, textures); +} +void GLES2GetActiveAttrib( + GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, + GLenum* type, char* name) { + gles2::GetGLContext( + )->GetActiveAttrib(program, index, bufsize, length, size, type, name); +} +void GLES2GetActiveUniform( + GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, + GLenum* type, char* name) { + gles2::GetGLContext( + )->GetActiveUniform(program, index, bufsize, length, size, type, name); +} +void GLES2GetAttachedShaders( + GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) { + gles2::GetGLContext()->GetAttachedShaders(program, maxcount, count, shaders); +} +int GLES2GetAttribLocation(GLuint program, const char* name) { + return gles2::GetGLContext()->GetAttribLocation(program, name); +} +void GLES2GetBooleanv(GLenum pname, GLboolean* params) { + gles2::GetGLContext()->GetBooleanv(pname, params); +} +void GLES2GetBufferParameteriv(GLenum target, GLenum pname, GLint* params) { + gles2::GetGLContext()->GetBufferParameteriv(target, pname, params); +} +GLenum GLES2GetError() { + return gles2::GetGLContext()->GetError(); +} +void GLES2GetFloatv(GLenum pname, GLfloat* params) { + gles2::GetGLContext()->GetFloatv(pname, params); +} +void GLES2GetFramebufferAttachmentParameteriv( + GLenum target, GLenum attachment, GLenum pname, GLint* params) { + gles2::GetGLContext( + )->GetFramebufferAttachmentParameteriv( + target, attachment, pname, params); +} +void GLES2GetIntegerv(GLenum pname, GLint* params) { + gles2::GetGLContext()->GetIntegerv(pname, params); +} +void GLES2GetProgramiv(GLuint program, GLenum pname, GLint* params) { + gles2::GetGLContext()->GetProgramiv(program, pname, params); +} +void GLES2GetProgramInfoLog( + GLuint program, GLsizei bufsize, GLsizei* length, char* infolog) { + gles2::GetGLContext()->GetProgramInfoLog(program, bufsize, length, infolog); +} +void GLES2GetRenderbufferParameteriv( + GLenum target, GLenum pname, GLint* params) { + gles2::GetGLContext()->GetRenderbufferParameteriv(target, pname, params); +} +void GLES2GetShaderiv(GLuint shader, GLenum pname, GLint* params) { + gles2::GetGLContext()->GetShaderiv(shader, pname, params); +} +void GLES2GetShaderInfoLog( + GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog) { + gles2::GetGLContext()->GetShaderInfoLog(shader, bufsize, length, infolog); +} +void GLES2GetShaderPrecisionFormat( + GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) { + gles2::GetGLContext( + )->GetShaderPrecisionFormat(shadertype, precisiontype, range, precision); +} +void GLES2GetShaderSource( + GLuint shader, GLsizei bufsize, GLsizei* length, char* source) { + gles2::GetGLContext()->GetShaderSource(shader, bufsize, length, source); +} +const GLubyte* GLES2GetString(GLenum name) { + return gles2::GetGLContext()->GetString(name); +} +void GLES2GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) { + gles2::GetGLContext()->GetTexParameterfv(target, pname, params); +} +void GLES2GetTexParameteriv(GLenum target, GLenum pname, GLint* params) { + gles2::GetGLContext()->GetTexParameteriv(target, pname, params); +} +void GLES2GetUniformfv(GLuint program, GLint location, GLfloat* params) { + gles2::GetGLContext()->GetUniformfv(program, location, params); +} +void GLES2GetUniformiv(GLuint program, GLint location, GLint* params) { + gles2::GetGLContext()->GetUniformiv(program, location, params); +} +int GLES2GetUniformLocation(GLuint program, const char* name) { + return gles2::GetGLContext()->GetUniformLocation(program, name); +} +void GLES2GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) { + gles2::GetGLContext()->GetVertexAttribfv(index, pname, params); +} +void GLES2GetVertexAttribiv(GLuint index, GLenum pname, GLint* params) { + gles2::GetGLContext()->GetVertexAttribiv(index, pname, params); +} +void GLES2GetVertexAttribPointerv(GLuint index, GLenum pname, void** pointer) { + gles2::GetGLContext()->GetVertexAttribPointerv(index, pname, pointer); +} +void GLES2Hint(GLenum target, GLenum mode) { + gles2::GetGLContext()->Hint(target, mode); +} +GLboolean GLES2IsBuffer(GLuint buffer) { + return gles2::GetGLContext()->IsBuffer(buffer); +} +GLboolean GLES2IsEnabled(GLenum cap) { + return gles2::GetGLContext()->IsEnabled(cap); +} +GLboolean GLES2IsFramebuffer(GLuint framebuffer) { + return gles2::GetGLContext()->IsFramebuffer(framebuffer); +} +GLboolean GLES2IsProgram(GLuint program) { + return gles2::GetGLContext()->IsProgram(program); +} +GLboolean GLES2IsRenderbuffer(GLuint renderbuffer) { + return gles2::GetGLContext()->IsRenderbuffer(renderbuffer); +} +GLboolean GLES2IsShader(GLuint shader) { + return gles2::GetGLContext()->IsShader(shader); +} +GLboolean GLES2IsTexture(GLuint texture) { + return gles2::GetGLContext()->IsTexture(texture); +} +void GLES2LineWidth(GLfloat width) { + gles2::GetGLContext()->LineWidth(width); +} +void GLES2LinkProgram(GLuint program) { + gles2::GetGLContext()->LinkProgram(program); +} +void GLES2PixelStorei(GLenum pname, GLint param) { + gles2::GetGLContext()->PixelStorei(pname, param); +} +void GLES2PolygonOffset(GLfloat factor, GLfloat units) { + gles2::GetGLContext()->PolygonOffset(factor, units); +} +void GLES2ReadPixels( + GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, + void* pixels) { + gles2::GetGLContext()->ReadPixels(x, y, width, height, format, type, pixels); +} +void GLES2RenderbufferStorage( + GLenum target, GLenum internalformat, GLsizei width, GLsizei height) { + gles2::GetGLContext( + )->RenderbufferStorage(target, internalformat, width, height); +} +void GLES2SampleCoverage(GLclampf value, GLboolean invert) { + gles2::GetGLContext()->SampleCoverage(value, invert); +} +void GLES2Scissor(GLint x, GLint y, GLsizei width, GLsizei height) { + gles2::GetGLContext()->Scissor(x, y, width, height); +} +void GLES2ShaderSource( + GLuint shader, GLsizei count, const char** string, const GLint* length) { + gles2::GetGLContext()->ShaderSource(shader, count, string, length); +} +void GLES2StencilFunc(GLenum func, GLint ref, GLuint mask) { + gles2::GetGLContext()->StencilFunc(func, ref, mask); +} +void GLES2StencilFuncSeparate( + GLenum face, GLenum func, GLint ref, GLuint mask) { + gles2::GetGLContext()->StencilFuncSeparate(face, func, ref, mask); +} +void GLES2StencilMask(GLuint mask) { + gles2::GetGLContext()->StencilMask(mask); +} +void GLES2StencilMaskSeparate(GLenum face, GLuint mask) { + gles2::GetGLContext()->StencilMaskSeparate(face, mask); +} +void GLES2StencilOp(GLenum fail, GLenum zfail, GLenum zpass) { + gles2::GetGLContext()->StencilOp(fail, zfail, zpass); +} +void GLES2StencilOpSeparate( + GLenum face, GLenum fail, GLenum zfail, GLenum zpass) { + gles2::GetGLContext()->StencilOpSeparate(face, fail, zfail, zpass); +} +void GLES2TexImage2D( + GLenum target, GLint level, GLint internalformat, GLsizei width, + GLsizei height, GLint border, GLenum format, GLenum type, + const void* pixels) { + gles2::GetGLContext( + )->TexImage2D( + target, level, internalformat, width, height, border, format, type, + pixels); +} +void GLES2TexParameterf(GLenum target, GLenum pname, GLfloat param) { + gles2::GetGLContext()->TexParameterf(target, pname, param); +} +void GLES2TexParameterfv(GLenum target, GLenum pname, const GLfloat* params) { + gles2::GetGLContext()->TexParameterfv(target, pname, params); +} +void GLES2TexParameteri(GLenum target, GLenum pname, GLint param) { + gles2::GetGLContext()->TexParameteri(target, pname, param); +} +void GLES2TexParameteriv(GLenum target, GLenum pname, const GLint* params) { + gles2::GetGLContext()->TexParameteriv(target, pname, params); +} +void GLES2TexSubImage2D( + GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, GLenum type, const void* pixels) { + gles2::GetGLContext( + )->TexSubImage2D( + target, level, xoffset, yoffset, width, height, format, type, + pixels); +} +void GLES2Uniform1f(GLint location, GLfloat x) { + gles2::GetGLContext()->Uniform1f(location, x); +} +void GLES2Uniform1fv(GLint location, GLsizei count, const GLfloat* v) { + gles2::GetGLContext()->Uniform1fv(location, count, v); +} +void GLES2Uniform1i(GLint location, GLint x) { + gles2::GetGLContext()->Uniform1i(location, x); +} +void GLES2Uniform1iv(GLint location, GLsizei count, const GLint* v) { + gles2::GetGLContext()->Uniform1iv(location, count, v); +} +void GLES2Uniform2f(GLint location, GLfloat x, GLfloat y) { + gles2::GetGLContext()->Uniform2f(location, x, y); +} +void GLES2Uniform2fv(GLint location, GLsizei count, const GLfloat* v) { + gles2::GetGLContext()->Uniform2fv(location, count, v); +} +void GLES2Uniform2i(GLint location, GLint x, GLint y) { + gles2::GetGLContext()->Uniform2i(location, x, y); +} +void GLES2Uniform2iv(GLint location, GLsizei count, const GLint* v) { + gles2::GetGLContext()->Uniform2iv(location, count, v); +} +void GLES2Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) { + gles2::GetGLContext()->Uniform3f(location, x, y, z); +} +void GLES2Uniform3fv(GLint location, GLsizei count, const GLfloat* v) { + gles2::GetGLContext()->Uniform3fv(location, count, v); +} +void GLES2Uniform3i(GLint location, GLint x, GLint y, GLint z) { + gles2::GetGLContext()->Uniform3i(location, x, y, z); +} +void GLES2Uniform3iv(GLint location, GLsizei count, const GLint* v) { + gles2::GetGLContext()->Uniform3iv(location, count, v); +} +void GLES2Uniform4f( + GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { + gles2::GetGLContext()->Uniform4f(location, x, y, z, w); +} +void GLES2Uniform4fv(GLint location, GLsizei count, const GLfloat* v) { + gles2::GetGLContext()->Uniform4fv(location, count, v); +} +void GLES2Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) { + gles2::GetGLContext()->Uniform4i(location, x, y, z, w); +} +void GLES2Uniform4iv(GLint location, GLsizei count, const GLint* v) { + gles2::GetGLContext()->Uniform4iv(location, count, v); +} +void GLES2UniformMatrix2fv( + GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { + gles2::GetGLContext()->UniformMatrix2fv(location, count, transpose, value); +} +void GLES2UniformMatrix3fv( + GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { + gles2::GetGLContext()->UniformMatrix3fv(location, count, transpose, value); +} +void GLES2UniformMatrix4fv( + GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { + gles2::GetGLContext()->UniformMatrix4fv(location, count, transpose, value); +} +void GLES2UseProgram(GLuint program) { + gles2::GetGLContext()->UseProgram(program); +} +void GLES2ValidateProgram(GLuint program) { + gles2::GetGLContext()->ValidateProgram(program); +} +void GLES2VertexAttrib1f(GLuint indx, GLfloat x) { + gles2::GetGLContext()->VertexAttrib1f(indx, x); +} +void GLES2VertexAttrib1fv(GLuint indx, const GLfloat* values) { + gles2::GetGLContext()->VertexAttrib1fv(indx, values); +} +void GLES2VertexAttrib2f(GLuint indx, GLfloat x, GLfloat y) { + gles2::GetGLContext()->VertexAttrib2f(indx, x, y); +} +void GLES2VertexAttrib2fv(GLuint indx, const GLfloat* values) { + gles2::GetGLContext()->VertexAttrib2fv(indx, values); +} +void GLES2VertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z) { + gles2::GetGLContext()->VertexAttrib3f(indx, x, y, z); +} +void GLES2VertexAttrib3fv(GLuint indx, const GLfloat* values) { + gles2::GetGLContext()->VertexAttrib3fv(indx, values); +} +void GLES2VertexAttrib4f( + GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { + gles2::GetGLContext()->VertexAttrib4f(indx, x, y, z, w); +} +void GLES2VertexAttrib4fv(GLuint indx, const GLfloat* values) { + gles2::GetGLContext()->VertexAttrib4fv(indx, values); +} +void GLES2VertexAttribPointer( + GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, + const void* ptr) { + gles2::GetGLContext( + )->VertexAttribPointer(indx, size, type, normalized, stride, ptr); +} +void GLES2Viewport(GLint x, GLint y, GLsizei width, GLsizei height) { + gles2::GetGLContext()->Viewport(x, y, width, height); +} +void GLES2SwapBuffers() { + gles2::GetGLContext()->SwapBuffers(); +} + diff --git a/gpu/command_buffer/client/gles2_cmd_helper.cc b/gpu/command_buffer/client/gles2_cmd_helper.cc new file mode 100644 index 0000000..1dff914 --- /dev/null +++ b/gpu/command_buffer/client/gles2_cmd_helper.cc @@ -0,0 +1,14 @@ +// Copyright (c) 2006-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/client/gles2_cmd_helper.h" + +namespace command_buffer { + +// Currently this is a place holder. + +} // namespace command_buffer + + + diff --git a/gpu/command_buffer/client/gles2_cmd_helper.h b/gpu/command_buffer/client/gles2_cmd_helper.h new file mode 100644 index 0000000..9a1a741 --- /dev/null +++ b/gpu/command_buffer/client/gles2_cmd_helper.h @@ -0,0 +1,36 @@ +// Copyright (c) 2006-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. + +#ifndef GPU_COMMAND_BUFFER_CLIENT_GLES2_CMD_HELPER_H +#define GPU_COMMAND_BUFFER_CLIENT_GLES2_CMD_HELPER_H + +#include "gpu/command_buffer/client/cmd_buffer_helper.h" +#include "gpu/command_buffer/common/gles2_cmd_format.h" + +namespace command_buffer { +namespace gles2 { + +// A class that helps write GL command buffers. +class GLES2CmdHelper : public CommandBufferHelper { + public: + explicit GLES2CmdHelper(command_buffer::CommandBuffer* command_buffer) + : CommandBufferHelper(command_buffer) { + } + virtual ~GLES2CmdHelper() { + } + + // Include the auto-generated part of this class. We split this because it + // means we can easily edit the non-auto generated parts right here in this + // file instead of having to edit some template or the code generator. + #include "gpu/command_buffer/client/gles2_cmd_helper_autogen.h" + + private: + DISALLOW_COPY_AND_ASSIGN(GLES2CmdHelper); +}; + +} // namespace gles2 +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_CMD_HELPER_H + diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h new file mode 100644 index 0000000..1cfee5b --- /dev/null +++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h @@ -0,0 +1,1143 @@ + void ActiveTexture(GLenum texture) { + gles2::ActiveTexture& c = GetCmdSpace<gles2::ActiveTexture>(); + c.Init(texture); + } + + void AttachShader(GLuint program, GLuint shader) { + gles2::AttachShader& c = GetCmdSpace<gles2::AttachShader>(); + c.Init(program, shader); + } + + void BindAttribLocation( + GLuint program, GLuint index, uint32 name_shm_id, uint32 name_shm_offset, + uint32 data_size) { + gles2::BindAttribLocation& c = GetCmdSpace<gles2::BindAttribLocation>(); + c.Init(program, index, name_shm_id, name_shm_offset, data_size); + } + + void BindAttribLocationImmediate( + GLuint program, GLuint index, const char* name) { + const uint32 size = gles2::BindAttribLocationImmediate::ComputeSize(name); + gles2::BindAttribLocationImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::BindAttribLocationImmediate>( + size); + c.Init(program, index, name); + } + + void BindBuffer(GLenum target, GLuint buffer) { + gles2::BindBuffer& c = GetCmdSpace<gles2::BindBuffer>(); + c.Init(target, buffer); + } + + void BindFramebuffer(GLenum target, GLuint framebuffer) { + gles2::BindFramebuffer& c = GetCmdSpace<gles2::BindFramebuffer>(); + c.Init(target, framebuffer); + } + + void BindRenderbuffer(GLenum target, GLuint renderbuffer) { + gles2::BindRenderbuffer& c = GetCmdSpace<gles2::BindRenderbuffer>(); + c.Init(target, renderbuffer); + } + + void BindTexture(GLenum target, GLuint texture) { + gles2::BindTexture& c = GetCmdSpace<gles2::BindTexture>(); + c.Init(target, texture); + } + + void BlendColor( + GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { + gles2::BlendColor& c = GetCmdSpace<gles2::BlendColor>(); + c.Init(red, green, blue, alpha); + } + + void BlendEquation(GLenum mode) { + gles2::BlendEquation& c = GetCmdSpace<gles2::BlendEquation>(); + c.Init(mode); + } + + void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) { + gles2::BlendEquationSeparate& c = + GetCmdSpace<gles2::BlendEquationSeparate>(); + c.Init(modeRGB, modeAlpha); + } + + void BlendFunc(GLenum sfactor, GLenum dfactor) { + gles2::BlendFunc& c = GetCmdSpace<gles2::BlendFunc>(); + c.Init(sfactor, dfactor); + } + + void BlendFuncSeparate( + GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) { + gles2::BlendFuncSeparate& c = GetCmdSpace<gles2::BlendFuncSeparate>(); + c.Init(srcRGB, dstRGB, srcAlpha, dstAlpha); + } + + void BufferData( + GLenum target, GLsizeiptr size, uint32 data_shm_id, + uint32 data_shm_offset, GLenum usage) { + gles2::BufferData& c = GetCmdSpace<gles2::BufferData>(); + c.Init(target, size, data_shm_id, data_shm_offset, usage); + } + + void BufferDataImmediate(GLenum target, GLsizeiptr size, GLenum usage) { + const uint32 s = 0; // TODO(gman): compute correct size + gles2::BufferDataImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::BufferDataImmediate>(s); + c.Init(target, size, usage); + } + + void BufferSubData( + GLenum target, GLintptr offset, GLsizeiptr size, uint32 data_shm_id, + uint32 data_shm_offset) { + gles2::BufferSubData& c = GetCmdSpace<gles2::BufferSubData>(); + c.Init(target, offset, size, data_shm_id, data_shm_offset); + } + + void BufferSubDataImmediate( + GLenum target, GLintptr offset, GLsizeiptr size) { + const uint32 s = 0; // TODO(gman): compute correct size + gles2::BufferSubDataImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::BufferSubDataImmediate>(s); + c.Init(target, offset, size); + } + + void CheckFramebufferStatus(GLenum target) { + gles2::CheckFramebufferStatus& c = + GetCmdSpace<gles2::CheckFramebufferStatus>(); + c.Init(target); + } + + void Clear(GLbitfield mask) { + gles2::Clear& c = GetCmdSpace<gles2::Clear>(); + c.Init(mask); + } + + void ClearColor( + GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { + gles2::ClearColor& c = GetCmdSpace<gles2::ClearColor>(); + c.Init(red, green, blue, alpha); + } + + void ClearDepthf(GLclampf depth) { + gles2::ClearDepthf& c = GetCmdSpace<gles2::ClearDepthf>(); + c.Init(depth); + } + + void ClearStencil(GLint s) { + gles2::ClearStencil& c = GetCmdSpace<gles2::ClearStencil>(); + c.Init(s); + } + + void ColorMask( + GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { + gles2::ColorMask& c = GetCmdSpace<gles2::ColorMask>(); + c.Init(red, green, blue, alpha); + } + + void CompileShader(GLuint shader) { + gles2::CompileShader& c = GetCmdSpace<gles2::CompileShader>(); + c.Init(shader); + } + + void CompressedTexImage2D( + GLenum target, GLint level, GLenum internalformat, GLsizei width, + GLsizei height, GLint border, GLsizei imageSize, uint32 data_shm_id, + uint32 data_shm_offset) { + gles2::CompressedTexImage2D& c = + GetCmdSpace<gles2::CompressedTexImage2D>(); + c.Init( + target, level, internalformat, width, height, border, imageSize, + data_shm_id, data_shm_offset); + } + + void CompressedTexImage2DImmediate( + GLenum target, GLint level, GLenum internalformat, GLsizei width, + GLsizei height, GLint border, GLsizei imageSize) { + const uint32 s = 0; // TODO(gman): compute correct size + gles2::CompressedTexImage2DImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::CompressedTexImage2DImmediate>(s); + c.Init(target, level, internalformat, width, height, border, imageSize); + } + + void CompressedTexSubImage2D( + GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, GLsizei imageSize, uint32 data_shm_id, + uint32 data_shm_offset) { + gles2::CompressedTexSubImage2D& c = + GetCmdSpace<gles2::CompressedTexSubImage2D>(); + c.Init( + target, level, xoffset, yoffset, width, height, format, imageSize, + data_shm_id, data_shm_offset); + } + + void CompressedTexSubImage2DImmediate( + GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, GLsizei imageSize) { + const uint32 s = 0; // TODO(gman): compute correct size + gles2::CompressedTexSubImage2DImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::CompressedTexSubImage2DImmediate>( + s); + c.Init(target, level, xoffset, yoffset, width, height, format, imageSize); + } + + void CopyTexImage2D( + GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, + GLsizei width, GLsizei height, GLint border) { + gles2::CopyTexImage2D& c = GetCmdSpace<gles2::CopyTexImage2D>(); + c.Init(target, level, internalformat, x, y, width, height, border); + } + + void CopyTexSubImage2D( + GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, + GLint y, GLsizei width, GLsizei height) { + gles2::CopyTexSubImage2D& c = GetCmdSpace<gles2::CopyTexSubImage2D>(); + c.Init(target, level, xoffset, yoffset, x, y, width, height); + } + + void CreateProgram(uint32 client_id) { + gles2::CreateProgram& c = GetCmdSpace<gles2::CreateProgram>(); + c.Init(client_id); + } + + void CreateShader(GLenum type, uint32 client_id) { + gles2::CreateShader& c = GetCmdSpace<gles2::CreateShader>(); + c.Init(type, client_id); + } + + void CullFace(GLenum mode) { + gles2::CullFace& c = GetCmdSpace<gles2::CullFace>(); + c.Init(mode); + } + + void DeleteBuffers( + GLsizei n, uint32 buffers_shm_id, uint32 buffers_shm_offset) { + gles2::DeleteBuffers& c = GetCmdSpace<gles2::DeleteBuffers>(); + c.Init(n, buffers_shm_id, buffers_shm_offset); + } + + void DeleteBuffersImmediate(GLsizei n, const GLuint* buffers) { + const uint32 size = gles2::DeleteBuffersImmediate::ComputeSize(n); + gles2::DeleteBuffersImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::DeleteBuffersImmediate>(size); + c.Init(n, buffers); + } + + void DeleteFramebuffers( + GLsizei n, uint32 framebuffers_shm_id, uint32 framebuffers_shm_offset) { + gles2::DeleteFramebuffers& c = GetCmdSpace<gles2::DeleteFramebuffers>(); + c.Init(n, framebuffers_shm_id, framebuffers_shm_offset); + } + + void DeleteFramebuffersImmediate(GLsizei n, const GLuint* framebuffers) { + const uint32 size = gles2::DeleteFramebuffersImmediate::ComputeSize(n); + gles2::DeleteFramebuffersImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::DeleteFramebuffersImmediate>( + size); + c.Init(n, framebuffers); + } + + void DeleteProgram(GLuint program) { + gles2::DeleteProgram& c = GetCmdSpace<gles2::DeleteProgram>(); + c.Init(program); + } + + void DeleteRenderbuffers( + GLsizei n, uint32 renderbuffers_shm_id, + uint32 renderbuffers_shm_offset) { + gles2::DeleteRenderbuffers& c = GetCmdSpace<gles2::DeleteRenderbuffers>(); + c.Init(n, renderbuffers_shm_id, renderbuffers_shm_offset); + } + + void DeleteRenderbuffersImmediate(GLsizei n, const GLuint* renderbuffers) { + const uint32 size = gles2::DeleteRenderbuffersImmediate::ComputeSize(n); + gles2::DeleteRenderbuffersImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::DeleteRenderbuffersImmediate>( + size); + c.Init(n, renderbuffers); + } + + void DeleteShader(GLuint shader) { + gles2::DeleteShader& c = GetCmdSpace<gles2::DeleteShader>(); + c.Init(shader); + } + + void DeleteTextures( + GLsizei n, uint32 textures_shm_id, uint32 textures_shm_offset) { + gles2::DeleteTextures& c = GetCmdSpace<gles2::DeleteTextures>(); + c.Init(n, textures_shm_id, textures_shm_offset); + } + + void DeleteTexturesImmediate(GLsizei n, const GLuint* textures) { + const uint32 size = gles2::DeleteTexturesImmediate::ComputeSize(n); + gles2::DeleteTexturesImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::DeleteTexturesImmediate>(size); + c.Init(n, textures); + } + + void DepthFunc(GLenum func) { + gles2::DepthFunc& c = GetCmdSpace<gles2::DepthFunc>(); + c.Init(func); + } + + void DepthMask(GLboolean flag) { + gles2::DepthMask& c = GetCmdSpace<gles2::DepthMask>(); + c.Init(flag); + } + + void DepthRangef(GLclampf zNear, GLclampf zFar) { + gles2::DepthRangef& c = GetCmdSpace<gles2::DepthRangef>(); + c.Init(zNear, zFar); + } + + void DetachShader(GLuint program, GLuint shader) { + gles2::DetachShader& c = GetCmdSpace<gles2::DetachShader>(); + c.Init(program, shader); + } + + void Disable(GLenum cap) { + gles2::Disable& c = GetCmdSpace<gles2::Disable>(); + c.Init(cap); + } + + void DisableVertexAttribArray(GLuint index) { + gles2::DisableVertexAttribArray& c = + GetCmdSpace<gles2::DisableVertexAttribArray>(); + c.Init(index); + } + + void DrawArrays(GLenum mode, GLint first, GLsizei count) { + gles2::DrawArrays& c = GetCmdSpace<gles2::DrawArrays>(); + c.Init(mode, first, count); + } + + void DrawElements( + GLenum mode, GLsizei count, GLenum type, GLuint index_offset) { + gles2::DrawElements& c = GetCmdSpace<gles2::DrawElements>(); + c.Init(mode, count, type, index_offset); + } + + void Enable(GLenum cap) { + gles2::Enable& c = GetCmdSpace<gles2::Enable>(); + c.Init(cap); + } + + void EnableVertexAttribArray(GLuint index) { + gles2::EnableVertexAttribArray& c = + GetCmdSpace<gles2::EnableVertexAttribArray>(); + c.Init(index); + } + + void Finish() { + gles2::Finish& c = GetCmdSpace<gles2::Finish>(); + c.Init(); + } + + void Flush() { + gles2::Flush& c = GetCmdSpace<gles2::Flush>(); + c.Init(); + } + + void FramebufferRenderbuffer( + GLenum target, GLenum attachment, GLenum renderbuffertarget, + GLuint renderbuffer) { + gles2::FramebufferRenderbuffer& c = + GetCmdSpace<gles2::FramebufferRenderbuffer>(); + c.Init(target, attachment, renderbuffertarget, renderbuffer); + } + + void FramebufferTexture2D( + GLenum target, GLenum attachment, GLenum textarget, GLuint texture, + GLint level) { + gles2::FramebufferTexture2D& c = + GetCmdSpace<gles2::FramebufferTexture2D>(); + c.Init(target, attachment, textarget, texture, level); + } + + void FrontFace(GLenum mode) { + gles2::FrontFace& c = GetCmdSpace<gles2::FrontFace>(); + c.Init(mode); + } + + void GenBuffers( + GLsizei n, uint32 buffers_shm_id, uint32 buffers_shm_offset) { + gles2::GenBuffers& c = GetCmdSpace<gles2::GenBuffers>(); + c.Init(n, buffers_shm_id, buffers_shm_offset); + } + + void GenBuffersImmediate(GLsizei n, GLuint* buffers) { + const uint32 size = gles2::GenBuffersImmediate::ComputeSize(n); + gles2::GenBuffersImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::GenBuffersImmediate>(size); + c.Init(n, buffers); + } + + void GenerateMipmap(GLenum target) { + gles2::GenerateMipmap& c = GetCmdSpace<gles2::GenerateMipmap>(); + c.Init(target); + } + + void GenFramebuffers( + GLsizei n, uint32 framebuffers_shm_id, uint32 framebuffers_shm_offset) { + gles2::GenFramebuffers& c = GetCmdSpace<gles2::GenFramebuffers>(); + c.Init(n, framebuffers_shm_id, framebuffers_shm_offset); + } + + void GenFramebuffersImmediate(GLsizei n, GLuint* framebuffers) { + const uint32 size = gles2::GenFramebuffersImmediate::ComputeSize(n); + gles2::GenFramebuffersImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::GenFramebuffersImmediate>(size); + c.Init(n, framebuffers); + } + + void GenRenderbuffers( + GLsizei n, uint32 renderbuffers_shm_id, + uint32 renderbuffers_shm_offset) { + gles2::GenRenderbuffers& c = GetCmdSpace<gles2::GenRenderbuffers>(); + c.Init(n, renderbuffers_shm_id, renderbuffers_shm_offset); + } + + void GenRenderbuffersImmediate(GLsizei n, GLuint* renderbuffers) { + const uint32 size = gles2::GenRenderbuffersImmediate::ComputeSize(n); + gles2::GenRenderbuffersImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::GenRenderbuffersImmediate>(size); + c.Init(n, renderbuffers); + } + + void GenTextures( + GLsizei n, uint32 textures_shm_id, uint32 textures_shm_offset) { + gles2::GenTextures& c = GetCmdSpace<gles2::GenTextures>(); + c.Init(n, textures_shm_id, textures_shm_offset); + } + + void GenTexturesImmediate(GLsizei n, GLuint* textures) { + const uint32 size = gles2::GenTexturesImmediate::ComputeSize(n); + gles2::GenTexturesImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::GenTexturesImmediate>(size); + c.Init(n, textures); + } + + void GetActiveAttrib( + GLuint program, GLuint index, GLsizei bufsize, uint32 length_shm_id, + uint32 length_shm_offset, uint32 size_shm_id, uint32 size_shm_offset, + uint32 type_shm_id, uint32 type_shm_offset, uint32 name_shm_id, + uint32 name_shm_offset) { + gles2::GetActiveAttrib& c = GetCmdSpace<gles2::GetActiveAttrib>(); + c.Init( + program, index, bufsize, length_shm_id, length_shm_offset, size_shm_id, + size_shm_offset, type_shm_id, type_shm_offset, name_shm_id, + name_shm_offset); + } + + void GetActiveUniform( + GLuint program, GLuint index, GLsizei bufsize, uint32 length_shm_id, + uint32 length_shm_offset, uint32 size_shm_id, uint32 size_shm_offset, + uint32 type_shm_id, uint32 type_shm_offset, uint32 name_shm_id, + uint32 name_shm_offset) { + gles2::GetActiveUniform& c = GetCmdSpace<gles2::GetActiveUniform>(); + c.Init( + program, index, bufsize, length_shm_id, length_shm_offset, size_shm_id, + size_shm_offset, type_shm_id, type_shm_offset, name_shm_id, + name_shm_offset); + } + + void GetAttachedShaders( + GLuint program, GLsizei maxcount, uint32 count_shm_id, + uint32 count_shm_offset, uint32 shaders_shm_id, + uint32 shaders_shm_offset) { + gles2::GetAttachedShaders& c = GetCmdSpace<gles2::GetAttachedShaders>(); + c.Init( + program, maxcount, count_shm_id, count_shm_offset, shaders_shm_id, + shaders_shm_offset); + } + + void GetAttribLocation( + GLuint program, uint32 name_shm_id, uint32 name_shm_offset, + uint32 data_size) { + gles2::GetAttribLocation& c = GetCmdSpace<gles2::GetAttribLocation>(); + c.Init(program, name_shm_id, name_shm_offset, data_size); + } + + void GetAttribLocationImmediate(GLuint program, const char* name) { + const uint32 size = gles2::GetAttribLocationImmediate::ComputeSize(name); + gles2::GetAttribLocationImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::GetAttribLocationImmediate>(size); + c.Init(program, name); + } + + void GetBooleanv( + GLenum pname, uint32 params_shm_id, uint32 params_shm_offset) { + gles2::GetBooleanv& c = GetCmdSpace<gles2::GetBooleanv>(); + c.Init(pname, params_shm_id, params_shm_offset); + } + + void GetBufferParameteriv( + GLenum target, GLenum pname, uint32 params_shm_id, + uint32 params_shm_offset) { + gles2::GetBufferParameteriv& c = + GetCmdSpace<gles2::GetBufferParameteriv>(); + c.Init(target, pname, params_shm_id, params_shm_offset); + } + + void GetError(uint32 result_shm_id, uint32 result_shm_offset) { + gles2::GetError& c = GetCmdSpace<gles2::GetError>(); + c.Init(result_shm_id, result_shm_offset); + } + + void GetFloatv( + GLenum pname, uint32 params_shm_id, uint32 params_shm_offset) { + gles2::GetFloatv& c = GetCmdSpace<gles2::GetFloatv>(); + c.Init(pname, params_shm_id, params_shm_offset); + } + + void GetFramebufferAttachmentParameteriv( + GLenum target, GLenum attachment, GLenum pname, uint32 params_shm_id, + uint32 params_shm_offset) { + gles2::GetFramebufferAttachmentParameteriv& c = + GetCmdSpace<gles2::GetFramebufferAttachmentParameteriv>(); + c.Init(target, attachment, pname, params_shm_id, params_shm_offset); + } + + void GetIntegerv( + GLenum pname, uint32 params_shm_id, uint32 params_shm_offset) { + gles2::GetIntegerv& c = GetCmdSpace<gles2::GetIntegerv>(); + c.Init(pname, params_shm_id, params_shm_offset); + } + + void GetProgramiv( + GLuint program, GLenum pname, uint32 params_shm_id, + uint32 params_shm_offset) { + gles2::GetProgramiv& c = GetCmdSpace<gles2::GetProgramiv>(); + c.Init(program, pname, params_shm_id, params_shm_offset); + } + + void GetProgramInfoLog( + GLuint program, GLsizei bufsize, uint32 length_shm_id, + uint32 length_shm_offset, uint32 infolog_shm_id, + uint32 infolog_shm_offset) { + gles2::GetProgramInfoLog& c = GetCmdSpace<gles2::GetProgramInfoLog>(); + c.Init( + program, bufsize, length_shm_id, length_shm_offset, infolog_shm_id, + infolog_shm_offset); + } + + void GetRenderbufferParameteriv( + GLenum target, GLenum pname, uint32 params_shm_id, + uint32 params_shm_offset) { + gles2::GetRenderbufferParameteriv& c = + GetCmdSpace<gles2::GetRenderbufferParameteriv>(); + c.Init(target, pname, params_shm_id, params_shm_offset); + } + + void GetShaderiv( + GLuint shader, GLenum pname, uint32 params_shm_id, + uint32 params_shm_offset) { + gles2::GetShaderiv& c = GetCmdSpace<gles2::GetShaderiv>(); + c.Init(shader, pname, params_shm_id, params_shm_offset); + } + + void GetShaderInfoLog( + GLuint shader, GLsizei bufsize, uint32 length_shm_id, + uint32 length_shm_offset, uint32 infolog_shm_id, + uint32 infolog_shm_offset) { + gles2::GetShaderInfoLog& c = GetCmdSpace<gles2::GetShaderInfoLog>(); + c.Init( + shader, bufsize, length_shm_id, length_shm_offset, infolog_shm_id, + infolog_shm_offset); + } + + void GetShaderPrecisionFormat( + GLenum shadertype, GLenum precisiontype, uint32 range_shm_id, + uint32 range_shm_offset, uint32 precision_shm_id, + uint32 precision_shm_offset) { + gles2::GetShaderPrecisionFormat& c = + GetCmdSpace<gles2::GetShaderPrecisionFormat>(); + c.Init( + shadertype, precisiontype, range_shm_id, range_shm_offset, + precision_shm_id, precision_shm_offset); + } + + void GetShaderSource( + GLuint shader, GLsizei bufsize, uint32 length_shm_id, + uint32 length_shm_offset, uint32 source_shm_id, + uint32 source_shm_offset) { + gles2::GetShaderSource& c = GetCmdSpace<gles2::GetShaderSource>(); + c.Init( + shader, bufsize, length_shm_id, length_shm_offset, source_shm_id, + source_shm_offset); + } + + void GetString(GLenum name) { + gles2::GetString& c = GetCmdSpace<gles2::GetString>(); + c.Init(name); + } + + void GetTexParameterfv( + GLenum target, GLenum pname, uint32 params_shm_id, + uint32 params_shm_offset) { + gles2::GetTexParameterfv& c = GetCmdSpace<gles2::GetTexParameterfv>(); + c.Init(target, pname, params_shm_id, params_shm_offset); + } + + void GetTexParameteriv( + GLenum target, GLenum pname, uint32 params_shm_id, + uint32 params_shm_offset) { + gles2::GetTexParameteriv& c = GetCmdSpace<gles2::GetTexParameteriv>(); + c.Init(target, pname, params_shm_id, params_shm_offset); + } + + void GetUniformfv( + GLuint program, GLint location, uint32 params_shm_id, + uint32 params_shm_offset) { + gles2::GetUniformfv& c = GetCmdSpace<gles2::GetUniformfv>(); + c.Init(program, location, params_shm_id, params_shm_offset); + } + + void GetUniformiv( + GLuint program, GLint location, uint32 params_shm_id, + uint32 params_shm_offset) { + gles2::GetUniformiv& c = GetCmdSpace<gles2::GetUniformiv>(); + c.Init(program, location, params_shm_id, params_shm_offset); + } + + void GetUniformLocation( + GLuint program, uint32 name_shm_id, uint32 name_shm_offset, + uint32 data_size) { + gles2::GetUniformLocation& c = GetCmdSpace<gles2::GetUniformLocation>(); + c.Init(program, name_shm_id, name_shm_offset, data_size); + } + + void GetUniformLocationImmediate(GLuint program, const char* name) { + const uint32 size = gles2::GetUniformLocationImmediate::ComputeSize(name); + gles2::GetUniformLocationImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::GetUniformLocationImmediate>( + size); + c.Init(program, name); + } + + void GetVertexAttribfv( + GLuint index, GLenum pname, uint32 params_shm_id, + uint32 params_shm_offset) { + gles2::GetVertexAttribfv& c = GetCmdSpace<gles2::GetVertexAttribfv>(); + c.Init(index, pname, params_shm_id, params_shm_offset); + } + + void GetVertexAttribiv( + GLuint index, GLenum pname, uint32 params_shm_id, + uint32 params_shm_offset) { + gles2::GetVertexAttribiv& c = GetCmdSpace<gles2::GetVertexAttribiv>(); + c.Init(index, pname, params_shm_id, params_shm_offset); + } + + void GetVertexAttribPointerv( + GLuint index, GLenum pname, uint32 pointer_shm_id, + uint32 pointer_shm_offset) { + gles2::GetVertexAttribPointerv& c = + GetCmdSpace<gles2::GetVertexAttribPointerv>(); + c.Init(index, pname, pointer_shm_id, pointer_shm_offset); + } + + void Hint(GLenum target, GLenum mode) { + gles2::Hint& c = GetCmdSpace<gles2::Hint>(); + c.Init(target, mode); + } + + void IsBuffer( + GLuint buffer, uint32 result_shm_id, uint32 result_shm_offset) { + gles2::IsBuffer& c = GetCmdSpace<gles2::IsBuffer>(); + c.Init(buffer, result_shm_id, result_shm_offset); + } + + void IsEnabled(GLenum cap, uint32 result_shm_id, uint32 result_shm_offset) { + gles2::IsEnabled& c = GetCmdSpace<gles2::IsEnabled>(); + c.Init(cap, result_shm_id, result_shm_offset); + } + + void IsFramebuffer( + GLuint framebuffer, uint32 result_shm_id, uint32 result_shm_offset) { + gles2::IsFramebuffer& c = GetCmdSpace<gles2::IsFramebuffer>(); + c.Init(framebuffer, result_shm_id, result_shm_offset); + } + + void IsProgram( + GLuint program, uint32 result_shm_id, uint32 result_shm_offset) { + gles2::IsProgram& c = GetCmdSpace<gles2::IsProgram>(); + c.Init(program, result_shm_id, result_shm_offset); + } + + void IsRenderbuffer( + GLuint renderbuffer, uint32 result_shm_id, uint32 result_shm_offset) { + gles2::IsRenderbuffer& c = GetCmdSpace<gles2::IsRenderbuffer>(); + c.Init(renderbuffer, result_shm_id, result_shm_offset); + } + + void IsShader( + GLuint shader, uint32 result_shm_id, uint32 result_shm_offset) { + gles2::IsShader& c = GetCmdSpace<gles2::IsShader>(); + c.Init(shader, result_shm_id, result_shm_offset); + } + + void IsTexture( + GLuint texture, uint32 result_shm_id, uint32 result_shm_offset) { + gles2::IsTexture& c = GetCmdSpace<gles2::IsTexture>(); + c.Init(texture, result_shm_id, result_shm_offset); + } + + void LineWidth(GLfloat width) { + gles2::LineWidth& c = GetCmdSpace<gles2::LineWidth>(); + c.Init(width); + } + + void LinkProgram(GLuint program) { + gles2::LinkProgram& c = GetCmdSpace<gles2::LinkProgram>(); + c.Init(program); + } + + void PixelStorei(GLenum pname, GLint param) { + gles2::PixelStorei& c = GetCmdSpace<gles2::PixelStorei>(); + c.Init(pname, param); + } + + void PolygonOffset(GLfloat factor, GLfloat units) { + gles2::PolygonOffset& c = GetCmdSpace<gles2::PolygonOffset>(); + c.Init(factor, units); + } + + void ReadPixels( + GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, + GLenum type, uint32 pixels_shm_id, uint32 pixels_shm_offset) { + gles2::ReadPixels& c = GetCmdSpace<gles2::ReadPixels>(); + c.Init( + x, y, width, height, format, type, pixels_shm_id, pixels_shm_offset); + } + + void RenderbufferStorage( + GLenum target, GLenum internalformat, GLsizei width, GLsizei height) { + gles2::RenderbufferStorage& c = GetCmdSpace<gles2::RenderbufferStorage>(); + c.Init(target, internalformat, width, height); + } + + void SampleCoverage(GLclampf value, GLboolean invert) { + gles2::SampleCoverage& c = GetCmdSpace<gles2::SampleCoverage>(); + c.Init(value, invert); + } + + void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) { + gles2::Scissor& c = GetCmdSpace<gles2::Scissor>(); + c.Init(x, y, width, height); + } + + void ShaderSource( + GLuint shader, GLsizei count, uint32 data_shm_id, uint32 data_shm_offset, + uint32 data_size) { + gles2::ShaderSource& c = GetCmdSpace<gles2::ShaderSource>(); + c.Init(shader, count, data_shm_id, data_shm_offset, data_size); + } + + void ShaderSourceImmediate(GLuint shader, GLsizei count, uint32 data_size) { + const uint32 s = 0; // TODO(gman): compute correct size + gles2::ShaderSourceImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::ShaderSourceImmediate>(s); + c.Init(shader, count, data_size); + } + + void StencilFunc(GLenum func, GLint ref, GLuint mask) { + gles2::StencilFunc& c = GetCmdSpace<gles2::StencilFunc>(); + c.Init(func, ref, mask); + } + + void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) { + gles2::StencilFuncSeparate& c = GetCmdSpace<gles2::StencilFuncSeparate>(); + c.Init(face, func, ref, mask); + } + + void StencilMask(GLuint mask) { + gles2::StencilMask& c = GetCmdSpace<gles2::StencilMask>(); + c.Init(mask); + } + + void StencilMaskSeparate(GLenum face, GLuint mask) { + gles2::StencilMaskSeparate& c = GetCmdSpace<gles2::StencilMaskSeparate>(); + c.Init(face, mask); + } + + void StencilOp(GLenum fail, GLenum zfail, GLenum zpass) { + gles2::StencilOp& c = GetCmdSpace<gles2::StencilOp>(); + c.Init(fail, zfail, zpass); + } + + void StencilOpSeparate( + GLenum face, GLenum fail, GLenum zfail, GLenum zpass) { + gles2::StencilOpSeparate& c = GetCmdSpace<gles2::StencilOpSeparate>(); + c.Init(face, fail, zfail, zpass); + } + + void TexImage2D( + GLenum target, GLint level, GLint internalformat, GLsizei width, + GLsizei height, GLint border, GLenum format, GLenum type, + uint32 pixels_shm_id, uint32 pixels_shm_offset) { + gles2::TexImage2D& c = GetCmdSpace<gles2::TexImage2D>(); + c.Init( + target, level, internalformat, width, height, border, format, type, + pixels_shm_id, pixels_shm_offset); + } + + void TexImage2DImmediate( + GLenum target, GLint level, GLint internalformat, GLsizei width, + GLsizei height, GLint border, GLenum format, GLenum type) { + const uint32 s = 0; // TODO(gman): compute correct size + gles2::TexImage2DImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::TexImage2DImmediate>(s); + c.Init(target, level, internalformat, width, height, border, format, type); + } + + void TexParameterf(GLenum target, GLenum pname, GLfloat param) { + gles2::TexParameterf& c = GetCmdSpace<gles2::TexParameterf>(); + c.Init(target, pname, param); + } + + void TexParameterfv( + GLenum target, GLenum pname, uint32 params_shm_id, + uint32 params_shm_offset) { + gles2::TexParameterfv& c = GetCmdSpace<gles2::TexParameterfv>(); + c.Init(target, pname, params_shm_id, params_shm_offset); + } + + void TexParameterfvImmediate( + GLenum target, GLenum pname, const GLfloat* params) { + const uint32 size = gles2::TexParameterfvImmediate::ComputeSize(); + gles2::TexParameterfvImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::TexParameterfvImmediate>(size); + c.Init(target, pname, params); + } + + void TexParameteri(GLenum target, GLenum pname, GLint param) { + gles2::TexParameteri& c = GetCmdSpace<gles2::TexParameteri>(); + c.Init(target, pname, param); + } + + void TexParameteriv( + GLenum target, GLenum pname, uint32 params_shm_id, + uint32 params_shm_offset) { + gles2::TexParameteriv& c = GetCmdSpace<gles2::TexParameteriv>(); + c.Init(target, pname, params_shm_id, params_shm_offset); + } + + void TexParameterivImmediate( + GLenum target, GLenum pname, const GLint* params) { + const uint32 size = gles2::TexParameterivImmediate::ComputeSize(); + gles2::TexParameterivImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::TexParameterivImmediate>(size); + c.Init(target, pname, params); + } + + void TexSubImage2D( + GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, GLenum type, uint32 pixels_shm_id, + uint32 pixels_shm_offset) { + gles2::TexSubImage2D& c = GetCmdSpace<gles2::TexSubImage2D>(); + c.Init( + target, level, xoffset, yoffset, width, height, format, type, + pixels_shm_id, pixels_shm_offset); + } + + void TexSubImage2DImmediate( + GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, GLenum type) { + const uint32 s = 0; // TODO(gman): compute correct size + gles2::TexSubImage2DImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::TexSubImage2DImmediate>(s); + c.Init(target, level, xoffset, yoffset, width, height, format, type); + } + + void Uniform1f(GLint location, GLfloat x) { + gles2::Uniform1f& c = GetCmdSpace<gles2::Uniform1f>(); + c.Init(location, x); + } + + void Uniform1fv( + GLint location, GLsizei count, uint32 v_shm_id, uint32 v_shm_offset) { + gles2::Uniform1fv& c = GetCmdSpace<gles2::Uniform1fv>(); + c.Init(location, count, v_shm_id, v_shm_offset); + } + + void Uniform1fvImmediate(GLint location, GLsizei count, const GLfloat* v) { + const uint32 size = gles2::Uniform1fvImmediate::ComputeSize(count); + gles2::Uniform1fvImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::Uniform1fvImmediate>(size); + c.Init(location, count, v); + } + + void Uniform1i(GLint location, GLint x) { + gles2::Uniform1i& c = GetCmdSpace<gles2::Uniform1i>(); + c.Init(location, x); + } + + void Uniform1iv( + GLint location, GLsizei count, uint32 v_shm_id, uint32 v_shm_offset) { + gles2::Uniform1iv& c = GetCmdSpace<gles2::Uniform1iv>(); + c.Init(location, count, v_shm_id, v_shm_offset); + } + + void Uniform1ivImmediate(GLint location, GLsizei count, const GLint* v) { + const uint32 size = gles2::Uniform1ivImmediate::ComputeSize(count); + gles2::Uniform1ivImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::Uniform1ivImmediate>(size); + c.Init(location, count, v); + } + + void Uniform2f(GLint location, GLfloat x, GLfloat y) { + gles2::Uniform2f& c = GetCmdSpace<gles2::Uniform2f>(); + c.Init(location, x, y); + } + + void Uniform2fv( + GLint location, GLsizei count, uint32 v_shm_id, uint32 v_shm_offset) { + gles2::Uniform2fv& c = GetCmdSpace<gles2::Uniform2fv>(); + c.Init(location, count, v_shm_id, v_shm_offset); + } + + void Uniform2fvImmediate(GLint location, GLsizei count, const GLfloat* v) { + const uint32 size = gles2::Uniform2fvImmediate::ComputeSize(count); + gles2::Uniform2fvImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::Uniform2fvImmediate>(size); + c.Init(location, count, v); + } + + void Uniform2i(GLint location, GLint x, GLint y) { + gles2::Uniform2i& c = GetCmdSpace<gles2::Uniform2i>(); + c.Init(location, x, y); + } + + void Uniform2iv( + GLint location, GLsizei count, uint32 v_shm_id, uint32 v_shm_offset) { + gles2::Uniform2iv& c = GetCmdSpace<gles2::Uniform2iv>(); + c.Init(location, count, v_shm_id, v_shm_offset); + } + + void Uniform2ivImmediate(GLint location, GLsizei count, const GLint* v) { + const uint32 size = gles2::Uniform2ivImmediate::ComputeSize(count); + gles2::Uniform2ivImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::Uniform2ivImmediate>(size); + c.Init(location, count, v); + } + + void Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) { + gles2::Uniform3f& c = GetCmdSpace<gles2::Uniform3f>(); + c.Init(location, x, y, z); + } + + void Uniform3fv( + GLint location, GLsizei count, uint32 v_shm_id, uint32 v_shm_offset) { + gles2::Uniform3fv& c = GetCmdSpace<gles2::Uniform3fv>(); + c.Init(location, count, v_shm_id, v_shm_offset); + } + + void Uniform3fvImmediate(GLint location, GLsizei count, const GLfloat* v) { + const uint32 size = gles2::Uniform3fvImmediate::ComputeSize(count); + gles2::Uniform3fvImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::Uniform3fvImmediate>(size); + c.Init(location, count, v); + } + + void Uniform3i(GLint location, GLint x, GLint y, GLint z) { + gles2::Uniform3i& c = GetCmdSpace<gles2::Uniform3i>(); + c.Init(location, x, y, z); + } + + void Uniform3iv( + GLint location, GLsizei count, uint32 v_shm_id, uint32 v_shm_offset) { + gles2::Uniform3iv& c = GetCmdSpace<gles2::Uniform3iv>(); + c.Init(location, count, v_shm_id, v_shm_offset); + } + + void Uniform3ivImmediate(GLint location, GLsizei count, const GLint* v) { + const uint32 size = gles2::Uniform3ivImmediate::ComputeSize(count); + gles2::Uniform3ivImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::Uniform3ivImmediate>(size); + c.Init(location, count, v); + } + + void Uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { + gles2::Uniform4f& c = GetCmdSpace<gles2::Uniform4f>(); + c.Init(location, x, y, z, w); + } + + void Uniform4fv( + GLint location, GLsizei count, uint32 v_shm_id, uint32 v_shm_offset) { + gles2::Uniform4fv& c = GetCmdSpace<gles2::Uniform4fv>(); + c.Init(location, count, v_shm_id, v_shm_offset); + } + + void Uniform4fvImmediate(GLint location, GLsizei count, const GLfloat* v) { + const uint32 size = gles2::Uniform4fvImmediate::ComputeSize(count); + gles2::Uniform4fvImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::Uniform4fvImmediate>(size); + c.Init(location, count, v); + } + + void Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) { + gles2::Uniform4i& c = GetCmdSpace<gles2::Uniform4i>(); + c.Init(location, x, y, z, w); + } + + void Uniform4iv( + GLint location, GLsizei count, uint32 v_shm_id, uint32 v_shm_offset) { + gles2::Uniform4iv& c = GetCmdSpace<gles2::Uniform4iv>(); + c.Init(location, count, v_shm_id, v_shm_offset); + } + + void Uniform4ivImmediate(GLint location, GLsizei count, const GLint* v) { + const uint32 size = gles2::Uniform4ivImmediate::ComputeSize(count); + gles2::Uniform4ivImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::Uniform4ivImmediate>(size); + c.Init(location, count, v); + } + + void UniformMatrix2fv( + GLint location, GLsizei count, GLboolean transpose, uint32 value_shm_id, + uint32 value_shm_offset) { + gles2::UniformMatrix2fv& c = GetCmdSpace<gles2::UniformMatrix2fv>(); + c.Init(location, count, transpose, value_shm_id, value_shm_offset); + } + + void UniformMatrix2fvImmediate( + GLint location, GLsizei count, GLboolean transpose, + const GLfloat* value) { + const uint32 size = gles2::UniformMatrix2fvImmediate::ComputeSize(count); + gles2::UniformMatrix2fvImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::UniformMatrix2fvImmediate>(size); + c.Init(location, count, transpose, value); + } + + void UniformMatrix3fv( + GLint location, GLsizei count, GLboolean transpose, uint32 value_shm_id, + uint32 value_shm_offset) { + gles2::UniformMatrix3fv& c = GetCmdSpace<gles2::UniformMatrix3fv>(); + c.Init(location, count, transpose, value_shm_id, value_shm_offset); + } + + void UniformMatrix3fvImmediate( + GLint location, GLsizei count, GLboolean transpose, + const GLfloat* value) { + const uint32 size = gles2::UniformMatrix3fvImmediate::ComputeSize(count); + gles2::UniformMatrix3fvImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::UniformMatrix3fvImmediate>(size); + c.Init(location, count, transpose, value); + } + + void UniformMatrix4fv( + GLint location, GLsizei count, GLboolean transpose, uint32 value_shm_id, + uint32 value_shm_offset) { + gles2::UniformMatrix4fv& c = GetCmdSpace<gles2::UniformMatrix4fv>(); + c.Init(location, count, transpose, value_shm_id, value_shm_offset); + } + + void UniformMatrix4fvImmediate( + GLint location, GLsizei count, GLboolean transpose, + const GLfloat* value) { + const uint32 size = gles2::UniformMatrix4fvImmediate::ComputeSize(count); + gles2::UniformMatrix4fvImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::UniformMatrix4fvImmediate>(size); + c.Init(location, count, transpose, value); + } + + void UseProgram(GLuint program) { + gles2::UseProgram& c = GetCmdSpace<gles2::UseProgram>(); + c.Init(program); + } + + void ValidateProgram(GLuint program) { + gles2::ValidateProgram& c = GetCmdSpace<gles2::ValidateProgram>(); + c.Init(program); + } + + void VertexAttrib1f(GLuint indx, GLfloat x) { + gles2::VertexAttrib1f& c = GetCmdSpace<gles2::VertexAttrib1f>(); + c.Init(indx, x); + } + + void VertexAttrib1fv( + GLuint indx, uint32 values_shm_id, uint32 values_shm_offset) { + gles2::VertexAttrib1fv& c = GetCmdSpace<gles2::VertexAttrib1fv>(); + c.Init(indx, values_shm_id, values_shm_offset); + } + + void VertexAttrib1fvImmediate(GLuint indx, const GLfloat* values) { + const uint32 size = gles2::VertexAttrib1fvImmediate::ComputeSize(); + gles2::VertexAttrib1fvImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::VertexAttrib1fvImmediate>(size); + c.Init(indx, values); + } + + void VertexAttrib2f(GLuint indx, GLfloat x, GLfloat y) { + gles2::VertexAttrib2f& c = GetCmdSpace<gles2::VertexAttrib2f>(); + c.Init(indx, x, y); + } + + void VertexAttrib2fv( + GLuint indx, uint32 values_shm_id, uint32 values_shm_offset) { + gles2::VertexAttrib2fv& c = GetCmdSpace<gles2::VertexAttrib2fv>(); + c.Init(indx, values_shm_id, values_shm_offset); + } + + void VertexAttrib2fvImmediate(GLuint indx, const GLfloat* values) { + const uint32 size = gles2::VertexAttrib2fvImmediate::ComputeSize(); + gles2::VertexAttrib2fvImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::VertexAttrib2fvImmediate>(size); + c.Init(indx, values); + } + + void VertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z) { + gles2::VertexAttrib3f& c = GetCmdSpace<gles2::VertexAttrib3f>(); + c.Init(indx, x, y, z); + } + + void VertexAttrib3fv( + GLuint indx, uint32 values_shm_id, uint32 values_shm_offset) { + gles2::VertexAttrib3fv& c = GetCmdSpace<gles2::VertexAttrib3fv>(); + c.Init(indx, values_shm_id, values_shm_offset); + } + + void VertexAttrib3fvImmediate(GLuint indx, const GLfloat* values) { + const uint32 size = gles2::VertexAttrib3fvImmediate::ComputeSize(); + gles2::VertexAttrib3fvImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::VertexAttrib3fvImmediate>(size); + c.Init(indx, values); + } + + void VertexAttrib4f( + GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { + gles2::VertexAttrib4f& c = GetCmdSpace<gles2::VertexAttrib4f>(); + c.Init(indx, x, y, z, w); + } + + void VertexAttrib4fv( + GLuint indx, uint32 values_shm_id, uint32 values_shm_offset) { + gles2::VertexAttrib4fv& c = GetCmdSpace<gles2::VertexAttrib4fv>(); + c.Init(indx, values_shm_id, values_shm_offset); + } + + void VertexAttrib4fvImmediate(GLuint indx, const GLfloat* values) { + const uint32 size = gles2::VertexAttrib4fvImmediate::ComputeSize(); + gles2::VertexAttrib4fvImmediate& c = + GetImmediateCmdSpaceTotalSize<gles2::VertexAttrib4fvImmediate>(size); + c.Init(indx, values); + } + + void VertexAttribPointer( + GLuint indx, GLint size, GLenum type, GLboolean normalized, + GLsizei stride, GLuint offset) { + gles2::VertexAttribPointer& c = GetCmdSpace<gles2::VertexAttribPointer>(); + c.Init(indx, size, type, normalized, stride, offset); + } + + void Viewport(GLint x, GLint y, GLsizei width, GLsizei height) { + gles2::Viewport& c = GetCmdSpace<gles2::Viewport>(); + c.Init(x, y, width, height); + } + + void SwapBuffers() { + gles2::SwapBuffers& c = GetCmdSpace<gles2::SwapBuffers>(); + c.Init(); + } + diff --git a/gpu/command_buffer/client/gles2_demo.cc b/gpu/command_buffer/client/gles2_demo.cc new file mode 100644 index 0000000..04419c3 --- /dev/null +++ b/gpu/command_buffer/client/gles2_demo.cc @@ -0,0 +1,203 @@ +// Copyright (c) 2006-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 is here so other GLES2 related files can have a common set of +// includes where appropriate. + +#include <windows.h> +#include <windowsx.h> +#include <shellapi.h> +#include <stdlib.h> +#include <stdio.h> +#include "base/ref_counted.h" +#include "base/shared_memory.h" +#include "base/scoped_ptr.h" +#include "gpu/command_buffer/service/gpu_processor.h" +#include "gpu/command_buffer/service/command_buffer_service.h" +#include "gpu/np_utils/np_utils.h" +#include "gpu/command_buffer/client/gles2_implementation.h" +#include "gpu/command_buffer/client/gles2_lib.h" +#include "gpu/command_buffer/client/gles2_demo_c.h" +#include "gpu/command_buffer/client/gles2_demo_cc.h" + +using base::SharedMemory; +using command_buffer::GPUProcessor; +using command_buffer::CommandBufferService; +using command_buffer::gles2::GLES2CmdHelper; +using command_buffer::gles2::GLES2Implementation; + +class GLES2Demo { + public: + GLES2Demo(); + + bool GLES2Demo::Setup(NPP npp, void* hwnd, int32 size); + + private: + DISALLOW_COPY_AND_ASSIGN(GLES2Demo); +}; + +GLES2Demo::GLES2Demo() { +} + +bool GLES2Demo::Setup(NPP npp, void* hwnd, int32 size) { + scoped_ptr<SharedMemory> ring_buffer(new SharedMemory); + if (!ring_buffer->Create(std::wstring(), false, false, size)) { + return NULL; + } + + if (!ring_buffer->Map(size)) { + return NULL; + } + + scoped_ptr<CommandBufferService> command_buffer(new CommandBufferService); + if (!command_buffer->Initialize(ring_buffer.release())) { + return NULL; + } + + scoped_refptr<GPUProcessor> gpu_processor( + new GPUProcessor(npp, command_buffer.get())); + if (!gpu_processor->Initialize(reinterpret_cast<HWND>(hwnd))) { + return NULL; + } + + command_buffer->SetPutOffsetChangeCallback( + NewCallback(gpu_processor.get(), &GPUProcessor::ProcessCommands)); + + GLES2CmdHelper* helper = new GLES2CmdHelper(command_buffer.get()); + if (!helper->Initialize()) { + // TODO(gman): cleanup. + return false; + } + + size_t transfer_buffer_size = 512 * 1024; + int32 transfer_buffer_id = + command_buffer->CreateTransferBuffer(transfer_buffer_size); + void* transfer_buffer = + command_buffer->GetTransferBuffer(transfer_buffer_id); + + gles2::g_gl_impl = new GLES2Implementation(helper, + transfer_buffer, + transfer_buffer_id); + + return command_buffer.release() != NULL; +} + +#if defined(OS_WIN) +LRESULT CALLBACK WindowProc( + HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param) { + switch (msg) { + case WM_CLOSE: + DestroyWindow(hwnd); + break; + case WM_DESTROY: + PostQuitMessage(0); + break; + case WM_PAINT: { + GLFromCPPTestFunction(); + GLFromCTestFunction(); + // TODO(gman): Not sure how SwapBuffer should be exposed. + gles2::GetGLContext()->SwapBuffers(); + break; + } + default: + return ::DefWindowProc(hwnd, msg, w_param, l_param); + } + return 0; +} + +HINSTANCE GetInstance(void) { + HWND hwnd = GetConsoleWindow(); + return reinterpret_cast<HINSTANCE>(GetWindowLong(hwnd, GWL_HINSTANCE)); +} + +void ProcessMessages(void* in_hwnd) { + HWND hwnd = reinterpret_cast<HWND>(in_hwnd); + MSG msg; + + bool done = false; + while (!done) { + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + if (msg.message == WM_QUIT) { + done = true; + } + // dispatch the message + TranslateMessage(&msg); + DispatchMessage(&msg); + } + if (!done) { + InvalidateRect(hwnd, NULL, TRUE); + } + } +} + +#endif + +void* SetupWindow() { +#if defined(OS_WIN) + HINSTANCE instance = GetInstance(); + WNDCLASSEX wc = {0}; + wc.lpszClassName = L"MY_WINDOWS_CLASS"; + wc.cbSize = sizeof(WNDCLASSEX); + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = ::WindowProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = instance; + wc.hIcon = ::LoadIcon(instance, IDI_APPLICATION); + wc.hIconSm = NULL; + wc.hCursor = ::LoadCursor(instance, IDC_ARROW); + wc.hbrBackground = static_cast<HBRUSH>(::GetStockObject(BLACK_BRUSH)); + wc.lpszMenuName = NULL; + + if (!::RegisterClassEx(&wc)) + return false; + + // Leaving this window onscreen leads to a redraw error which makes it + // a hassle to debug tests in an IDE, so we place the window somewhere that + // won't happen. + HWND hwnd = ::CreateWindowExW( + NULL, + wc.lpszClassName, + L"", + WS_OVERLAPPEDWINDOW, + 10, + 0, + 512, + 512, + 0, + 0, + instance, + 0); + + if (hwnd == NULL) { + return false; + } + + ::ShowWindow(hwnd, SW_SHOWNORMAL); + + + return hwnd; +#else +#error Need code. +#endif +} + +int main(int argc, const char** argv) { + const int32 kCommandBufferSize = 1024 * 1024; + GLES2Demo* demo = new GLES2Demo(); + + void* hwnd = SetupWindow(); + if (!hwnd) { + ::fprintf(stdout, "Could not setup window.\n"); + return EXIT_FAILURE; + } + + demo->Setup(NULL, hwnd, kCommandBufferSize); + + ProcessMessages(hwnd); + + return EXIT_SUCCESS; +} + + diff --git a/gpu/command_buffer/client/gles2_demo_c.c b/gpu/command_buffer/client/gles2_demo_c.c new file mode 100644 index 0000000..44b2c57 --- /dev/null +++ b/gpu/command_buffer/client/gles2_demo_c.c @@ -0,0 +1,15 @@ +// Copyright (c) 2006-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 is here so other GLES2 related files can have a common set of +// includes where appropriate. + +#include <GLES2/gl2.h> +#include "gpu/command_buffer/client/gles2_demo_c.h" + +void GLFromCTestFunction() { + glClear(GL_COLOR_BUFFER_BIT); +} + + diff --git a/gpu/command_buffer/client/gles2_demo_c.h b/gpu/command_buffer/client/gles2_demo_c.h new file mode 100644 index 0000000..0cd1478 --- /dev/null +++ b/gpu/command_buffer/client/gles2_demo_c.h @@ -0,0 +1,22 @@ +// Copyright (c) 2006-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. + +// A Test that we can access GL from c. + +#ifndef GPU_COMMAND_BUFFER_CLIENT_GLES2_DEMO_C_H +#define GPU_COMMAND_BUFFER_CLIENT_GLES2_DEMO_C_H + +#ifdef __cplusplus +extern "C" { +#endif + +void GLFromCTestFunction(); + +#ifdef __cplusplus +} +#endif + +#endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_DEMO_C_H + + diff --git a/gpu/command_buffer/client/gles2_demo_cc.cc b/gpu/command_buffer/client/gles2_demo_cc.cc new file mode 100644 index 0000000..d7a023c --- /dev/null +++ b/gpu/command_buffer/client/gles2_demo_cc.cc @@ -0,0 +1,21 @@ +// Copyright (c) 2006-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 is here so other GLES2 related files can have a common set of +// includes where appropriate. + +#include <GLES2/gl2.h> +#include "gpu/command_buffer/client/gles2_demo_cc.h" + +void GLFromCPPTestFunction() { + static bool foo = true; + foo = !foo; + glClearColor( + foo ? 1.0f : 0.0f, + foo ? 0.0f : 1.0f, + 1.0f, + 1.0f); +} + + diff --git a/gpu/command_buffer/client/gles2_demo_cc.h b/gpu/command_buffer/client/gles2_demo_cc.h new file mode 100644 index 0000000..7f88d0e --- /dev/null +++ b/gpu/command_buffer/client/gles2_demo_cc.h @@ -0,0 +1,14 @@ +// Copyright (c) 2006-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. + +// A Test that we can access GL from C++. + +#ifndef GPU_COMMAND_BUFFER_CLIENT_GLES2_DEMO_CC_H +#define GPU_COMMAND_BUFFER_CLIENT_GLES2_DEMO_CC_H + +void GLFromCPPTestFunction(); + +#endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_DEMO_CC_H + + diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc new file mode 100644 index 0000000..e60e68b --- /dev/null +++ b/gpu/command_buffer/client/gles2_implementation.cc @@ -0,0 +1,154 @@ +// Copyright (c) 2006-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. + +// A class to emluate GLES2 over command buffers. + +#include "gpu/command_buffer/client/gles2_implementation.h" +// TODO(gman): remove when all functions have been implemented. +#include "gpu/command_buffer/client/gles2_implementation_gen.h" +#include "gpu/command_buffer/common/gles2_cmd_utils.h" + +namespace command_buffer { +namespace gles2 { + +GLES2Implementation::GLES2Implementation( + GLES2CmdHelper* helper, + void* transfer_buffer, + int transfer_buffer_id) + : util_(0), // TODO(gman): Get real number of compressed texture formats. + helper_(helper), + shared_memory_(transfer_buffer, transfer_buffer_id), + pack_alignment_(4), + unpack_alignment_(4) { +} + +void GLES2Implementation::MakeIds(GLsizei n, GLuint* ids) { + for (GLsizei ii = 0; ii < n; ++ii) { + ids[ii] = id_allocator_.AllocateID(); + } +} + +void GLES2Implementation::FreeIds(GLsizei n, const GLuint* ids) { + for (GLsizei ii = 0; ii < n; ++ii) { + id_allocator_.FreeID(ids[ii]); + } +} + +void GLES2Implementation::DrawElements( + GLenum mode, GLsizei count, GLenum type, const void* indices) { + helper_->DrawElements(mode, count, type, reinterpret_cast<GLuint>(indices)); +} + +void GLES2Implementation::VertexAttribPointer( + GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, + const void* ptr) { + helper_->VertexAttribPointer(index, size, type, normalized, stride, + reinterpret_cast<GLuint>(ptr)); +} + +void GLES2Implementation::ShaderSource( + GLuint shader, GLsizei count, const char** string, const GLint* length) { + // TODO(gman): change to use buckets and check that there is enough room. + uint32* offsets = shared_memory_.GetAddressAs<uint32*>(0); + char* strings = reinterpret_cast<char*>(offsets + count); + + uint32 offset = count * sizeof(*offsets); + for (GLsizei ii = 0; ii < count; ++ii) { + uint32 len = length ? length[ii] : strlen(string[ii]); + memcpy(strings + offset, string[ii], len); + offset += len; + offsets[ii] = offset; + } + + helper_->ShaderSource(shader, count, shared_memory_.GetId(), 0, offset); + // TODO(gman): Should insert token but not wait until we need shared memory + // again. Really, I should implement a shared memory manager that puts + // things in the next unused part of shared memory and only blocks + // when it needs more memory. + int32 token = helper_->InsertToken(); + helper_->WaitForToken(token); +} + +void GLES2Implementation::BufferData( + GLenum target, GLsizeiptr size, const void* data, GLenum usage) { + // TODO(gman): Switch to use buckets alwayst or at least if no room in shared + // memory. + memcpy(shared_memory_.GetAddress(0), data, size); + helper_->BufferData(target, size, shared_memory_.GetId(), 0, usage); + int32 token = helper_->InsertToken(); + helper_->WaitForToken(token); +} + +void GLES2Implementation::BufferSubData( + GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { + // TODO(gman): Switch to use buckets alwayst or at least if no room in shared + // memory. + memcpy(shared_memory_.GetAddress(0), data, size); + helper_->BufferSubData(target, offset, size, shared_memory_.GetId(), 0); + int32 token = helper_->InsertToken(); + helper_->WaitForToken(token); +} + +void GLES2Implementation::CompressedTexImage2D( + GLenum target, GLint level, GLenum internalformat, GLsizei width, + GLsizei height, GLint border, GLsizei imageSize, const void* data) { + // TODO(gman): Switch to use buckets alwayst or at least if no room in shared + // memory. + memcpy(shared_memory_.GetAddress(0), data, imageSize); + helper_->CompressedTexImage2D( + target, level, internalformat, width, height, border, imageSize, + shared_memory_.GetId(), 0); + int32 token = helper_->InsertToken(); + helper_->WaitForToken(token); +} + +void GLES2Implementation::CompressedTexSubImage2D( + GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, GLsizei imageSize, const void* data) { + // TODO(gman): Switch to use buckets alwayst or at least if no room in shared + // memory. + memcpy(shared_memory_.GetAddress(0), data, imageSize); + helper_->CompressedTexSubImage2D( + target, level, xoffset, yoffset, width, height, format, imageSize, + shared_memory_.GetId(), 0); + int32 token = helper_->InsertToken(); + helper_->WaitForToken(token); +} + +void GLES2Implementation::TexImage2D( + GLenum target, GLint level, GLint internalformat, GLsizei width, + GLsizei height, GLint border, GLenum format, GLenum type, + const void* pixels) { + // TODO(gman): Switch to use buckets alwayst or at least if no room in shared + // memory. + uint32 pixels_size = GLES2Util::ComputeImageDataSize( + width, height, format, type, unpack_alignment_); + memcpy(shared_memory_.GetAddress(0), pixels, pixels_size); + helper_->TexImage2D( + target, level, internalformat, width, height, border, format, type, + shared_memory_.GetId(), 0); + int32 token = helper_->InsertToken(); + helper_->WaitForToken(token); +} + +void GLES2Implementation::TexSubImage2D( + GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, GLenum type, const void* pixels) { + // TODO(gman): Switch to use buckets alwayst or at least if no room in shared + // memory. + uint32 pixels_size = GLES2Util::ComputeImageDataSize( + width, height, format, type, unpack_alignment_); + memcpy(shared_memory_.GetAddress(0), pixels, pixels_size); + helper_->TexSubImage2D( + target, level, xoffset, yoffset, width, height, format, type, + shared_memory_.GetId(), 0); + int32 token = helper_->InsertToken(); + helper_->WaitForToken(token); +} + + +} // namespace gles2 +} // namespace command_buffer + + diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h new file mode 100644 index 0000000..2df52ca --- /dev/null +++ b/gpu/command_buffer/client/gles2_implementation.h @@ -0,0 +1,93 @@ +// Copyright (c) 2006-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. + +#ifndef GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_H +#define GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_H + +#include "base/shared_memory.h" +#include "gpu/command_buffer/common/gles2_cmd_utils.h" +#include "gpu/command_buffer/client/gles2_cmd_helper.h" +#include "gpu/command_buffer/client/id_allocator.h" + +namespace command_buffer { +namespace gles2 { + +// A class to help with shared memory. +class SharedMemoryHelper { + public: + SharedMemoryHelper(void* address, int id) + : address_(address), + id_(id) { + } + + unsigned int GetOffset(void* address) const { + return static_cast<int8*>(address) - + static_cast<int8*>(address_); + } + + void* GetAddress(unsigned int offset) const { + return static_cast<int8*>(address_) + offset; + } + + template <typename T> + T GetAddressAs(unsigned int offset) const { + return static_cast<T>(GetAddress(offset)); + } + + unsigned int GetId() const { + return id_; + } + + private: + void* address_; + int id_; + + DISALLOW_COPY_AND_ASSIGN(SharedMemoryHelper); +}; + +// This class emulates GLES2 over command buffers. It can be used by a client +// program so that the program does not need deal with shared memory and command +// buffer management. See gl2_lib.h. Note that there is a performance gain to +// be had by changing your code to use command buffers directly by using the +// GLES2CmdHelper but that entails changing your code to use and deal with +// shared memory and synchronization issues. +class GLES2Implementation { + public: + GLES2Implementation( + GLES2CmdHelper* helper, + void* transfer_buffer, + int transfer_buffer_id); // TODO: add size. + + // Include the auto-generated part of this class. We split this because + // it means we can easily edit the non-auto generated parts right here in + // this file instead of having to edit some template or the code generator. + #include "gpu/command_buffer/client/gles2_implementation_autogen.h" + + private: + // Makes a set of Ids for glGen___ functions. + void MakeIds(GLsizei n, GLuint* ids); + + // Frees a set of Ids for glDelete___ functions. + void FreeIds(GLsizei n, const GLuint* ids); + + GLES2Util util_; + GLES2CmdHelper* helper_; + IdAllocator id_allocator_; + SharedMemoryHelper shared_memory_; // TODO(gman): rename transfer_buffer_. + + // pack alignment as last set by glPixelStorei + GLint pack_alignment_; + + // unpack alignment as last set by glPixelStorei + GLint unpack_alignment_; + + DISALLOW_COPY_AND_ASSIGN(GLES2Implementation); +}; + + +} // namespace gles2 +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_H + diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h new file mode 100644 index 0000000..940454b --- /dev/null +++ b/gpu/command_buffer/client/gles2_implementation_autogen.h @@ -0,0 +1,684 @@ +// This file is auto-generated. DO NOT EDIT! + +// This file is included by gles2_implementation.h to declare the +// GL api functions. +void ActiveTexture(GLenum texture) { + helper_->ActiveTexture(texture); +} + +void AttachShader(GLuint program, GLuint shader) { + helper_->AttachShader(program, shader); +} + +void BindAttribLocation(GLuint program, GLuint index, const char* name) { + // TODO(gman): This needs to change to use SendString. + helper_->BindAttribLocationImmediate(program, index, name); +} + +void BindBuffer(GLenum target, GLuint buffer) { + helper_->BindBuffer(target, buffer); +} + +void BindFramebuffer(GLenum target, GLuint framebuffer) { + helper_->BindFramebuffer(target, framebuffer); +} + +void BindRenderbuffer(GLenum target, GLuint renderbuffer) { + helper_->BindRenderbuffer(target, renderbuffer); +} + +void BindTexture(GLenum target, GLuint texture) { + helper_->BindTexture(target, texture); +} + +void BlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { + helper_->BlendColor(red, green, blue, alpha); +} + +void BlendEquation(GLenum mode) { + helper_->BlendEquation(mode); +} + +void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) { + helper_->BlendEquationSeparate(modeRGB, modeAlpha); +} + +void BlendFunc(GLenum sfactor, GLenum dfactor) { + helper_->BlendFunc(sfactor, dfactor); +} + +void BlendFuncSeparate( + GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) { + helper_->BlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); +} + +void BufferData( + GLenum target, GLsizeiptr size, const void* data, GLenum usage); + +void BufferSubData( + GLenum target, GLintptr offset, GLsizeiptr size, const void* data); + +GLenum CheckFramebufferStatus(GLenum target); + +void Clear(GLbitfield mask) { + helper_->Clear(mask); +} + +void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { + helper_->ClearColor(red, green, blue, alpha); +} + +void ClearDepthf(GLclampf depth) { + helper_->ClearDepthf(depth); +} + +void ClearStencil(GLint s) { + helper_->ClearStencil(s); +} + +void ColorMask( + GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { + helper_->ColorMask(red, green, blue, alpha); +} + +void CompileShader(GLuint shader) { + helper_->CompileShader(shader); +} + +void CompressedTexImage2D( + GLenum target, GLint level, GLenum internalformat, GLsizei width, + GLsizei height, GLint border, GLsizei imageSize, const void* data); + +void CompressedTexSubImage2D( + GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, GLsizei imageSize, const void* data); + +void CopyTexImage2D( + GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, + GLsizei width, GLsizei height, GLint border) { + helper_->CopyTexImage2D( + target, level, internalformat, x, y, width, height, border); +} + +void CopyTexSubImage2D( + GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, + GLsizei width, GLsizei height) { + helper_->CopyTexSubImage2D( + target, level, xoffset, yoffset, x, y, width, height); +} + +GLuint CreateProgram() { + GLuint client_id; + MakeIds(1, &client_id); + helper_->CreateProgram(client_id); + return client_id; +} + +GLuint CreateShader(GLenum type) { + GLuint client_id; + MakeIds(1, &client_id); + helper_->CreateShader(type, client_id); + return client_id; +} + +void CullFace(GLenum mode) { + helper_->CullFace(mode); +} + +void DeleteBuffers(GLsizei n, const GLuint* buffers) { + FreeIds(n, buffers); + helper_->DeleteBuffersImmediate(n, buffers); +} + +void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers) { + FreeIds(n, framebuffers); + helper_->DeleteFramebuffersImmediate(n, framebuffers); +} + +void DeleteProgram(GLuint program) { + helper_->DeleteProgram(program); +} + +void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) { + FreeIds(n, renderbuffers); + helper_->DeleteRenderbuffersImmediate(n, renderbuffers); +} + +void DeleteShader(GLuint shader) { + helper_->DeleteShader(shader); +} + +void DeleteTextures(GLsizei n, const GLuint* textures) { + FreeIds(n, textures); + helper_->DeleteTexturesImmediate(n, textures); +} + +void DepthFunc(GLenum func) { + helper_->DepthFunc(func); +} + +void DepthMask(GLboolean flag) { + helper_->DepthMask(flag); +} + +void DepthRangef(GLclampf zNear, GLclampf zFar) { + helper_->DepthRangef(zNear, zFar); +} + +void DetachShader(GLuint program, GLuint shader) { + helper_->DetachShader(program, shader); +} + +void Disable(GLenum cap) { + helper_->Disable(cap); +} + +void DisableVertexAttribArray(GLuint index) { + helper_->DisableVertexAttribArray(index); +} + +void DrawArrays(GLenum mode, GLint first, GLsizei count) { + helper_->DrawArrays(mode, first, count); +} + +void DrawElements( + GLenum mode, GLsizei count, GLenum type, const void* indices); + +void Enable(GLenum cap) { + helper_->Enable(cap); +} + +void EnableVertexAttribArray(GLuint index) { + helper_->EnableVertexAttribArray(index); +} + +void Finish() { + helper_->Finish(); +} + +void Flush() { + helper_->Flush(); +} + +void FramebufferRenderbuffer( + GLenum target, GLenum attachment, GLenum renderbuffertarget, + GLuint renderbuffer) { + helper_->FramebufferRenderbuffer( + target, attachment, renderbuffertarget, renderbuffer); +} + +void FramebufferTexture2D( + GLenum target, GLenum attachment, GLenum textarget, GLuint texture, + GLint level) { + helper_->FramebufferTexture2D(target, attachment, textarget, texture, level); +} + +void FrontFace(GLenum mode) { + helper_->FrontFace(mode); +} + +void GenBuffers(GLsizei n, GLuint* buffers) { + MakeIds(n, buffers); + helper_->GenBuffersImmediate(n, buffers); +} + +void GenerateMipmap(GLenum target) { + helper_->GenerateMipmap(target); +} + +void GenFramebuffers(GLsizei n, GLuint* framebuffers) { + MakeIds(n, framebuffers); + helper_->GenFramebuffersImmediate(n, framebuffers); +} + +void GenRenderbuffers(GLsizei n, GLuint* renderbuffers) { + MakeIds(n, renderbuffers); + helper_->GenRenderbuffersImmediate(n, renderbuffers); +} + +void GenTextures(GLsizei n, GLuint* textures) { + MakeIds(n, textures); + helper_->GenTexturesImmediate(n, textures); +} + +void GetActiveAttrib( + GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, + GLenum* type, char* name); + +void GetActiveUniform( + GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, + GLenum* type, char* name); + +void GetAttachedShaders( + GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders); + +int GetAttribLocation(GLuint program, const char* name) { + // TODO(gman): This needs to change to use SendString. + GLint* result = shared_memory_.GetAddressAs<GLint*>(0); + DCHECK(false); // pass in shared memory + helper_->GetAttribLocationImmediate(program, name); + int32 token = helper_->InsertToken(); + helper_->WaitForToken(token); + return *result; +} + +void GetBooleanv(GLenum pname, GLboolean* params) { + helper_->GetBooleanv(pname, shared_memory_.GetId(), 0); + int32 token = helper_->InsertToken(); + helper_->WaitForToken(token); + GLsizei num_values = util_.GLGetNumValuesReturned(pname); + memcpy(params, shared_memory_.GetAddress(0), + num_values * sizeof(*params)); +} + +void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params) { + helper_->GetBufferParameteriv(target, pname, shared_memory_.GetId(), 0); + int32 token = helper_->InsertToken(); + helper_->WaitForToken(token); + GLsizei num_values = util_.GLGetNumValuesReturned(pname); + memcpy(params, shared_memory_.GetAddress(0), + num_values * sizeof(*params)); +} + +GLenum GetError() { + helper_->GetError(shared_memory_.GetId(), 0); + int32 token = helper_->InsertToken(); + helper_->WaitForToken(token); + return *shared_memory_.GetAddressAs<GLenum*>(0); +} + +void GetFloatv(GLenum pname, GLfloat* params) { + helper_->GetFloatv(pname, shared_memory_.GetId(), 0); + int32 token = helper_->InsertToken(); + helper_->WaitForToken(token); + GLsizei num_values = util_.GLGetNumValuesReturned(pname); + memcpy(params, shared_memory_.GetAddress(0), + num_values * sizeof(*params)); +} + +void GetFramebufferAttachmentParameteriv( + GLenum target, GLenum attachment, GLenum pname, GLint* params) { + helper_->GetFramebufferAttachmentParameteriv( + target, attachment, pname, shared_memory_.GetId(), 0); + int32 token = helper_->InsertToken(); + helper_->WaitForToken(token); + GLsizei num_values = util_.GLGetNumValuesReturned(pname); + memcpy(params, shared_memory_.GetAddress(0), + num_values * sizeof(*params)); +} + +void GetIntegerv(GLenum pname, GLint* params) { + helper_->GetIntegerv(pname, shared_memory_.GetId(), 0); + int32 token = helper_->InsertToken(); + helper_->WaitForToken(token); + GLsizei num_values = util_.GLGetNumValuesReturned(pname); + memcpy(params, shared_memory_.GetAddress(0), + num_values * sizeof(*params)); +} + +void GetProgramiv(GLuint program, GLenum pname, GLint* params) { + helper_->GetProgramiv(program, pname, shared_memory_.GetId(), 0); + int32 token = helper_->InsertToken(); + helper_->WaitForToken(token); + GLsizei num_values = util_.GLGetNumValuesReturned(pname); + memcpy(params, shared_memory_.GetAddress(0), + num_values * sizeof(*params)); +} + +// TODO(gman): Implement this +void GetProgramInfoLog( + GLuint program, GLsizei bufsize, GLsizei* length, char* infolog); + +void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) { + helper_->GetRenderbufferParameteriv( + target, pname, shared_memory_.GetId(), 0); + int32 token = helper_->InsertToken(); + helper_->WaitForToken(token); + GLsizei num_values = util_.GLGetNumValuesReturned(pname); + memcpy(params, shared_memory_.GetAddress(0), + num_values * sizeof(*params)); +} + +void GetShaderiv(GLuint shader, GLenum pname, GLint* params) { + helper_->GetShaderiv(shader, pname, shared_memory_.GetId(), 0); + int32 token = helper_->InsertToken(); + helper_->WaitForToken(token); + GLsizei num_values = util_.GLGetNumValuesReturned(pname); + memcpy(params, shared_memory_.GetAddress(0), + num_values * sizeof(*params)); +} + +// TODO(gman): Implement this +void GetShaderInfoLog( + GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog); + +void GetShaderPrecisionFormat( + GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision); + +// TODO(gman): Implement this +void GetShaderSource( + GLuint shader, GLsizei bufsize, GLsizei* length, char* source); + +const GLubyte* GetString(GLenum name); + +void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) { + helper_->GetTexParameterfv(target, pname, shared_memory_.GetId(), 0); + int32 token = helper_->InsertToken(); + helper_->WaitForToken(token); + GLsizei num_values = util_.GLGetNumValuesReturned(pname); + memcpy(params, shared_memory_.GetAddress(0), + num_values * sizeof(*params)); +} + +void GetTexParameteriv(GLenum target, GLenum pname, GLint* params) { + helper_->GetTexParameteriv(target, pname, shared_memory_.GetId(), 0); + int32 token = helper_->InsertToken(); + helper_->WaitForToken(token); + GLsizei num_values = util_.GLGetNumValuesReturned(pname); + memcpy(params, shared_memory_.GetAddress(0), + num_values * sizeof(*params)); +} + +void GetUniformfv(GLuint program, GLint location, GLfloat* params); + +void GetUniformiv(GLuint program, GLint location, GLint* params); + +int GetUniformLocation(GLuint program, const char* name) { + // TODO(gman): This needs to change to use SendString. + GLint* result = shared_memory_.GetAddressAs<GLint*>(0); + DCHECK(false); // pass in shared memory + helper_->GetUniformLocationImmediate(program, name); + int32 token = helper_->InsertToken(); + helper_->WaitForToken(token); + return *result; +} + +void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) { + helper_->GetVertexAttribfv(index, pname, shared_memory_.GetId(), 0); + int32 token = helper_->InsertToken(); + helper_->WaitForToken(token); + GLsizei num_values = util_.GLGetNumValuesReturned(pname); + memcpy(params, shared_memory_.GetAddress(0), + num_values * sizeof(*params)); +} + +void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params) { + helper_->GetVertexAttribiv(index, pname, shared_memory_.GetId(), 0); + int32 token = helper_->InsertToken(); + helper_->WaitForToken(token); + GLsizei num_values = util_.GLGetNumValuesReturned(pname); + memcpy(params, shared_memory_.GetAddress(0), + num_values * sizeof(*params)); +} + +void GetVertexAttribPointerv(GLuint index, GLenum pname, void** pointer); + +void Hint(GLenum target, GLenum mode) { + helper_->Hint(target, mode); +} + +GLboolean IsBuffer(GLuint buffer) { + helper_->IsBuffer(buffer, shared_memory_.GetId(), 0); + int32 token = helper_->InsertToken(); + helper_->WaitForToken(token); + return *shared_memory_.GetAddressAs<GLboolean*>(0); +} + +GLboolean IsEnabled(GLenum cap) { + helper_->IsEnabled(cap, shared_memory_.GetId(), 0); + int32 token = helper_->InsertToken(); + helper_->WaitForToken(token); + return *shared_memory_.GetAddressAs<GLboolean*>(0); +} + +GLboolean IsFramebuffer(GLuint framebuffer) { + helper_->IsFramebuffer(framebuffer, shared_memory_.GetId(), 0); + int32 token = helper_->InsertToken(); + helper_->WaitForToken(token); + return *shared_memory_.GetAddressAs<GLboolean*>(0); +} + +GLboolean IsProgram(GLuint program) { + helper_->IsProgram(program, shared_memory_.GetId(), 0); + int32 token = helper_->InsertToken(); + helper_->WaitForToken(token); + return *shared_memory_.GetAddressAs<GLboolean*>(0); +} + +GLboolean IsRenderbuffer(GLuint renderbuffer) { + helper_->IsRenderbuffer(renderbuffer, shared_memory_.GetId(), 0); + int32 token = helper_->InsertToken(); + helper_->WaitForToken(token); + return *shared_memory_.GetAddressAs<GLboolean*>(0); +} + +GLboolean IsShader(GLuint shader) { + helper_->IsShader(shader, shared_memory_.GetId(), 0); + int32 token = helper_->InsertToken(); + helper_->WaitForToken(token); + return *shared_memory_.GetAddressAs<GLboolean*>(0); +} + +GLboolean IsTexture(GLuint texture) { + helper_->IsTexture(texture, shared_memory_.GetId(), 0); + int32 token = helper_->InsertToken(); + helper_->WaitForToken(token); + return *shared_memory_.GetAddressAs<GLboolean*>(0); +} + +void LineWidth(GLfloat width) { + helper_->LineWidth(width); +} + +void LinkProgram(GLuint program) { + helper_->LinkProgram(program); +} + +void PixelStorei(GLenum pname, GLint param) { + helper_->PixelStorei(pname, param); +} + +void PolygonOffset(GLfloat factor, GLfloat units) { + helper_->PolygonOffset(factor, units); +} + +void ReadPixels( + GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, + void* pixels); + +void RenderbufferStorage( + GLenum target, GLenum internalformat, GLsizei width, GLsizei height) { + helper_->RenderbufferStorage(target, internalformat, width, height); +} + +void SampleCoverage(GLclampf value, GLboolean invert) { + helper_->SampleCoverage(value, invert); +} + +void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) { + helper_->Scissor(x, y, width, height); +} + +void ShaderSource( + GLuint shader, GLsizei count, const char** string, const GLint* length); + +void StencilFunc(GLenum func, GLint ref, GLuint mask) { + helper_->StencilFunc(func, ref, mask); +} + +void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) { + helper_->StencilFuncSeparate(face, func, ref, mask); +} + +void StencilMask(GLuint mask) { + helper_->StencilMask(mask); +} + +void StencilMaskSeparate(GLenum face, GLuint mask) { + helper_->StencilMaskSeparate(face, mask); +} + +void StencilOp(GLenum fail, GLenum zfail, GLenum zpass) { + helper_->StencilOp(fail, zfail, zpass); +} + +void StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) { + helper_->StencilOpSeparate(face, fail, zfail, zpass); +} + +void TexImage2D( + GLenum target, GLint level, GLint internalformat, GLsizei width, + GLsizei height, GLint border, GLenum format, GLenum type, + const void* pixels); + +void TexParameterf(GLenum target, GLenum pname, GLfloat param) { + helper_->TexParameterf(target, pname, param); +} + +void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params) { + helper_->TexParameterfvImmediate(target, pname, params); +} + +void TexParameteri(GLenum target, GLenum pname, GLint param) { + helper_->TexParameteri(target, pname, param); +} + +void TexParameteriv(GLenum target, GLenum pname, const GLint* params) { + helper_->TexParameterivImmediate(target, pname, params); +} + +void TexSubImage2D( + GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, + GLsizei height, GLenum format, GLenum type, const void* pixels); + +void Uniform1f(GLint location, GLfloat x) { + helper_->Uniform1f(location, x); +} + +void Uniform1fv(GLint location, GLsizei count, const GLfloat* v) { + helper_->Uniform1fvImmediate(location, count, v); +} + +void Uniform1i(GLint location, GLint x) { + helper_->Uniform1i(location, x); +} + +void Uniform1iv(GLint location, GLsizei count, const GLint* v) { + helper_->Uniform1ivImmediate(location, count, v); +} + +void Uniform2f(GLint location, GLfloat x, GLfloat y) { + helper_->Uniform2f(location, x, y); +} + +void Uniform2fv(GLint location, GLsizei count, const GLfloat* v) { + helper_->Uniform2fvImmediate(location, count, v); +} + +void Uniform2i(GLint location, GLint x, GLint y) { + helper_->Uniform2i(location, x, y); +} + +void Uniform2iv(GLint location, GLsizei count, const GLint* v) { + helper_->Uniform2ivImmediate(location, count, v); +} + +void Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) { + helper_->Uniform3f(location, x, y, z); +} + +void Uniform3fv(GLint location, GLsizei count, const GLfloat* v) { + helper_->Uniform3fvImmediate(location, count, v); +} + +void Uniform3i(GLint location, GLint x, GLint y, GLint z) { + helper_->Uniform3i(location, x, y, z); +} + +void Uniform3iv(GLint location, GLsizei count, const GLint* v) { + helper_->Uniform3ivImmediate(location, count, v); +} + +void Uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { + helper_->Uniform4f(location, x, y, z, w); +} + +void Uniform4fv(GLint location, GLsizei count, const GLfloat* v) { + helper_->Uniform4fvImmediate(location, count, v); +} + +void Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) { + helper_->Uniform4i(location, x, y, z, w); +} + +void Uniform4iv(GLint location, GLsizei count, const GLint* v) { + helper_->Uniform4ivImmediate(location, count, v); +} + +void UniformMatrix2fv( + GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { + helper_->UniformMatrix2fvImmediate(location, count, transpose, value); +} + +void UniformMatrix3fv( + GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { + helper_->UniformMatrix3fvImmediate(location, count, transpose, value); +} + +void UniformMatrix4fv( + GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { + helper_->UniformMatrix4fvImmediate(location, count, transpose, value); +} + +void UseProgram(GLuint program) { + helper_->UseProgram(program); +} + +void ValidateProgram(GLuint program) { + helper_->ValidateProgram(program); +} + +void VertexAttrib1f(GLuint indx, GLfloat x) { + helper_->VertexAttrib1f(indx, x); +} + +void VertexAttrib1fv(GLuint indx, const GLfloat* values) { + helper_->VertexAttrib1fvImmediate(indx, values); +} + +void VertexAttrib2f(GLuint indx, GLfloat x, GLfloat y) { + helper_->VertexAttrib2f(indx, x, y); +} + +void VertexAttrib2fv(GLuint indx, const GLfloat* values) { + helper_->VertexAttrib2fvImmediate(indx, values); +} + +void VertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z) { + helper_->VertexAttrib3f(indx, x, y, z); +} + +void VertexAttrib3fv(GLuint indx, const GLfloat* values) { + helper_->VertexAttrib3fvImmediate(indx, values); +} + +void VertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { + helper_->VertexAttrib4f(indx, x, y, z, w); +} + +void VertexAttrib4fv(GLuint indx, const GLfloat* values) { + helper_->VertexAttrib4fvImmediate(indx, values); +} + +void VertexAttribPointer( + GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, + const void* ptr); + +void Viewport(GLint x, GLint y, GLsizei width, GLsizei height) { + helper_->Viewport(x, y, width, height); +} + +void SwapBuffers() { + helper_->SwapBuffers(); +} + diff --git a/gpu/command_buffer/client/gles2_implementation_gen.h b/gpu/command_buffer/client/gles2_implementation_gen.h new file mode 100644 index 0000000..d385f8f --- /dev/null +++ b/gpu/command_buffer/client/gles2_implementation_gen.h @@ -0,0 +1,72 @@ + +// Copyright (c) 2006-2008 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. + + +// A class to emluate GLES2 over command buffers. + +#include "gpu/command_buffer/client/gles2_implementation.h" + +namespace command_buffer { +namespace gles2 { + +GLenum GLES2Implementation::CheckFramebufferStatus(GLenum target) { + return 0; +} + +void GLES2Implementation::GetActiveAttrib( + GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, + GLenum* type, char* name) { +} + +void GLES2Implementation::GetActiveUniform( + GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, + GLenum* type, char* name) { +} + +void GLES2Implementation::GetAttachedShaders( + GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) { +} + +void GLES2Implementation::GetProgramInfoLog( + GLuint program, GLsizei bufsize, GLsizei* length, char* infolog) { +} + +void GLES2Implementation::GetShaderInfoLog( + GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog) { +} + +void GLES2Implementation::GetShaderPrecisionFormat( + GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) { +} + +void GLES2Implementation::GetShaderSource( + GLuint shader, GLsizei bufsize, GLsizei* length, char* source) { +} + +const GLubyte* GLES2Implementation::GetString(GLenum name) { + return 0; +} + +void GLES2Implementation::GetUniformfv( + GLuint program, GLint location, GLfloat* params) { +} + +void GLES2Implementation::GetUniformiv( + GLuint program, GLint location, GLint* params) { +} + +void GLES2Implementation::GetVertexAttribPointerv( + GLuint index, GLenum pname, void** pointer) { +} + +void GLES2Implementation::ReadPixels( + GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, + void* pixels) { +} + + +} // namespace gles2 +} // namespace command_buffer + diff --git a/gpu/command_buffer/client/gles2_lib.cc b/gpu/command_buffer/client/gles2_lib.cc new file mode 100644 index 0000000..681f7ad --- /dev/null +++ b/gpu/command_buffer/client/gles2_lib.cc @@ -0,0 +1,20 @@ +// Copyright (c) 2006-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/client/gles2_lib.h" + +namespace gles2 { + +::command_buffer::gles2::GLES2Implementation* g_gl_impl; + +bool InitGLES2Lib() { + // TODO(gman): Encapulate initalizing the GLES2 library for client apps. + return false; +} + +} // namespace gles2 + + + + diff --git a/gpu/command_buffer/client/gles2_lib.h b/gpu/command_buffer/client/gles2_lib.h new file mode 100644 index 0000000..589d2050 --- /dev/null +++ b/gpu/command_buffer/client/gles2_lib.h @@ -0,0 +1,26 @@ +// Copyright (c) 2006-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. + +// These functions emluate GLES2 over command buffers. + +#ifndef GPU_COMMAND_BUFFER_CLIENT_GLES2_LIB_H +#define GPU_COMMAND_BUFFER_CLIENT_GLES2_LIB_H + +#include "gpu/command_buffer/client/gles2_implementation.h" + +namespace gles2 { + +extern ::command_buffer::gles2::GLES2Implementation* g_gl_impl; + +inline ::command_buffer::gles2::GLES2Implementation* GetGLContext() { + return g_gl_impl; +} + +// Initializes the GLES2 library. +bool InitGLES2Lib(); + +} // namespace gles2 + +#endif // GPU_COMMAND_BUFFER_CLIENT_GLES2_LIB_H + diff --git a/gpu/command_buffer/client/id_allocator.cc b/gpu/command_buffer/client/id_allocator.cc new file mode 100644 index 0000000..49104e5 --- /dev/null +++ b/gpu/command_buffer/client/id_allocator.cc @@ -0,0 +1,85 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the implementation of IdAllocator. + +#include "gpu/command_buffer/client/id_allocator.h" + +namespace command_buffer { + +IdAllocator::IdAllocator() : bitmap_(1) { bitmap_[0] = 0; } + +static const unsigned int kBitsPerUint32 = sizeof(Uint32) * 8; // NOLINT + +// Looks for the first non-full entry, and return the first free bit in that +// entry. If all the entries are full, it will return the first bit of an entry +// that would be appended, but doesn't actually append that entry to the vector. +unsigned int IdAllocator::FindFirstFree() const { + size_t size = bitmap_.size(); + for (unsigned int i = 0; i < size; ++i) { + Uint32 value = bitmap_[i]; + if (value != 0xffffffffU) { + for (unsigned int j = 0; j < kBitsPerUint32; ++j) { + if (!(value & (1 << j))) return i * kBitsPerUint32 + j; + } + DLOG(FATAL) << "Code should not reach here."; + } + } + return size*kBitsPerUint32; +} + +// Sets the correct bit in the proper entry, resizing the vector if needed. +void IdAllocator::SetBit(unsigned int bit, bool value) { + size_t size = bitmap_.size(); + if (bit >= size * kBitsPerUint32) { + size_t newsize = bit / kBitsPerUint32 + 1; + bitmap_.resize(newsize); + for (size_t i = size; i < newsize; ++i) bitmap_[i] = 0; + } + Uint32 mask = 1U << (bit % kBitsPerUint32); + if (value) { + bitmap_[bit / kBitsPerUint32] |= mask; + } else { + bitmap_[bit / kBitsPerUint32] &= ~mask; + } +} + +// Gets the bit from the proper entry. This doesn't resize the vector, just +// returns false if the bit is beyond the last entry. +bool IdAllocator::GetBit(unsigned int bit) const { + size_t size = bitmap_.size(); + if (bit / kBitsPerUint32 >= size) return false; + Uint32 mask = 1U << (bit % kBitsPerUint32); + return (bitmap_[bit / kBitsPerUint32] & mask) != 0; +} + +} // namespace command_buffer diff --git a/gpu/command_buffer/client/id_allocator.h b/gpu/command_buffer/client/id_allocator.h new file mode 100644 index 0000000..b2b14b9 --- /dev/null +++ b/gpu/command_buffer/client/id_allocator.h @@ -0,0 +1,78 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the definition of the IdAllocator class. + +#ifndef GPU_COMMAND_BUFFER_CLIENT_CROSS_ID_ALLOCATOR_H_ +#define GPU_COMMAND_BUFFER_CLIENT_CROSS_ID_ALLOCATOR_H_ + +#include <vector> +#include "base/basictypes.h" +#include "gpu/command_buffer/common/types.h" +#include "gpu/command_buffer/common/resource.h" + +namespace command_buffer { + +// A class to manage the allocation of resource IDs. It uses a bitfield stored +// into a vector of unsigned ints. +class IdAllocator { + public: + IdAllocator(); + + // Allocates a new resource ID. + command_buffer::ResourceId AllocateID() { + unsigned int bit = FindFirstFree(); + SetBit(bit, true); + return bit; + } + + // Frees a resource ID. + void FreeID(command_buffer::ResourceId id) { + SetBit(id, false); + } + + // Checks whether or not a resource ID is in use. + bool InUse(command_buffer::ResourceId id) { + return GetBit(id); + } + private: + void SetBit(unsigned int bit, bool value); + bool GetBit(unsigned int bit) const; + unsigned int FindFirstFree() const; + + std::vector<Uint32> bitmap_; + DISALLOW_COPY_AND_ASSIGN(IdAllocator); +}; + +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_CLIENT_CROSS_ID_ALLOCATOR_H_ diff --git a/gpu/command_buffer/client/id_allocator_test.cc b/gpu/command_buffer/client/id_allocator_test.cc new file mode 100644 index 0000000..bb8d5f9b --- /dev/null +++ b/gpu/command_buffer/client/id_allocator_test.cc @@ -0,0 +1,112 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file has the unit tests for the IdAllocator class. + +#include "gpu/command_buffer/client/id_allocator.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace command_buffer { + +using command_buffer::ResourceId; + +class IdAllocatorTest : public testing::Test { + protected: + virtual void SetUp() {} + virtual void TearDown() {} + + IdAllocator* id_allocator() { return &id_allocator_; } + + private: + IdAllocator id_allocator_; +}; + +// Checks basic functionality: AllocateID, FreeID, InUse. +TEST_F(IdAllocatorTest, TestBasic) { + IdAllocator *allocator = id_allocator(); + // Check that resource 0 is not in use + EXPECT_FALSE(allocator->InUse(0)); + + // Allocate an ID, check that it's in use. + ResourceId id1 = allocator->AllocateID(); + EXPECT_TRUE(allocator->InUse(id1)); + + // Allocate another ID, check that it's in use, and different from the first + // one. + ResourceId id2 = allocator->AllocateID(); + EXPECT_TRUE(allocator->InUse(id2)); + EXPECT_NE(id1, id2); + + // Free one of the IDs, check that it's not in use any more. + allocator->FreeID(id1); + EXPECT_FALSE(allocator->InUse(id1)); + + // Frees the other ID, check that it's not in use any more. + allocator->FreeID(id2); + EXPECT_FALSE(allocator->InUse(id2)); +} + +// Checks that the resource IDs are allocated conservatively, and re-used after +// being freed. +TEST_F(IdAllocatorTest, TestAdvanced) { + IdAllocator *allocator = id_allocator(); + + // Allocate a significant number of resources. + const unsigned int kNumResources = 100; + ResourceId ids[kNumResources]; + for (unsigned int i = 0; i < kNumResources; ++i) { + ids[i] = allocator->AllocateID(); + EXPECT_TRUE(allocator->InUse(ids[i])); + } + + // Check that the allocation is conservative with resource IDs, that is that + // the resource IDs don't go over kNumResources - so that the service doesn't + // have to allocate too many internal structures when the resources are used. + for (unsigned int i = 0; i < kNumResources; ++i) { + EXPECT_GT(kNumResources, ids[i]); + } + + // Check that the next resources are still free. + for (unsigned int i = 0; i < kNumResources; ++i) { + EXPECT_FALSE(allocator->InUse(kNumResources + i)); + } + + // Check that a new allocation re-uses the resource we just freed. + ResourceId id1 = ids[kNumResources / 2]; + allocator->FreeID(id1); + EXPECT_FALSE(allocator->InUse(id1)); + ResourceId id2 = allocator->AllocateID(); + EXPECT_TRUE(allocator->InUse(id2)); + EXPECT_EQ(id1, id2); +} + +} // namespace command_buffer diff --git a/gpu/command_buffer/common/GLES2/gl2.h b/gpu/command_buffer/common/GLES2/gl2.h new file mode 100644 index 0000000..6293ee4 --- /dev/null +++ b/gpu/command_buffer/common/GLES2/gl2.h @@ -0,0 +1,319 @@ +#ifndef __gl2_h_ +#define __gl2_h_ + +/* $Revision: 8784 $ on $Date:: 2009-09-02 09:49:17 -0700 #$ */ + +/* + * This document is licensed under the SGI Free Software B License Version + * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . + */ + +#include <GLES2/gl2types.h> + +#ifdef __cplusplus +#include "gpu/command_buffer/client/gles2_lib.h" +#define GLES2_GET_FUN(name) gles2::GetGLContext()->name +#else +#define GLES2_GET_FUN(name) GLES2 ## name +#endif + +/*------------------------------------------------------------------------- + * GL core functions. + *-----------------------------------------------------------------------*/ +#undef GL_APICALL +#define GL_APICALL +#undef GL_APIENTRY +#define GL_APIENTRY + +#define glActiveTexture GLES2_GET_FUN(ActiveTexture) +#define glAttachShader GLES2_GET_FUN(AttachShader) +#define glBindAttribLocation GLES2_GET_FUN(BindAttribLocation) +#define glBindBuffer GLES2_GET_FUN(BindBuffer) +#define glBindFramebuffer GLES2_GET_FUN(BindFramebuffer) +#define glBindRenderbuffer GLES2_GET_FUN(BindRenderbuffer) +#define glBindTexture GLES2_GET_FUN(BindTexture) +#define glBlendColor GLES2_GET_FUN(BlendColor) +#define glBlendEquation GLES2_GET_FUN(BlendEquation) +#define glBlendEquationSeparate GLES2_GET_FUN(BlendEquationSeparate) +#define glBlendFunc GLES2_GET_FUN(BlendFunc) +#define glBlendFuncSeparate GLES2_GET_FUN(BlendFuncSeparate) +#define glBufferData GLES2_GET_FUN(BufferData) +#define glBufferSubData GLES2_GET_FUN(BufferSubData) +#define glCheckFramebufferStatus GLES2_GET_FUN(CheckFramebufferStatus) +#define glClear GLES2_GET_FUN(Clear) +#define glClearColor GLES2_GET_FUN(ClearColor) +#define glClearDepthf GLES2_GET_FUN(ClearDepthf) +#define glClearStencil GLES2_GET_FUN(ClearStencil) +#define glColorMask GLES2_GET_FUN(ColorMask) +#define glCompileShader GLES2_GET_FUN(CompileShader) +#define glCompressedTexImage2D GLES2_GET_FUN(CompressedTexImage2D) +#define glCompressedTexSubImage2D GLES2_GET_FUN(CompressedTexSubImage2D) +#define glCopyTexImage2D GLES2_GET_FUN(CopyTexImage2D) +#define glCopyTexSubImage2D GLES2_GET_FUN(CopyTexSubImage2D) +#define glCreateProgram GLES2_GET_FUN(CreateProgram) +#define glCreateShader GLES2_GET_FUN(CreateShader) +#define glCullFace GLES2_GET_FUN(CullFace) +#define glDeleteBuffers GLES2_GET_FUN(DeleteBuffers) +#define glDeleteFramebuffers GLES2_GET_FUN(DeleteFramebuffers) +#define glDeleteProgram GLES2_GET_FUN(DeleteProgram) +#define glDeleteRenderbuffers GLES2_GET_FUN(DeleteRenderbuffers) +#define glDeleteShader GLES2_GET_FUN(DeleteShader) +#define glDeleteTextures GLES2_GET_FUN(DeleteTextures) +#define glDepthFunc GLES2_GET_FUN(DepthFunc) +#define glDepthMask GLES2_GET_FUN(DepthMask) +#define glDepthRangef GLES2_GET_FUN(DepthRangef) +#define glDetachShader GLES2_GET_FUN(DetachShader) +#define glDisable GLES2_GET_FUN(Disable) +#define glDisableVertexAttribArray GLES2_GET_FUN(DisableVertexAttribArray) +#define glDrawArrays GLES2_GET_FUN(DrawArrays) +#define glDrawElements GLES2_GET_FUN(DrawElements) +#define glEnable GLES2_GET_FUN(Enable) +#define glEnableVertexAttribArray GLES2_GET_FUN(EnableVertexAttribArray) +#define glFinish GLES2_GET_FUN(Finish) +#define glFlush GLES2_GET_FUN(Flush) +#define glFramebufferRenderbuffer GLES2_GET_FUN(FramebufferRenderbuffer) +#define glFramebufferTexture2D GLES2_GET_FUN(FramebufferTexture2D) +#define glFrontFace GLES2_GET_FUN(FrontFace) +#define glGenBuffers GLES2_GET_FUN(GenBuffers) +#define glGenerateMipmap GLES2_GET_FUN(GenerateMipmap) +#define glGenFramebuffers GLES2_GET_FUN(GenFramebuffers) +#define glGenRenderbuffers GLES2_GET_FUN(GenRenderbuffers) +#define glGenTextures GLES2_GET_FUN(GenTextures) +#define glGetActiveAttrib GLES2_GET_FUN(GetActiveAttrib) +#define glGetActiveUniform GLES2_GET_FUN(GetActiveUniform) +#define glGetAttachedShaders GLES2_GET_FUN(GetAttachedShaders) +#define glGetAttribLocation GLES2_GET_FUN(GetAttribLocation) +#define glGetBooleanv GLES2_GET_FUN(GetBooleanv) +#define glGetBufferParameteriv GLES2_GET_FUN(GetBufferParameteriv) +#define glGetError GLES2_GET_FUN(GetError) +#define glGetFloatv GLES2_GET_FUN(GetFloatv) +#define glGetFramebufferAttachmentParameteriv GLES2_GET_FUN(GetFramebufferAttachmentParameteriv) +#define glGetIntegerv GLES2_GET_FUN(GetIntegerv) +#define glGetProgramiv GLES2_GET_FUN(GetProgramiv) +#define glGetProgramInfoLog GLES2_GET_FUN(GetProgramInfoLog) +#define glGetRenderbufferParameteriv GLES2_GET_FUN(GetRenderbufferParameteriv) +#define glGetShaderiv GLES2_GET_FUN(GetShaderiv) +#define glGetShaderInfoLog GLES2_GET_FUN(GetShaderInfoLog) +#define glGetShaderPrecisionFormat GLES2_GET_FUN(GetShaderPrecisionFormat) +#define glGetShaderSource GLES2_GET_FUN(GetShaderSource) +#define glGetString GLES2_GET_FUN(GetString) +#define glGetTexParameterfv GLES2_GET_FUN(GetTexParameterfv) +#define glGetTexParameteriv GLES2_GET_FUN(GetTexParameteriv) +#define glGetUniformfv GLES2_GET_FUN(GetUniformfv) +#define glGetUniformiv GLES2_GET_FUN(GetUniformiv) +#define glGetUniformLocation GLES2_GET_FUN(GetUniformLocation) +#define glGetVertexAttribfv GLES2_GET_FUN(GetVertexAttribfv) +#define glGetVertexAttribiv GLES2_GET_FUN(GetVertexAttribiv) +#define glGetVertexAttribPointerv GLES2_GET_FUN(GetVertexAttribPointerv) +#define glHint GLES2_GET_FUN(Hint) +#define glIsBuffer GLES2_GET_FUN(IsBuffer) +#define glIsEnabled GLES2_GET_FUN(IsEnabled) +#define glIsFramebuffer GLES2_GET_FUN(IsFramebuffer) +#define glIsProgram GLES2_GET_FUN(IsProgram) +#define glIsRenderbuffer GLES2_GET_FUN(IsRenderbuffer) +#define glIsShader GLES2_GET_FUN(IsShader) +#define glIsTexture GLES2_GET_FUN(IsTexture) +#define glLineWidth GLES2_GET_FUN(LineWidth) +#define glLinkProgram GLES2_GET_FUN(LinkProgram) +#define glPixelStorei GLES2_GET_FUN(PixelStorei) +#define glPolygonOffset GLES2_GET_FUN(PolygonOffset) +#define glReadPixels GLES2_GET_FUN(ReadPixels) +#define glReleaseShaderCompiler GLES2_GET_FUN(ReleaseShaderCompiler) +#define glRenderbufferStorage GLES2_GET_FUN(RenderbufferStorage) +#define glSampleCoverage GLES2_GET_FUN(SampleCoverage) +#define glScissor GLES2_GET_FUN(Scissor) +#define glShaderBinary GLES2_GET_FUN(ShaderBinary) +#define glShaderSource GLES2_GET_FUN(ShaderSource) +#define glStencilFunc GLES2_GET_FUN(StencilFunc) +#define glStencilFuncSeparate GLES2_GET_FUN(StencilFuncSeparate) +#define glStencilMask GLES2_GET_FUN(StencilMask) +#define glStencilMaskSeparate GLES2_GET_FUN(StencilMaskSeparate) +#define glStencilOp GLES2_GET_FUN(StencilOp) +#define glStencilOpSeparate GLES2_GET_FUN(StencilOpSeparate) +#define glTexImage2D GLES2_GET_FUN(TexImage2D) +#define glTexParameterf GLES2_GET_FUN(TexParameterf) +#define glTexParameterfv GLES2_GET_FUN(TexParameterfv) +#define glTexParameteri GLES2_GET_FUN(TexParameteri) +#define glTexParameteriv GLES2_GET_FUN(TexParameteriv) +#define glTexSubImage2D GLES2_GET_FUN(TexSubImage2D) +#define glUniform1f GLES2_GET_FUN(Uniform1f) +#define glUniform1fv GLES2_GET_FUN(Uniform1fv) +#define glUniform1i GLES2_GET_FUN(Uniform1i) +#define glUniform1iv GLES2_GET_FUN(Uniform1iv) +#define glUniform2f GLES2_GET_FUN(Uniform2f) +#define glUniform2fv GLES2_GET_FUN(Uniform2fv) +#define glUniform2i GLES2_GET_FUN(Uniform2i) +#define glUniform2iv GLES2_GET_FUN(Uniform2iv) +#define glUniform3f GLES2_GET_FUN(Uniform3f) +#define glUniform3fv GLES2_GET_FUN(Uniform3fv) +#define glUniform3i GLES2_GET_FUN(Uniform3i) +#define glUniform3iv GLES2_GET_FUN(Uniform3iv) +#define glUniform4f GLES2_GET_FUN(Uniform4f) +#define glUniform4fv GLES2_GET_FUN(Uniform4fv) +#define glUniform4i GLES2_GET_FUN(Uniform4i) +#define glUniform4iv GLES2_GET_FUN(Uniform4iv) +#define glUniformMatrix2fv GLES2_GET_FUN(UniformMatrix2fv) +#define glUniformMatrix3fv GLES2_GET_FUN(UniformMatrix3fv) +#define glUniformMatrix4fv GLES2_GET_FUN(UniformMatrix4fv) +#define glUseProgram GLES2_GET_FUN(UseProgram) +#define glValidateProgram GLES2_GET_FUN(ValidateProgram) +#define glVertexAttrib1f GLES2_GET_FUN(VertexAttrib1f) +#define glVertexAttrib1fv GLES2_GET_FUN(VertexAttrib1fv) +#define glVertexAttrib2f GLES2_GET_FUN(VertexAttrib2f) +#define glVertexAttrib2fv GLES2_GET_FUN(VertexAttrib2fv) +#define glVertexAttrib3f GLES2_GET_FUN(VertexAttrib3f) +#define glVertexAttrib3fv GLES2_GET_FUN(VertexAttrib3fv) +#define glVertexAttrib4f GLES2_GET_FUN(VertexAttrib4f) +#define glVertexAttrib4fv GLES2_GET_FUN(VertexAttrib4fv) +#define glVertexAttribPointer GLES2_GET_FUN(VertexAttribPointer) +#define glViewport GLES2_GET_FUN(Viewport) + +#ifndef __cplusplus + +GL_APICALL void GL_APIENTRY glActiveTexture (GLenum texture); +GL_APICALL void GL_APIENTRY glAttachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const char* name); +GL_APICALL void GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer); +GL_APICALL void GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer); +GL_APICALL void GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glBindTexture (GLenum target, GLuint texture); +GL_APICALL void GL_APIENTRY glBlendColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +GL_APICALL void GL_APIENTRY glBlendEquation ( GLenum mode ); +GL_APICALL void GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha); +GL_APICALL void GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); +GL_APICALL void GL_APIENTRY glBlendFuncSeparate (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); +GL_APICALL void GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void* data, GLenum usage); +GL_APICALL void GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void* data); +GL_APICALL GLenum GL_APIENTRY glCheckFramebufferStatus (GLenum target); +GL_APICALL void GL_APIENTRY glClear (GLbitfield mask); +GL_APICALL void GL_APIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); +GL_APICALL void GL_APIENTRY glClearDepthf (GLclampf depth); +GL_APICALL void GL_APIENTRY glClearStencil (GLint s); +GL_APICALL void GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +GL_APICALL void GL_APIENTRY glCompileShader (GLuint shader); +GL_APICALL void GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data); +GL_APICALL void GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data); +GL_APICALL void GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GL_APICALL void GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL GLuint GL_APIENTRY glCreateProgram (void); +GL_APICALL GLuint GL_APIENTRY glCreateShader (GLenum type); +GL_APICALL void GL_APIENTRY glCullFace (GLenum mode); +GL_APICALL void GL_APIENTRY glDeleteBuffers (GLsizei n, const GLuint* buffers); +GL_APICALL void GL_APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint* framebuffers); +GL_APICALL void GL_APIENTRY glDeleteProgram (GLuint program); +GL_APICALL void GL_APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint* renderbuffers); +GL_APICALL void GL_APIENTRY glDeleteShader (GLuint shader); +GL_APICALL void GL_APIENTRY glDeleteTextures (GLsizei n, const GLuint* textures); +GL_APICALL void GL_APIENTRY glDepthFunc (GLenum func); +GL_APICALL void GL_APIENTRY glDepthMask (GLboolean flag); +GL_APICALL void GL_APIENTRY glDepthRangef (GLclampf zNear, GLclampf zFar); +GL_APICALL void GL_APIENTRY glDetachShader (GLuint program, GLuint shader); +GL_APICALL void GL_APIENTRY glDisable (GLenum cap); +GL_APICALL void GL_APIENTRY glDisableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); +GL_APICALL void GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void* indices); +GL_APICALL void GL_APIENTRY glEnable (GLenum cap); +GL_APICALL void GL_APIENTRY glEnableVertexAttribArray (GLuint index); +GL_APICALL void GL_APIENTRY glFinish (void); +GL_APICALL void GL_APIENTRY glFlush (void); +GL_APICALL void GL_APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); +GL_APICALL void GL_APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GL_APICALL void GL_APIENTRY glFrontFace (GLenum mode); +GL_APICALL void GL_APIENTRY glGenBuffers (GLsizei n, GLuint* buffers); +GL_APICALL void GL_APIENTRY glGenerateMipmap (GLenum target); +GL_APICALL void GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint* framebuffers); +GL_APICALL void GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint* renderbuffers); +GL_APICALL void GL_APIENTRY glGenTextures (GLsizei n, GLuint* textures); +GL_APICALL void GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name); +GL_APICALL void GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name); +GL_APICALL void GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders); +GL_APICALL int GL_APIENTRY glGetAttribLocation (GLuint program, const char* name); +GL_APICALL void GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean* params); +GL_APICALL void GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint* params); +GL_APICALL GLenum GL_APIENTRY glGetError (void); +GL_APICALL void GL_APIENTRY glGetFloatv (GLenum pname, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetIntegerv (GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufsize, GLsizei* length, char* infolog); +GL_APICALL void GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog); +GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision); +GL_APICALL void GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufsize, GLsizei* length, char* source); +GL_APICALL const GLubyte* GL_APIENTRY glGetString (GLenum name); +GL_APICALL void GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint* params); +GL_APICALL int GL_APIENTRY glGetUniformLocation (GLuint program, const char* name); +GL_APICALL void GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat* params); +GL_APICALL void GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint* params); +GL_APICALL void GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void** pointer); +GL_APICALL void GL_APIENTRY glHint (GLenum target, GLenum mode); +GL_APICALL GLboolean GL_APIENTRY glIsBuffer (GLuint buffer); +GL_APICALL GLboolean GL_APIENTRY glIsEnabled (GLenum cap); +GL_APICALL GLboolean GL_APIENTRY glIsFramebuffer (GLuint framebuffer); +GL_APICALL GLboolean GL_APIENTRY glIsProgram (GLuint program); +GL_APICALL GLboolean GL_APIENTRY glIsRenderbuffer (GLuint renderbuffer); +GL_APICALL GLboolean GL_APIENTRY glIsShader (GLuint shader); +GL_APICALL GLboolean GL_APIENTRY glIsTexture (GLuint texture); +GL_APICALL void GL_APIENTRY glLineWidth (GLfloat width); +GL_APICALL void GL_APIENTRY glLinkProgram (GLuint program); +GL_APICALL void GL_APIENTRY glPixelStorei (GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units); +GL_APICALL void GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels); +GL_APICALL void GL_APIENTRY glReleaseShaderCompiler (void); +GL_APICALL void GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glSampleCoverage (GLclampf value, GLboolean invert); +GL_APICALL void GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glShaderBinary (GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length); +GL_APICALL void GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const char** string, const GLint* length); +GL_APICALL void GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMask (GLuint mask); +GL_APICALL void GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask); +GL_APICALL void GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); +GL_APICALL void GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum fail, GLenum zfail, GLenum zpass); +GL_APICALL void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels); +GL_APICALL void GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); +GL_APICALL void GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat* params); +GL_APICALL void GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); +GL_APICALL void GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint* params); +GL_APICALL void GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels); +GL_APICALL void GL_APIENTRY glUniform1f (GLint location, GLfloat x); +GL_APICALL void GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform1i (GLint location, GLint x); +GL_APICALL void GL_APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform2f (GLint location, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform2i (GLint location, GLint x, GLint y); +GL_APICALL void GL_APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform3f (GLint location, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform3i (GLint location, GLint x, GLint y, GLint z); +GL_APICALL void GL_APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniform4f (GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat* v); +GL_APICALL void GL_APIENTRY glUniform4i (GLint location, GLint x, GLint y, GLint z, GLint w); +GL_APICALL void GL_APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint* v); +GL_APICALL void GL_APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); +GL_APICALL void GL_APIENTRY glUseProgram (GLuint program); +GL_APICALL void GL_APIENTRY glValidateProgram (GLuint program); +GL_APICALL void GL_APIENTRY glVertexAttrib1f (GLuint indx, GLfloat x); +GL_APICALL void GL_APIENTRY glVertexAttrib1fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttrib2f (GLuint indx, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glVertexAttrib2fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttrib3f (GLuint indx, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glVertexAttrib3fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint indx, const GLfloat* values); +GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr); +GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); + +#endif // __cplusplus + +#endif /* __gl2_h_ */ + diff --git a/gpu/command_buffer/common/GLES2/gl2platform.h b/gpu/command_buffer/common/GLES2/gl2platform.h new file mode 100644 index 0000000..3e9036c --- /dev/null +++ b/gpu/command_buffer/common/GLES2/gl2platform.h @@ -0,0 +1,29 @@ +#ifndef __gl2platform_h_ +#define __gl2platform_h_ + +/* $Revision: 7173 $ on $Date:: 2009-01-09 11:18:21 -0800 #$ */ + +/* + * This document is licensed under the SGI Free Software B License Version + * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . + */ + +/* Platform-specific types and definitions for OpenGL ES 2.X gl2.h + * Last modified on 2008/12/19 + * + * Adopters may modify khrplatform.h and this file to suit their platform. + * You are encouraged to submit all modifications to the Khronos group so that + * they can be included in future versions of this file. Please submit changes + * by sending them to the public Khronos Bugzilla (http://khronos.org/bugzilla) + * by filing a bug against product "OpenGL-ES" component "Registry". + */ + +#include <KHR/khrplatform.h> + +#ifndef GL_APICALL +#define GL_APICALL KHRONOS_APICALL +#endif + +#define GL_APIENTRY KHRONOS_APIENTRY + +#endif /* __gl2platform_h_ */ diff --git a/gpu/command_buffer/common/GLES2/gl2types.h b/gpu/command_buffer/common/GLES2/gl2types.h new file mode 100644 index 0000000..85046d1 --- /dev/null +++ b/gpu/command_buffer/common/GLES2/gl2types.h @@ -0,0 +1,464 @@ +#ifndef __gl2types_h_ +#define __gl2types_h_ + +#include <GLES2/gl2platform.h> + +/* + * This document is licensed under the SGI Free Software B License Version + * 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . + */ + +/*------------------------------------------------------------------------- + * Data type definitions + *-----------------------------------------------------------------------*/ + +typedef void GLvoid; +typedef unsigned int GLenum; +typedef unsigned char GLboolean; +typedef unsigned int GLbitfield; +typedef khronos_int8_t GLbyte; +typedef short GLshort; +typedef int GLint; +typedef int GLsizei; +typedef khronos_uint8_t GLubyte; +typedef unsigned short GLushort; +typedef unsigned int GLuint; +typedef khronos_float_t GLfloat; +typedef khronos_float_t GLclampf; +typedef khronos_int32_t GLfixed; + +/* GL types for handling large vertex buffer objects */ +typedef khronos_intptr_t GLintptr; +typedef khronos_ssize_t GLsizeiptr; + +/* OpenGL ES core versions */ +#define GL_ES_VERSION_2_0 1 + +/* ClearBufferMask */ +#define GL_DEPTH_BUFFER_BIT 0x00000100 +#define GL_STENCIL_BUFFER_BIT 0x00000400 +#define GL_COLOR_BUFFER_BIT 0x00004000 + +/* Boolean */ +#define GL_FALSE 0 +#define GL_TRUE 1 + +/* BeginMode */ +#define GL_POINTS 0x0000 +#define GL_LINES 0x0001 +#define GL_LINE_LOOP 0x0002 +#define GL_LINE_STRIP 0x0003 +#define GL_TRIANGLES 0x0004 +#define GL_TRIANGLE_STRIP 0x0005 +#define GL_TRIANGLE_FAN 0x0006 + +/* AlphaFunction (not supported in ES20) */ +/* GL_NEVER */ +/* GL_LESS */ +/* GL_EQUAL */ +/* GL_LEQUAL */ +/* GL_GREATER */ +/* GL_NOTEQUAL */ +/* GL_GEQUAL */ +/* GL_ALWAYS */ + +/* BlendingFactorDest */ +#define GL_ZERO 0 +#define GL_ONE 1 +#define GL_SRC_COLOR 0x0300 +#define GL_ONE_MINUS_SRC_COLOR 0x0301 +#define GL_SRC_ALPHA 0x0302 +#define GL_ONE_MINUS_SRC_ALPHA 0x0303 +#define GL_DST_ALPHA 0x0304 +#define GL_ONE_MINUS_DST_ALPHA 0x0305 + +/* BlendingFactorSrc */ +/* GL_ZERO */ +/* GL_ONE */ +#define GL_DST_COLOR 0x0306 +#define GL_ONE_MINUS_DST_COLOR 0x0307 +#define GL_SRC_ALPHA_SATURATE 0x0308 +/* GL_SRC_ALPHA */ +/* GL_ONE_MINUS_SRC_ALPHA */ +/* GL_DST_ALPHA */ +/* GL_ONE_MINUS_DST_ALPHA */ + +/* BlendEquationSeparate */ +#define GL_FUNC_ADD 0x8006 +#define GL_BLEND_EQUATION 0x8009 +#define GL_BLEND_EQUATION_RGB 0x8009 /* same as BLEND_EQUATION */ +#define GL_BLEND_EQUATION_ALPHA 0x883D + +/* BlendSubtract */ +#define GL_FUNC_SUBTRACT 0x800A +#define GL_FUNC_REVERSE_SUBTRACT 0x800B + +/* Separate Blend Functions */ +#define GL_BLEND_DST_RGB 0x80C8 +#define GL_BLEND_SRC_RGB 0x80C9 +#define GL_BLEND_DST_ALPHA 0x80CA +#define GL_BLEND_SRC_ALPHA 0x80CB +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 +#define GL_BLEND_COLOR 0x8005 + +/* Buffer Objects */ +#define GL_ARRAY_BUFFER 0x8892 +#define GL_ELEMENT_ARRAY_BUFFER 0x8893 +#define GL_ARRAY_BUFFER_BINDING 0x8894 +#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 + +#define GL_STREAM_DRAW 0x88E0 +#define GL_STATIC_DRAW 0x88E4 +#define GL_DYNAMIC_DRAW 0x88E8 + +#define GL_BUFFER_SIZE 0x8764 +#define GL_BUFFER_USAGE 0x8765 + +#define GL_CURRENT_VERTEX_ATTRIB 0x8626 + +/* CullFaceMode */ +#define GL_FRONT 0x0404 +#define GL_BACK 0x0405 +#define GL_FRONT_AND_BACK 0x0408 + +/* DepthFunction */ +/* GL_NEVER */ +/* GL_LESS */ +/* GL_EQUAL */ +/* GL_LEQUAL */ +/* GL_GREATER */ +/* GL_NOTEQUAL */ +/* GL_GEQUAL */ +/* GL_ALWAYS */ + +/* EnableCap */ +#define GL_TEXTURE_2D 0x0DE1 +#define GL_CULL_FACE 0x0B44 +#define GL_BLEND 0x0BE2 +#define GL_DITHER 0x0BD0 +#define GL_STENCIL_TEST 0x0B90 +#define GL_DEPTH_TEST 0x0B71 +#define GL_SCISSOR_TEST 0x0C11 +#define GL_POLYGON_OFFSET_FILL 0x8037 +#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E +#define GL_SAMPLE_COVERAGE 0x80A0 + +/* ErrorCode */ +#define GL_NO_ERROR 0 +#define GL_INVALID_ENUM 0x0500 +#define GL_INVALID_VALUE 0x0501 +#define GL_INVALID_OPERATION 0x0502 +#define GL_OUT_OF_MEMORY 0x0505 + +/* FrontFaceDirection */ +#define GL_CW 0x0900 +#define GL_CCW 0x0901 + +/* GetPName */ +#define GL_LINE_WIDTH 0x0B21 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_CULL_FACE_MODE 0x0B45 +#define GL_FRONT_FACE 0x0B46 +#define GL_DEPTH_RANGE 0x0B70 +#define GL_DEPTH_WRITEMASK 0x0B72 +#define GL_DEPTH_CLEAR_VALUE 0x0B73 +#define GL_DEPTH_FUNC 0x0B74 +#define GL_STENCIL_CLEAR_VALUE 0x0B91 +#define GL_STENCIL_FUNC 0x0B92 +#define GL_STENCIL_FAIL 0x0B94 +#define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 +#define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 +#define GL_STENCIL_REF 0x0B97 +#define GL_STENCIL_VALUE_MASK 0x0B93 +#define GL_STENCIL_WRITEMASK 0x0B98 +#define GL_STENCIL_BACK_FUNC 0x8800 +#define GL_STENCIL_BACK_FAIL 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 +#define GL_STENCIL_BACK_REF 0x8CA3 +#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 +#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 +#define GL_VIEWPORT 0x0BA2 +#define GL_SCISSOR_BOX 0x0C10 +/* GL_SCISSOR_TEST */ +#define GL_COLOR_CLEAR_VALUE 0x0C22 +#define GL_COLOR_WRITEMASK 0x0C23 +#define GL_UNPACK_ALIGNMENT 0x0CF5 +#define GL_PACK_ALIGNMENT 0x0D05 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_ALPHA_BITS 0x0D55 +#define GL_DEPTH_BITS 0x0D56 +#define GL_STENCIL_BITS 0x0D57 +#define GL_POLYGON_OFFSET_UNITS 0x2A00 +/* GL_POLYGON_OFFSET_FILL */ +#define GL_POLYGON_OFFSET_FACTOR 0x8038 +#define GL_TEXTURE_BINDING_2D 0x8069 +#define GL_SAMPLE_BUFFERS 0x80A8 +#define GL_SAMPLES 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT 0x80AB + +/* GetTextureParameter */ +/* GL_TEXTURE_MAG_FILTER */ +/* GL_TEXTURE_MIN_FILTER */ +/* GL_TEXTURE_WRAP_S */ +/* GL_TEXTURE_WRAP_T */ + +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 + +/* HintMode */ +#define GL_DONT_CARE 0x1100 +#define GL_FASTEST 0x1101 +#define GL_NICEST 0x1102 + +/* HintTarget */ +#define GL_GENERATE_MIPMAP_HINT 0x8192 + +/* DataType */ +#define GL_BYTE 0x1400 +#define GL_UNSIGNED_BYTE 0x1401 +#define GL_SHORT 0x1402 +#define GL_UNSIGNED_SHORT 0x1403 +#define GL_INT 0x1404 +#define GL_UNSIGNED_INT 0x1405 +#define GL_FLOAT 0x1406 +#define GL_FIXED 0x140C + +/* PixelFormat */ +#define GL_DEPTH_COMPONENT 0x1902 +#define GL_ALPHA 0x1906 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A + +/* PixelType */ +/* GL_UNSIGNED_BYTE */ +#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 +#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 +#define GL_UNSIGNED_SHORT_5_6_5 0x8363 + +/* Shaders */ +#define GL_FRAGMENT_SHADER 0x8B30 +#define GL_VERTEX_SHADER 0x8B31 +#define GL_MAX_VERTEX_ATTRIBS 0x8869 +#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB +#define GL_MAX_VARYING_VECTORS 0x8DFC +#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D +#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C +#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 +#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD +#define GL_SHADER_TYPE 0x8B4F +#define GL_DELETE_STATUS 0x8B80 +#define GL_LINK_STATUS 0x8B82 +#define GL_VALIDATE_STATUS 0x8B83 +#define GL_ATTACHED_SHADERS 0x8B85 +#define GL_ACTIVE_UNIFORMS 0x8B86 +#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 +#define GL_ACTIVE_ATTRIBUTES 0x8B89 +#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A +#define GL_SHADING_LANGUAGE_VERSION 0x8B8C +#define GL_CURRENT_PROGRAM 0x8B8D + +/* StencilFunction */ +#define GL_NEVER 0x0200 +#define GL_LESS 0x0201 +#define GL_EQUAL 0x0202 +#define GL_LEQUAL 0x0203 +#define GL_GREATER 0x0204 +#define GL_NOTEQUAL 0x0205 +#define GL_GEQUAL 0x0206 +#define GL_ALWAYS 0x0207 + +/* StencilOp */ +/* GL_ZERO */ +#define GL_KEEP 0x1E00 +#define GL_REPLACE 0x1E01 +#define GL_INCR 0x1E02 +#define GL_DECR 0x1E03 +#define GL_INVERT 0x150A +#define GL_INCR_WRAP 0x8507 +#define GL_DECR_WRAP 0x8508 + +/* StringName */ +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 + +/* TextureMagFilter */ +#define GL_NEAREST 0x2600 +#define GL_LINEAR 0x2601 + +/* TextureMinFilter */ +/* GL_NEAREST */ +/* GL_LINEAR */ +#define GL_NEAREST_MIPMAP_NEAREST 0x2700 +#define GL_LINEAR_MIPMAP_NEAREST 0x2701 +#define GL_NEAREST_MIPMAP_LINEAR 0x2702 +#define GL_LINEAR_MIPMAP_LINEAR 0x2703 + +/* TextureParameterName */ +#define GL_TEXTURE_MAG_FILTER 0x2800 +#define GL_TEXTURE_MIN_FILTER 0x2801 +#define GL_TEXTURE_WRAP_S 0x2802 +#define GL_TEXTURE_WRAP_T 0x2803 + +/* TextureTarget */ +/* GL_TEXTURE_2D */ +#define GL_TEXTURE 0x1702 + +#define GL_TEXTURE_CUBE_MAP 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C + +/* TextureUnit */ +#define GL_TEXTURE0 0x84C0 +#define GL_TEXTURE1 0x84C1 +#define GL_TEXTURE2 0x84C2 +#define GL_TEXTURE3 0x84C3 +#define GL_TEXTURE4 0x84C4 +#define GL_TEXTURE5 0x84C5 +#define GL_TEXTURE6 0x84C6 +#define GL_TEXTURE7 0x84C7 +#define GL_TEXTURE8 0x84C8 +#define GL_TEXTURE9 0x84C9 +#define GL_TEXTURE10 0x84CA +#define GL_TEXTURE11 0x84CB +#define GL_TEXTURE12 0x84CC +#define GL_TEXTURE13 0x84CD +#define GL_TEXTURE14 0x84CE +#define GL_TEXTURE15 0x84CF +#define GL_TEXTURE16 0x84D0 +#define GL_TEXTURE17 0x84D1 +#define GL_TEXTURE18 0x84D2 +#define GL_TEXTURE19 0x84D3 +#define GL_TEXTURE20 0x84D4 +#define GL_TEXTURE21 0x84D5 +#define GL_TEXTURE22 0x84D6 +#define GL_TEXTURE23 0x84D7 +#define GL_TEXTURE24 0x84D8 +#define GL_TEXTURE25 0x84D9 +#define GL_TEXTURE26 0x84DA +#define GL_TEXTURE27 0x84DB +#define GL_TEXTURE28 0x84DC +#define GL_TEXTURE29 0x84DD +#define GL_TEXTURE30 0x84DE +#define GL_TEXTURE31 0x84DF +#define GL_ACTIVE_TEXTURE 0x84E0 + +/* TextureWrapMode */ +#define GL_REPEAT 0x2901 +#define GL_CLAMP_TO_EDGE 0x812F +#define GL_MIRRORED_REPEAT 0x8370 + +/* Uniform Types */ +#define GL_FLOAT_VEC2 0x8B50 +#define GL_FLOAT_VEC3 0x8B51 +#define GL_FLOAT_VEC4 0x8B52 +#define GL_INT_VEC2 0x8B53 +#define GL_INT_VEC3 0x8B54 +#define GL_INT_VEC4 0x8B55 +#define GL_BOOL 0x8B56 +#define GL_BOOL_VEC2 0x8B57 +#define GL_BOOL_VEC3 0x8B58 +#define GL_BOOL_VEC4 0x8B59 +#define GL_FLOAT_MAT2 0x8B5A +#define GL_FLOAT_MAT3 0x8B5B +#define GL_FLOAT_MAT4 0x8B5C +#define GL_SAMPLER_2D 0x8B5E +#define GL_SAMPLER_CUBE 0x8B60 + +/* Vertex Arrays */ +#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 +#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 +#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 +#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 +#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A +#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 +#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F + +/* Read Format */ +#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B + +/* Shader Source */ +#define GL_COMPILE_STATUS 0x8B81 +#define GL_INFO_LOG_LENGTH 0x8B84 +#define GL_SHADER_SOURCE_LENGTH 0x8B88 +#define GL_SHADER_COMPILER 0x8DFA + +/* Shader Binary */ +#define GL_SHADER_BINARY_FORMATS 0x8DF8 +#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 + +/* Shader Precision-Specified Types */ +#define GL_LOW_FLOAT 0x8DF0 +#define GL_MEDIUM_FLOAT 0x8DF1 +#define GL_HIGH_FLOAT 0x8DF2 +#define GL_LOW_INT 0x8DF3 +#define GL_MEDIUM_INT 0x8DF4 +#define GL_HIGH_INT 0x8DF5 + +/* Framebuffer Object. */ +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 + +#define GL_RGBA4 0x8056 +#define GL_RGB5_A1 0x8057 +#define GL_RGB565 0x8D62 +#define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_STENCIL_INDEX 0x1901 +#define GL_STENCIL_INDEX8 0x8D48 + +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 +#define GL_RENDERBUFFER_RED_SIZE 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 + +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 + +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 + +#define GL_NONE 0 + +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 0x8CD9 +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD + +#define GL_FRAMEBUFFER_BINDING 0x8CA6 +#define GL_RENDERBUFFER_BINDING 0x8CA7 +#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 + +#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 + +#endif // __gl2types_h_ + diff --git a/gpu/command_buffer/common/KHR/khrplatform.h b/gpu/command_buffer/common/KHR/khrplatform.h new file mode 100644 index 0000000..8341f71b --- /dev/null +++ b/gpu/command_buffer/common/KHR/khrplatform.h @@ -0,0 +1,269 @@ +#ifndef __khrplatform_h_ +#define __khrplatform_h_ + +/* +** Copyright (c) 2008-2009 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are furnished to do so, subject to +** the following conditions: +** +** The above copyright notice and this permission notice shall be included +** in all copies or substantial portions of the Materials. +** +** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +/* Khronos platform-specific types and definitions. + * + * $Revision: 7820 $ on $Date: 2009-04-03 13:46:26 -0700 (Fri, 03 Apr 2009) $ + * + * Adopters may modify this file to suit their platform. Adopters are + * encouraged to submit platform specific modifications to the Khronos + * group so that they can be included in future versions of this file. + * Please submit changes by sending them to the public Khronos Bugzilla + * (http://khronos.org/bugzilla) by filing a bug against product + * "Khronos (general)" component "Registry". + * + * A predefined template which fills in some of the bug fields can be + * reached using http://tinyurl.com/khrplatform-h-bugreport, but you + * must create a Bugzilla login first. + * + * + * See the Implementer's Guidelines for information about where this file + * should be located on your system and for more details of its use: + * http://www.khronos.org/registry/implementers_guide.pdf + * + * This file should be included as + * #include <KHR/khrplatform.h> + * by Khronos client API header files that use its types and defines. + * + * The types in khrplatform.h should only be used to define API-specific types. + * + * Types defined in khrplatform.h: + * khronos_int8_t signed 8 bit + * khronos_uint8_t unsigned 8 bit + * khronos_int16_t signed 16 bit + * khronos_uint16_t unsigned 16 bit + * khronos_int32_t signed 32 bit + * khronos_uint32_t unsigned 32 bit + * khronos_int64_t signed 64 bit + * khronos_uint64_t unsigned 64 bit + * khronos_intptr_t signed same number of bits as a pointer + * khronos_uintptr_t unsigned same number of bits as a pointer + * khronos_ssize_t signed size + * khronos_usize_t unsigned size + * khronos_float_t signed 32 bit floating point + * khronos_time_ns_t unsigned 64 bit time in nanoseconds + * khronos_utime_nanoseconds_t unsigned time interval or absolute time in + * nanoseconds + * khronos_stime_nanoseconds_t signed time interval in nanoseconds + * khronos_boolean_enum_t enumerated boolean type. This should + * only be used as a base type when a client API's boolean type is + * an enum. Client APIs which use an integer or other type for + * booleans cannot use this as the base type for their boolean. + * + * Tokens defined in khrplatform.h: + * + * KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values. + * + * KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0. + * KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0. + * + * Calling convention macros defined in this file: + * KHRONOS_APICALL + * KHRONOS_APIENTRY + * KHRONOS_APIATTRIBUTES + * + * These may be used in function prototypes as: + * + * KHRONOS_APICALL void KHRONOS_APIENTRY funcname( + * int arg1, + * int arg2) KHRONOS_APIATTRIBUTES; + */ + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APICALL + *------------------------------------------------------------------------- + * This precedes the return type of the function in the function prototype. + */ +#if defined(_WIN32) && !defined(__SCITECH_SNAP__) +# define KHRONOS_APICALL __declspec(dllimport) +#elif defined (__SYMBIAN32__) +# define KHRONOS_APICALL IMPORT_C +#else +# define KHRONOS_APICALL +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIENTRY + *------------------------------------------------------------------------- + * This follows the return type of the function and precedes the function + * name in the function prototype. + */ +#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) + /* Win32 but not WinCE */ +# define KHRONOS_APIENTRY __stdcall +#else +# define KHRONOS_APIENTRY +#endif + +/*------------------------------------------------------------------------- + * Definition of KHRONOS_APIATTRIBUTES + *------------------------------------------------------------------------- + * This follows the closing parenthesis of the function prototype arguments. + */ +#if defined (__ARMCC_2__) +#define KHRONOS_APIATTRIBUTES __softfp +#else +#define KHRONOS_APIATTRIBUTES +#endif + +/*------------------------------------------------------------------------- + * basic type definitions + *-----------------------------------------------------------------------*/ +#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__) + + +/* + * Using <stdint.h> + */ +#include <stdint.h> +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(__VMS ) || defined(__sgi) + +/* + * Using <inttypes.h> + */ +#include <inttypes.h> +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(_WIN32) && !defined(__SCITECH_SNAP__) + +/* + * Win32 + */ +typedef __int32 khronos_int32_t; +typedef unsigned __int32 khronos_uint32_t; +typedef __int64 khronos_int64_t; +typedef unsigned __int64 khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif defined(__sun__) || defined(__digital__) + +/* + * Sun or Digital + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#if defined(__arch64__) || defined(_LP64) +typedef long int khronos_int64_t; +typedef unsigned long int khronos_uint64_t; +#else +typedef long long int khronos_int64_t; +typedef unsigned long long int khronos_uint64_t; +#endif /* __arch64__ */ +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#elif 0 + +/* + * Hypothetical platform with no float or int64 support + */ +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#define KHRONOS_SUPPORT_INT64 0 +#define KHRONOS_SUPPORT_FLOAT 0 + +#else + +/* + * Generic fallback + */ +#include <stdint.h> +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 + +#endif + + +/* + * Types that are (so far) the same on all platforms + */ +typedef signed char khronos_int8_t; +typedef unsigned char khronos_uint8_t; +typedef signed short int khronos_int16_t; +typedef unsigned short int khronos_uint16_t; +typedef signed long int khronos_intptr_t; +typedef unsigned long int khronos_uintptr_t; +typedef signed long int khronos_ssize_t; +typedef unsigned long int khronos_usize_t; + +#if KHRONOS_SUPPORT_FLOAT +/* + * Float type + */ +typedef float khronos_float_t; +#endif + +#if KHRONOS_SUPPORT_INT64 +/* Time types + * + * These types can be used to represent a time interval in nanoseconds or + * an absolute Unadjusted System Time. Unadjusted System Time is the number + * of nanoseconds since some arbitrary system event (e.g. since the last + * time the system booted). The Unadjusted System Time is an unsigned + * 64 bit value that wraps back to 0 every 584 years. Time intervals + * may be either signed or unsigned. + */ +typedef khronos_uint64_t khronos_utime_nanoseconds_t; +typedef khronos_int64_t khronos_stime_nanoseconds_t; +#endif + +/* + * Dummy value used to pad enum types to 32 bits. + */ +#ifndef KHRONOS_MAX_ENUM +#define KHRONOS_MAX_ENUM 0x7FFFFFFF +#endif + +/* + * Enumerated boolean type + * + * Values other than zero should be considered to be true. Therefore + * comparisons should not be made against KHRONOS_TRUE. + */ +typedef enum { + KHRONOS_FALSE = 0, + KHRONOS_TRUE = 1, + KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM +} khronos_boolean_enum_t; + +#endif /* __khrplatform_h_ */ diff --git a/gpu/command_buffer/common/bitfield_helpers.h b/gpu/command_buffer/common/bitfield_helpers.h new file mode 100644 index 0000000..b74374d --- /dev/null +++ b/gpu/command_buffer/common/bitfield_helpers.h @@ -0,0 +1,68 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains a helper template class used to access bit fields in +// unsigned int_ts. + +#ifndef GPU_COMMAND_BUFFER_COMMON_CROSS_BITFIELD_HELPERS_H_ +#define GPU_COMMAND_BUFFER_COMMON_CROSS_BITFIELD_HELPERS_H_ + +namespace command_buffer { + +// Bitfield template class, used to access bit fields in unsigned int_ts. +template<int shift, int length> class BitField { + public: + static const unsigned int kShift = shift; + static const unsigned int kLength = length; + // the following is really (1<<length)-1 but also work for length == 32 + // without compiler warning. + static const unsigned int kMask = 1U + ((1U << (length-1)) - 1U) * 2U; + + // Gets the value contained in this field. + static unsigned int Get(unsigned int container) { + return (container >> kShift) & kMask; + } + + // Makes a value that can be or-ed into this field. + static unsigned int MakeValue(unsigned int value) { + return (value & kMask) << kShift; + } + + // Changes the value of this field. + static void Set(unsigned int *container, unsigned int field_value) { + *container = (*container & ~(kMask << kShift)) | MakeValue(field_value); + } +}; + +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_COMMON_CROSS_BITFIELD_HELPERS_H_ diff --git a/gpu/command_buffer/common/bitfield_helpers_test.cc b/gpu/command_buffer/common/bitfield_helpers_test.cc new file mode 100644 index 0000000..779b540 --- /dev/null +++ b/gpu/command_buffer/common/bitfield_helpers_test.cc @@ -0,0 +1,66 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// Tests for the bitfield helper class. + +#include "testing/gtest/include/gtest/gtest.h" +#include "gpu/command_buffer/common/bitfield_helpers.h" + +namespace command_buffer { + +// Tests that BitField<>::Get returns the right bits. +TEST(BitFieldTest, TestGet) { + unsigned int value = 0x12345678u; + EXPECT_EQ(0x8u, (BitField<0, 4>::Get(value))); + EXPECT_EQ(0x45u, (BitField<12, 8>::Get(value))); + EXPECT_EQ(0x12345678u, (BitField<0, 32>::Get(value))); +} + +// Tests that BitField<>::MakeValue generates the right bits. +TEST(BitFieldTest, TestMakeValue) { + EXPECT_EQ(0x00000003u, (BitField<0, 4>::MakeValue(0x3))); + EXPECT_EQ(0x00023000u, (BitField<12, 8>::MakeValue(0x123))); + EXPECT_EQ(0x87654321u, (BitField<0, 32>::MakeValue(0x87654321))); +} + +// Tests that BitField<>::Set modifies the right bits. +TEST(BitFieldTest, TestSet) { + unsigned int value = 0x12345678u; + BitField<0, 4>::Set(&value, 0x9); + EXPECT_EQ(0x12345679u, value); + BitField<12, 8>::Set(&value, 0x123); + EXPECT_EQ(0x12323679u, value); + BitField<0, 32>::Set(&value, 0x87654321); + EXPECT_EQ(0x87654321u, value); +} + +} // namespace command_buffer diff --git a/gpu/command_buffer/common/cmd_buffer_common.cc b/gpu/command_buffer/common/cmd_buffer_common.cc new file mode 100644 index 0000000..e9172eb --- /dev/null +++ b/gpu/command_buffer/common/cmd_buffer_common.cc @@ -0,0 +1,57 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the binary format definition of the command buffer and +// command buffer commands. + +#include "gpu/command_buffer/common/cmd_buffer_common.h" + +namespace command_buffer { +namespace cmd { + +const char* GetCommandName(CommandId command_id) { + static const char* const names[] = { + #define COMMON_COMMAND_BUFFER_CMD_OP(name) # name, + + COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP) + + #undef COMMON_COMMAND_BUFFER_CMD_OP + }; + + int id = static_cast<int>(command_id); + return (id >= 0 && id < kNumCommands) ? names[id] : "*unknown-command*"; +} + +} // namespace cmd +} // namespace command_buffer + + diff --git a/gpu/command_buffer/common/cmd_buffer_common.h b/gpu/command_buffer/common/cmd_buffer_common.h new file mode 100644 index 0000000..b17b135 --- /dev/null +++ b/gpu/command_buffer/common/cmd_buffer_common.h @@ -0,0 +1,269 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the common parts of command buffer formats. + +#ifndef GPU_COMMAND_BUFFER_COMMON_CROSS_CMD_BUFFER_COMMON_H_ +#define GPU_COMMAND_BUFFER_COMMON_CROSS_CMD_BUFFER_COMMON_H_ + +#include "base/basictypes.h" +#include "gpu/command_buffer/common/types.h" +#include "gpu/command_buffer/common/bitfield_helpers.h" +#include "gpu/command_buffer/common/logging.h" + +namespace command_buffer { + +namespace cmd { + enum ArgFlags { + kFixed = 0x0, + kAtLeastN = 0x1, + }; +} // namespace cmd + +// Computes the number of command buffer entries needed for a certain size. In +// other words it rounds up to a multiple of entries. +inline uint32 ComputeNumEntries(size_t size_in_bytes) { + return static_cast<uint32>( + (size_in_bytes + sizeof(uint32) - 1) / sizeof(uint32)); // NOLINT +} + +// Rounds up to a multiple of entries in bytes. +inline size_t RoundSizeToMultipleOfEntries(size_t size_in_bytes) { + return ComputeNumEntries(size_in_bytes) * sizeof(uint32); // NOLINT +} + +// Struct that defines the command header in the command buffer. +struct CommandHeader { + Uint32 size:8; + Uint32 command:24; + + void Init(uint32 _command, uint32 _size) { + DCHECK_LT(_size, 256u); + command = _command; + size = _size; + } + + // Sets the header based on the passed in command. Can not be used for + // variable sized commands like immediate commands or Noop. + template <typename T> + void SetCmd() { + COMPILE_ASSERT(T::kArgFlags == cmd::kFixed, Cmd_kArgFlags_not_kFixed); + Init(T::kCmdId, ComputeNumEntries(sizeof(T))); // NOLINT + } + + // Sets the header by a size in bytes of the immediate data after the command. + template <typename T> + void SetCmdBySize(uint32 size_of_data_in_bytes) { + COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); + Init(T::kCmdId, + ComputeNumEntries(sizeof(T) + size_of_data_in_bytes)); // NOLINT + } + + // Sets the header by a size in bytes. + template <typename T> + void SetCmdByTotalSize(uint32 size_in_bytes) { + COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); + DCHECK_GE(size_in_bytes, sizeof(T)); // NOLINT + Init(T::kCmdId, ComputeNumEntries(size_in_bytes)); + } +}; + +COMPILE_ASSERT(sizeof(CommandHeader) == 4, Sizeof_CommandHeader_is_not_4); + +// Union that defines possible command buffer entries. +union CommandBufferEntry { + CommandHeader value_header; + Uint32 value_uint32; + Int32 value_int32; + float value_float; +}; + +COMPILE_ASSERT(sizeof(CommandBufferEntry) == 4, + Sizeof_CommandBufferEntry_is_not_4); + + +// Make sure the compiler does not add extra padding to any of the command +// structures. +#pragma pack(push, 1) + +// Gets the address of memory just after a structure in a typesafe way. This is +// used for IMMEDIATE commands to get the address of the place to put the data. +// Immediate command put their data direclty in the command buffer. +// Parameters: +// cmd: Address of command. +template <typename T> +void* ImmediateDataAddress(T* cmd) { + COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); + return reinterpret_cast<char*>(cmd) + sizeof(*cmd); +} + +// Gets the address of the place to put the next command in a typesafe way. +// This can only be used for fixed sized commands. +template <typename T> +// Parameters: +// cmd: Address of command. +void* NextCmdAddress(void* cmd) { + COMPILE_ASSERT(T::kArgFlags == cmd::kFixed, Cmd_kArgFlags_not_kFixed); + return reinterpret_cast<char*>(cmd) + sizeof(T); +} + +// Gets the address of the place to put the next command in a typesafe way. +// This can only be used for variable sized command like IMMEDIATE commands. +// Parameters: +// cmd: Address of command. +// size_of_data_in_bytes: Size of the data for the command. +template <typename T> +void* NextImmediateCmdAddress(void* cmd, uint32 size_of_data_in_bytes) { + COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); + return reinterpret_cast<char*>(cmd) + sizeof(T) + // NOLINT + RoundSizeToMultipleOfEntries(size_of_data_in_bytes); +} + +// Gets the address of the place to put the next command in a typesafe way. +// This can only be used for variable sized command like IMMEDIATE commands. +// Parameters: +// cmd: Address of command. +// size_of_cmd_in_bytes: Size of the cmd and data. +template <typename T> +void* NextImmediateCmdAddressTotalSize(void* cmd, uint32 total_size_in_bytes) { + COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN); + DCHECK_GE(total_size_in_bytes, sizeof(T)); // NOLINT + return reinterpret_cast<char*>(cmd) + + RoundSizeToMultipleOfEntries(total_size_in_bytes); +} + +struct SharedMemory { + void Init(uint32 _id, uint32 _offset) { + id = _id; + offset = _offset; + } + + uint32 id; + uint32 offset; +}; + +COMPILE_ASSERT(offsetof(SharedMemory, id) == 0, + Offsetof_SharedMemory_id_not_0); +COMPILE_ASSERT(offsetof(SharedMemory, offset) == 4, + Offsetof_SharedMemory_offset_not_4); + + +namespace cmd { + +// This macro is used to safely and convienently expand the list of commnad +// buffer commands in to various lists and never have them get out of sync. To +// add a new command, add it this list, create the corresponding structure below +// and then add a function in gapi_decoder.cc called Handle_COMMAND_NAME where +// COMMAND_NAME is the name of your command structure. +// +// NOTE: THE ORDER OF THESE MUST NOT CHANGE (their id is derived by order) +#define COMMON_COMMAND_BUFFER_CMDS(OP) \ + OP(Noop) /* 0 */ \ + OP(SetToken) /* 1 */ \ + +// Common commands. +enum CommandId { + #define COMMON_COMMAND_BUFFER_CMD_OP(name) k ## name, + + COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP) + + #undef COMMON_COMMAND_BUFFER_CMD_OP + + kNumCommands, + kLastCommonId = 1023, // reserve 1024 spaces for common commands. +}; + +COMPILE_ASSERT(kNumCommands - 1 <= kLastCommonId, Too_many_common_commands); + +const char* GetCommandName(CommandId id); + +struct Noop { + typedef Noop ValueType; + static const CommandId kCmdId = kNoop; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + void SetHeader(uint32 skip_count) { + header.Init(kCmdId, skip_count + 1); + } + + void Init(uint32 skip_count) { + SetHeader(skip_count); + } + + static void* Set(void* cmd, uint32 skip_count) { + static_cast<ValueType*>(cmd)->Init(skip_count); + return NextImmediateCmdAddress<ValueType>( + cmd, skip_count * sizeof(CommandBufferEntry)); // NOLINT + } + + CommandHeader header; +}; + +COMPILE_ASSERT(sizeof(Noop) == 4, Sizeof_Noop_is_not_4); +COMPILE_ASSERT(offsetof(Noop, header) == 0, Offsetof_Noop_header_not_0); + +struct SetToken { + typedef SetToken ValueType; + static const CommandId kCmdId = kSetToken; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(uint32 _token) { + SetHeader(); + token = _token; + } + static void* Set(void* cmd, uint32 token) { + static_cast<ValueType*>(cmd)->Init(token); + return NextCmdAddress<ValueType>(cmd); + } + + CommandHeader header; + uint32 token; +}; + +COMPILE_ASSERT(sizeof(SetToken) == 8, Sizeof_SetToken_is_not_8); +COMPILE_ASSERT(offsetof(SetToken, header) == 0, + Offsetof_SetToken_header_not_0); +COMPILE_ASSERT(offsetof(SetToken, token) == 4, + Offsetof_SetToken_token_not_4); + +} // namespace cmd + +#pragma pack(pop) + +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_COMMON_CROSS_CMD_BUFFER_COMMON_H_ + diff --git a/gpu/command_buffer/common/command_buffer.h b/gpu/command_buffer/common/command_buffer.h new file mode 100644 index 0000000..3ce841a --- /dev/null +++ b/gpu/command_buffer/common/command_buffer.h @@ -0,0 +1,97 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_COMMAND_BUFFER_COMMON_COMMAND_BUFFER_H_ +#define GPU_COMMAND_BUFFER_COMMON_COMMAND_BUFFER_H_ + +#include "base/shared_memory.h" +#include "base/task.h" + +namespace command_buffer { + +// Common interface for CommandBuffer implementations. +class CommandBuffer { + public: + CommandBuffer() { + } + + virtual ~CommandBuffer() { + } + + // Initialize the command buffer with the given ring buffer. Takes ownership + // of ring buffer. + virtual bool Initialize(::base::SharedMemory* ring_buffer) = 0; + + // Gets the shared memory ring buffer object for the command buffer. + virtual ::base::SharedMemory* GetRingBuffer() = 0; + + virtual int32 GetSize() = 0; + + // The writer calls this to update its put offset. This function returns the + // reader's most recent get offset. Does not return until after the put offset + // change callback has been invoked. Returns -1 if the put offset is invalid. + virtual int32 SyncOffsets(int32 put_offset) = 0; + + // Returns the current get offset. This can be called from any thread. + virtual int32 GetGetOffset() = 0; + + // Sets the current get offset. This can be called from any thread. + virtual void SetGetOffset(int32 get_offset) = 0; + + // Returns the current put offset. This can be called from any thread. + virtual int32 GetPutOffset() = 0; + + // Sets a callback that should be posted on another thread whenever the put + // offset is changed. The callback must not return until some progress has + // been made (unless the command buffer is empty), i.e. the + // get offset must have changed. It need not process the entire command + // buffer though. This allows concurrency between the writer and the reader + // while giving the writer a means of waiting for the reader to make some + // progress before attempting to write more to the command buffer. Avoiding + // the use of a synchronization primitive like a condition variable to + // synchronize reader and writer reduces the risk of deadlock. + // Takes ownership of callback. The callback is invoked on the plugin thread. + virtual void SetPutOffsetChangeCallback(Callback0::Type* callback) = 0; + + // Create a shared memory transfer buffer and return a handle that uniquely + // identifies it or -1 on error. + virtual int32 CreateTransferBuffer(size_t size) = 0; + + // Destroy a shared memory transfer buffer and recycle the handle. + virtual void DestroyTransferBuffer(int32 id) = 0; + + // Get the shared memory associated with a handle. + virtual ::base::SharedMemory* GetTransferBuffer(int32 handle) = 0; + + // Get the current token value. This is used for by the writer to defer + // changes to shared memory objects until the reader has reached a certain + // point in the command buffer. The reader is responsible for updating the + // token value, for example in response to an asynchronous set token command + // embedded in the command buffer. The default token value is zero. + virtual int32 GetToken() = 0; + + // Allows the reader to update the current token value. + virtual void SetToken(int32 token) = 0; + + // Get the current parse error and reset it to zero. Zero means no error. Non- + // zero means error. The default error status is zero. + virtual int32 ResetParseError() = 0; + + // Allows the reader to set the current parse error. + virtual void SetParseError(int32 parse_error) = 0; + + // Returns whether the command buffer is in the error state. + virtual bool GetErrorStatus() = 0; + + // Allows the reader to set the error status. Once in an error state, the + // command buffer cannot recover and ceases to process commands. + virtual void RaiseErrorStatus() = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(CommandBuffer); +}; + +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_COMMON_COMMAND_BUFFER_H_ diff --git a/gpu/command_buffer/common/command_buffer_mock.h b/gpu/command_buffer/common/command_buffer_mock.h new file mode 100644 index 0000000..faa5536 --- /dev/null +++ b/gpu/command_buffer/common/command_buffer_mock.h @@ -0,0 +1,48 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_COMMAND_BUFFER_COMMON_COMMAND_BUFFER_MOCK_H_ +#define GPU_COMMAND_BUFFER_COMMON_COMMAND_BUFFER_MOCK_H_ + +#include "gpu/command_buffer/common/command_buffer.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace command_buffer { + +// An NPObject that implements a shared memory command buffer and a synchronous +// API to manage the put and get pointers. +class MockCommandBuffer : public CommandBuffer { + public: + MockCommandBuffer() { + ON_CALL(*this, GetRingBuffer()) + .WillByDefault(testing::Return(static_cast<::base::SharedMemory*>(NULL))); + ON_CALL(*this, GetTransferBuffer(testing::_)) + .WillByDefault(testing::Return(static_cast<::base::SharedMemory*>(NULL))); + } + + MOCK_METHOD1(Initialize, bool(::base::SharedMemory* ring_buffer)); + MOCK_METHOD0(GetRingBuffer, ::base::SharedMemory*()); + MOCK_METHOD0(GetSize, int32()); + MOCK_METHOD1(SyncOffsets, int32(int32 put_offset)); + MOCK_METHOD0(GetGetOffset, int32()); + MOCK_METHOD1(SetGetOffset, void(int32 get_offset)); + MOCK_METHOD0(GetPutOffset, int32()); + MOCK_METHOD1(SetPutOffsetChangeCallback, void(Callback0::Type* callback)); + MOCK_METHOD1(CreateTransferBuffer, int32(size_t size)); + MOCK_METHOD1(DestroyTransferBuffer, void(int32 handle)); + MOCK_METHOD1(GetTransferBuffer, ::base::SharedMemory*(int32 handle)); + MOCK_METHOD0(GetToken, int32()); + MOCK_METHOD1(SetToken, void(int32 token)); + MOCK_METHOD0(ResetParseError, int32()); + MOCK_METHOD1(SetParseError, void(int32 parse_erro)); + MOCK_METHOD0(GetErrorStatus, bool()); + MOCK_METHOD0(RaiseErrorStatus, void()); + + private: + DISALLOW_COPY_AND_ASSIGN(MockCommandBuffer); +}; + +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_COMMON_COMMAND_BUFFER_MOCK_H_ diff --git a/gpu/command_buffer/common/constants.h b/gpu/command_buffer/common/constants.h new file mode 100644 index 0000000..ee874cd --- /dev/null +++ b/gpu/command_buffer/common/constants.h @@ -0,0 +1,71 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef O3D_COMMAND_BUFFER_COMMON_CROSS_CONSTANTS_H_ +#define O3D_COMMAND_BUFFER_COMMON_CROSS_CONSTANTS_H_ + +#include "base/basictypes.h" + +namespace command_buffer { + +typedef int32 CommandBufferOffset; +const CommandBufferOffset kInvalidCommandBufferOffset = -1; + +// Status of the command buffer service. It does not process commands +// (meaning: get will not change) unless in kParsing state. +namespace parser_status { + enum ParserStatus { + kNotConnected, // The service is not connected - initial state. + kNoBuffer, // The service is connected but no buffer was set. + kParsing, // The service is connected, and parsing commands from the + // buffer. + kParseError, // Parsing stopped because a parse error was found. + }; +} + +namespace parse_error { + enum ParseError { + kParseNoError, + kParseInvalidSize, + kParseOutOfBounds, + kParseUnknownCommand, + kParseInvalidArguments, + }; +} + +// Invalid shared memory Id, returned by RegisterSharedMemory in case of +// failure. +const int32 kInvalidSharedMemoryId = -1; + +} // namespace command_buffer + +#endif // O3D_COMMAND_BUFFER_COMMON_CROSS_CONSTANTS_H_ diff --git a/gpu/command_buffer/common/gles2_cmd_format.cc b/gpu/command_buffer/common/gles2_cmd_format.cc new file mode 100644 index 0000000..62e297d --- /dev/null +++ b/gpu/command_buffer/common/gles2_cmd_format.cc @@ -0,0 +1,33 @@ +// Copyright (c) 2006-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 contains the binary format definition of the command buffer and +// command buffer commands. + +// We explicitly do NOT include gles2_cmd_format.h here because client side +// and service side have different requirements. +#include "gpu/command_buffer/common/cmd_buffer_common.h" + +namespace command_buffer { +namespace gles2 { + +#include "gpu/command_buffer/common/gles2_cmd_ids_autogen.h" + +const char* GetCommandName(CommandId id) { + static const char* const names[] = { + #define GLES2_CMD_OP(name) "k" # name, + + GLES2_COMMAND_LIST(GLES2_CMD_OP) + + #undef GLES2_CMD_OP + }; + + return (static_cast<int>(id) >= 0 && static_cast<int>(id) < kNumCommands) ? + names[id] : "*unknown-command*"; +} + +} // namespace gles2 +} // namespace command_buffer + + diff --git a/gpu/command_buffer/common/gles2_cmd_format.h b/gpu/command_buffer/common/gles2_cmd_format.h new file mode 100644 index 0000000..729149d --- /dev/null +++ b/gpu/command_buffer/common/gles2_cmd_format.h @@ -0,0 +1,36 @@ +// Copyright (c) 2006-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 defines the GLES2 command buffer commands. + +#ifndef GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_H +#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 +#include <GL/glew.h> +#if defined(OS_WIN) +#include <GL/wglew.h> +#endif +#else +#include <GLES2/gl2types.h> +#endif + +#include "base/basictypes.h" +#include "gpu/command_buffer/common/types.h" +#include "gpu/command_buffer/common/bitfield_helpers.h" +#include "gpu/command_buffer/common/cmd_buffer_common.h" +#include "gpu/command_buffer/common/gles2_cmd_ids.h" + +namespace command_buffer { +namespace gles2 { + +#include "gpu/command_buffer/common/gles2_cmd_format_autogen.h" + +} // namespace gles2 +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_H + diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h new file mode 100644 index 0000000..e15713a --- /dev/null +++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h @@ -0,0 +1,8278 @@ +// This file is auto-generated. DO NOT EDIT! + +#pragma pack(push, 1) + +struct ActiveTexture { + typedef ActiveTexture ValueType; + static const CommandId kCmdId = kActiveTexture; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _texture) { + SetHeader(); + texture = _texture; + } + + void* Set(void* cmd, GLenum _texture) { + static_cast<ValueType*>(cmd)->Init(_texture); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 texture; +}; + +COMPILE_ASSERT(sizeof(ActiveTexture) == 8, + Sizeof_ActiveTexture_is_not_8); +COMPILE_ASSERT(offsetof(ActiveTexture, header) == 0, + OffsetOf_ActiveTexture_header_not_0); +COMPILE_ASSERT(offsetof(ActiveTexture, texture) == 4, + OffsetOf_ActiveTexture_texture_not_4); + +struct AttachShader { + typedef AttachShader ValueType; + static const CommandId kCmdId = kAttachShader; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLuint _program, GLuint _shader) { + SetHeader(); + program = _program; + shader = _shader; + } + + void* Set(void* cmd, GLuint _program, GLuint _shader) { + static_cast<ValueType*>(cmd)->Init(_program, _shader); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 program; + uint32 shader; +}; + +COMPILE_ASSERT(sizeof(AttachShader) == 12, + Sizeof_AttachShader_is_not_12); +COMPILE_ASSERT(offsetof(AttachShader, header) == 0, + OffsetOf_AttachShader_header_not_0); +COMPILE_ASSERT(offsetof(AttachShader, program) == 4, + OffsetOf_AttachShader_program_not_4); +COMPILE_ASSERT(offsetof(AttachShader, shader) == 8, + OffsetOf_AttachShader_shader_not_8); + +struct BindAttribLocation { + typedef BindAttribLocation ValueType; + static const CommandId kCmdId = kBindAttribLocation; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLuint _program, GLuint _index, uint32 _name_shm_id, + uint32 _name_shm_offset, uint32 _data_size) { + SetHeader(); + program = _program; + index = _index; + name_shm_id = _name_shm_id; + name_shm_offset = _name_shm_offset; + data_size = _data_size; + } + + void* Set( + void* cmd, GLuint _program, GLuint _index, uint32 _name_shm_id, + uint32 _name_shm_offset, uint32 _data_size) { + static_cast<ValueType*>( + cmd)->Init( + _program, _index, _name_shm_id, _name_shm_offset, _data_size); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 program; + uint32 index; + uint32 name_shm_id; + uint32 name_shm_offset; + uint32 data_size; +}; + +COMPILE_ASSERT(sizeof(BindAttribLocation) == 24, + Sizeof_BindAttribLocation_is_not_24); +COMPILE_ASSERT(offsetof(BindAttribLocation, header) == 0, + OffsetOf_BindAttribLocation_header_not_0); +COMPILE_ASSERT(offsetof(BindAttribLocation, program) == 4, + OffsetOf_BindAttribLocation_program_not_4); +COMPILE_ASSERT(offsetof(BindAttribLocation, index) == 8, + OffsetOf_BindAttribLocation_index_not_8); +COMPILE_ASSERT(offsetof(BindAttribLocation, name_shm_id) == 12, + OffsetOf_BindAttribLocation_name_shm_id_not_12); +COMPILE_ASSERT(offsetof(BindAttribLocation, name_shm_offset) == 16, + OffsetOf_BindAttribLocation_name_shm_offset_not_16); +COMPILE_ASSERT(offsetof(BindAttribLocation, data_size) == 20, + OffsetOf_BindAttribLocation_data_size_not_20); + +struct BindAttribLocationImmediate { + typedef BindAttribLocationImmediate ValueType; + static const CommandId kCmdId = kBindAttribLocationImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeDataSize(const char* s) { + return strlen(s); + } + + static uint32 ComputeSize(const char* s) { + return static_cast<uint32>( + sizeof(ValueType) + ComputeDataSize(s)); // NOLINT + } + + void SetHeader(const char* s) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(s)); + } + + void Init(GLuint _program, GLuint _index, const char* _name) { + SetHeader(_name); + program = _program; + index = _index; + data_size = strlen(_name); + memcpy(ImmediateDataAddress(this), _name, data_size); + } + + void* Set(void* cmd, GLuint _program, GLuint _index, const char* _name) { + static_cast<ValueType*>(cmd)->Init(_program, _index, _name); + const uint32 size = ComputeSize(_name); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + command_buffer::CommandHeader header; + uint32 program; + uint32 index; + uint32 data_size; +}; + +COMPILE_ASSERT(sizeof(BindAttribLocationImmediate) == 16, + Sizeof_BindAttribLocationImmediate_is_not_16); +COMPILE_ASSERT(offsetof(BindAttribLocationImmediate, header) == 0, + OffsetOf_BindAttribLocationImmediate_header_not_0); +COMPILE_ASSERT(offsetof(BindAttribLocationImmediate, program) == 4, + OffsetOf_BindAttribLocationImmediate_program_not_4); +COMPILE_ASSERT(offsetof(BindAttribLocationImmediate, index) == 8, + OffsetOf_BindAttribLocationImmediate_index_not_8); +COMPILE_ASSERT(offsetof(BindAttribLocationImmediate, data_size) == 12, + OffsetOf_BindAttribLocationImmediate_data_size_not_12); + +struct BindBuffer { + typedef BindBuffer ValueType; + static const CommandId kCmdId = kBindBuffer; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _target, GLuint _buffer) { + SetHeader(); + target = _target; + buffer = _buffer; + } + + void* Set(void* cmd, GLenum _target, GLuint _buffer) { + static_cast<ValueType*>(cmd)->Init(_target, _buffer); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 buffer; +}; + +COMPILE_ASSERT(sizeof(BindBuffer) == 12, + Sizeof_BindBuffer_is_not_12); +COMPILE_ASSERT(offsetof(BindBuffer, header) == 0, + OffsetOf_BindBuffer_header_not_0); +COMPILE_ASSERT(offsetof(BindBuffer, target) == 4, + OffsetOf_BindBuffer_target_not_4); +COMPILE_ASSERT(offsetof(BindBuffer, buffer) == 8, + OffsetOf_BindBuffer_buffer_not_8); + +struct BindFramebuffer { + typedef BindFramebuffer ValueType; + static const CommandId kCmdId = kBindFramebuffer; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _target, GLuint _framebuffer) { + SetHeader(); + target = _target; + framebuffer = _framebuffer; + } + + void* Set(void* cmd, GLenum _target, GLuint _framebuffer) { + static_cast<ValueType*>(cmd)->Init(_target, _framebuffer); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 framebuffer; +}; + +COMPILE_ASSERT(sizeof(BindFramebuffer) == 12, + Sizeof_BindFramebuffer_is_not_12); +COMPILE_ASSERT(offsetof(BindFramebuffer, header) == 0, + OffsetOf_BindFramebuffer_header_not_0); +COMPILE_ASSERT(offsetof(BindFramebuffer, target) == 4, + OffsetOf_BindFramebuffer_target_not_4); +COMPILE_ASSERT(offsetof(BindFramebuffer, framebuffer) == 8, + OffsetOf_BindFramebuffer_framebuffer_not_8); + +struct BindRenderbuffer { + typedef BindRenderbuffer ValueType; + static const CommandId kCmdId = kBindRenderbuffer; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _target, GLuint _renderbuffer) { + SetHeader(); + target = _target; + renderbuffer = _renderbuffer; + } + + void* Set(void* cmd, GLenum _target, GLuint _renderbuffer) { + static_cast<ValueType*>(cmd)->Init(_target, _renderbuffer); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 renderbuffer; +}; + +COMPILE_ASSERT(sizeof(BindRenderbuffer) == 12, + Sizeof_BindRenderbuffer_is_not_12); +COMPILE_ASSERT(offsetof(BindRenderbuffer, header) == 0, + OffsetOf_BindRenderbuffer_header_not_0); +COMPILE_ASSERT(offsetof(BindRenderbuffer, target) == 4, + OffsetOf_BindRenderbuffer_target_not_4); +COMPILE_ASSERT(offsetof(BindRenderbuffer, renderbuffer) == 8, + OffsetOf_BindRenderbuffer_renderbuffer_not_8); + +struct BindTexture { + typedef BindTexture ValueType; + static const CommandId kCmdId = kBindTexture; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _target, GLuint _texture) { + SetHeader(); + target = _target; + texture = _texture; + } + + void* Set(void* cmd, GLenum _target, GLuint _texture) { + static_cast<ValueType*>(cmd)->Init(_target, _texture); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 texture; +}; + +COMPILE_ASSERT(sizeof(BindTexture) == 12, + Sizeof_BindTexture_is_not_12); +COMPILE_ASSERT(offsetof(BindTexture, header) == 0, + OffsetOf_BindTexture_header_not_0); +COMPILE_ASSERT(offsetof(BindTexture, target) == 4, + OffsetOf_BindTexture_target_not_4); +COMPILE_ASSERT(offsetof(BindTexture, texture) == 8, + OffsetOf_BindTexture_texture_not_8); + +struct BlendColor { + typedef BlendColor ValueType; + static const CommandId kCmdId = kBlendColor; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLclampf _red, GLclampf _green, GLclampf _blue, GLclampf _alpha) { + SetHeader(); + red = _red; + green = _green; + blue = _blue; + alpha = _alpha; + } + + void* Set( + void* cmd, GLclampf _red, GLclampf _green, GLclampf _blue, + GLclampf _alpha) { + static_cast<ValueType*>(cmd)->Init(_red, _green, _blue, _alpha); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + float red; + float green; + float blue; + float alpha; +}; + +COMPILE_ASSERT(sizeof(BlendColor) == 20, + Sizeof_BlendColor_is_not_20); +COMPILE_ASSERT(offsetof(BlendColor, header) == 0, + OffsetOf_BlendColor_header_not_0); +COMPILE_ASSERT(offsetof(BlendColor, red) == 4, + OffsetOf_BlendColor_red_not_4); +COMPILE_ASSERT(offsetof(BlendColor, green) == 8, + OffsetOf_BlendColor_green_not_8); +COMPILE_ASSERT(offsetof(BlendColor, blue) == 12, + OffsetOf_BlendColor_blue_not_12); +COMPILE_ASSERT(offsetof(BlendColor, alpha) == 16, + OffsetOf_BlendColor_alpha_not_16); + +struct BlendEquation { + typedef BlendEquation ValueType; + static const CommandId kCmdId = kBlendEquation; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _mode) { + SetHeader(); + mode = _mode; + } + + void* Set(void* cmd, GLenum _mode) { + static_cast<ValueType*>(cmd)->Init(_mode); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 mode; +}; + +COMPILE_ASSERT(sizeof(BlendEquation) == 8, + Sizeof_BlendEquation_is_not_8); +COMPILE_ASSERT(offsetof(BlendEquation, header) == 0, + OffsetOf_BlendEquation_header_not_0); +COMPILE_ASSERT(offsetof(BlendEquation, mode) == 4, + OffsetOf_BlendEquation_mode_not_4); + +struct BlendEquationSeparate { + typedef BlendEquationSeparate ValueType; + static const CommandId kCmdId = kBlendEquationSeparate; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _modeRGB, GLenum _modeAlpha) { + SetHeader(); + modeRGB = _modeRGB; + modeAlpha = _modeAlpha; + } + + void* Set(void* cmd, GLenum _modeRGB, GLenum _modeAlpha) { + static_cast<ValueType*>(cmd)->Init(_modeRGB, _modeAlpha); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 modeRGB; + uint32 modeAlpha; +}; + +COMPILE_ASSERT(sizeof(BlendEquationSeparate) == 12, + Sizeof_BlendEquationSeparate_is_not_12); +COMPILE_ASSERT(offsetof(BlendEquationSeparate, header) == 0, + OffsetOf_BlendEquationSeparate_header_not_0); +COMPILE_ASSERT(offsetof(BlendEquationSeparate, modeRGB) == 4, + OffsetOf_BlendEquationSeparate_modeRGB_not_4); +COMPILE_ASSERT(offsetof(BlendEquationSeparate, modeAlpha) == 8, + OffsetOf_BlendEquationSeparate_modeAlpha_not_8); + +struct BlendFunc { + typedef BlendFunc ValueType; + static const CommandId kCmdId = kBlendFunc; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _sfactor, GLenum _dfactor) { + SetHeader(); + sfactor = _sfactor; + dfactor = _dfactor; + } + + void* Set(void* cmd, GLenum _sfactor, GLenum _dfactor) { + static_cast<ValueType*>(cmd)->Init(_sfactor, _dfactor); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 sfactor; + uint32 dfactor; +}; + +COMPILE_ASSERT(sizeof(BlendFunc) == 12, + Sizeof_BlendFunc_is_not_12); +COMPILE_ASSERT(offsetof(BlendFunc, header) == 0, + OffsetOf_BlendFunc_header_not_0); +COMPILE_ASSERT(offsetof(BlendFunc, sfactor) == 4, + OffsetOf_BlendFunc_sfactor_not_4); +COMPILE_ASSERT(offsetof(BlendFunc, dfactor) == 8, + OffsetOf_BlendFunc_dfactor_not_8); + +struct BlendFuncSeparate { + typedef BlendFuncSeparate ValueType; + static const CommandId kCmdId = kBlendFuncSeparate; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLenum _srcRGB, GLenum _dstRGB, GLenum _srcAlpha, GLenum _dstAlpha) { + SetHeader(); + srcRGB = _srcRGB; + dstRGB = _dstRGB; + srcAlpha = _srcAlpha; + dstAlpha = _dstAlpha; + } + + void* Set( + void* cmd, GLenum _srcRGB, GLenum _dstRGB, GLenum _srcAlpha, + GLenum _dstAlpha) { + static_cast<ValueType*>(cmd)->Init(_srcRGB, _dstRGB, _srcAlpha, _dstAlpha); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 srcRGB; + uint32 dstRGB; + uint32 srcAlpha; + uint32 dstAlpha; +}; + +COMPILE_ASSERT(sizeof(BlendFuncSeparate) == 20, + Sizeof_BlendFuncSeparate_is_not_20); +COMPILE_ASSERT(offsetof(BlendFuncSeparate, header) == 0, + OffsetOf_BlendFuncSeparate_header_not_0); +COMPILE_ASSERT(offsetof(BlendFuncSeparate, srcRGB) == 4, + OffsetOf_BlendFuncSeparate_srcRGB_not_4); +COMPILE_ASSERT(offsetof(BlendFuncSeparate, dstRGB) == 8, + OffsetOf_BlendFuncSeparate_dstRGB_not_8); +COMPILE_ASSERT(offsetof(BlendFuncSeparate, srcAlpha) == 12, + OffsetOf_BlendFuncSeparate_srcAlpha_not_12); +COMPILE_ASSERT(offsetof(BlendFuncSeparate, dstAlpha) == 16, + OffsetOf_BlendFuncSeparate_dstAlpha_not_16); + +struct BufferData { + typedef BufferData ValueType; + static const CommandId kCmdId = kBufferData; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLenum _target, GLsizeiptr _size, uint32 _data_shm_id, + uint32 _data_shm_offset, GLenum _usage) { + SetHeader(); + target = _target; + size = _size; + data_shm_id = _data_shm_id; + data_shm_offset = _data_shm_offset; + usage = _usage; + } + + void* Set( + void* cmd, GLenum _target, GLsizeiptr _size, uint32 _data_shm_id, + uint32 _data_shm_offset, GLenum _usage) { + static_cast<ValueType*>( + cmd)->Init(_target, _size, _data_shm_id, _data_shm_offset, _usage); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 size; + uint32 data_shm_id; + uint32 data_shm_offset; + uint32 usage; +}; + +COMPILE_ASSERT(sizeof(BufferData) == 24, + Sizeof_BufferData_is_not_24); +COMPILE_ASSERT(offsetof(BufferData, header) == 0, + OffsetOf_BufferData_header_not_0); +COMPILE_ASSERT(offsetof(BufferData, target) == 4, + OffsetOf_BufferData_target_not_4); +COMPILE_ASSERT(offsetof(BufferData, size) == 8, + OffsetOf_BufferData_size_not_8); +COMPILE_ASSERT(offsetof(BufferData, data_shm_id) == 12, + OffsetOf_BufferData_data_shm_id_not_12); +COMPILE_ASSERT(offsetof(BufferData, data_shm_offset) == 16, + OffsetOf_BufferData_data_shm_offset_not_16); +COMPILE_ASSERT(offsetof(BufferData, usage) == 20, + OffsetOf_BufferData_usage_not_20); + +struct BufferDataImmediate { + typedef BufferDataImmediate ValueType; + static const CommandId kCmdId = kBufferDataImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeSize(uint32 size_in_bytes) { + return static_cast<uint32>( + sizeof(ValueType) + // NOLINT + RoundSizeToMultipleOfEntries(size_in_bytes)); + } + + void SetHeader(uint32 size_in_bytes) { + header.SetCmdByTotalSize<ValueType>(size_in_bytes); + } + + void Init(GLenum _target, GLsizeiptr _size, GLenum _usage) { + uint32 total_size = ComputeSize(_size); + SetHeader(total_size); + target = _target; + size = _size; + usage = _usage; + } + + void* Set(void* cmd, GLenum _target, GLsizeiptr _size, GLenum _usage) { + uint32 total_size = ComputeSize(_size); + static_cast<ValueType*>(cmd)->Init(_target, _size, _usage); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, total_size); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 size; + uint32 usage; +}; + +COMPILE_ASSERT(sizeof(BufferDataImmediate) == 16, + Sizeof_BufferDataImmediate_is_not_16); +COMPILE_ASSERT(offsetof(BufferDataImmediate, header) == 0, + OffsetOf_BufferDataImmediate_header_not_0); +COMPILE_ASSERT(offsetof(BufferDataImmediate, target) == 4, + OffsetOf_BufferDataImmediate_target_not_4); +COMPILE_ASSERT(offsetof(BufferDataImmediate, size) == 8, + OffsetOf_BufferDataImmediate_size_not_8); +COMPILE_ASSERT(offsetof(BufferDataImmediate, usage) == 12, + OffsetOf_BufferDataImmediate_usage_not_12); + +struct BufferSubData { + typedef BufferSubData ValueType; + static const CommandId kCmdId = kBufferSubData; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLenum _target, GLintptr _offset, GLsizeiptr _size, uint32 _data_shm_id, + uint32 _data_shm_offset) { + SetHeader(); + target = _target; + offset = _offset; + size = _size; + data_shm_id = _data_shm_id; + data_shm_offset = _data_shm_offset; + } + + void* Set( + void* cmd, GLenum _target, GLintptr _offset, GLsizeiptr _size, + uint32 _data_shm_id, uint32 _data_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_target, _offset, _size, _data_shm_id, _data_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 offset; + uint32 size; + uint32 data_shm_id; + uint32 data_shm_offset; +}; + +COMPILE_ASSERT(sizeof(BufferSubData) == 24, + Sizeof_BufferSubData_is_not_24); +COMPILE_ASSERT(offsetof(BufferSubData, header) == 0, + OffsetOf_BufferSubData_header_not_0); +COMPILE_ASSERT(offsetof(BufferSubData, target) == 4, + OffsetOf_BufferSubData_target_not_4); +COMPILE_ASSERT(offsetof(BufferSubData, offset) == 8, + OffsetOf_BufferSubData_offset_not_8); +COMPILE_ASSERT(offsetof(BufferSubData, size) == 12, + OffsetOf_BufferSubData_size_not_12); +COMPILE_ASSERT(offsetof(BufferSubData, data_shm_id) == 16, + OffsetOf_BufferSubData_data_shm_id_not_16); +COMPILE_ASSERT(offsetof(BufferSubData, data_shm_offset) == 20, + OffsetOf_BufferSubData_data_shm_offset_not_20); + +struct BufferSubDataImmediate { + typedef BufferSubDataImmediate ValueType; + static const CommandId kCmdId = kBufferSubDataImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeSize(uint32 size_in_bytes) { + return static_cast<uint32>( + sizeof(ValueType) + // NOLINT + RoundSizeToMultipleOfEntries(size_in_bytes)); + } + + void SetHeader(uint32 size_in_bytes) { + header.SetCmdByTotalSize<ValueType>(size_in_bytes); + } + + void Init(GLenum _target, GLintptr _offset, GLsizeiptr _size) { + uint32 total_size = ComputeSize(_size); + SetHeader(total_size); + target = _target; + offset = _offset; + size = _size; + } + + void* Set(void* cmd, GLenum _target, GLintptr _offset, GLsizeiptr _size) { + uint32 total_size = ComputeSize(_size); + static_cast<ValueType*>(cmd)->Init(_target, _offset, _size); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, total_size); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 offset; + uint32 size; +}; + +COMPILE_ASSERT(sizeof(BufferSubDataImmediate) == 16, + Sizeof_BufferSubDataImmediate_is_not_16); +COMPILE_ASSERT(offsetof(BufferSubDataImmediate, header) == 0, + OffsetOf_BufferSubDataImmediate_header_not_0); +COMPILE_ASSERT(offsetof(BufferSubDataImmediate, target) == 4, + OffsetOf_BufferSubDataImmediate_target_not_4); +COMPILE_ASSERT(offsetof(BufferSubDataImmediate, offset) == 8, + OffsetOf_BufferSubDataImmediate_offset_not_8); +COMPILE_ASSERT(offsetof(BufferSubDataImmediate, size) == 12, + OffsetOf_BufferSubDataImmediate_size_not_12); + +struct CheckFramebufferStatus { + typedef CheckFramebufferStatus ValueType; + static const CommandId kCmdId = kCheckFramebufferStatus; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _target) { + SetHeader(); + target = _target; + } + + void* Set(void* cmd, GLenum _target) { + static_cast<ValueType*>(cmd)->Init(_target); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 target; +}; + +COMPILE_ASSERT(sizeof(CheckFramebufferStatus) == 8, + Sizeof_CheckFramebufferStatus_is_not_8); +COMPILE_ASSERT(offsetof(CheckFramebufferStatus, header) == 0, + OffsetOf_CheckFramebufferStatus_header_not_0); +COMPILE_ASSERT(offsetof(CheckFramebufferStatus, target) == 4, + OffsetOf_CheckFramebufferStatus_target_not_4); + +struct Clear { + typedef Clear ValueType; + static const CommandId kCmdId = kClear; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLbitfield _mask) { + SetHeader(); + mask = _mask; + } + + void* Set(void* cmd, GLbitfield _mask) { + static_cast<ValueType*>(cmd)->Init(_mask); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 mask; +}; + +COMPILE_ASSERT(sizeof(Clear) == 8, + Sizeof_Clear_is_not_8); +COMPILE_ASSERT(offsetof(Clear, header) == 0, + OffsetOf_Clear_header_not_0); +COMPILE_ASSERT(offsetof(Clear, mask) == 4, + OffsetOf_Clear_mask_not_4); + +struct ClearColor { + typedef ClearColor ValueType; + static const CommandId kCmdId = kClearColor; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLclampf _red, GLclampf _green, GLclampf _blue, GLclampf _alpha) { + SetHeader(); + red = _red; + green = _green; + blue = _blue; + alpha = _alpha; + } + + void* Set( + void* cmd, GLclampf _red, GLclampf _green, GLclampf _blue, + GLclampf _alpha) { + static_cast<ValueType*>(cmd)->Init(_red, _green, _blue, _alpha); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + float red; + float green; + float blue; + float alpha; +}; + +COMPILE_ASSERT(sizeof(ClearColor) == 20, + Sizeof_ClearColor_is_not_20); +COMPILE_ASSERT(offsetof(ClearColor, header) == 0, + OffsetOf_ClearColor_header_not_0); +COMPILE_ASSERT(offsetof(ClearColor, red) == 4, + OffsetOf_ClearColor_red_not_4); +COMPILE_ASSERT(offsetof(ClearColor, green) == 8, + OffsetOf_ClearColor_green_not_8); +COMPILE_ASSERT(offsetof(ClearColor, blue) == 12, + OffsetOf_ClearColor_blue_not_12); +COMPILE_ASSERT(offsetof(ClearColor, alpha) == 16, + OffsetOf_ClearColor_alpha_not_16); + +struct ClearDepthf { + typedef ClearDepthf ValueType; + static const CommandId kCmdId = kClearDepthf; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLclampf _depth) { + SetHeader(); + depth = _depth; + } + + void* Set(void* cmd, GLclampf _depth) { + static_cast<ValueType*>(cmd)->Init(_depth); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + float depth; +}; + +COMPILE_ASSERT(sizeof(ClearDepthf) == 8, + Sizeof_ClearDepthf_is_not_8); +COMPILE_ASSERT(offsetof(ClearDepthf, header) == 0, + OffsetOf_ClearDepthf_header_not_0); +COMPILE_ASSERT(offsetof(ClearDepthf, depth) == 4, + OffsetOf_ClearDepthf_depth_not_4); + +struct ClearStencil { + typedef ClearStencil ValueType; + static const CommandId kCmdId = kClearStencil; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLint _s) { + SetHeader(); + s = _s; + } + + void* Set(void* cmd, GLint _s) { + static_cast<ValueType*>(cmd)->Init(_s); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 s; +}; + +COMPILE_ASSERT(sizeof(ClearStencil) == 8, + Sizeof_ClearStencil_is_not_8); +COMPILE_ASSERT(offsetof(ClearStencil, header) == 0, + OffsetOf_ClearStencil_header_not_0); +COMPILE_ASSERT(offsetof(ClearStencil, s) == 4, + OffsetOf_ClearStencil_s_not_4); + +struct ColorMask { + typedef ColorMask ValueType; + static const CommandId kCmdId = kColorMask; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLboolean _red, GLboolean _green, GLboolean _blue, GLboolean _alpha) { + SetHeader(); + red = _red; + green = _green; + blue = _blue; + alpha = _alpha; + } + + void* Set( + void* cmd, GLboolean _red, GLboolean _green, GLboolean _blue, + GLboolean _alpha) { + static_cast<ValueType*>(cmd)->Init(_red, _green, _blue, _alpha); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 red; + uint32 green; + uint32 blue; + uint32 alpha; +}; + +COMPILE_ASSERT(sizeof(ColorMask) == 20, + Sizeof_ColorMask_is_not_20); +COMPILE_ASSERT(offsetof(ColorMask, header) == 0, + OffsetOf_ColorMask_header_not_0); +COMPILE_ASSERT(offsetof(ColorMask, red) == 4, + OffsetOf_ColorMask_red_not_4); +COMPILE_ASSERT(offsetof(ColorMask, green) == 8, + OffsetOf_ColorMask_green_not_8); +COMPILE_ASSERT(offsetof(ColorMask, blue) == 12, + OffsetOf_ColorMask_blue_not_12); +COMPILE_ASSERT(offsetof(ColorMask, alpha) == 16, + OffsetOf_ColorMask_alpha_not_16); + +struct CompileShader { + typedef CompileShader ValueType; + static const CommandId kCmdId = kCompileShader; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLuint _shader) { + SetHeader(); + shader = _shader; + } + + void* Set(void* cmd, GLuint _shader) { + static_cast<ValueType*>(cmd)->Init(_shader); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 shader; +}; + +COMPILE_ASSERT(sizeof(CompileShader) == 8, + Sizeof_CompileShader_is_not_8); +COMPILE_ASSERT(offsetof(CompileShader, header) == 0, + OffsetOf_CompileShader_header_not_0); +COMPILE_ASSERT(offsetof(CompileShader, shader) == 4, + OffsetOf_CompileShader_shader_not_4); + +struct CompressedTexImage2D { + typedef CompressedTexImage2D ValueType; + static const CommandId kCmdId = kCompressedTexImage2D; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLenum _target, GLint _level, GLenum _internalformat, GLsizei _width, + GLsizei _height, GLint _border, GLsizei _imageSize, uint32 _data_shm_id, + uint32 _data_shm_offset) { + SetHeader(); + target = _target; + level = _level; + internalformat = _internalformat; + width = _width; + height = _height; + border = _border; + imageSize = _imageSize; + data_shm_id = _data_shm_id; + data_shm_offset = _data_shm_offset; + } + + void* Set( + void* cmd, GLenum _target, GLint _level, GLenum _internalformat, + GLsizei _width, GLsizei _height, GLint _border, GLsizei _imageSize, + uint32 _data_shm_id, uint32 _data_shm_offset) { + static_cast<ValueType*>( + cmd)->Init( + _target, _level, _internalformat, _width, _height, _border, + _imageSize, _data_shm_id, _data_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 level; + uint32 internalformat; + uint32 width; + uint32 height; + uint32 border; + uint32 imageSize; + uint32 data_shm_id; + uint32 data_shm_offset; +}; + +COMPILE_ASSERT(sizeof(CompressedTexImage2D) == 40, + Sizeof_CompressedTexImage2D_is_not_40); +COMPILE_ASSERT(offsetof(CompressedTexImage2D, header) == 0, + OffsetOf_CompressedTexImage2D_header_not_0); +COMPILE_ASSERT(offsetof(CompressedTexImage2D, target) == 4, + OffsetOf_CompressedTexImage2D_target_not_4); +COMPILE_ASSERT(offsetof(CompressedTexImage2D, level) == 8, + OffsetOf_CompressedTexImage2D_level_not_8); +COMPILE_ASSERT(offsetof(CompressedTexImage2D, internalformat) == 12, + OffsetOf_CompressedTexImage2D_internalformat_not_12); +COMPILE_ASSERT(offsetof(CompressedTexImage2D, width) == 16, + OffsetOf_CompressedTexImage2D_width_not_16); +COMPILE_ASSERT(offsetof(CompressedTexImage2D, height) == 20, + OffsetOf_CompressedTexImage2D_height_not_20); +COMPILE_ASSERT(offsetof(CompressedTexImage2D, border) == 24, + OffsetOf_CompressedTexImage2D_border_not_24); +COMPILE_ASSERT(offsetof(CompressedTexImage2D, imageSize) == 28, + OffsetOf_CompressedTexImage2D_imageSize_not_28); +COMPILE_ASSERT(offsetof(CompressedTexImage2D, data_shm_id) == 32, + OffsetOf_CompressedTexImage2D_data_shm_id_not_32); +COMPILE_ASSERT(offsetof(CompressedTexImage2D, data_shm_offset) == 36, + OffsetOf_CompressedTexImage2D_data_shm_offset_not_36); + +struct CompressedTexImage2DImmediate { + typedef CompressedTexImage2DImmediate ValueType; + static const CommandId kCmdId = kCompressedTexImage2DImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeSize(uint32 size_in_bytes) { + return static_cast<uint32>( + sizeof(ValueType) + // NOLINT + RoundSizeToMultipleOfEntries(size_in_bytes)); + } + + void SetHeader(uint32 size_in_bytes) { + header.SetCmdByTotalSize<ValueType>(size_in_bytes); + } + + void Init( + GLenum _target, GLint _level, GLenum _internalformat, GLsizei _width, + GLsizei _height, GLint _border, GLsizei _imageSize) { + uint32 total_size = ComputeSize(_imageSize); + SetHeader(total_size); + target = _target; + level = _level; + internalformat = _internalformat; + width = _width; + height = _height; + border = _border; + imageSize = _imageSize; + } + + void* Set( + void* cmd, GLenum _target, GLint _level, GLenum _internalformat, + GLsizei _width, GLsizei _height, GLint _border, GLsizei _imageSize) { + uint32 total_size = ComputeSize(_imageSize); + static_cast<ValueType*>( + cmd)->Init( + _target, _level, _internalformat, _width, _height, _border, + _imageSize); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, total_size); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 level; + uint32 internalformat; + uint32 width; + uint32 height; + uint32 border; + uint32 imageSize; +}; + +COMPILE_ASSERT(sizeof(CompressedTexImage2DImmediate) == 32, + Sizeof_CompressedTexImage2DImmediate_is_not_32); +COMPILE_ASSERT(offsetof(CompressedTexImage2DImmediate, header) == 0, + OffsetOf_CompressedTexImage2DImmediate_header_not_0); +COMPILE_ASSERT(offsetof(CompressedTexImage2DImmediate, target) == 4, + OffsetOf_CompressedTexImage2DImmediate_target_not_4); +COMPILE_ASSERT(offsetof(CompressedTexImage2DImmediate, level) == 8, + OffsetOf_CompressedTexImage2DImmediate_level_not_8); +COMPILE_ASSERT(offsetof(CompressedTexImage2DImmediate, internalformat) == 12, + OffsetOf_CompressedTexImage2DImmediate_internalformat_not_12); +COMPILE_ASSERT(offsetof(CompressedTexImage2DImmediate, width) == 16, + OffsetOf_CompressedTexImage2DImmediate_width_not_16); +COMPILE_ASSERT(offsetof(CompressedTexImage2DImmediate, height) == 20, + OffsetOf_CompressedTexImage2DImmediate_height_not_20); +COMPILE_ASSERT(offsetof(CompressedTexImage2DImmediate, border) == 24, + OffsetOf_CompressedTexImage2DImmediate_border_not_24); +COMPILE_ASSERT(offsetof(CompressedTexImage2DImmediate, imageSize) == 28, + OffsetOf_CompressedTexImage2DImmediate_imageSize_not_28); + +struct CompressedTexSubImage2D { + typedef CompressedTexSubImage2D ValueType; + static const CommandId kCmdId = kCompressedTexSubImage2D; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLenum _target, GLint _level, GLint _xoffset, GLint _yoffset, + GLsizei _width, GLsizei _height, GLenum _format, GLsizei _imageSize, + uint32 _data_shm_id, uint32 _data_shm_offset) { + SetHeader(); + target = _target; + level = _level; + xoffset = _xoffset; + yoffset = _yoffset; + width = _width; + height = _height; + format = _format; + imageSize = _imageSize; + data_shm_id = _data_shm_id; + data_shm_offset = _data_shm_offset; + } + + void* Set( + void* cmd, GLenum _target, GLint _level, GLint _xoffset, GLint _yoffset, + GLsizei _width, GLsizei _height, GLenum _format, GLsizei _imageSize, + uint32 _data_shm_id, uint32 _data_shm_offset) { + static_cast<ValueType*>( + cmd)->Init( + _target, _level, _xoffset, _yoffset, _width, _height, _format, + _imageSize, _data_shm_id, _data_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 level; + uint32 xoffset; + uint32 yoffset; + uint32 width; + uint32 height; + uint32 format; + uint32 imageSize; + uint32 data_shm_id; + uint32 data_shm_offset; +}; + +COMPILE_ASSERT(sizeof(CompressedTexSubImage2D) == 44, + Sizeof_CompressedTexSubImage2D_is_not_44); +COMPILE_ASSERT(offsetof(CompressedTexSubImage2D, header) == 0, + OffsetOf_CompressedTexSubImage2D_header_not_0); +COMPILE_ASSERT(offsetof(CompressedTexSubImage2D, target) == 4, + OffsetOf_CompressedTexSubImage2D_target_not_4); +COMPILE_ASSERT(offsetof(CompressedTexSubImage2D, level) == 8, + OffsetOf_CompressedTexSubImage2D_level_not_8); +COMPILE_ASSERT(offsetof(CompressedTexSubImage2D, xoffset) == 12, + OffsetOf_CompressedTexSubImage2D_xoffset_not_12); +COMPILE_ASSERT(offsetof(CompressedTexSubImage2D, yoffset) == 16, + OffsetOf_CompressedTexSubImage2D_yoffset_not_16); +COMPILE_ASSERT(offsetof(CompressedTexSubImage2D, width) == 20, + OffsetOf_CompressedTexSubImage2D_width_not_20); +COMPILE_ASSERT(offsetof(CompressedTexSubImage2D, height) == 24, + OffsetOf_CompressedTexSubImage2D_height_not_24); +COMPILE_ASSERT(offsetof(CompressedTexSubImage2D, format) == 28, + OffsetOf_CompressedTexSubImage2D_format_not_28); +COMPILE_ASSERT(offsetof(CompressedTexSubImage2D, imageSize) == 32, + OffsetOf_CompressedTexSubImage2D_imageSize_not_32); +COMPILE_ASSERT(offsetof(CompressedTexSubImage2D, data_shm_id) == 36, + OffsetOf_CompressedTexSubImage2D_data_shm_id_not_36); +COMPILE_ASSERT(offsetof(CompressedTexSubImage2D, data_shm_offset) == 40, + OffsetOf_CompressedTexSubImage2D_data_shm_offset_not_40); + +struct CompressedTexSubImage2DImmediate { + typedef CompressedTexSubImage2DImmediate ValueType; + static const CommandId kCmdId = kCompressedTexSubImage2DImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeSize(uint32 size_in_bytes) { + return static_cast<uint32>( + sizeof(ValueType) + // NOLINT + RoundSizeToMultipleOfEntries(size_in_bytes)); + } + + void SetHeader(uint32 size_in_bytes) { + header.SetCmdByTotalSize<ValueType>(size_in_bytes); + } + + void Init( + GLenum _target, GLint _level, GLint _xoffset, GLint _yoffset, + GLsizei _width, GLsizei _height, GLenum _format, GLsizei _imageSize) { + uint32 total_size = ComputeSize(_imageSize); + SetHeader(total_size); + target = _target; + level = _level; + xoffset = _xoffset; + yoffset = _yoffset; + width = _width; + height = _height; + format = _format; + imageSize = _imageSize; + } + + void* Set( + void* cmd, GLenum _target, GLint _level, GLint _xoffset, GLint _yoffset, + GLsizei _width, GLsizei _height, GLenum _format, GLsizei _imageSize) { + uint32 total_size = ComputeSize(_imageSize); + static_cast<ValueType*>( + cmd)->Init( + _target, _level, _xoffset, _yoffset, _width, _height, _format, + _imageSize); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, total_size); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 level; + uint32 xoffset; + uint32 yoffset; + uint32 width; + uint32 height; + uint32 format; + uint32 imageSize; +}; + +COMPILE_ASSERT(sizeof(CompressedTexSubImage2DImmediate) == 36, + Sizeof_CompressedTexSubImage2DImmediate_is_not_36); +COMPILE_ASSERT(offsetof(CompressedTexSubImage2DImmediate, header) == 0, + OffsetOf_CompressedTexSubImage2DImmediate_header_not_0); +COMPILE_ASSERT(offsetof(CompressedTexSubImage2DImmediate, target) == 4, + OffsetOf_CompressedTexSubImage2DImmediate_target_not_4); +COMPILE_ASSERT(offsetof(CompressedTexSubImage2DImmediate, level) == 8, + OffsetOf_CompressedTexSubImage2DImmediate_level_not_8); +COMPILE_ASSERT(offsetof(CompressedTexSubImage2DImmediate, xoffset) == 12, + OffsetOf_CompressedTexSubImage2DImmediate_xoffset_not_12); +COMPILE_ASSERT(offsetof(CompressedTexSubImage2DImmediate, yoffset) == 16, + OffsetOf_CompressedTexSubImage2DImmediate_yoffset_not_16); +COMPILE_ASSERT(offsetof(CompressedTexSubImage2DImmediate, width) == 20, + OffsetOf_CompressedTexSubImage2DImmediate_width_not_20); +COMPILE_ASSERT(offsetof(CompressedTexSubImage2DImmediate, height) == 24, + OffsetOf_CompressedTexSubImage2DImmediate_height_not_24); +COMPILE_ASSERT(offsetof(CompressedTexSubImage2DImmediate, format) == 28, + OffsetOf_CompressedTexSubImage2DImmediate_format_not_28); +COMPILE_ASSERT(offsetof(CompressedTexSubImage2DImmediate, imageSize) == 32, + OffsetOf_CompressedTexSubImage2DImmediate_imageSize_not_32); + +struct CopyTexImage2D { + typedef CopyTexImage2D ValueType; + static const CommandId kCmdId = kCopyTexImage2D; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLenum _target, GLint _level, GLenum _internalformat, GLint _x, GLint _y, + GLsizei _width, GLsizei _height, GLint _border) { + SetHeader(); + target = _target; + level = _level; + internalformat = _internalformat; + x = _x; + y = _y; + width = _width; + height = _height; + border = _border; + } + + void* Set( + void* cmd, GLenum _target, GLint _level, GLenum _internalformat, GLint _x, + GLint _y, GLsizei _width, GLsizei _height, GLint _border) { + static_cast<ValueType*>( + cmd)->Init( + _target, _level, _internalformat, _x, _y, _width, _height, + _border); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 level; + uint32 internalformat; + uint32 x; + uint32 y; + uint32 width; + uint32 height; + uint32 border; +}; + +COMPILE_ASSERT(sizeof(CopyTexImage2D) == 36, + Sizeof_CopyTexImage2D_is_not_36); +COMPILE_ASSERT(offsetof(CopyTexImage2D, header) == 0, + OffsetOf_CopyTexImage2D_header_not_0); +COMPILE_ASSERT(offsetof(CopyTexImage2D, target) == 4, + OffsetOf_CopyTexImage2D_target_not_4); +COMPILE_ASSERT(offsetof(CopyTexImage2D, level) == 8, + OffsetOf_CopyTexImage2D_level_not_8); +COMPILE_ASSERT(offsetof(CopyTexImage2D, internalformat) == 12, + OffsetOf_CopyTexImage2D_internalformat_not_12); +COMPILE_ASSERT(offsetof(CopyTexImage2D, x) == 16, + OffsetOf_CopyTexImage2D_x_not_16); +COMPILE_ASSERT(offsetof(CopyTexImage2D, y) == 20, + OffsetOf_CopyTexImage2D_y_not_20); +COMPILE_ASSERT(offsetof(CopyTexImage2D, width) == 24, + OffsetOf_CopyTexImage2D_width_not_24); +COMPILE_ASSERT(offsetof(CopyTexImage2D, height) == 28, + OffsetOf_CopyTexImage2D_height_not_28); +COMPILE_ASSERT(offsetof(CopyTexImage2D, border) == 32, + OffsetOf_CopyTexImage2D_border_not_32); + +struct CopyTexSubImage2D { + typedef CopyTexSubImage2D ValueType; + static const CommandId kCmdId = kCopyTexSubImage2D; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLenum _target, GLint _level, GLint _xoffset, GLint _yoffset, GLint _x, + GLint _y, GLsizei _width, GLsizei _height) { + SetHeader(); + target = _target; + level = _level; + xoffset = _xoffset; + yoffset = _yoffset; + x = _x; + y = _y; + width = _width; + height = _height; + } + + void* Set( + void* cmd, GLenum _target, GLint _level, GLint _xoffset, GLint _yoffset, + GLint _x, GLint _y, GLsizei _width, GLsizei _height) { + static_cast<ValueType*>( + cmd)->Init( + _target, _level, _xoffset, _yoffset, _x, _y, _width, _height); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 level; + uint32 xoffset; + uint32 yoffset; + uint32 x; + uint32 y; + uint32 width; + uint32 height; +}; + +COMPILE_ASSERT(sizeof(CopyTexSubImage2D) == 36, + Sizeof_CopyTexSubImage2D_is_not_36); +COMPILE_ASSERT(offsetof(CopyTexSubImage2D, header) == 0, + OffsetOf_CopyTexSubImage2D_header_not_0); +COMPILE_ASSERT(offsetof(CopyTexSubImage2D, target) == 4, + OffsetOf_CopyTexSubImage2D_target_not_4); +COMPILE_ASSERT(offsetof(CopyTexSubImage2D, level) == 8, + OffsetOf_CopyTexSubImage2D_level_not_8); +COMPILE_ASSERT(offsetof(CopyTexSubImage2D, xoffset) == 12, + OffsetOf_CopyTexSubImage2D_xoffset_not_12); +COMPILE_ASSERT(offsetof(CopyTexSubImage2D, yoffset) == 16, + OffsetOf_CopyTexSubImage2D_yoffset_not_16); +COMPILE_ASSERT(offsetof(CopyTexSubImage2D, x) == 20, + OffsetOf_CopyTexSubImage2D_x_not_20); +COMPILE_ASSERT(offsetof(CopyTexSubImage2D, y) == 24, + OffsetOf_CopyTexSubImage2D_y_not_24); +COMPILE_ASSERT(offsetof(CopyTexSubImage2D, width) == 28, + OffsetOf_CopyTexSubImage2D_width_not_28); +COMPILE_ASSERT(offsetof(CopyTexSubImage2D, height) == 32, + OffsetOf_CopyTexSubImage2D_height_not_32); + +struct CreateProgram { + typedef CreateProgram ValueType; + static const CommandId kCmdId = kCreateProgram; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(uint32 _client_id) { + SetHeader(); + client_id = _client_id; + } + + void* Set(void* cmd, uint32 _client_id) { + static_cast<ValueType*>(cmd)->Init(_client_id); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 client_id; +}; + +COMPILE_ASSERT(sizeof(CreateProgram) == 8, + Sizeof_CreateProgram_is_not_8); +COMPILE_ASSERT(offsetof(CreateProgram, header) == 0, + OffsetOf_CreateProgram_header_not_0); +COMPILE_ASSERT(offsetof(CreateProgram, client_id) == 4, + OffsetOf_CreateProgram_client_id_not_4); + +struct CreateShader { + typedef CreateShader ValueType; + static const CommandId kCmdId = kCreateShader; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _type, uint32 _client_id) { + SetHeader(); + type = _type; + client_id = _client_id; + } + + void* Set(void* cmd, GLenum _type, uint32 _client_id) { + static_cast<ValueType*>(cmd)->Init(_type, _client_id); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 type; + uint32 client_id; +}; + +COMPILE_ASSERT(sizeof(CreateShader) == 12, + Sizeof_CreateShader_is_not_12); +COMPILE_ASSERT(offsetof(CreateShader, header) == 0, + OffsetOf_CreateShader_header_not_0); +COMPILE_ASSERT(offsetof(CreateShader, type) == 4, + OffsetOf_CreateShader_type_not_4); +COMPILE_ASSERT(offsetof(CreateShader, client_id) == 8, + OffsetOf_CreateShader_client_id_not_8); + +struct CullFace { + typedef CullFace ValueType; + static const CommandId kCmdId = kCullFace; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _mode) { + SetHeader(); + mode = _mode; + } + + void* Set(void* cmd, GLenum _mode) { + static_cast<ValueType*>(cmd)->Init(_mode); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 mode; +}; + +COMPILE_ASSERT(sizeof(CullFace) == 8, + Sizeof_CullFace_is_not_8); +COMPILE_ASSERT(offsetof(CullFace, header) == 0, + OffsetOf_CullFace_header_not_0); +COMPILE_ASSERT(offsetof(CullFace, mode) == 4, + OffsetOf_CullFace_mode_not_4); + +struct DeleteBuffers { + typedef DeleteBuffers ValueType; + static const CommandId kCmdId = kDeleteBuffers; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLsizei _n, uint32 _buffers_shm_id, uint32 _buffers_shm_offset) { + SetHeader(); + n = _n; + buffers_shm_id = _buffers_shm_id; + buffers_shm_offset = _buffers_shm_offset; + } + + void* Set( + void* cmd, GLsizei _n, uint32 _buffers_shm_id, + uint32 _buffers_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_n, _buffers_shm_id, _buffers_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 n; + uint32 buffers_shm_id; + uint32 buffers_shm_offset; +}; + +COMPILE_ASSERT(sizeof(DeleteBuffers) == 16, + Sizeof_DeleteBuffers_is_not_16); +COMPILE_ASSERT(offsetof(DeleteBuffers, header) == 0, + OffsetOf_DeleteBuffers_header_not_0); +COMPILE_ASSERT(offsetof(DeleteBuffers, n) == 4, + OffsetOf_DeleteBuffers_n_not_4); +COMPILE_ASSERT(offsetof(DeleteBuffers, buffers_shm_id) == 8, + OffsetOf_DeleteBuffers_buffers_shm_id_not_8); +COMPILE_ASSERT(offsetof(DeleteBuffers, buffers_shm_offset) == 12, + OffsetOf_DeleteBuffers_buffers_shm_offset_not_12); + +struct DeleteBuffersImmediate { + typedef DeleteBuffersImmediate ValueType; + static const CommandId kCmdId = kDeleteBuffersImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeDataSize(GLsizei n) { + return static_cast<uint32>(sizeof(GLuint) * n); // NOLINT + } + + static uint32 ComputeSize(GLsizei n) { + return static_cast<uint32>( + sizeof(ValueType) + ComputeDataSize(n)); // NOLINT + } + + void SetHeader(GLsizei n) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(n)); + } + + void Init(GLsizei _n, const GLuint* _buffers) { + SetHeader(_n); + n = _n; + memcpy(ImmediateDataAddress(this), + _buffers, ComputeDataSize(_n)); + } + + void* Set(void* cmd, GLsizei _n, const GLuint* _buffers) { + static_cast<ValueType*>(cmd)->Init(_n, _buffers); + const uint32 size = ComputeSize(_n); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + command_buffer::CommandHeader header; + uint32 n; +}; + +COMPILE_ASSERT(sizeof(DeleteBuffersImmediate) == 8, + Sizeof_DeleteBuffersImmediate_is_not_8); +COMPILE_ASSERT(offsetof(DeleteBuffersImmediate, header) == 0, + OffsetOf_DeleteBuffersImmediate_header_not_0); +COMPILE_ASSERT(offsetof(DeleteBuffersImmediate, n) == 4, + OffsetOf_DeleteBuffersImmediate_n_not_4); + +struct DeleteFramebuffers { + typedef DeleteFramebuffers ValueType; + static const CommandId kCmdId = kDeleteFramebuffers; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLsizei _n, uint32 _framebuffers_shm_id, + uint32 _framebuffers_shm_offset) { + SetHeader(); + n = _n; + framebuffers_shm_id = _framebuffers_shm_id; + framebuffers_shm_offset = _framebuffers_shm_offset; + } + + void* Set( + void* cmd, GLsizei _n, uint32 _framebuffers_shm_id, + uint32 _framebuffers_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_n, _framebuffers_shm_id, _framebuffers_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 n; + uint32 framebuffers_shm_id; + uint32 framebuffers_shm_offset; +}; + +COMPILE_ASSERT(sizeof(DeleteFramebuffers) == 16, + Sizeof_DeleteFramebuffers_is_not_16); +COMPILE_ASSERT(offsetof(DeleteFramebuffers, header) == 0, + OffsetOf_DeleteFramebuffers_header_not_0); +COMPILE_ASSERT(offsetof(DeleteFramebuffers, n) == 4, + OffsetOf_DeleteFramebuffers_n_not_4); +COMPILE_ASSERT(offsetof(DeleteFramebuffers, framebuffers_shm_id) == 8, + OffsetOf_DeleteFramebuffers_framebuffers_shm_id_not_8); +COMPILE_ASSERT(offsetof(DeleteFramebuffers, framebuffers_shm_offset) == 12, + OffsetOf_DeleteFramebuffers_framebuffers_shm_offset_not_12); + +struct DeleteFramebuffersImmediate { + typedef DeleteFramebuffersImmediate ValueType; + static const CommandId kCmdId = kDeleteFramebuffersImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeDataSize(GLsizei n) { + return static_cast<uint32>(sizeof(GLuint) * n); // NOLINT + } + + static uint32 ComputeSize(GLsizei n) { + return static_cast<uint32>( + sizeof(ValueType) + ComputeDataSize(n)); // NOLINT + } + + void SetHeader(GLsizei n) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(n)); + } + + void Init(GLsizei _n, const GLuint* _framebuffers) { + SetHeader(_n); + n = _n; + memcpy(ImmediateDataAddress(this), + _framebuffers, ComputeDataSize(_n)); + } + + void* Set(void* cmd, GLsizei _n, const GLuint* _framebuffers) { + static_cast<ValueType*>(cmd)->Init(_n, _framebuffers); + const uint32 size = ComputeSize(_n); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + command_buffer::CommandHeader header; + uint32 n; +}; + +COMPILE_ASSERT(sizeof(DeleteFramebuffersImmediate) == 8, + Sizeof_DeleteFramebuffersImmediate_is_not_8); +COMPILE_ASSERT(offsetof(DeleteFramebuffersImmediate, header) == 0, + OffsetOf_DeleteFramebuffersImmediate_header_not_0); +COMPILE_ASSERT(offsetof(DeleteFramebuffersImmediate, n) == 4, + OffsetOf_DeleteFramebuffersImmediate_n_not_4); + +struct DeleteProgram { + typedef DeleteProgram ValueType; + static const CommandId kCmdId = kDeleteProgram; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLuint _program) { + SetHeader(); + program = _program; + } + + void* Set(void* cmd, GLuint _program) { + static_cast<ValueType*>(cmd)->Init(_program); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 program; +}; + +COMPILE_ASSERT(sizeof(DeleteProgram) == 8, + Sizeof_DeleteProgram_is_not_8); +COMPILE_ASSERT(offsetof(DeleteProgram, header) == 0, + OffsetOf_DeleteProgram_header_not_0); +COMPILE_ASSERT(offsetof(DeleteProgram, program) == 4, + OffsetOf_DeleteProgram_program_not_4); + +struct DeleteRenderbuffers { + typedef DeleteRenderbuffers ValueType; + static const CommandId kCmdId = kDeleteRenderbuffers; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLsizei _n, uint32 _renderbuffers_shm_id, + uint32 _renderbuffers_shm_offset) { + SetHeader(); + n = _n; + renderbuffers_shm_id = _renderbuffers_shm_id; + renderbuffers_shm_offset = _renderbuffers_shm_offset; + } + + void* Set( + void* cmd, GLsizei _n, uint32 _renderbuffers_shm_id, + uint32 _renderbuffers_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_n, _renderbuffers_shm_id, _renderbuffers_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 n; + uint32 renderbuffers_shm_id; + uint32 renderbuffers_shm_offset; +}; + +COMPILE_ASSERT(sizeof(DeleteRenderbuffers) == 16, + Sizeof_DeleteRenderbuffers_is_not_16); +COMPILE_ASSERT(offsetof(DeleteRenderbuffers, header) == 0, + OffsetOf_DeleteRenderbuffers_header_not_0); +COMPILE_ASSERT(offsetof(DeleteRenderbuffers, n) == 4, + OffsetOf_DeleteRenderbuffers_n_not_4); +COMPILE_ASSERT(offsetof(DeleteRenderbuffers, renderbuffers_shm_id) == 8, + OffsetOf_DeleteRenderbuffers_renderbuffers_shm_id_not_8); +COMPILE_ASSERT(offsetof(DeleteRenderbuffers, renderbuffers_shm_offset) == 12, + OffsetOf_DeleteRenderbuffers_renderbuffers_shm_offset_not_12); + +struct DeleteRenderbuffersImmediate { + typedef DeleteRenderbuffersImmediate ValueType; + static const CommandId kCmdId = kDeleteRenderbuffersImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeDataSize(GLsizei n) { + return static_cast<uint32>(sizeof(GLuint) * n); // NOLINT + } + + static uint32 ComputeSize(GLsizei n) { + return static_cast<uint32>( + sizeof(ValueType) + ComputeDataSize(n)); // NOLINT + } + + void SetHeader(GLsizei n) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(n)); + } + + void Init(GLsizei _n, const GLuint* _renderbuffers) { + SetHeader(_n); + n = _n; + memcpy(ImmediateDataAddress(this), + _renderbuffers, ComputeDataSize(_n)); + } + + void* Set(void* cmd, GLsizei _n, const GLuint* _renderbuffers) { + static_cast<ValueType*>(cmd)->Init(_n, _renderbuffers); + const uint32 size = ComputeSize(_n); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + command_buffer::CommandHeader header; + uint32 n; +}; + +COMPILE_ASSERT(sizeof(DeleteRenderbuffersImmediate) == 8, + Sizeof_DeleteRenderbuffersImmediate_is_not_8); +COMPILE_ASSERT(offsetof(DeleteRenderbuffersImmediate, header) == 0, + OffsetOf_DeleteRenderbuffersImmediate_header_not_0); +COMPILE_ASSERT(offsetof(DeleteRenderbuffersImmediate, n) == 4, + OffsetOf_DeleteRenderbuffersImmediate_n_not_4); + +struct DeleteShader { + typedef DeleteShader ValueType; + static const CommandId kCmdId = kDeleteShader; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLuint _shader) { + SetHeader(); + shader = _shader; + } + + void* Set(void* cmd, GLuint _shader) { + static_cast<ValueType*>(cmd)->Init(_shader); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 shader; +}; + +COMPILE_ASSERT(sizeof(DeleteShader) == 8, + Sizeof_DeleteShader_is_not_8); +COMPILE_ASSERT(offsetof(DeleteShader, header) == 0, + OffsetOf_DeleteShader_header_not_0); +COMPILE_ASSERT(offsetof(DeleteShader, shader) == 4, + OffsetOf_DeleteShader_shader_not_4); + +struct DeleteTextures { + typedef DeleteTextures ValueType; + static const CommandId kCmdId = kDeleteTextures; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLsizei _n, uint32 _textures_shm_id, uint32 _textures_shm_offset) { + SetHeader(); + n = _n; + textures_shm_id = _textures_shm_id; + textures_shm_offset = _textures_shm_offset; + } + + void* Set( + void* cmd, GLsizei _n, uint32 _textures_shm_id, + uint32 _textures_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_n, _textures_shm_id, _textures_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 n; + uint32 textures_shm_id; + uint32 textures_shm_offset; +}; + +COMPILE_ASSERT(sizeof(DeleteTextures) == 16, + Sizeof_DeleteTextures_is_not_16); +COMPILE_ASSERT(offsetof(DeleteTextures, header) == 0, + OffsetOf_DeleteTextures_header_not_0); +COMPILE_ASSERT(offsetof(DeleteTextures, n) == 4, + OffsetOf_DeleteTextures_n_not_4); +COMPILE_ASSERT(offsetof(DeleteTextures, textures_shm_id) == 8, + OffsetOf_DeleteTextures_textures_shm_id_not_8); +COMPILE_ASSERT(offsetof(DeleteTextures, textures_shm_offset) == 12, + OffsetOf_DeleteTextures_textures_shm_offset_not_12); + +struct DeleteTexturesImmediate { + typedef DeleteTexturesImmediate ValueType; + static const CommandId kCmdId = kDeleteTexturesImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeDataSize(GLsizei n) { + return static_cast<uint32>(sizeof(GLuint) * n); // NOLINT + } + + static uint32 ComputeSize(GLsizei n) { + return static_cast<uint32>( + sizeof(ValueType) + ComputeDataSize(n)); // NOLINT + } + + void SetHeader(GLsizei n) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(n)); + } + + void Init(GLsizei _n, const GLuint* _textures) { + SetHeader(_n); + n = _n; + memcpy(ImmediateDataAddress(this), + _textures, ComputeDataSize(_n)); + } + + void* Set(void* cmd, GLsizei _n, const GLuint* _textures) { + static_cast<ValueType*>(cmd)->Init(_n, _textures); + const uint32 size = ComputeSize(_n); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + command_buffer::CommandHeader header; + uint32 n; +}; + +COMPILE_ASSERT(sizeof(DeleteTexturesImmediate) == 8, + Sizeof_DeleteTexturesImmediate_is_not_8); +COMPILE_ASSERT(offsetof(DeleteTexturesImmediate, header) == 0, + OffsetOf_DeleteTexturesImmediate_header_not_0); +COMPILE_ASSERT(offsetof(DeleteTexturesImmediate, n) == 4, + OffsetOf_DeleteTexturesImmediate_n_not_4); + +struct DepthFunc { + typedef DepthFunc ValueType; + static const CommandId kCmdId = kDepthFunc; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _func) { + SetHeader(); + func = _func; + } + + void* Set(void* cmd, GLenum _func) { + static_cast<ValueType*>(cmd)->Init(_func); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 func; +}; + +COMPILE_ASSERT(sizeof(DepthFunc) == 8, + Sizeof_DepthFunc_is_not_8); +COMPILE_ASSERT(offsetof(DepthFunc, header) == 0, + OffsetOf_DepthFunc_header_not_0); +COMPILE_ASSERT(offsetof(DepthFunc, func) == 4, + OffsetOf_DepthFunc_func_not_4); + +struct DepthMask { + typedef DepthMask ValueType; + static const CommandId kCmdId = kDepthMask; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLboolean _flag) { + SetHeader(); + flag = _flag; + } + + void* Set(void* cmd, GLboolean _flag) { + static_cast<ValueType*>(cmd)->Init(_flag); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 flag; +}; + +COMPILE_ASSERT(sizeof(DepthMask) == 8, + Sizeof_DepthMask_is_not_8); +COMPILE_ASSERT(offsetof(DepthMask, header) == 0, + OffsetOf_DepthMask_header_not_0); +COMPILE_ASSERT(offsetof(DepthMask, flag) == 4, + OffsetOf_DepthMask_flag_not_4); + +struct DepthRangef { + typedef DepthRangef ValueType; + static const CommandId kCmdId = kDepthRangef; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLclampf _zNear, GLclampf _zFar) { + SetHeader(); + zNear = _zNear; + zFar = _zFar; + } + + void* Set(void* cmd, GLclampf _zNear, GLclampf _zFar) { + static_cast<ValueType*>(cmd)->Init(_zNear, _zFar); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + float zNear; + float zFar; +}; + +COMPILE_ASSERT(sizeof(DepthRangef) == 12, + Sizeof_DepthRangef_is_not_12); +COMPILE_ASSERT(offsetof(DepthRangef, header) == 0, + OffsetOf_DepthRangef_header_not_0); +COMPILE_ASSERT(offsetof(DepthRangef, zNear) == 4, + OffsetOf_DepthRangef_zNear_not_4); +COMPILE_ASSERT(offsetof(DepthRangef, zFar) == 8, + OffsetOf_DepthRangef_zFar_not_8); + +struct DetachShader { + typedef DetachShader ValueType; + static const CommandId kCmdId = kDetachShader; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLuint _program, GLuint _shader) { + SetHeader(); + program = _program; + shader = _shader; + } + + void* Set(void* cmd, GLuint _program, GLuint _shader) { + static_cast<ValueType*>(cmd)->Init(_program, _shader); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 program; + uint32 shader; +}; + +COMPILE_ASSERT(sizeof(DetachShader) == 12, + Sizeof_DetachShader_is_not_12); +COMPILE_ASSERT(offsetof(DetachShader, header) == 0, + OffsetOf_DetachShader_header_not_0); +COMPILE_ASSERT(offsetof(DetachShader, program) == 4, + OffsetOf_DetachShader_program_not_4); +COMPILE_ASSERT(offsetof(DetachShader, shader) == 8, + OffsetOf_DetachShader_shader_not_8); + +struct Disable { + typedef Disable ValueType; + static const CommandId kCmdId = kDisable; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _cap) { + SetHeader(); + cap = _cap; + } + + void* Set(void* cmd, GLenum _cap) { + static_cast<ValueType*>(cmd)->Init(_cap); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 cap; +}; + +COMPILE_ASSERT(sizeof(Disable) == 8, + Sizeof_Disable_is_not_8); +COMPILE_ASSERT(offsetof(Disable, header) == 0, + OffsetOf_Disable_header_not_0); +COMPILE_ASSERT(offsetof(Disable, cap) == 4, + OffsetOf_Disable_cap_not_4); + +struct DisableVertexAttribArray { + typedef DisableVertexAttribArray ValueType; + static const CommandId kCmdId = kDisableVertexAttribArray; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLuint _index) { + SetHeader(); + index = _index; + } + + void* Set(void* cmd, GLuint _index) { + static_cast<ValueType*>(cmd)->Init(_index); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 index; +}; + +COMPILE_ASSERT(sizeof(DisableVertexAttribArray) == 8, + Sizeof_DisableVertexAttribArray_is_not_8); +COMPILE_ASSERT(offsetof(DisableVertexAttribArray, header) == 0, + OffsetOf_DisableVertexAttribArray_header_not_0); +COMPILE_ASSERT(offsetof(DisableVertexAttribArray, index) == 4, + OffsetOf_DisableVertexAttribArray_index_not_4); + +struct DrawArrays { + typedef DrawArrays ValueType; + static const CommandId kCmdId = kDrawArrays; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _mode, GLint _first, GLsizei _count) { + SetHeader(); + mode = _mode; + first = _first; + count = _count; + } + + void* Set(void* cmd, GLenum _mode, GLint _first, GLsizei _count) { + static_cast<ValueType*>(cmd)->Init(_mode, _first, _count); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 mode; + uint32 first; + uint32 count; +}; + +COMPILE_ASSERT(sizeof(DrawArrays) == 16, + Sizeof_DrawArrays_is_not_16); +COMPILE_ASSERT(offsetof(DrawArrays, header) == 0, + OffsetOf_DrawArrays_header_not_0); +COMPILE_ASSERT(offsetof(DrawArrays, mode) == 4, + OffsetOf_DrawArrays_mode_not_4); +COMPILE_ASSERT(offsetof(DrawArrays, first) == 8, + OffsetOf_DrawArrays_first_not_8); +COMPILE_ASSERT(offsetof(DrawArrays, count) == 12, + OffsetOf_DrawArrays_count_not_12); + +struct DrawElements { + typedef DrawElements ValueType; + static const CommandId kCmdId = kDrawElements; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _mode, GLsizei _count, GLenum _type, GLuint _index_offset) { + SetHeader(); + mode = _mode; + count = _count; + type = _type; + index_offset = _index_offset; + } + + void* Set( + void* cmd, GLenum _mode, GLsizei _count, GLenum _type, + GLuint _index_offset) { + static_cast<ValueType*>(cmd)->Init(_mode, _count, _type, _index_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 mode; + uint32 count; + uint32 type; + uint32 index_offset; +}; + +COMPILE_ASSERT(sizeof(DrawElements) == 20, + Sizeof_DrawElements_is_not_20); +COMPILE_ASSERT(offsetof(DrawElements, header) == 0, + OffsetOf_DrawElements_header_not_0); +COMPILE_ASSERT(offsetof(DrawElements, mode) == 4, + OffsetOf_DrawElements_mode_not_4); +COMPILE_ASSERT(offsetof(DrawElements, count) == 8, + OffsetOf_DrawElements_count_not_8); +COMPILE_ASSERT(offsetof(DrawElements, type) == 12, + OffsetOf_DrawElements_type_not_12); +COMPILE_ASSERT(offsetof(DrawElements, index_offset) == 16, + OffsetOf_DrawElements_index_offset_not_16); + +struct Enable { + typedef Enable ValueType; + static const CommandId kCmdId = kEnable; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _cap) { + SetHeader(); + cap = _cap; + } + + void* Set(void* cmd, GLenum _cap) { + static_cast<ValueType*>(cmd)->Init(_cap); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 cap; +}; + +COMPILE_ASSERT(sizeof(Enable) == 8, + Sizeof_Enable_is_not_8); +COMPILE_ASSERT(offsetof(Enable, header) == 0, + OffsetOf_Enable_header_not_0); +COMPILE_ASSERT(offsetof(Enable, cap) == 4, + OffsetOf_Enable_cap_not_4); + +struct EnableVertexAttribArray { + typedef EnableVertexAttribArray ValueType; + static const CommandId kCmdId = kEnableVertexAttribArray; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLuint _index) { + SetHeader(); + index = _index; + } + + void* Set(void* cmd, GLuint _index) { + static_cast<ValueType*>(cmd)->Init(_index); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 index; +}; + +COMPILE_ASSERT(sizeof(EnableVertexAttribArray) == 8, + Sizeof_EnableVertexAttribArray_is_not_8); +COMPILE_ASSERT(offsetof(EnableVertexAttribArray, header) == 0, + OffsetOf_EnableVertexAttribArray_header_not_0); +COMPILE_ASSERT(offsetof(EnableVertexAttribArray, index) == 4, + OffsetOf_EnableVertexAttribArray_index_not_4); + +struct Finish { + typedef Finish ValueType; + static const CommandId kCmdId = kFinish; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init() { + SetHeader(); + } + + void* Set(void* cmd) { + static_cast<ValueType*>(cmd)->Init(); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; +}; + +COMPILE_ASSERT(sizeof(Finish) == 4, + Sizeof_Finish_is_not_4); +COMPILE_ASSERT(offsetof(Finish, header) == 0, + OffsetOf_Finish_header_not_0); + +struct Flush { + typedef Flush ValueType; + static const CommandId kCmdId = kFlush; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init() { + SetHeader(); + } + + void* Set(void* cmd) { + static_cast<ValueType*>(cmd)->Init(); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; +}; + +COMPILE_ASSERT(sizeof(Flush) == 4, + Sizeof_Flush_is_not_4); +COMPILE_ASSERT(offsetof(Flush, header) == 0, + OffsetOf_Flush_header_not_0); + +struct FramebufferRenderbuffer { + typedef FramebufferRenderbuffer ValueType; + static const CommandId kCmdId = kFramebufferRenderbuffer; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLenum _target, GLenum _attachment, GLenum _renderbuffertarget, + GLuint _renderbuffer) { + SetHeader(); + target = _target; + attachment = _attachment; + renderbuffertarget = _renderbuffertarget; + renderbuffer = _renderbuffer; + } + + void* Set( + void* cmd, GLenum _target, GLenum _attachment, GLenum _renderbuffertarget, + GLuint _renderbuffer) { + static_cast<ValueType*>( + cmd)->Init(_target, _attachment, _renderbuffertarget, _renderbuffer); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 attachment; + uint32 renderbuffertarget; + uint32 renderbuffer; +}; + +COMPILE_ASSERT(sizeof(FramebufferRenderbuffer) == 20, + Sizeof_FramebufferRenderbuffer_is_not_20); +COMPILE_ASSERT(offsetof(FramebufferRenderbuffer, header) == 0, + OffsetOf_FramebufferRenderbuffer_header_not_0); +COMPILE_ASSERT(offsetof(FramebufferRenderbuffer, target) == 4, + OffsetOf_FramebufferRenderbuffer_target_not_4); +COMPILE_ASSERT(offsetof(FramebufferRenderbuffer, attachment) == 8, + OffsetOf_FramebufferRenderbuffer_attachment_not_8); +COMPILE_ASSERT(offsetof(FramebufferRenderbuffer, renderbuffertarget) == 12, + OffsetOf_FramebufferRenderbuffer_renderbuffertarget_not_12); +COMPILE_ASSERT(offsetof(FramebufferRenderbuffer, renderbuffer) == 16, + OffsetOf_FramebufferRenderbuffer_renderbuffer_not_16); + +struct FramebufferTexture2D { + typedef FramebufferTexture2D ValueType; + static const CommandId kCmdId = kFramebufferTexture2D; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLenum _target, GLenum _attachment, GLenum _textarget, GLuint _texture, + GLint _level) { + SetHeader(); + target = _target; + attachment = _attachment; + textarget = _textarget; + texture = _texture; + level = _level; + } + + void* Set( + void* cmd, GLenum _target, GLenum _attachment, GLenum _textarget, + GLuint _texture, GLint _level) { + static_cast<ValueType*>( + cmd)->Init(_target, _attachment, _textarget, _texture, _level); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 attachment; + uint32 textarget; + uint32 texture; + uint32 level; +}; + +COMPILE_ASSERT(sizeof(FramebufferTexture2D) == 24, + Sizeof_FramebufferTexture2D_is_not_24); +COMPILE_ASSERT(offsetof(FramebufferTexture2D, header) == 0, + OffsetOf_FramebufferTexture2D_header_not_0); +COMPILE_ASSERT(offsetof(FramebufferTexture2D, target) == 4, + OffsetOf_FramebufferTexture2D_target_not_4); +COMPILE_ASSERT(offsetof(FramebufferTexture2D, attachment) == 8, + OffsetOf_FramebufferTexture2D_attachment_not_8); +COMPILE_ASSERT(offsetof(FramebufferTexture2D, textarget) == 12, + OffsetOf_FramebufferTexture2D_textarget_not_12); +COMPILE_ASSERT(offsetof(FramebufferTexture2D, texture) == 16, + OffsetOf_FramebufferTexture2D_texture_not_16); +COMPILE_ASSERT(offsetof(FramebufferTexture2D, level) == 20, + OffsetOf_FramebufferTexture2D_level_not_20); + +struct FrontFace { + typedef FrontFace ValueType; + static const CommandId kCmdId = kFrontFace; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _mode) { + SetHeader(); + mode = _mode; + } + + void* Set(void* cmd, GLenum _mode) { + static_cast<ValueType*>(cmd)->Init(_mode); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 mode; +}; + +COMPILE_ASSERT(sizeof(FrontFace) == 8, + Sizeof_FrontFace_is_not_8); +COMPILE_ASSERT(offsetof(FrontFace, header) == 0, + OffsetOf_FrontFace_header_not_0); +COMPILE_ASSERT(offsetof(FrontFace, mode) == 4, + OffsetOf_FrontFace_mode_not_4); + +struct GenBuffers { + typedef GenBuffers ValueType; + static const CommandId kCmdId = kGenBuffers; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLsizei _n, uint32 _buffers_shm_id, uint32 _buffers_shm_offset) { + SetHeader(); + n = _n; + buffers_shm_id = _buffers_shm_id; + buffers_shm_offset = _buffers_shm_offset; + } + + void* Set( + void* cmd, GLsizei _n, uint32 _buffers_shm_id, + uint32 _buffers_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_n, _buffers_shm_id, _buffers_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 n; + uint32 buffers_shm_id; + uint32 buffers_shm_offset; +}; + +COMPILE_ASSERT(sizeof(GenBuffers) == 16, + Sizeof_GenBuffers_is_not_16); +COMPILE_ASSERT(offsetof(GenBuffers, header) == 0, + OffsetOf_GenBuffers_header_not_0); +COMPILE_ASSERT(offsetof(GenBuffers, n) == 4, + OffsetOf_GenBuffers_n_not_4); +COMPILE_ASSERT(offsetof(GenBuffers, buffers_shm_id) == 8, + OffsetOf_GenBuffers_buffers_shm_id_not_8); +COMPILE_ASSERT(offsetof(GenBuffers, buffers_shm_offset) == 12, + OffsetOf_GenBuffers_buffers_shm_offset_not_12); + +struct GenBuffersImmediate { + typedef GenBuffersImmediate ValueType; + static const CommandId kCmdId = kGenBuffersImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeDataSize(GLsizei n) { + return static_cast<uint32>(sizeof(GLuint) * n); // NOLINT + } + + static uint32 ComputeSize(GLsizei n) { + return static_cast<uint32>( + sizeof(ValueType) + ComputeDataSize(n)); // NOLINT + } + + void SetHeader(GLsizei n) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(n)); + } + + void Init(GLsizei _n, GLuint* _buffers) { + SetHeader(_n); + n = _n; + memcpy(ImmediateDataAddress(this), + _buffers, ComputeDataSize(_n)); + } + + void* Set(void* cmd, GLsizei _n, GLuint* _buffers) { + static_cast<ValueType*>(cmd)->Init(_n, _buffers); + const uint32 size = ComputeSize(_n); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + command_buffer::CommandHeader header; + uint32 n; +}; + +COMPILE_ASSERT(sizeof(GenBuffersImmediate) == 8, + Sizeof_GenBuffersImmediate_is_not_8); +COMPILE_ASSERT(offsetof(GenBuffersImmediate, header) == 0, + OffsetOf_GenBuffersImmediate_header_not_0); +COMPILE_ASSERT(offsetof(GenBuffersImmediate, n) == 4, + OffsetOf_GenBuffersImmediate_n_not_4); + +struct GenerateMipmap { + typedef GenerateMipmap ValueType; + static const CommandId kCmdId = kGenerateMipmap; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _target) { + SetHeader(); + target = _target; + } + + void* Set(void* cmd, GLenum _target) { + static_cast<ValueType*>(cmd)->Init(_target); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 target; +}; + +COMPILE_ASSERT(sizeof(GenerateMipmap) == 8, + Sizeof_GenerateMipmap_is_not_8); +COMPILE_ASSERT(offsetof(GenerateMipmap, header) == 0, + OffsetOf_GenerateMipmap_header_not_0); +COMPILE_ASSERT(offsetof(GenerateMipmap, target) == 4, + OffsetOf_GenerateMipmap_target_not_4); + +struct GenFramebuffers { + typedef GenFramebuffers ValueType; + static const CommandId kCmdId = kGenFramebuffers; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLsizei _n, uint32 _framebuffers_shm_id, + uint32 _framebuffers_shm_offset) { + SetHeader(); + n = _n; + framebuffers_shm_id = _framebuffers_shm_id; + framebuffers_shm_offset = _framebuffers_shm_offset; + } + + void* Set( + void* cmd, GLsizei _n, uint32 _framebuffers_shm_id, + uint32 _framebuffers_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_n, _framebuffers_shm_id, _framebuffers_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 n; + uint32 framebuffers_shm_id; + uint32 framebuffers_shm_offset; +}; + +COMPILE_ASSERT(sizeof(GenFramebuffers) == 16, + Sizeof_GenFramebuffers_is_not_16); +COMPILE_ASSERT(offsetof(GenFramebuffers, header) == 0, + OffsetOf_GenFramebuffers_header_not_0); +COMPILE_ASSERT(offsetof(GenFramebuffers, n) == 4, + OffsetOf_GenFramebuffers_n_not_4); +COMPILE_ASSERT(offsetof(GenFramebuffers, framebuffers_shm_id) == 8, + OffsetOf_GenFramebuffers_framebuffers_shm_id_not_8); +COMPILE_ASSERT(offsetof(GenFramebuffers, framebuffers_shm_offset) == 12, + OffsetOf_GenFramebuffers_framebuffers_shm_offset_not_12); + +struct GenFramebuffersImmediate { + typedef GenFramebuffersImmediate ValueType; + static const CommandId kCmdId = kGenFramebuffersImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeDataSize(GLsizei n) { + return static_cast<uint32>(sizeof(GLuint) * n); // NOLINT + } + + static uint32 ComputeSize(GLsizei n) { + return static_cast<uint32>( + sizeof(ValueType) + ComputeDataSize(n)); // NOLINT + } + + void SetHeader(GLsizei n) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(n)); + } + + void Init(GLsizei _n, GLuint* _framebuffers) { + SetHeader(_n); + n = _n; + memcpy(ImmediateDataAddress(this), + _framebuffers, ComputeDataSize(_n)); + } + + void* Set(void* cmd, GLsizei _n, GLuint* _framebuffers) { + static_cast<ValueType*>(cmd)->Init(_n, _framebuffers); + const uint32 size = ComputeSize(_n); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + command_buffer::CommandHeader header; + uint32 n; +}; + +COMPILE_ASSERT(sizeof(GenFramebuffersImmediate) == 8, + Sizeof_GenFramebuffersImmediate_is_not_8); +COMPILE_ASSERT(offsetof(GenFramebuffersImmediate, header) == 0, + OffsetOf_GenFramebuffersImmediate_header_not_0); +COMPILE_ASSERT(offsetof(GenFramebuffersImmediate, n) == 4, + OffsetOf_GenFramebuffersImmediate_n_not_4); + +struct GenRenderbuffers { + typedef GenRenderbuffers ValueType; + static const CommandId kCmdId = kGenRenderbuffers; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLsizei _n, uint32 _renderbuffers_shm_id, + uint32 _renderbuffers_shm_offset) { + SetHeader(); + n = _n; + renderbuffers_shm_id = _renderbuffers_shm_id; + renderbuffers_shm_offset = _renderbuffers_shm_offset; + } + + void* Set( + void* cmd, GLsizei _n, uint32 _renderbuffers_shm_id, + uint32 _renderbuffers_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_n, _renderbuffers_shm_id, _renderbuffers_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 n; + uint32 renderbuffers_shm_id; + uint32 renderbuffers_shm_offset; +}; + +COMPILE_ASSERT(sizeof(GenRenderbuffers) == 16, + Sizeof_GenRenderbuffers_is_not_16); +COMPILE_ASSERT(offsetof(GenRenderbuffers, header) == 0, + OffsetOf_GenRenderbuffers_header_not_0); +COMPILE_ASSERT(offsetof(GenRenderbuffers, n) == 4, + OffsetOf_GenRenderbuffers_n_not_4); +COMPILE_ASSERT(offsetof(GenRenderbuffers, renderbuffers_shm_id) == 8, + OffsetOf_GenRenderbuffers_renderbuffers_shm_id_not_8); +COMPILE_ASSERT(offsetof(GenRenderbuffers, renderbuffers_shm_offset) == 12, + OffsetOf_GenRenderbuffers_renderbuffers_shm_offset_not_12); + +struct GenRenderbuffersImmediate { + typedef GenRenderbuffersImmediate ValueType; + static const CommandId kCmdId = kGenRenderbuffersImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeDataSize(GLsizei n) { + return static_cast<uint32>(sizeof(GLuint) * n); // NOLINT + } + + static uint32 ComputeSize(GLsizei n) { + return static_cast<uint32>( + sizeof(ValueType) + ComputeDataSize(n)); // NOLINT + } + + void SetHeader(GLsizei n) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(n)); + } + + void Init(GLsizei _n, GLuint* _renderbuffers) { + SetHeader(_n); + n = _n; + memcpy(ImmediateDataAddress(this), + _renderbuffers, ComputeDataSize(_n)); + } + + void* Set(void* cmd, GLsizei _n, GLuint* _renderbuffers) { + static_cast<ValueType*>(cmd)->Init(_n, _renderbuffers); + const uint32 size = ComputeSize(_n); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + command_buffer::CommandHeader header; + uint32 n; +}; + +COMPILE_ASSERT(sizeof(GenRenderbuffersImmediate) == 8, + Sizeof_GenRenderbuffersImmediate_is_not_8); +COMPILE_ASSERT(offsetof(GenRenderbuffersImmediate, header) == 0, + OffsetOf_GenRenderbuffersImmediate_header_not_0); +COMPILE_ASSERT(offsetof(GenRenderbuffersImmediate, n) == 4, + OffsetOf_GenRenderbuffersImmediate_n_not_4); + +struct GenTextures { + typedef GenTextures ValueType; + static const CommandId kCmdId = kGenTextures; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLsizei _n, uint32 _textures_shm_id, uint32 _textures_shm_offset) { + SetHeader(); + n = _n; + textures_shm_id = _textures_shm_id; + textures_shm_offset = _textures_shm_offset; + } + + void* Set( + void* cmd, GLsizei _n, uint32 _textures_shm_id, + uint32 _textures_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_n, _textures_shm_id, _textures_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 n; + uint32 textures_shm_id; + uint32 textures_shm_offset; +}; + +COMPILE_ASSERT(sizeof(GenTextures) == 16, + Sizeof_GenTextures_is_not_16); +COMPILE_ASSERT(offsetof(GenTextures, header) == 0, + OffsetOf_GenTextures_header_not_0); +COMPILE_ASSERT(offsetof(GenTextures, n) == 4, + OffsetOf_GenTextures_n_not_4); +COMPILE_ASSERT(offsetof(GenTextures, textures_shm_id) == 8, + OffsetOf_GenTextures_textures_shm_id_not_8); +COMPILE_ASSERT(offsetof(GenTextures, textures_shm_offset) == 12, + OffsetOf_GenTextures_textures_shm_offset_not_12); + +struct GenTexturesImmediate { + typedef GenTexturesImmediate ValueType; + static const CommandId kCmdId = kGenTexturesImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeDataSize(GLsizei n) { + return static_cast<uint32>(sizeof(GLuint) * n); // NOLINT + } + + static uint32 ComputeSize(GLsizei n) { + return static_cast<uint32>( + sizeof(ValueType) + ComputeDataSize(n)); // NOLINT + } + + void SetHeader(GLsizei n) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(n)); + } + + void Init(GLsizei _n, GLuint* _textures) { + SetHeader(_n); + n = _n; + memcpy(ImmediateDataAddress(this), + _textures, ComputeDataSize(_n)); + } + + void* Set(void* cmd, GLsizei _n, GLuint* _textures) { + static_cast<ValueType*>(cmd)->Init(_n, _textures); + const uint32 size = ComputeSize(_n); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + command_buffer::CommandHeader header; + uint32 n; +}; + +COMPILE_ASSERT(sizeof(GenTexturesImmediate) == 8, + Sizeof_GenTexturesImmediate_is_not_8); +COMPILE_ASSERT(offsetof(GenTexturesImmediate, header) == 0, + OffsetOf_GenTexturesImmediate_header_not_0); +COMPILE_ASSERT(offsetof(GenTexturesImmediate, n) == 4, + OffsetOf_GenTexturesImmediate_n_not_4); + +struct GetActiveAttrib { + typedef GetActiveAttrib ValueType; + static const CommandId kCmdId = kGetActiveAttrib; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLuint _program, GLuint _index, GLsizei _bufsize, uint32 _length_shm_id, + uint32 _length_shm_offset, uint32 _size_shm_id, uint32 _size_shm_offset, + uint32 _type_shm_id, uint32 _type_shm_offset, uint32 _name_shm_id, + uint32 _name_shm_offset) { + SetHeader(); + program = _program; + index = _index; + bufsize = _bufsize; + length_shm_id = _length_shm_id; + length_shm_offset = _length_shm_offset; + size_shm_id = _size_shm_id; + size_shm_offset = _size_shm_offset; + type_shm_id = _type_shm_id; + type_shm_offset = _type_shm_offset; + name_shm_id = _name_shm_id; + name_shm_offset = _name_shm_offset; + } + + void* Set( + void* cmd, GLuint _program, GLuint _index, GLsizei _bufsize, + uint32 _length_shm_id, uint32 _length_shm_offset, uint32 _size_shm_id, + uint32 _size_shm_offset, uint32 _type_shm_id, uint32 _type_shm_offset, + uint32 _name_shm_id, uint32 _name_shm_offset) { + static_cast<ValueType*>( + cmd)->Init( + _program, _index, _bufsize, _length_shm_id, _length_shm_offset, + _size_shm_id, _size_shm_offset, _type_shm_id, _type_shm_offset, + _name_shm_id, _name_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 program; + uint32 index; + uint32 bufsize; + uint32 length_shm_id; + uint32 length_shm_offset; + uint32 size_shm_id; + uint32 size_shm_offset; + uint32 type_shm_id; + uint32 type_shm_offset; + uint32 name_shm_id; + uint32 name_shm_offset; +}; + +COMPILE_ASSERT(sizeof(GetActiveAttrib) == 48, + Sizeof_GetActiveAttrib_is_not_48); +COMPILE_ASSERT(offsetof(GetActiveAttrib, header) == 0, + OffsetOf_GetActiveAttrib_header_not_0); +COMPILE_ASSERT(offsetof(GetActiveAttrib, program) == 4, + OffsetOf_GetActiveAttrib_program_not_4); +COMPILE_ASSERT(offsetof(GetActiveAttrib, index) == 8, + OffsetOf_GetActiveAttrib_index_not_8); +COMPILE_ASSERT(offsetof(GetActiveAttrib, bufsize) == 12, + OffsetOf_GetActiveAttrib_bufsize_not_12); +COMPILE_ASSERT(offsetof(GetActiveAttrib, length_shm_id) == 16, + OffsetOf_GetActiveAttrib_length_shm_id_not_16); +COMPILE_ASSERT(offsetof(GetActiveAttrib, length_shm_offset) == 20, + OffsetOf_GetActiveAttrib_length_shm_offset_not_20); +COMPILE_ASSERT(offsetof(GetActiveAttrib, size_shm_id) == 24, + OffsetOf_GetActiveAttrib_size_shm_id_not_24); +COMPILE_ASSERT(offsetof(GetActiveAttrib, size_shm_offset) == 28, + OffsetOf_GetActiveAttrib_size_shm_offset_not_28); +COMPILE_ASSERT(offsetof(GetActiveAttrib, type_shm_id) == 32, + OffsetOf_GetActiveAttrib_type_shm_id_not_32); +COMPILE_ASSERT(offsetof(GetActiveAttrib, type_shm_offset) == 36, + OffsetOf_GetActiveAttrib_type_shm_offset_not_36); +COMPILE_ASSERT(offsetof(GetActiveAttrib, name_shm_id) == 40, + OffsetOf_GetActiveAttrib_name_shm_id_not_40); +COMPILE_ASSERT(offsetof(GetActiveAttrib, name_shm_offset) == 44, + OffsetOf_GetActiveAttrib_name_shm_offset_not_44); + +struct GetActiveUniform { + typedef GetActiveUniform ValueType; + static const CommandId kCmdId = kGetActiveUniform; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLuint _program, GLuint _index, GLsizei _bufsize, uint32 _length_shm_id, + uint32 _length_shm_offset, uint32 _size_shm_id, uint32 _size_shm_offset, + uint32 _type_shm_id, uint32 _type_shm_offset, uint32 _name_shm_id, + uint32 _name_shm_offset) { + SetHeader(); + program = _program; + index = _index; + bufsize = _bufsize; + length_shm_id = _length_shm_id; + length_shm_offset = _length_shm_offset; + size_shm_id = _size_shm_id; + size_shm_offset = _size_shm_offset; + type_shm_id = _type_shm_id; + type_shm_offset = _type_shm_offset; + name_shm_id = _name_shm_id; + name_shm_offset = _name_shm_offset; + } + + void* Set( + void* cmd, GLuint _program, GLuint _index, GLsizei _bufsize, + uint32 _length_shm_id, uint32 _length_shm_offset, uint32 _size_shm_id, + uint32 _size_shm_offset, uint32 _type_shm_id, uint32 _type_shm_offset, + uint32 _name_shm_id, uint32 _name_shm_offset) { + static_cast<ValueType*>( + cmd)->Init( + _program, _index, _bufsize, _length_shm_id, _length_shm_offset, + _size_shm_id, _size_shm_offset, _type_shm_id, _type_shm_offset, + _name_shm_id, _name_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 program; + uint32 index; + uint32 bufsize; + uint32 length_shm_id; + uint32 length_shm_offset; + uint32 size_shm_id; + uint32 size_shm_offset; + uint32 type_shm_id; + uint32 type_shm_offset; + uint32 name_shm_id; + uint32 name_shm_offset; +}; + +COMPILE_ASSERT(sizeof(GetActiveUniform) == 48, + Sizeof_GetActiveUniform_is_not_48); +COMPILE_ASSERT(offsetof(GetActiveUniform, header) == 0, + OffsetOf_GetActiveUniform_header_not_0); +COMPILE_ASSERT(offsetof(GetActiveUniform, program) == 4, + OffsetOf_GetActiveUniform_program_not_4); +COMPILE_ASSERT(offsetof(GetActiveUniform, index) == 8, + OffsetOf_GetActiveUniform_index_not_8); +COMPILE_ASSERT(offsetof(GetActiveUniform, bufsize) == 12, + OffsetOf_GetActiveUniform_bufsize_not_12); +COMPILE_ASSERT(offsetof(GetActiveUniform, length_shm_id) == 16, + OffsetOf_GetActiveUniform_length_shm_id_not_16); +COMPILE_ASSERT(offsetof(GetActiveUniform, length_shm_offset) == 20, + OffsetOf_GetActiveUniform_length_shm_offset_not_20); +COMPILE_ASSERT(offsetof(GetActiveUniform, size_shm_id) == 24, + OffsetOf_GetActiveUniform_size_shm_id_not_24); +COMPILE_ASSERT(offsetof(GetActiveUniform, size_shm_offset) == 28, + OffsetOf_GetActiveUniform_size_shm_offset_not_28); +COMPILE_ASSERT(offsetof(GetActiveUniform, type_shm_id) == 32, + OffsetOf_GetActiveUniform_type_shm_id_not_32); +COMPILE_ASSERT(offsetof(GetActiveUniform, type_shm_offset) == 36, + OffsetOf_GetActiveUniform_type_shm_offset_not_36); +COMPILE_ASSERT(offsetof(GetActiveUniform, name_shm_id) == 40, + OffsetOf_GetActiveUniform_name_shm_id_not_40); +COMPILE_ASSERT(offsetof(GetActiveUniform, name_shm_offset) == 44, + OffsetOf_GetActiveUniform_name_shm_offset_not_44); + +struct GetAttachedShaders { + typedef GetAttachedShaders ValueType; + static const CommandId kCmdId = kGetAttachedShaders; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLuint _program, GLsizei _maxcount, uint32 _count_shm_id, + uint32 _count_shm_offset, uint32 _shaders_shm_id, + uint32 _shaders_shm_offset) { + SetHeader(); + program = _program; + maxcount = _maxcount; + count_shm_id = _count_shm_id; + count_shm_offset = _count_shm_offset; + shaders_shm_id = _shaders_shm_id; + shaders_shm_offset = _shaders_shm_offset; + } + + void* Set( + void* cmd, GLuint _program, GLsizei _maxcount, uint32 _count_shm_id, + uint32 _count_shm_offset, uint32 _shaders_shm_id, + uint32 _shaders_shm_offset) { + static_cast<ValueType*>( + cmd)->Init( + _program, _maxcount, _count_shm_id, _count_shm_offset, + _shaders_shm_id, _shaders_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 program; + uint32 maxcount; + uint32 count_shm_id; + uint32 count_shm_offset; + uint32 shaders_shm_id; + uint32 shaders_shm_offset; +}; + +COMPILE_ASSERT(sizeof(GetAttachedShaders) == 28, + Sizeof_GetAttachedShaders_is_not_28); +COMPILE_ASSERT(offsetof(GetAttachedShaders, header) == 0, + OffsetOf_GetAttachedShaders_header_not_0); +COMPILE_ASSERT(offsetof(GetAttachedShaders, program) == 4, + OffsetOf_GetAttachedShaders_program_not_4); +COMPILE_ASSERT(offsetof(GetAttachedShaders, maxcount) == 8, + OffsetOf_GetAttachedShaders_maxcount_not_8); +COMPILE_ASSERT(offsetof(GetAttachedShaders, count_shm_id) == 12, + OffsetOf_GetAttachedShaders_count_shm_id_not_12); +COMPILE_ASSERT(offsetof(GetAttachedShaders, count_shm_offset) == 16, + OffsetOf_GetAttachedShaders_count_shm_offset_not_16); +COMPILE_ASSERT(offsetof(GetAttachedShaders, shaders_shm_id) == 20, + OffsetOf_GetAttachedShaders_shaders_shm_id_not_20); +COMPILE_ASSERT(offsetof(GetAttachedShaders, shaders_shm_offset) == 24, + OffsetOf_GetAttachedShaders_shaders_shm_offset_not_24); + +struct GetAttribLocation { + typedef GetAttribLocation ValueType; + static const CommandId kCmdId = kGetAttribLocation; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLuint _program, uint32 _name_shm_id, uint32 _name_shm_offset, + uint32 _data_size) { + SetHeader(); + program = _program; + name_shm_id = _name_shm_id; + name_shm_offset = _name_shm_offset; + data_size = _data_size; + } + + void* Set( + void* cmd, GLuint _program, uint32 _name_shm_id, uint32 _name_shm_offset, + uint32 _data_size) { + static_cast<ValueType*>( + cmd)->Init(_program, _name_shm_id, _name_shm_offset, _data_size); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 program; + uint32 name_shm_id; + uint32 name_shm_offset; + uint32 data_size; +}; + +COMPILE_ASSERT(sizeof(GetAttribLocation) == 20, + Sizeof_GetAttribLocation_is_not_20); +COMPILE_ASSERT(offsetof(GetAttribLocation, header) == 0, + OffsetOf_GetAttribLocation_header_not_0); +COMPILE_ASSERT(offsetof(GetAttribLocation, program) == 4, + OffsetOf_GetAttribLocation_program_not_4); +COMPILE_ASSERT(offsetof(GetAttribLocation, name_shm_id) == 8, + OffsetOf_GetAttribLocation_name_shm_id_not_8); +COMPILE_ASSERT(offsetof(GetAttribLocation, name_shm_offset) == 12, + OffsetOf_GetAttribLocation_name_shm_offset_not_12); +COMPILE_ASSERT(offsetof(GetAttribLocation, data_size) == 16, + OffsetOf_GetAttribLocation_data_size_not_16); + +struct GetAttribLocationImmediate { + typedef GetAttribLocationImmediate ValueType; + static const CommandId kCmdId = kGetAttribLocationImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeDataSize(const char* s) { + return strlen(s); + } + + static uint32 ComputeSize(const char* s) { + return static_cast<uint32>( + sizeof(ValueType) + ComputeDataSize(s)); // NOLINT + } + + void SetHeader(const char* s) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(s)); + } + + void Init(GLuint _program, const char* _name) { + SetHeader(_name); + program = _program; + data_size = strlen(_name); + memcpy(ImmediateDataAddress(this), _name, data_size); + } + + void* Set(void* cmd, GLuint _program, const char* _name) { + static_cast<ValueType*>(cmd)->Init(_program, _name); + const uint32 size = ComputeSize(_name); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + command_buffer::CommandHeader header; + uint32 program; + uint32 data_size; +}; + +COMPILE_ASSERT(sizeof(GetAttribLocationImmediate) == 12, + Sizeof_GetAttribLocationImmediate_is_not_12); +COMPILE_ASSERT(offsetof(GetAttribLocationImmediate, header) == 0, + OffsetOf_GetAttribLocationImmediate_header_not_0); +COMPILE_ASSERT(offsetof(GetAttribLocationImmediate, program) == 4, + OffsetOf_GetAttribLocationImmediate_program_not_4); +COMPILE_ASSERT(offsetof(GetAttribLocationImmediate, data_size) == 8, + OffsetOf_GetAttribLocationImmediate_data_size_not_8); + +struct GetBooleanv { + typedef GetBooleanv ValueType; + static const CommandId kCmdId = kGetBooleanv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _pname, uint32 _params_shm_id, uint32 _params_shm_offset) { + SetHeader(); + pname = _pname; + params_shm_id = _params_shm_id; + params_shm_offset = _params_shm_offset; + } + + void* Set( + void* cmd, GLenum _pname, uint32 _params_shm_id, + uint32 _params_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_pname, _params_shm_id, _params_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 pname; + uint32 params_shm_id; + uint32 params_shm_offset; +}; + +COMPILE_ASSERT(sizeof(GetBooleanv) == 16, + Sizeof_GetBooleanv_is_not_16); +COMPILE_ASSERT(offsetof(GetBooleanv, header) == 0, + OffsetOf_GetBooleanv_header_not_0); +COMPILE_ASSERT(offsetof(GetBooleanv, pname) == 4, + OffsetOf_GetBooleanv_pname_not_4); +COMPILE_ASSERT(offsetof(GetBooleanv, params_shm_id) == 8, + OffsetOf_GetBooleanv_params_shm_id_not_8); +COMPILE_ASSERT(offsetof(GetBooleanv, params_shm_offset) == 12, + OffsetOf_GetBooleanv_params_shm_offset_not_12); + +struct GetBufferParameteriv { + typedef GetBufferParameteriv ValueType; + static const CommandId kCmdId = kGetBufferParameteriv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLenum _target, GLenum _pname, uint32 _params_shm_id, + uint32 _params_shm_offset) { + SetHeader(); + target = _target; + pname = _pname; + params_shm_id = _params_shm_id; + params_shm_offset = _params_shm_offset; + } + + void* Set( + void* cmd, GLenum _target, GLenum _pname, uint32 _params_shm_id, + uint32 _params_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_target, _pname, _params_shm_id, _params_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 pname; + uint32 params_shm_id; + uint32 params_shm_offset; +}; + +COMPILE_ASSERT(sizeof(GetBufferParameteriv) == 20, + Sizeof_GetBufferParameteriv_is_not_20); +COMPILE_ASSERT(offsetof(GetBufferParameteriv, header) == 0, + OffsetOf_GetBufferParameteriv_header_not_0); +COMPILE_ASSERT(offsetof(GetBufferParameteriv, target) == 4, + OffsetOf_GetBufferParameteriv_target_not_4); +COMPILE_ASSERT(offsetof(GetBufferParameteriv, pname) == 8, + OffsetOf_GetBufferParameteriv_pname_not_8); +COMPILE_ASSERT(offsetof(GetBufferParameteriv, params_shm_id) == 12, + OffsetOf_GetBufferParameteriv_params_shm_id_not_12); +COMPILE_ASSERT(offsetof(GetBufferParameteriv, params_shm_offset) == 16, + OffsetOf_GetBufferParameteriv_params_shm_offset_not_16); + +struct GetError { + typedef GetError ValueType; + static const CommandId kCmdId = kGetError; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(uint32 _result_shm_id, uint32 _result_shm_offset) { + SetHeader(); + result_shm_id = _result_shm_id; + result_shm_offset = _result_shm_offset; + } + + void* Set(void* cmd, uint32 _result_shm_id, uint32 _result_shm_offset) { + static_cast<ValueType*>(cmd)->Init(_result_shm_id, _result_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 result_shm_id; + uint32 result_shm_offset; +}; + +COMPILE_ASSERT(sizeof(GetError) == 12, + Sizeof_GetError_is_not_12); +COMPILE_ASSERT(offsetof(GetError, header) == 0, + OffsetOf_GetError_header_not_0); +COMPILE_ASSERT(offsetof(GetError, result_shm_id) == 4, + OffsetOf_GetError_result_shm_id_not_4); +COMPILE_ASSERT(offsetof(GetError, result_shm_offset) == 8, + OffsetOf_GetError_result_shm_offset_not_8); + +struct GetFloatv { + typedef GetFloatv ValueType; + static const CommandId kCmdId = kGetFloatv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _pname, uint32 _params_shm_id, uint32 _params_shm_offset) { + SetHeader(); + pname = _pname; + params_shm_id = _params_shm_id; + params_shm_offset = _params_shm_offset; + } + + void* Set( + void* cmd, GLenum _pname, uint32 _params_shm_id, + uint32 _params_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_pname, _params_shm_id, _params_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 pname; + uint32 params_shm_id; + uint32 params_shm_offset; +}; + +COMPILE_ASSERT(sizeof(GetFloatv) == 16, + Sizeof_GetFloatv_is_not_16); +COMPILE_ASSERT(offsetof(GetFloatv, header) == 0, + OffsetOf_GetFloatv_header_not_0); +COMPILE_ASSERT(offsetof(GetFloatv, pname) == 4, + OffsetOf_GetFloatv_pname_not_4); +COMPILE_ASSERT(offsetof(GetFloatv, params_shm_id) == 8, + OffsetOf_GetFloatv_params_shm_id_not_8); +COMPILE_ASSERT(offsetof(GetFloatv, params_shm_offset) == 12, + OffsetOf_GetFloatv_params_shm_offset_not_12); + +struct GetFramebufferAttachmentParameteriv { + typedef GetFramebufferAttachmentParameteriv ValueType; + static const CommandId kCmdId = kGetFramebufferAttachmentParameteriv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLenum _target, GLenum _attachment, GLenum _pname, uint32 _params_shm_id, + uint32 _params_shm_offset) { + SetHeader(); + target = _target; + attachment = _attachment; + pname = _pname; + params_shm_id = _params_shm_id; + params_shm_offset = _params_shm_offset; + } + + void* Set( + void* cmd, GLenum _target, GLenum _attachment, GLenum _pname, + uint32 _params_shm_id, uint32 _params_shm_offset) { + static_cast<ValueType*>( + cmd)->Init( + _target, _attachment, _pname, _params_shm_id, _params_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 attachment; + uint32 pname; + uint32 params_shm_id; + uint32 params_shm_offset; +}; + +COMPILE_ASSERT(sizeof(GetFramebufferAttachmentParameteriv) == 24, + Sizeof_GetFramebufferAttachmentParameteriv_is_not_24); +COMPILE_ASSERT(offsetof(GetFramebufferAttachmentParameteriv, header) == 0, + OffsetOf_GetFramebufferAttachmentParameteriv_header_not_0); +COMPILE_ASSERT(offsetof(GetFramebufferAttachmentParameteriv, target) == 4, + OffsetOf_GetFramebufferAttachmentParameteriv_target_not_4); +COMPILE_ASSERT(offsetof(GetFramebufferAttachmentParameteriv, attachment) == 8, + OffsetOf_GetFramebufferAttachmentParameteriv_attachment_not_8); +COMPILE_ASSERT(offsetof(GetFramebufferAttachmentParameteriv, pname) == 12, + OffsetOf_GetFramebufferAttachmentParameteriv_pname_not_12); +COMPILE_ASSERT( + offsetof(GetFramebufferAttachmentParameteriv, params_shm_id) == 16, + OffsetOf_GetFramebufferAttachmentParameteriv_params_shm_id_not_16); +COMPILE_ASSERT( + offsetof(GetFramebufferAttachmentParameteriv, params_shm_offset) == 20, + OffsetOf_GetFramebufferAttachmentParameteriv_params_shm_offset_not_20); + +struct GetIntegerv { + typedef GetIntegerv ValueType; + static const CommandId kCmdId = kGetIntegerv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _pname, uint32 _params_shm_id, uint32 _params_shm_offset) { + SetHeader(); + pname = _pname; + params_shm_id = _params_shm_id; + params_shm_offset = _params_shm_offset; + } + + void* Set( + void* cmd, GLenum _pname, uint32 _params_shm_id, + uint32 _params_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_pname, _params_shm_id, _params_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 pname; + uint32 params_shm_id; + uint32 params_shm_offset; +}; + +COMPILE_ASSERT(sizeof(GetIntegerv) == 16, + Sizeof_GetIntegerv_is_not_16); +COMPILE_ASSERT(offsetof(GetIntegerv, header) == 0, + OffsetOf_GetIntegerv_header_not_0); +COMPILE_ASSERT(offsetof(GetIntegerv, pname) == 4, + OffsetOf_GetIntegerv_pname_not_4); +COMPILE_ASSERT(offsetof(GetIntegerv, params_shm_id) == 8, + OffsetOf_GetIntegerv_params_shm_id_not_8); +COMPILE_ASSERT(offsetof(GetIntegerv, params_shm_offset) == 12, + OffsetOf_GetIntegerv_params_shm_offset_not_12); + +struct GetProgramiv { + typedef GetProgramiv ValueType; + static const CommandId kCmdId = kGetProgramiv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLuint _program, GLenum _pname, uint32 _params_shm_id, + uint32 _params_shm_offset) { + SetHeader(); + program = _program; + pname = _pname; + params_shm_id = _params_shm_id; + params_shm_offset = _params_shm_offset; + } + + void* Set( + void* cmd, GLuint _program, GLenum _pname, uint32 _params_shm_id, + uint32 _params_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_program, _pname, _params_shm_id, _params_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 program; + uint32 pname; + uint32 params_shm_id; + uint32 params_shm_offset; +}; + +COMPILE_ASSERT(sizeof(GetProgramiv) == 20, + Sizeof_GetProgramiv_is_not_20); +COMPILE_ASSERT(offsetof(GetProgramiv, header) == 0, + OffsetOf_GetProgramiv_header_not_0); +COMPILE_ASSERT(offsetof(GetProgramiv, program) == 4, + OffsetOf_GetProgramiv_program_not_4); +COMPILE_ASSERT(offsetof(GetProgramiv, pname) == 8, + OffsetOf_GetProgramiv_pname_not_8); +COMPILE_ASSERT(offsetof(GetProgramiv, params_shm_id) == 12, + OffsetOf_GetProgramiv_params_shm_id_not_12); +COMPILE_ASSERT(offsetof(GetProgramiv, params_shm_offset) == 16, + OffsetOf_GetProgramiv_params_shm_offset_not_16); + +struct GetProgramInfoLog { + typedef GetProgramInfoLog ValueType; + static const CommandId kCmdId = kGetProgramInfoLog; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLuint _program, GLsizei _bufsize, uint32 _length_shm_id, + uint32 _length_shm_offset, uint32 _infolog_shm_id, + uint32 _infolog_shm_offset) { + SetHeader(); + program = _program; + bufsize = _bufsize; + length_shm_id = _length_shm_id; + length_shm_offset = _length_shm_offset; + infolog_shm_id = _infolog_shm_id; + infolog_shm_offset = _infolog_shm_offset; + } + + void* Set( + void* cmd, GLuint _program, GLsizei _bufsize, uint32 _length_shm_id, + uint32 _length_shm_offset, uint32 _infolog_shm_id, + uint32 _infolog_shm_offset) { + static_cast<ValueType*>( + cmd)->Init( + _program, _bufsize, _length_shm_id, _length_shm_offset, + _infolog_shm_id, _infolog_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 program; + uint32 bufsize; + uint32 length_shm_id; + uint32 length_shm_offset; + uint32 infolog_shm_id; + uint32 infolog_shm_offset; +}; + +COMPILE_ASSERT(sizeof(GetProgramInfoLog) == 28, + Sizeof_GetProgramInfoLog_is_not_28); +COMPILE_ASSERT(offsetof(GetProgramInfoLog, header) == 0, + OffsetOf_GetProgramInfoLog_header_not_0); +COMPILE_ASSERT(offsetof(GetProgramInfoLog, program) == 4, + OffsetOf_GetProgramInfoLog_program_not_4); +COMPILE_ASSERT(offsetof(GetProgramInfoLog, bufsize) == 8, + OffsetOf_GetProgramInfoLog_bufsize_not_8); +COMPILE_ASSERT(offsetof(GetProgramInfoLog, length_shm_id) == 12, + OffsetOf_GetProgramInfoLog_length_shm_id_not_12); +COMPILE_ASSERT(offsetof(GetProgramInfoLog, length_shm_offset) == 16, + OffsetOf_GetProgramInfoLog_length_shm_offset_not_16); +COMPILE_ASSERT(offsetof(GetProgramInfoLog, infolog_shm_id) == 20, + OffsetOf_GetProgramInfoLog_infolog_shm_id_not_20); +COMPILE_ASSERT(offsetof(GetProgramInfoLog, infolog_shm_offset) == 24, + OffsetOf_GetProgramInfoLog_infolog_shm_offset_not_24); + +struct GetRenderbufferParameteriv { + typedef GetRenderbufferParameteriv ValueType; + static const CommandId kCmdId = kGetRenderbufferParameteriv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLenum _target, GLenum _pname, uint32 _params_shm_id, + uint32 _params_shm_offset) { + SetHeader(); + target = _target; + pname = _pname; + params_shm_id = _params_shm_id; + params_shm_offset = _params_shm_offset; + } + + void* Set( + void* cmd, GLenum _target, GLenum _pname, uint32 _params_shm_id, + uint32 _params_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_target, _pname, _params_shm_id, _params_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 pname; + uint32 params_shm_id; + uint32 params_shm_offset; +}; + +COMPILE_ASSERT(sizeof(GetRenderbufferParameteriv) == 20, + Sizeof_GetRenderbufferParameteriv_is_not_20); +COMPILE_ASSERT(offsetof(GetRenderbufferParameteriv, header) == 0, + OffsetOf_GetRenderbufferParameteriv_header_not_0); +COMPILE_ASSERT(offsetof(GetRenderbufferParameteriv, target) == 4, + OffsetOf_GetRenderbufferParameteriv_target_not_4); +COMPILE_ASSERT(offsetof(GetRenderbufferParameteriv, pname) == 8, + OffsetOf_GetRenderbufferParameteriv_pname_not_8); +COMPILE_ASSERT(offsetof(GetRenderbufferParameteriv, params_shm_id) == 12, + OffsetOf_GetRenderbufferParameteriv_params_shm_id_not_12); +COMPILE_ASSERT(offsetof(GetRenderbufferParameteriv, params_shm_offset) == 16, + OffsetOf_GetRenderbufferParameteriv_params_shm_offset_not_16); + +struct GetShaderiv { + typedef GetShaderiv ValueType; + static const CommandId kCmdId = kGetShaderiv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLuint _shader, GLenum _pname, uint32 _params_shm_id, + uint32 _params_shm_offset) { + SetHeader(); + shader = _shader; + pname = _pname; + params_shm_id = _params_shm_id; + params_shm_offset = _params_shm_offset; + } + + void* Set( + void* cmd, GLuint _shader, GLenum _pname, uint32 _params_shm_id, + uint32 _params_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_shader, _pname, _params_shm_id, _params_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 shader; + uint32 pname; + uint32 params_shm_id; + uint32 params_shm_offset; +}; + +COMPILE_ASSERT(sizeof(GetShaderiv) == 20, + Sizeof_GetShaderiv_is_not_20); +COMPILE_ASSERT(offsetof(GetShaderiv, header) == 0, + OffsetOf_GetShaderiv_header_not_0); +COMPILE_ASSERT(offsetof(GetShaderiv, shader) == 4, + OffsetOf_GetShaderiv_shader_not_4); +COMPILE_ASSERT(offsetof(GetShaderiv, pname) == 8, + OffsetOf_GetShaderiv_pname_not_8); +COMPILE_ASSERT(offsetof(GetShaderiv, params_shm_id) == 12, + OffsetOf_GetShaderiv_params_shm_id_not_12); +COMPILE_ASSERT(offsetof(GetShaderiv, params_shm_offset) == 16, + OffsetOf_GetShaderiv_params_shm_offset_not_16); + +struct GetShaderInfoLog { + typedef GetShaderInfoLog ValueType; + static const CommandId kCmdId = kGetShaderInfoLog; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLuint _shader, GLsizei _bufsize, uint32 _length_shm_id, + uint32 _length_shm_offset, uint32 _infolog_shm_id, + uint32 _infolog_shm_offset) { + SetHeader(); + shader = _shader; + bufsize = _bufsize; + length_shm_id = _length_shm_id; + length_shm_offset = _length_shm_offset; + infolog_shm_id = _infolog_shm_id; + infolog_shm_offset = _infolog_shm_offset; + } + + void* Set( + void* cmd, GLuint _shader, GLsizei _bufsize, uint32 _length_shm_id, + uint32 _length_shm_offset, uint32 _infolog_shm_id, + uint32 _infolog_shm_offset) { + static_cast<ValueType*>( + cmd)->Init( + _shader, _bufsize, _length_shm_id, _length_shm_offset, + _infolog_shm_id, _infolog_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 shader; + uint32 bufsize; + uint32 length_shm_id; + uint32 length_shm_offset; + uint32 infolog_shm_id; + uint32 infolog_shm_offset; +}; + +COMPILE_ASSERT(sizeof(GetShaderInfoLog) == 28, + Sizeof_GetShaderInfoLog_is_not_28); +COMPILE_ASSERT(offsetof(GetShaderInfoLog, header) == 0, + OffsetOf_GetShaderInfoLog_header_not_0); +COMPILE_ASSERT(offsetof(GetShaderInfoLog, shader) == 4, + OffsetOf_GetShaderInfoLog_shader_not_4); +COMPILE_ASSERT(offsetof(GetShaderInfoLog, bufsize) == 8, + OffsetOf_GetShaderInfoLog_bufsize_not_8); +COMPILE_ASSERT(offsetof(GetShaderInfoLog, length_shm_id) == 12, + OffsetOf_GetShaderInfoLog_length_shm_id_not_12); +COMPILE_ASSERT(offsetof(GetShaderInfoLog, length_shm_offset) == 16, + OffsetOf_GetShaderInfoLog_length_shm_offset_not_16); +COMPILE_ASSERT(offsetof(GetShaderInfoLog, infolog_shm_id) == 20, + OffsetOf_GetShaderInfoLog_infolog_shm_id_not_20); +COMPILE_ASSERT(offsetof(GetShaderInfoLog, infolog_shm_offset) == 24, + OffsetOf_GetShaderInfoLog_infolog_shm_offset_not_24); + +struct GetShaderPrecisionFormat { + typedef GetShaderPrecisionFormat ValueType; + static const CommandId kCmdId = kGetShaderPrecisionFormat; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLenum _shadertype, GLenum _precisiontype, uint32 _range_shm_id, + uint32 _range_shm_offset, uint32 _precision_shm_id, + uint32 _precision_shm_offset) { + SetHeader(); + shadertype = _shadertype; + precisiontype = _precisiontype; + range_shm_id = _range_shm_id; + range_shm_offset = _range_shm_offset; + precision_shm_id = _precision_shm_id; + precision_shm_offset = _precision_shm_offset; + } + + void* Set( + void* cmd, GLenum _shadertype, GLenum _precisiontype, + uint32 _range_shm_id, uint32 _range_shm_offset, uint32 _precision_shm_id, + uint32 _precision_shm_offset) { + static_cast<ValueType*>( + cmd)->Init( + _shadertype, _precisiontype, _range_shm_id, _range_shm_offset, + _precision_shm_id, _precision_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 shadertype; + uint32 precisiontype; + uint32 range_shm_id; + uint32 range_shm_offset; + uint32 precision_shm_id; + uint32 precision_shm_offset; +}; + +COMPILE_ASSERT(sizeof(GetShaderPrecisionFormat) == 28, + Sizeof_GetShaderPrecisionFormat_is_not_28); +COMPILE_ASSERT(offsetof(GetShaderPrecisionFormat, header) == 0, + OffsetOf_GetShaderPrecisionFormat_header_not_0); +COMPILE_ASSERT(offsetof(GetShaderPrecisionFormat, shadertype) == 4, + OffsetOf_GetShaderPrecisionFormat_shadertype_not_4); +COMPILE_ASSERT(offsetof(GetShaderPrecisionFormat, precisiontype) == 8, + OffsetOf_GetShaderPrecisionFormat_precisiontype_not_8); +COMPILE_ASSERT(offsetof(GetShaderPrecisionFormat, range_shm_id) == 12, + OffsetOf_GetShaderPrecisionFormat_range_shm_id_not_12); +COMPILE_ASSERT(offsetof(GetShaderPrecisionFormat, range_shm_offset) == 16, + OffsetOf_GetShaderPrecisionFormat_range_shm_offset_not_16); +COMPILE_ASSERT(offsetof(GetShaderPrecisionFormat, precision_shm_id) == 20, + OffsetOf_GetShaderPrecisionFormat_precision_shm_id_not_20); +COMPILE_ASSERT(offsetof(GetShaderPrecisionFormat, precision_shm_offset) == 24, + OffsetOf_GetShaderPrecisionFormat_precision_shm_offset_not_24); + +struct GetShaderSource { + typedef GetShaderSource ValueType; + static const CommandId kCmdId = kGetShaderSource; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLuint _shader, GLsizei _bufsize, uint32 _length_shm_id, + uint32 _length_shm_offset, uint32 _source_shm_id, + uint32 _source_shm_offset) { + SetHeader(); + shader = _shader; + bufsize = _bufsize; + length_shm_id = _length_shm_id; + length_shm_offset = _length_shm_offset; + source_shm_id = _source_shm_id; + source_shm_offset = _source_shm_offset; + } + + void* Set( + void* cmd, GLuint _shader, GLsizei _bufsize, uint32 _length_shm_id, + uint32 _length_shm_offset, uint32 _source_shm_id, + uint32 _source_shm_offset) { + static_cast<ValueType*>( + cmd)->Init( + _shader, _bufsize, _length_shm_id, _length_shm_offset, + _source_shm_id, _source_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 shader; + uint32 bufsize; + uint32 length_shm_id; + uint32 length_shm_offset; + uint32 source_shm_id; + uint32 source_shm_offset; +}; + +COMPILE_ASSERT(sizeof(GetShaderSource) == 28, + Sizeof_GetShaderSource_is_not_28); +COMPILE_ASSERT(offsetof(GetShaderSource, header) == 0, + OffsetOf_GetShaderSource_header_not_0); +COMPILE_ASSERT(offsetof(GetShaderSource, shader) == 4, + OffsetOf_GetShaderSource_shader_not_4); +COMPILE_ASSERT(offsetof(GetShaderSource, bufsize) == 8, + OffsetOf_GetShaderSource_bufsize_not_8); +COMPILE_ASSERT(offsetof(GetShaderSource, length_shm_id) == 12, + OffsetOf_GetShaderSource_length_shm_id_not_12); +COMPILE_ASSERT(offsetof(GetShaderSource, length_shm_offset) == 16, + OffsetOf_GetShaderSource_length_shm_offset_not_16); +COMPILE_ASSERT(offsetof(GetShaderSource, source_shm_id) == 20, + OffsetOf_GetShaderSource_source_shm_id_not_20); +COMPILE_ASSERT(offsetof(GetShaderSource, source_shm_offset) == 24, + OffsetOf_GetShaderSource_source_shm_offset_not_24); + +struct GetString { + typedef GetString ValueType; + static const CommandId kCmdId = kGetString; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _name) { + SetHeader(); + name = _name; + } + + void* Set(void* cmd, GLenum _name) { + static_cast<ValueType*>(cmd)->Init(_name); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 name; +}; + +COMPILE_ASSERT(sizeof(GetString) == 8, + Sizeof_GetString_is_not_8); +COMPILE_ASSERT(offsetof(GetString, header) == 0, + OffsetOf_GetString_header_not_0); +COMPILE_ASSERT(offsetof(GetString, name) == 4, + OffsetOf_GetString_name_not_4); + +struct GetTexParameterfv { + typedef GetTexParameterfv ValueType; + static const CommandId kCmdId = kGetTexParameterfv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLenum _target, GLenum _pname, uint32 _params_shm_id, + uint32 _params_shm_offset) { + SetHeader(); + target = _target; + pname = _pname; + params_shm_id = _params_shm_id; + params_shm_offset = _params_shm_offset; + } + + void* Set( + void* cmd, GLenum _target, GLenum _pname, uint32 _params_shm_id, + uint32 _params_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_target, _pname, _params_shm_id, _params_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 pname; + uint32 params_shm_id; + uint32 params_shm_offset; +}; + +COMPILE_ASSERT(sizeof(GetTexParameterfv) == 20, + Sizeof_GetTexParameterfv_is_not_20); +COMPILE_ASSERT(offsetof(GetTexParameterfv, header) == 0, + OffsetOf_GetTexParameterfv_header_not_0); +COMPILE_ASSERT(offsetof(GetTexParameterfv, target) == 4, + OffsetOf_GetTexParameterfv_target_not_4); +COMPILE_ASSERT(offsetof(GetTexParameterfv, pname) == 8, + OffsetOf_GetTexParameterfv_pname_not_8); +COMPILE_ASSERT(offsetof(GetTexParameterfv, params_shm_id) == 12, + OffsetOf_GetTexParameterfv_params_shm_id_not_12); +COMPILE_ASSERT(offsetof(GetTexParameterfv, params_shm_offset) == 16, + OffsetOf_GetTexParameterfv_params_shm_offset_not_16); + +struct GetTexParameteriv { + typedef GetTexParameteriv ValueType; + static const CommandId kCmdId = kGetTexParameteriv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLenum _target, GLenum _pname, uint32 _params_shm_id, + uint32 _params_shm_offset) { + SetHeader(); + target = _target; + pname = _pname; + params_shm_id = _params_shm_id; + params_shm_offset = _params_shm_offset; + } + + void* Set( + void* cmd, GLenum _target, GLenum _pname, uint32 _params_shm_id, + uint32 _params_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_target, _pname, _params_shm_id, _params_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 pname; + uint32 params_shm_id; + uint32 params_shm_offset; +}; + +COMPILE_ASSERT(sizeof(GetTexParameteriv) == 20, + Sizeof_GetTexParameteriv_is_not_20); +COMPILE_ASSERT(offsetof(GetTexParameteriv, header) == 0, + OffsetOf_GetTexParameteriv_header_not_0); +COMPILE_ASSERT(offsetof(GetTexParameteriv, target) == 4, + OffsetOf_GetTexParameteriv_target_not_4); +COMPILE_ASSERT(offsetof(GetTexParameteriv, pname) == 8, + OffsetOf_GetTexParameteriv_pname_not_8); +COMPILE_ASSERT(offsetof(GetTexParameteriv, params_shm_id) == 12, + OffsetOf_GetTexParameteriv_params_shm_id_not_12); +COMPILE_ASSERT(offsetof(GetTexParameteriv, params_shm_offset) == 16, + OffsetOf_GetTexParameteriv_params_shm_offset_not_16); + +struct GetUniformfv { + typedef GetUniformfv ValueType; + static const CommandId kCmdId = kGetUniformfv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLuint _program, GLint _location, uint32 _params_shm_id, + uint32 _params_shm_offset) { + SetHeader(); + program = _program; + location = _location; + params_shm_id = _params_shm_id; + params_shm_offset = _params_shm_offset; + } + + void* Set( + void* cmd, GLuint _program, GLint _location, uint32 _params_shm_id, + uint32 _params_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_program, _location, _params_shm_id, _params_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 program; + uint32 location; + uint32 params_shm_id; + uint32 params_shm_offset; +}; + +COMPILE_ASSERT(sizeof(GetUniformfv) == 20, + Sizeof_GetUniformfv_is_not_20); +COMPILE_ASSERT(offsetof(GetUniformfv, header) == 0, + OffsetOf_GetUniformfv_header_not_0); +COMPILE_ASSERT(offsetof(GetUniformfv, program) == 4, + OffsetOf_GetUniformfv_program_not_4); +COMPILE_ASSERT(offsetof(GetUniformfv, location) == 8, + OffsetOf_GetUniformfv_location_not_8); +COMPILE_ASSERT(offsetof(GetUniformfv, params_shm_id) == 12, + OffsetOf_GetUniformfv_params_shm_id_not_12); +COMPILE_ASSERT(offsetof(GetUniformfv, params_shm_offset) == 16, + OffsetOf_GetUniformfv_params_shm_offset_not_16); + +struct GetUniformiv { + typedef GetUniformiv ValueType; + static const CommandId kCmdId = kGetUniformiv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLuint _program, GLint _location, uint32 _params_shm_id, + uint32 _params_shm_offset) { + SetHeader(); + program = _program; + location = _location; + params_shm_id = _params_shm_id; + params_shm_offset = _params_shm_offset; + } + + void* Set( + void* cmd, GLuint _program, GLint _location, uint32 _params_shm_id, + uint32 _params_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_program, _location, _params_shm_id, _params_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 program; + uint32 location; + uint32 params_shm_id; + uint32 params_shm_offset; +}; + +COMPILE_ASSERT(sizeof(GetUniformiv) == 20, + Sizeof_GetUniformiv_is_not_20); +COMPILE_ASSERT(offsetof(GetUniformiv, header) == 0, + OffsetOf_GetUniformiv_header_not_0); +COMPILE_ASSERT(offsetof(GetUniformiv, program) == 4, + OffsetOf_GetUniformiv_program_not_4); +COMPILE_ASSERT(offsetof(GetUniformiv, location) == 8, + OffsetOf_GetUniformiv_location_not_8); +COMPILE_ASSERT(offsetof(GetUniformiv, params_shm_id) == 12, + OffsetOf_GetUniformiv_params_shm_id_not_12); +COMPILE_ASSERT(offsetof(GetUniformiv, params_shm_offset) == 16, + OffsetOf_GetUniformiv_params_shm_offset_not_16); + +struct GetUniformLocation { + typedef GetUniformLocation ValueType; + static const CommandId kCmdId = kGetUniformLocation; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLuint _program, uint32 _name_shm_id, uint32 _name_shm_offset, + uint32 _data_size) { + SetHeader(); + program = _program; + name_shm_id = _name_shm_id; + name_shm_offset = _name_shm_offset; + data_size = _data_size; + } + + void* Set( + void* cmd, GLuint _program, uint32 _name_shm_id, uint32 _name_shm_offset, + uint32 _data_size) { + static_cast<ValueType*>( + cmd)->Init(_program, _name_shm_id, _name_shm_offset, _data_size); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 program; + uint32 name_shm_id; + uint32 name_shm_offset; + uint32 data_size; +}; + +COMPILE_ASSERT(sizeof(GetUniformLocation) == 20, + Sizeof_GetUniformLocation_is_not_20); +COMPILE_ASSERT(offsetof(GetUniformLocation, header) == 0, + OffsetOf_GetUniformLocation_header_not_0); +COMPILE_ASSERT(offsetof(GetUniformLocation, program) == 4, + OffsetOf_GetUniformLocation_program_not_4); +COMPILE_ASSERT(offsetof(GetUniformLocation, name_shm_id) == 8, + OffsetOf_GetUniformLocation_name_shm_id_not_8); +COMPILE_ASSERT(offsetof(GetUniformLocation, name_shm_offset) == 12, + OffsetOf_GetUniformLocation_name_shm_offset_not_12); +COMPILE_ASSERT(offsetof(GetUniformLocation, data_size) == 16, + OffsetOf_GetUniformLocation_data_size_not_16); + +struct GetUniformLocationImmediate { + typedef GetUniformLocationImmediate ValueType; + static const CommandId kCmdId = kGetUniformLocationImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeDataSize(const char* s) { + return strlen(s); + } + + static uint32 ComputeSize(const char* s) { + return static_cast<uint32>( + sizeof(ValueType) + ComputeDataSize(s)); // NOLINT + } + + void SetHeader(const char* s) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(s)); + } + + void Init(GLuint _program, const char* _name) { + SetHeader(_name); + program = _program; + data_size = strlen(_name); + memcpy(ImmediateDataAddress(this), _name, data_size); + } + + void* Set(void* cmd, GLuint _program, const char* _name) { + static_cast<ValueType*>(cmd)->Init(_program, _name); + const uint32 size = ComputeSize(_name); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + command_buffer::CommandHeader header; + uint32 program; + uint32 data_size; +}; + +COMPILE_ASSERT(sizeof(GetUniformLocationImmediate) == 12, + Sizeof_GetUniformLocationImmediate_is_not_12); +COMPILE_ASSERT(offsetof(GetUniformLocationImmediate, header) == 0, + OffsetOf_GetUniformLocationImmediate_header_not_0); +COMPILE_ASSERT(offsetof(GetUniformLocationImmediate, program) == 4, + OffsetOf_GetUniformLocationImmediate_program_not_4); +COMPILE_ASSERT(offsetof(GetUniformLocationImmediate, data_size) == 8, + OffsetOf_GetUniformLocationImmediate_data_size_not_8); + +struct GetVertexAttribfv { + typedef GetVertexAttribfv ValueType; + static const CommandId kCmdId = kGetVertexAttribfv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLuint _index, GLenum _pname, uint32 _params_shm_id, + uint32 _params_shm_offset) { + SetHeader(); + index = _index; + pname = _pname; + params_shm_id = _params_shm_id; + params_shm_offset = _params_shm_offset; + } + + void* Set( + void* cmd, GLuint _index, GLenum _pname, uint32 _params_shm_id, + uint32 _params_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_index, _pname, _params_shm_id, _params_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 index; + uint32 pname; + uint32 params_shm_id; + uint32 params_shm_offset; +}; + +COMPILE_ASSERT(sizeof(GetVertexAttribfv) == 20, + Sizeof_GetVertexAttribfv_is_not_20); +COMPILE_ASSERT(offsetof(GetVertexAttribfv, header) == 0, + OffsetOf_GetVertexAttribfv_header_not_0); +COMPILE_ASSERT(offsetof(GetVertexAttribfv, index) == 4, + OffsetOf_GetVertexAttribfv_index_not_4); +COMPILE_ASSERT(offsetof(GetVertexAttribfv, pname) == 8, + OffsetOf_GetVertexAttribfv_pname_not_8); +COMPILE_ASSERT(offsetof(GetVertexAttribfv, params_shm_id) == 12, + OffsetOf_GetVertexAttribfv_params_shm_id_not_12); +COMPILE_ASSERT(offsetof(GetVertexAttribfv, params_shm_offset) == 16, + OffsetOf_GetVertexAttribfv_params_shm_offset_not_16); + +struct GetVertexAttribiv { + typedef GetVertexAttribiv ValueType; + static const CommandId kCmdId = kGetVertexAttribiv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLuint _index, GLenum _pname, uint32 _params_shm_id, + uint32 _params_shm_offset) { + SetHeader(); + index = _index; + pname = _pname; + params_shm_id = _params_shm_id; + params_shm_offset = _params_shm_offset; + } + + void* Set( + void* cmd, GLuint _index, GLenum _pname, uint32 _params_shm_id, + uint32 _params_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_index, _pname, _params_shm_id, _params_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 index; + uint32 pname; + uint32 params_shm_id; + uint32 params_shm_offset; +}; + +COMPILE_ASSERT(sizeof(GetVertexAttribiv) == 20, + Sizeof_GetVertexAttribiv_is_not_20); +COMPILE_ASSERT(offsetof(GetVertexAttribiv, header) == 0, + OffsetOf_GetVertexAttribiv_header_not_0); +COMPILE_ASSERT(offsetof(GetVertexAttribiv, index) == 4, + OffsetOf_GetVertexAttribiv_index_not_4); +COMPILE_ASSERT(offsetof(GetVertexAttribiv, pname) == 8, + OffsetOf_GetVertexAttribiv_pname_not_8); +COMPILE_ASSERT(offsetof(GetVertexAttribiv, params_shm_id) == 12, + OffsetOf_GetVertexAttribiv_params_shm_id_not_12); +COMPILE_ASSERT(offsetof(GetVertexAttribiv, params_shm_offset) == 16, + OffsetOf_GetVertexAttribiv_params_shm_offset_not_16); + +struct GetVertexAttribPointerv { + typedef GetVertexAttribPointerv ValueType; + static const CommandId kCmdId = kGetVertexAttribPointerv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLuint _index, GLenum _pname, uint32 _pointer_shm_id, + uint32 _pointer_shm_offset) { + SetHeader(); + index = _index; + pname = _pname; + pointer_shm_id = _pointer_shm_id; + pointer_shm_offset = _pointer_shm_offset; + } + + void* Set( + void* cmd, GLuint _index, GLenum _pname, uint32 _pointer_shm_id, + uint32 _pointer_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_index, _pname, _pointer_shm_id, _pointer_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 index; + uint32 pname; + uint32 pointer_shm_id; + uint32 pointer_shm_offset; +}; + +COMPILE_ASSERT(sizeof(GetVertexAttribPointerv) == 20, + Sizeof_GetVertexAttribPointerv_is_not_20); +COMPILE_ASSERT(offsetof(GetVertexAttribPointerv, header) == 0, + OffsetOf_GetVertexAttribPointerv_header_not_0); +COMPILE_ASSERT(offsetof(GetVertexAttribPointerv, index) == 4, + OffsetOf_GetVertexAttribPointerv_index_not_4); +COMPILE_ASSERT(offsetof(GetVertexAttribPointerv, pname) == 8, + OffsetOf_GetVertexAttribPointerv_pname_not_8); +COMPILE_ASSERT(offsetof(GetVertexAttribPointerv, pointer_shm_id) == 12, + OffsetOf_GetVertexAttribPointerv_pointer_shm_id_not_12); +COMPILE_ASSERT(offsetof(GetVertexAttribPointerv, pointer_shm_offset) == 16, + OffsetOf_GetVertexAttribPointerv_pointer_shm_offset_not_16); + +struct Hint { + typedef Hint ValueType; + static const CommandId kCmdId = kHint; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _target, GLenum _mode) { + SetHeader(); + target = _target; + mode = _mode; + } + + void* Set(void* cmd, GLenum _target, GLenum _mode) { + static_cast<ValueType*>(cmd)->Init(_target, _mode); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 mode; +}; + +COMPILE_ASSERT(sizeof(Hint) == 12, + Sizeof_Hint_is_not_12); +COMPILE_ASSERT(offsetof(Hint, header) == 0, + OffsetOf_Hint_header_not_0); +COMPILE_ASSERT(offsetof(Hint, target) == 4, + OffsetOf_Hint_target_not_4); +COMPILE_ASSERT(offsetof(Hint, mode) == 8, + OffsetOf_Hint_mode_not_8); + +struct IsBuffer { + typedef IsBuffer ValueType; + static const CommandId kCmdId = kIsBuffer; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLuint _buffer, uint32 _result_shm_id, uint32 _result_shm_offset) { + SetHeader(); + buffer = _buffer; + result_shm_id = _result_shm_id; + result_shm_offset = _result_shm_offset; + } + + void* Set( + void* cmd, GLuint _buffer, uint32 _result_shm_id, + uint32 _result_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_buffer, _result_shm_id, _result_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 buffer; + uint32 result_shm_id; + uint32 result_shm_offset; +}; + +COMPILE_ASSERT(sizeof(IsBuffer) == 16, + Sizeof_IsBuffer_is_not_16); +COMPILE_ASSERT(offsetof(IsBuffer, header) == 0, + OffsetOf_IsBuffer_header_not_0); +COMPILE_ASSERT(offsetof(IsBuffer, buffer) == 4, + OffsetOf_IsBuffer_buffer_not_4); +COMPILE_ASSERT(offsetof(IsBuffer, result_shm_id) == 8, + OffsetOf_IsBuffer_result_shm_id_not_8); +COMPILE_ASSERT(offsetof(IsBuffer, result_shm_offset) == 12, + OffsetOf_IsBuffer_result_shm_offset_not_12); + +struct IsEnabled { + typedef IsEnabled ValueType; + static const CommandId kCmdId = kIsEnabled; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _cap, uint32 _result_shm_id, uint32 _result_shm_offset) { + SetHeader(); + cap = _cap; + result_shm_id = _result_shm_id; + result_shm_offset = _result_shm_offset; + } + + void* Set( + void* cmd, GLenum _cap, uint32 _result_shm_id, + uint32 _result_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_cap, _result_shm_id, _result_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 cap; + uint32 result_shm_id; + uint32 result_shm_offset; +}; + +COMPILE_ASSERT(sizeof(IsEnabled) == 16, + Sizeof_IsEnabled_is_not_16); +COMPILE_ASSERT(offsetof(IsEnabled, header) == 0, + OffsetOf_IsEnabled_header_not_0); +COMPILE_ASSERT(offsetof(IsEnabled, cap) == 4, + OffsetOf_IsEnabled_cap_not_4); +COMPILE_ASSERT(offsetof(IsEnabled, result_shm_id) == 8, + OffsetOf_IsEnabled_result_shm_id_not_8); +COMPILE_ASSERT(offsetof(IsEnabled, result_shm_offset) == 12, + OffsetOf_IsEnabled_result_shm_offset_not_12); + +struct IsFramebuffer { + typedef IsFramebuffer ValueType; + static const CommandId kCmdId = kIsFramebuffer; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLuint _framebuffer, uint32 _result_shm_id, uint32 _result_shm_offset) { + SetHeader(); + framebuffer = _framebuffer; + result_shm_id = _result_shm_id; + result_shm_offset = _result_shm_offset; + } + + void* Set( + void* cmd, GLuint _framebuffer, uint32 _result_shm_id, + uint32 _result_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_framebuffer, _result_shm_id, _result_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 framebuffer; + uint32 result_shm_id; + uint32 result_shm_offset; +}; + +COMPILE_ASSERT(sizeof(IsFramebuffer) == 16, + Sizeof_IsFramebuffer_is_not_16); +COMPILE_ASSERT(offsetof(IsFramebuffer, header) == 0, + OffsetOf_IsFramebuffer_header_not_0); +COMPILE_ASSERT(offsetof(IsFramebuffer, framebuffer) == 4, + OffsetOf_IsFramebuffer_framebuffer_not_4); +COMPILE_ASSERT(offsetof(IsFramebuffer, result_shm_id) == 8, + OffsetOf_IsFramebuffer_result_shm_id_not_8); +COMPILE_ASSERT(offsetof(IsFramebuffer, result_shm_offset) == 12, + OffsetOf_IsFramebuffer_result_shm_offset_not_12); + +struct IsProgram { + typedef IsProgram ValueType; + static const CommandId kCmdId = kIsProgram; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLuint _program, uint32 _result_shm_id, uint32 _result_shm_offset) { + SetHeader(); + program = _program; + result_shm_id = _result_shm_id; + result_shm_offset = _result_shm_offset; + } + + void* Set( + void* cmd, GLuint _program, uint32 _result_shm_id, + uint32 _result_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_program, _result_shm_id, _result_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 program; + uint32 result_shm_id; + uint32 result_shm_offset; +}; + +COMPILE_ASSERT(sizeof(IsProgram) == 16, + Sizeof_IsProgram_is_not_16); +COMPILE_ASSERT(offsetof(IsProgram, header) == 0, + OffsetOf_IsProgram_header_not_0); +COMPILE_ASSERT(offsetof(IsProgram, program) == 4, + OffsetOf_IsProgram_program_not_4); +COMPILE_ASSERT(offsetof(IsProgram, result_shm_id) == 8, + OffsetOf_IsProgram_result_shm_id_not_8); +COMPILE_ASSERT(offsetof(IsProgram, result_shm_offset) == 12, + OffsetOf_IsProgram_result_shm_offset_not_12); + +struct IsRenderbuffer { + typedef IsRenderbuffer ValueType; + static const CommandId kCmdId = kIsRenderbuffer; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLuint _renderbuffer, uint32 _result_shm_id, uint32 _result_shm_offset) { + SetHeader(); + renderbuffer = _renderbuffer; + result_shm_id = _result_shm_id; + result_shm_offset = _result_shm_offset; + } + + void* Set( + void* cmd, GLuint _renderbuffer, uint32 _result_shm_id, + uint32 _result_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_renderbuffer, _result_shm_id, _result_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 renderbuffer; + uint32 result_shm_id; + uint32 result_shm_offset; +}; + +COMPILE_ASSERT(sizeof(IsRenderbuffer) == 16, + Sizeof_IsRenderbuffer_is_not_16); +COMPILE_ASSERT(offsetof(IsRenderbuffer, header) == 0, + OffsetOf_IsRenderbuffer_header_not_0); +COMPILE_ASSERT(offsetof(IsRenderbuffer, renderbuffer) == 4, + OffsetOf_IsRenderbuffer_renderbuffer_not_4); +COMPILE_ASSERT(offsetof(IsRenderbuffer, result_shm_id) == 8, + OffsetOf_IsRenderbuffer_result_shm_id_not_8); +COMPILE_ASSERT(offsetof(IsRenderbuffer, result_shm_offset) == 12, + OffsetOf_IsRenderbuffer_result_shm_offset_not_12); + +struct IsShader { + typedef IsShader ValueType; + static const CommandId kCmdId = kIsShader; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLuint _shader, uint32 _result_shm_id, uint32 _result_shm_offset) { + SetHeader(); + shader = _shader; + result_shm_id = _result_shm_id; + result_shm_offset = _result_shm_offset; + } + + void* Set( + void* cmd, GLuint _shader, uint32 _result_shm_id, + uint32 _result_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_shader, _result_shm_id, _result_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 shader; + uint32 result_shm_id; + uint32 result_shm_offset; +}; + +COMPILE_ASSERT(sizeof(IsShader) == 16, + Sizeof_IsShader_is_not_16); +COMPILE_ASSERT(offsetof(IsShader, header) == 0, + OffsetOf_IsShader_header_not_0); +COMPILE_ASSERT(offsetof(IsShader, shader) == 4, + OffsetOf_IsShader_shader_not_4); +COMPILE_ASSERT(offsetof(IsShader, result_shm_id) == 8, + OffsetOf_IsShader_result_shm_id_not_8); +COMPILE_ASSERT(offsetof(IsShader, result_shm_offset) == 12, + OffsetOf_IsShader_result_shm_offset_not_12); + +struct IsTexture { + typedef IsTexture ValueType; + static const CommandId kCmdId = kIsTexture; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLuint _texture, uint32 _result_shm_id, uint32 _result_shm_offset) { + SetHeader(); + texture = _texture; + result_shm_id = _result_shm_id; + result_shm_offset = _result_shm_offset; + } + + void* Set( + void* cmd, GLuint _texture, uint32 _result_shm_id, + uint32 _result_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_texture, _result_shm_id, _result_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 texture; + uint32 result_shm_id; + uint32 result_shm_offset; +}; + +COMPILE_ASSERT(sizeof(IsTexture) == 16, + Sizeof_IsTexture_is_not_16); +COMPILE_ASSERT(offsetof(IsTexture, header) == 0, + OffsetOf_IsTexture_header_not_0); +COMPILE_ASSERT(offsetof(IsTexture, texture) == 4, + OffsetOf_IsTexture_texture_not_4); +COMPILE_ASSERT(offsetof(IsTexture, result_shm_id) == 8, + OffsetOf_IsTexture_result_shm_id_not_8); +COMPILE_ASSERT(offsetof(IsTexture, result_shm_offset) == 12, + OffsetOf_IsTexture_result_shm_offset_not_12); + +struct LineWidth { + typedef LineWidth ValueType; + static const CommandId kCmdId = kLineWidth; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLfloat _width) { + SetHeader(); + width = _width; + } + + void* Set(void* cmd, GLfloat _width) { + static_cast<ValueType*>(cmd)->Init(_width); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + float width; +}; + +COMPILE_ASSERT(sizeof(LineWidth) == 8, + Sizeof_LineWidth_is_not_8); +COMPILE_ASSERT(offsetof(LineWidth, header) == 0, + OffsetOf_LineWidth_header_not_0); +COMPILE_ASSERT(offsetof(LineWidth, width) == 4, + OffsetOf_LineWidth_width_not_4); + +struct LinkProgram { + typedef LinkProgram ValueType; + static const CommandId kCmdId = kLinkProgram; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLuint _program) { + SetHeader(); + program = _program; + } + + void* Set(void* cmd, GLuint _program) { + static_cast<ValueType*>(cmd)->Init(_program); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 program; +}; + +COMPILE_ASSERT(sizeof(LinkProgram) == 8, + Sizeof_LinkProgram_is_not_8); +COMPILE_ASSERT(offsetof(LinkProgram, header) == 0, + OffsetOf_LinkProgram_header_not_0); +COMPILE_ASSERT(offsetof(LinkProgram, program) == 4, + OffsetOf_LinkProgram_program_not_4); + +struct PixelStorei { + typedef PixelStorei ValueType; + static const CommandId kCmdId = kPixelStorei; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _pname, GLint _param) { + SetHeader(); + pname = _pname; + param = _param; + } + + void* Set(void* cmd, GLenum _pname, GLint _param) { + static_cast<ValueType*>(cmd)->Init(_pname, _param); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 pname; + uint32 param; +}; + +COMPILE_ASSERT(sizeof(PixelStorei) == 12, + Sizeof_PixelStorei_is_not_12); +COMPILE_ASSERT(offsetof(PixelStorei, header) == 0, + OffsetOf_PixelStorei_header_not_0); +COMPILE_ASSERT(offsetof(PixelStorei, pname) == 4, + OffsetOf_PixelStorei_pname_not_4); +COMPILE_ASSERT(offsetof(PixelStorei, param) == 8, + OffsetOf_PixelStorei_param_not_8); + +struct PolygonOffset { + typedef PolygonOffset ValueType; + static const CommandId kCmdId = kPolygonOffset; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLfloat _factor, GLfloat _units) { + SetHeader(); + factor = _factor; + units = _units; + } + + void* Set(void* cmd, GLfloat _factor, GLfloat _units) { + static_cast<ValueType*>(cmd)->Init(_factor, _units); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + float factor; + float units; +}; + +COMPILE_ASSERT(sizeof(PolygonOffset) == 12, + Sizeof_PolygonOffset_is_not_12); +COMPILE_ASSERT(offsetof(PolygonOffset, header) == 0, + OffsetOf_PolygonOffset_header_not_0); +COMPILE_ASSERT(offsetof(PolygonOffset, factor) == 4, + OffsetOf_PolygonOffset_factor_not_4); +COMPILE_ASSERT(offsetof(PolygonOffset, units) == 8, + OffsetOf_PolygonOffset_units_not_8); + +struct ReadPixels { + typedef ReadPixels ValueType; + static const CommandId kCmdId = kReadPixels; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLint _x, GLint _y, GLsizei _width, GLsizei _height, GLenum _format, + GLenum _type, uint32 _pixels_shm_id, uint32 _pixels_shm_offset) { + SetHeader(); + x = _x; + y = _y; + width = _width; + height = _height; + format = _format; + type = _type; + pixels_shm_id = _pixels_shm_id; + pixels_shm_offset = _pixels_shm_offset; + } + + void* Set( + void* cmd, GLint _x, GLint _y, GLsizei _width, GLsizei _height, + GLenum _format, GLenum _type, uint32 _pixels_shm_id, + uint32 _pixels_shm_offset) { + static_cast<ValueType*>( + cmd)->Init( + _x, _y, _width, _height, _format, _type, _pixels_shm_id, + _pixels_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 x; + uint32 y; + uint32 width; + uint32 height; + uint32 format; + uint32 type; + uint32 pixels_shm_id; + uint32 pixels_shm_offset; +}; + +COMPILE_ASSERT(sizeof(ReadPixels) == 36, + Sizeof_ReadPixels_is_not_36); +COMPILE_ASSERT(offsetof(ReadPixels, header) == 0, + OffsetOf_ReadPixels_header_not_0); +COMPILE_ASSERT(offsetof(ReadPixels, x) == 4, + OffsetOf_ReadPixels_x_not_4); +COMPILE_ASSERT(offsetof(ReadPixels, y) == 8, + OffsetOf_ReadPixels_y_not_8); +COMPILE_ASSERT(offsetof(ReadPixels, width) == 12, + OffsetOf_ReadPixels_width_not_12); +COMPILE_ASSERT(offsetof(ReadPixels, height) == 16, + OffsetOf_ReadPixels_height_not_16); +COMPILE_ASSERT(offsetof(ReadPixels, format) == 20, + OffsetOf_ReadPixels_format_not_20); +COMPILE_ASSERT(offsetof(ReadPixels, type) == 24, + OffsetOf_ReadPixels_type_not_24); +COMPILE_ASSERT(offsetof(ReadPixels, pixels_shm_id) == 28, + OffsetOf_ReadPixels_pixels_shm_id_not_28); +COMPILE_ASSERT(offsetof(ReadPixels, pixels_shm_offset) == 32, + OffsetOf_ReadPixels_pixels_shm_offset_not_32); + +struct RenderbufferStorage { + typedef RenderbufferStorage ValueType; + static const CommandId kCmdId = kRenderbufferStorage; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLenum _target, GLenum _internalformat, GLsizei _width, + GLsizei _height) { + SetHeader(); + target = _target; + internalformat = _internalformat; + width = _width; + height = _height; + } + + void* Set( + void* cmd, GLenum _target, GLenum _internalformat, GLsizei _width, + GLsizei _height) { + static_cast<ValueType*>( + cmd)->Init(_target, _internalformat, _width, _height); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 internalformat; + uint32 width; + uint32 height; +}; + +COMPILE_ASSERT(sizeof(RenderbufferStorage) == 20, + Sizeof_RenderbufferStorage_is_not_20); +COMPILE_ASSERT(offsetof(RenderbufferStorage, header) == 0, + OffsetOf_RenderbufferStorage_header_not_0); +COMPILE_ASSERT(offsetof(RenderbufferStorage, target) == 4, + OffsetOf_RenderbufferStorage_target_not_4); +COMPILE_ASSERT(offsetof(RenderbufferStorage, internalformat) == 8, + OffsetOf_RenderbufferStorage_internalformat_not_8); +COMPILE_ASSERT(offsetof(RenderbufferStorage, width) == 12, + OffsetOf_RenderbufferStorage_width_not_12); +COMPILE_ASSERT(offsetof(RenderbufferStorage, height) == 16, + OffsetOf_RenderbufferStorage_height_not_16); + +struct SampleCoverage { + typedef SampleCoverage ValueType; + static const CommandId kCmdId = kSampleCoverage; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLclampf _value, GLboolean _invert) { + SetHeader(); + value = _value; + invert = _invert; + } + + void* Set(void* cmd, GLclampf _value, GLboolean _invert) { + static_cast<ValueType*>(cmd)->Init(_value, _invert); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + float value; + uint32 invert; +}; + +COMPILE_ASSERT(sizeof(SampleCoverage) == 12, + Sizeof_SampleCoverage_is_not_12); +COMPILE_ASSERT(offsetof(SampleCoverage, header) == 0, + OffsetOf_SampleCoverage_header_not_0); +COMPILE_ASSERT(offsetof(SampleCoverage, value) == 4, + OffsetOf_SampleCoverage_value_not_4); +COMPILE_ASSERT(offsetof(SampleCoverage, invert) == 8, + OffsetOf_SampleCoverage_invert_not_8); + +struct Scissor { + typedef Scissor ValueType; + static const CommandId kCmdId = kScissor; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLint _x, GLint _y, GLsizei _width, GLsizei _height) { + SetHeader(); + x = _x; + y = _y; + width = _width; + height = _height; + } + + void* Set(void* cmd, GLint _x, GLint _y, GLsizei _width, GLsizei _height) { + static_cast<ValueType*>(cmd)->Init(_x, _y, _width, _height); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 x; + uint32 y; + uint32 width; + uint32 height; +}; + +COMPILE_ASSERT(sizeof(Scissor) == 20, + Sizeof_Scissor_is_not_20); +COMPILE_ASSERT(offsetof(Scissor, header) == 0, + OffsetOf_Scissor_header_not_0); +COMPILE_ASSERT(offsetof(Scissor, x) == 4, + OffsetOf_Scissor_x_not_4); +COMPILE_ASSERT(offsetof(Scissor, y) == 8, + OffsetOf_Scissor_y_not_8); +COMPILE_ASSERT(offsetof(Scissor, width) == 12, + OffsetOf_Scissor_width_not_12); +COMPILE_ASSERT(offsetof(Scissor, height) == 16, + OffsetOf_Scissor_height_not_16); + +struct ShaderSource { + typedef ShaderSource ValueType; + static const CommandId kCmdId = kShaderSource; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLuint _shader, GLsizei _count, uint32 _data_shm_id, + uint32 _data_shm_offset, uint32 _data_size) { + SetHeader(); + shader = _shader; + count = _count; + data_shm_id = _data_shm_id; + data_shm_offset = _data_shm_offset; + data_size = _data_size; + } + + void* Set( + void* cmd, GLuint _shader, GLsizei _count, uint32 _data_shm_id, + uint32 _data_shm_offset, uint32 _data_size) { + static_cast<ValueType*>( + cmd)->Init( + _shader, _count, _data_shm_id, _data_shm_offset, _data_size); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 shader; + uint32 count; + uint32 data_shm_id; + uint32 data_shm_offset; + uint32 data_size; +}; + +COMPILE_ASSERT(sizeof(ShaderSource) == 24, + Sizeof_ShaderSource_is_not_24); +COMPILE_ASSERT(offsetof(ShaderSource, header) == 0, + OffsetOf_ShaderSource_header_not_0); +COMPILE_ASSERT(offsetof(ShaderSource, shader) == 4, + OffsetOf_ShaderSource_shader_not_4); +COMPILE_ASSERT(offsetof(ShaderSource, count) == 8, + OffsetOf_ShaderSource_count_not_8); +COMPILE_ASSERT(offsetof(ShaderSource, data_shm_id) == 12, + OffsetOf_ShaderSource_data_shm_id_not_12); +COMPILE_ASSERT(offsetof(ShaderSource, data_shm_offset) == 16, + OffsetOf_ShaderSource_data_shm_offset_not_16); +COMPILE_ASSERT(offsetof(ShaderSource, data_size) == 20, + OffsetOf_ShaderSource_data_size_not_20); + +struct ShaderSourceImmediate { + typedef ShaderSourceImmediate ValueType; + static const CommandId kCmdId = kShaderSourceImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeSize(uint32 size_in_bytes) { + return static_cast<uint32>( + sizeof(ValueType) + // NOLINT + RoundSizeToMultipleOfEntries(size_in_bytes)); + } + + void SetHeader(uint32 size_in_bytes) { + header.SetCmdByTotalSize<ValueType>(size_in_bytes); + } + + void Init(GLuint _shader, GLsizei _count, uint32 _data_size) { + uint32 total_size = ComputeSize(_data_size); + SetHeader(total_size); + shader = _shader; + count = _count; + data_size = _data_size; + } + + void* Set(void* cmd, GLuint _shader, GLsizei _count, uint32 _data_size) { + uint32 total_size = ComputeSize(_data_size); + static_cast<ValueType*>(cmd)->Init(_shader, _count, _data_size); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, total_size); + } + + command_buffer::CommandHeader header; + uint32 shader; + uint32 count; + uint32 data_size; +}; + +COMPILE_ASSERT(sizeof(ShaderSourceImmediate) == 16, + Sizeof_ShaderSourceImmediate_is_not_16); +COMPILE_ASSERT(offsetof(ShaderSourceImmediate, header) == 0, + OffsetOf_ShaderSourceImmediate_header_not_0); +COMPILE_ASSERT(offsetof(ShaderSourceImmediate, shader) == 4, + OffsetOf_ShaderSourceImmediate_shader_not_4); +COMPILE_ASSERT(offsetof(ShaderSourceImmediate, count) == 8, + OffsetOf_ShaderSourceImmediate_count_not_8); +COMPILE_ASSERT(offsetof(ShaderSourceImmediate, data_size) == 12, + OffsetOf_ShaderSourceImmediate_data_size_not_12); + +struct StencilFunc { + typedef StencilFunc ValueType; + static const CommandId kCmdId = kStencilFunc; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _func, GLint _ref, GLuint _mask) { + SetHeader(); + func = _func; + ref = _ref; + mask = _mask; + } + + void* Set(void* cmd, GLenum _func, GLint _ref, GLuint _mask) { + static_cast<ValueType*>(cmd)->Init(_func, _ref, _mask); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 func; + uint32 ref; + uint32 mask; +}; + +COMPILE_ASSERT(sizeof(StencilFunc) == 16, + Sizeof_StencilFunc_is_not_16); +COMPILE_ASSERT(offsetof(StencilFunc, header) == 0, + OffsetOf_StencilFunc_header_not_0); +COMPILE_ASSERT(offsetof(StencilFunc, func) == 4, + OffsetOf_StencilFunc_func_not_4); +COMPILE_ASSERT(offsetof(StencilFunc, ref) == 8, + OffsetOf_StencilFunc_ref_not_8); +COMPILE_ASSERT(offsetof(StencilFunc, mask) == 12, + OffsetOf_StencilFunc_mask_not_12); + +struct StencilFuncSeparate { + typedef StencilFuncSeparate ValueType; + static const CommandId kCmdId = kStencilFuncSeparate; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _face, GLenum _func, GLint _ref, GLuint _mask) { + SetHeader(); + face = _face; + func = _func; + ref = _ref; + mask = _mask; + } + + void* Set(void* cmd, GLenum _face, GLenum _func, GLint _ref, GLuint _mask) { + static_cast<ValueType*>(cmd)->Init(_face, _func, _ref, _mask); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 face; + uint32 func; + uint32 ref; + uint32 mask; +}; + +COMPILE_ASSERT(sizeof(StencilFuncSeparate) == 20, + Sizeof_StencilFuncSeparate_is_not_20); +COMPILE_ASSERT(offsetof(StencilFuncSeparate, header) == 0, + OffsetOf_StencilFuncSeparate_header_not_0); +COMPILE_ASSERT(offsetof(StencilFuncSeparate, face) == 4, + OffsetOf_StencilFuncSeparate_face_not_4); +COMPILE_ASSERT(offsetof(StencilFuncSeparate, func) == 8, + OffsetOf_StencilFuncSeparate_func_not_8); +COMPILE_ASSERT(offsetof(StencilFuncSeparate, ref) == 12, + OffsetOf_StencilFuncSeparate_ref_not_12); +COMPILE_ASSERT(offsetof(StencilFuncSeparate, mask) == 16, + OffsetOf_StencilFuncSeparate_mask_not_16); + +struct StencilMask { + typedef StencilMask ValueType; + static const CommandId kCmdId = kStencilMask; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLuint _mask) { + SetHeader(); + mask = _mask; + } + + void* Set(void* cmd, GLuint _mask) { + static_cast<ValueType*>(cmd)->Init(_mask); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 mask; +}; + +COMPILE_ASSERT(sizeof(StencilMask) == 8, + Sizeof_StencilMask_is_not_8); +COMPILE_ASSERT(offsetof(StencilMask, header) == 0, + OffsetOf_StencilMask_header_not_0); +COMPILE_ASSERT(offsetof(StencilMask, mask) == 4, + OffsetOf_StencilMask_mask_not_4); + +struct StencilMaskSeparate { + typedef StencilMaskSeparate ValueType; + static const CommandId kCmdId = kStencilMaskSeparate; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _face, GLuint _mask) { + SetHeader(); + face = _face; + mask = _mask; + } + + void* Set(void* cmd, GLenum _face, GLuint _mask) { + static_cast<ValueType*>(cmd)->Init(_face, _mask); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 face; + uint32 mask; +}; + +COMPILE_ASSERT(sizeof(StencilMaskSeparate) == 12, + Sizeof_StencilMaskSeparate_is_not_12); +COMPILE_ASSERT(offsetof(StencilMaskSeparate, header) == 0, + OffsetOf_StencilMaskSeparate_header_not_0); +COMPILE_ASSERT(offsetof(StencilMaskSeparate, face) == 4, + OffsetOf_StencilMaskSeparate_face_not_4); +COMPILE_ASSERT(offsetof(StencilMaskSeparate, mask) == 8, + OffsetOf_StencilMaskSeparate_mask_not_8); + +struct StencilOp { + typedef StencilOp ValueType; + static const CommandId kCmdId = kStencilOp; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _fail, GLenum _zfail, GLenum _zpass) { + SetHeader(); + fail = _fail; + zfail = _zfail; + zpass = _zpass; + } + + void* Set(void* cmd, GLenum _fail, GLenum _zfail, GLenum _zpass) { + static_cast<ValueType*>(cmd)->Init(_fail, _zfail, _zpass); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 fail; + uint32 zfail; + uint32 zpass; +}; + +COMPILE_ASSERT(sizeof(StencilOp) == 16, + Sizeof_StencilOp_is_not_16); +COMPILE_ASSERT(offsetof(StencilOp, header) == 0, + OffsetOf_StencilOp_header_not_0); +COMPILE_ASSERT(offsetof(StencilOp, fail) == 4, + OffsetOf_StencilOp_fail_not_4); +COMPILE_ASSERT(offsetof(StencilOp, zfail) == 8, + OffsetOf_StencilOp_zfail_not_8); +COMPILE_ASSERT(offsetof(StencilOp, zpass) == 12, + OffsetOf_StencilOp_zpass_not_12); + +struct StencilOpSeparate { + typedef StencilOpSeparate ValueType; + static const CommandId kCmdId = kStencilOpSeparate; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _face, GLenum _fail, GLenum _zfail, GLenum _zpass) { + SetHeader(); + face = _face; + fail = _fail; + zfail = _zfail; + zpass = _zpass; + } + + void* Set( + void* cmd, GLenum _face, GLenum _fail, GLenum _zfail, GLenum _zpass) { + static_cast<ValueType*>(cmd)->Init(_face, _fail, _zfail, _zpass); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 face; + uint32 fail; + uint32 zfail; + uint32 zpass; +}; + +COMPILE_ASSERT(sizeof(StencilOpSeparate) == 20, + Sizeof_StencilOpSeparate_is_not_20); +COMPILE_ASSERT(offsetof(StencilOpSeparate, header) == 0, + OffsetOf_StencilOpSeparate_header_not_0); +COMPILE_ASSERT(offsetof(StencilOpSeparate, face) == 4, + OffsetOf_StencilOpSeparate_face_not_4); +COMPILE_ASSERT(offsetof(StencilOpSeparate, fail) == 8, + OffsetOf_StencilOpSeparate_fail_not_8); +COMPILE_ASSERT(offsetof(StencilOpSeparate, zfail) == 12, + OffsetOf_StencilOpSeparate_zfail_not_12); +COMPILE_ASSERT(offsetof(StencilOpSeparate, zpass) == 16, + OffsetOf_StencilOpSeparate_zpass_not_16); + +struct TexImage2D { + typedef TexImage2D ValueType; + static const CommandId kCmdId = kTexImage2D; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLenum _target, GLint _level, GLint _internalformat, GLsizei _width, + GLsizei _height, GLint _border, GLenum _format, GLenum _type, + uint32 _pixels_shm_id, uint32 _pixels_shm_offset) { + SetHeader(); + target = _target; + level = _level; + internalformat = _internalformat; + width = _width; + height = _height; + border = _border; + format = _format; + type = _type; + pixels_shm_id = _pixels_shm_id; + pixels_shm_offset = _pixels_shm_offset; + } + + void* Set( + void* cmd, GLenum _target, GLint _level, GLint _internalformat, + GLsizei _width, GLsizei _height, GLint _border, GLenum _format, + GLenum _type, uint32 _pixels_shm_id, uint32 _pixels_shm_offset) { + static_cast<ValueType*>( + cmd)->Init( + _target, _level, _internalformat, _width, _height, _border, _format, + _type, _pixels_shm_id, _pixels_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 level; + uint32 internalformat; + uint32 width; + uint32 height; + uint32 border; + uint32 format; + uint32 type; + uint32 pixels_shm_id; + uint32 pixels_shm_offset; +}; + +COMPILE_ASSERT(sizeof(TexImage2D) == 44, + Sizeof_TexImage2D_is_not_44); +COMPILE_ASSERT(offsetof(TexImage2D, header) == 0, + OffsetOf_TexImage2D_header_not_0); +COMPILE_ASSERT(offsetof(TexImage2D, target) == 4, + OffsetOf_TexImage2D_target_not_4); +COMPILE_ASSERT(offsetof(TexImage2D, level) == 8, + OffsetOf_TexImage2D_level_not_8); +COMPILE_ASSERT(offsetof(TexImage2D, internalformat) == 12, + OffsetOf_TexImage2D_internalformat_not_12); +COMPILE_ASSERT(offsetof(TexImage2D, width) == 16, + OffsetOf_TexImage2D_width_not_16); +COMPILE_ASSERT(offsetof(TexImage2D, height) == 20, + OffsetOf_TexImage2D_height_not_20); +COMPILE_ASSERT(offsetof(TexImage2D, border) == 24, + OffsetOf_TexImage2D_border_not_24); +COMPILE_ASSERT(offsetof(TexImage2D, format) == 28, + OffsetOf_TexImage2D_format_not_28); +COMPILE_ASSERT(offsetof(TexImage2D, type) == 32, + OffsetOf_TexImage2D_type_not_32); +COMPILE_ASSERT(offsetof(TexImage2D, pixels_shm_id) == 36, + OffsetOf_TexImage2D_pixels_shm_id_not_36); +COMPILE_ASSERT(offsetof(TexImage2D, pixels_shm_offset) == 40, + OffsetOf_TexImage2D_pixels_shm_offset_not_40); + +struct TexImage2DImmediate { + typedef TexImage2DImmediate ValueType; + static const CommandId kCmdId = kTexImage2DImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeSize(uint32 size_in_bytes) { + return static_cast<uint32>( + sizeof(ValueType) + // NOLINT + RoundSizeToMultipleOfEntries(size_in_bytes)); + } + + void SetHeader(uint32 size_in_bytes) { + header.SetCmdByTotalSize<ValueType>(size_in_bytes); + } + + void Init( + GLenum _target, GLint _level, GLint _internalformat, GLsizei _width, + GLsizei _height, GLint _border, GLenum _format, GLenum _type) { + uint32 total_size = 0; // TODO(gman): get correct size + SetHeader(total_size); + target = _target; + level = _level; + internalformat = _internalformat; + width = _width; + height = _height; + border = _border; + format = _format; + type = _type; + } + + void* Set( + void* cmd, GLenum _target, GLint _level, GLint _internalformat, + GLsizei _width, GLsizei _height, GLint _border, GLenum _format, + GLenum _type) { + uint32 total_size = 0; // TODO(gman): get correct size + static_cast<ValueType*>( + cmd)->Init( + _target, _level, _internalformat, _width, _height, _border, _format, + _type); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, total_size); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 level; + uint32 internalformat; + uint32 width; + uint32 height; + uint32 border; + uint32 format; + uint32 type; +}; + +COMPILE_ASSERT(sizeof(TexImage2DImmediate) == 36, + Sizeof_TexImage2DImmediate_is_not_36); +COMPILE_ASSERT(offsetof(TexImage2DImmediate, header) == 0, + OffsetOf_TexImage2DImmediate_header_not_0); +COMPILE_ASSERT(offsetof(TexImage2DImmediate, target) == 4, + OffsetOf_TexImage2DImmediate_target_not_4); +COMPILE_ASSERT(offsetof(TexImage2DImmediate, level) == 8, + OffsetOf_TexImage2DImmediate_level_not_8); +COMPILE_ASSERT(offsetof(TexImage2DImmediate, internalformat) == 12, + OffsetOf_TexImage2DImmediate_internalformat_not_12); +COMPILE_ASSERT(offsetof(TexImage2DImmediate, width) == 16, + OffsetOf_TexImage2DImmediate_width_not_16); +COMPILE_ASSERT(offsetof(TexImage2DImmediate, height) == 20, + OffsetOf_TexImage2DImmediate_height_not_20); +COMPILE_ASSERT(offsetof(TexImage2DImmediate, border) == 24, + OffsetOf_TexImage2DImmediate_border_not_24); +COMPILE_ASSERT(offsetof(TexImage2DImmediate, format) == 28, + OffsetOf_TexImage2DImmediate_format_not_28); +COMPILE_ASSERT(offsetof(TexImage2DImmediate, type) == 32, + OffsetOf_TexImage2DImmediate_type_not_32); + +struct TexParameterf { + typedef TexParameterf ValueType; + static const CommandId kCmdId = kTexParameterf; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _target, GLenum _pname, GLfloat _param) { + SetHeader(); + target = _target; + pname = _pname; + param = _param; + } + + void* Set(void* cmd, GLenum _target, GLenum _pname, GLfloat _param) { + static_cast<ValueType*>(cmd)->Init(_target, _pname, _param); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 pname; + float param; +}; + +COMPILE_ASSERT(sizeof(TexParameterf) == 16, + Sizeof_TexParameterf_is_not_16); +COMPILE_ASSERT(offsetof(TexParameterf, header) == 0, + OffsetOf_TexParameterf_header_not_0); +COMPILE_ASSERT(offsetof(TexParameterf, target) == 4, + OffsetOf_TexParameterf_target_not_4); +COMPILE_ASSERT(offsetof(TexParameterf, pname) == 8, + OffsetOf_TexParameterf_pname_not_8); +COMPILE_ASSERT(offsetof(TexParameterf, param) == 12, + OffsetOf_TexParameterf_param_not_12); + +struct TexParameterfv { + typedef TexParameterfv ValueType; + static const CommandId kCmdId = kTexParameterfv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLenum _target, GLenum _pname, uint32 _params_shm_id, + uint32 _params_shm_offset) { + SetHeader(); + target = _target; + pname = _pname; + params_shm_id = _params_shm_id; + params_shm_offset = _params_shm_offset; + } + + void* Set( + void* cmd, GLenum _target, GLenum _pname, uint32 _params_shm_id, + uint32 _params_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_target, _pname, _params_shm_id, _params_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 pname; + uint32 params_shm_id; + uint32 params_shm_offset; +}; + +COMPILE_ASSERT(sizeof(TexParameterfv) == 20, + Sizeof_TexParameterfv_is_not_20); +COMPILE_ASSERT(offsetof(TexParameterfv, header) == 0, + OffsetOf_TexParameterfv_header_not_0); +COMPILE_ASSERT(offsetof(TexParameterfv, target) == 4, + OffsetOf_TexParameterfv_target_not_4); +COMPILE_ASSERT(offsetof(TexParameterfv, pname) == 8, + OffsetOf_TexParameterfv_pname_not_8); +COMPILE_ASSERT(offsetof(TexParameterfv, params_shm_id) == 12, + OffsetOf_TexParameterfv_params_shm_id_not_12); +COMPILE_ASSERT(offsetof(TexParameterfv, params_shm_offset) == 16, + OffsetOf_TexParameterfv_params_shm_offset_not_16); + +struct TexParameterfvImmediate { + typedef TexParameterfvImmediate ValueType; + static const CommandId kCmdId = kTexParameterfvImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeDataSize() { + return static_cast<uint32>( + sizeof(GLfloat) * 1); // NOLINT + } + + static uint32 ComputeSize() { + return static_cast<uint32>( + sizeof(ValueType) + ComputeDataSize()); // NOLINT + } + + void SetHeader() { + header.SetCmdByTotalSize<ValueType>(ComputeSize()); + } + + void Init(GLenum _target, GLenum _pname, const GLfloat* _params) { + SetHeader(); + target = _target; + pname = _pname; + memcpy(ImmediateDataAddress(this), + _params, ComputeDataSize()); + } + + void* Set(void* cmd, GLenum _target, GLenum _pname, const GLfloat* _params) { + static_cast<ValueType*>(cmd)->Init(_target, _pname, _params); + const uint32 size = ComputeSize(); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 pname; +}; + +COMPILE_ASSERT(sizeof(TexParameterfvImmediate) == 12, + Sizeof_TexParameterfvImmediate_is_not_12); +COMPILE_ASSERT(offsetof(TexParameterfvImmediate, header) == 0, + OffsetOf_TexParameterfvImmediate_header_not_0); +COMPILE_ASSERT(offsetof(TexParameterfvImmediate, target) == 4, + OffsetOf_TexParameterfvImmediate_target_not_4); +COMPILE_ASSERT(offsetof(TexParameterfvImmediate, pname) == 8, + OffsetOf_TexParameterfvImmediate_pname_not_8); + +struct TexParameteri { + typedef TexParameteri ValueType; + static const CommandId kCmdId = kTexParameteri; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLenum _target, GLenum _pname, GLint _param) { + SetHeader(); + target = _target; + pname = _pname; + param = _param; + } + + void* Set(void* cmd, GLenum _target, GLenum _pname, GLint _param) { + static_cast<ValueType*>(cmd)->Init(_target, _pname, _param); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 pname; + uint32 param; +}; + +COMPILE_ASSERT(sizeof(TexParameteri) == 16, + Sizeof_TexParameteri_is_not_16); +COMPILE_ASSERT(offsetof(TexParameteri, header) == 0, + OffsetOf_TexParameteri_header_not_0); +COMPILE_ASSERT(offsetof(TexParameteri, target) == 4, + OffsetOf_TexParameteri_target_not_4); +COMPILE_ASSERT(offsetof(TexParameteri, pname) == 8, + OffsetOf_TexParameteri_pname_not_8); +COMPILE_ASSERT(offsetof(TexParameteri, param) == 12, + OffsetOf_TexParameteri_param_not_12); + +struct TexParameteriv { + typedef TexParameteriv ValueType; + static const CommandId kCmdId = kTexParameteriv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLenum _target, GLenum _pname, uint32 _params_shm_id, + uint32 _params_shm_offset) { + SetHeader(); + target = _target; + pname = _pname; + params_shm_id = _params_shm_id; + params_shm_offset = _params_shm_offset; + } + + void* Set( + void* cmd, GLenum _target, GLenum _pname, uint32 _params_shm_id, + uint32 _params_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_target, _pname, _params_shm_id, _params_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 pname; + uint32 params_shm_id; + uint32 params_shm_offset; +}; + +COMPILE_ASSERT(sizeof(TexParameteriv) == 20, + Sizeof_TexParameteriv_is_not_20); +COMPILE_ASSERT(offsetof(TexParameteriv, header) == 0, + OffsetOf_TexParameteriv_header_not_0); +COMPILE_ASSERT(offsetof(TexParameteriv, target) == 4, + OffsetOf_TexParameteriv_target_not_4); +COMPILE_ASSERT(offsetof(TexParameteriv, pname) == 8, + OffsetOf_TexParameteriv_pname_not_8); +COMPILE_ASSERT(offsetof(TexParameteriv, params_shm_id) == 12, + OffsetOf_TexParameteriv_params_shm_id_not_12); +COMPILE_ASSERT(offsetof(TexParameteriv, params_shm_offset) == 16, + OffsetOf_TexParameteriv_params_shm_offset_not_16); + +struct TexParameterivImmediate { + typedef TexParameterivImmediate ValueType; + static const CommandId kCmdId = kTexParameterivImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeDataSize() { + return static_cast<uint32>( + sizeof(GLint) * 1); // NOLINT + } + + static uint32 ComputeSize() { + return static_cast<uint32>( + sizeof(ValueType) + ComputeDataSize()); // NOLINT + } + + void SetHeader() { + header.SetCmdByTotalSize<ValueType>(ComputeSize()); + } + + void Init(GLenum _target, GLenum _pname, const GLint* _params) { + SetHeader(); + target = _target; + pname = _pname; + memcpy(ImmediateDataAddress(this), + _params, ComputeDataSize()); + } + + void* Set(void* cmd, GLenum _target, GLenum _pname, const GLint* _params) { + static_cast<ValueType*>(cmd)->Init(_target, _pname, _params); + const uint32 size = ComputeSize(); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 pname; +}; + +COMPILE_ASSERT(sizeof(TexParameterivImmediate) == 12, + Sizeof_TexParameterivImmediate_is_not_12); +COMPILE_ASSERT(offsetof(TexParameterivImmediate, header) == 0, + OffsetOf_TexParameterivImmediate_header_not_0); +COMPILE_ASSERT(offsetof(TexParameterivImmediate, target) == 4, + OffsetOf_TexParameterivImmediate_target_not_4); +COMPILE_ASSERT(offsetof(TexParameterivImmediate, pname) == 8, + OffsetOf_TexParameterivImmediate_pname_not_8); + +struct TexSubImage2D { + typedef TexSubImage2D ValueType; + static const CommandId kCmdId = kTexSubImage2D; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLenum _target, GLint _level, GLint _xoffset, GLint _yoffset, + GLsizei _width, GLsizei _height, GLenum _format, GLenum _type, + uint32 _pixels_shm_id, uint32 _pixels_shm_offset) { + SetHeader(); + target = _target; + level = _level; + xoffset = _xoffset; + yoffset = _yoffset; + width = _width; + height = _height; + format = _format; + type = _type; + pixels_shm_id = _pixels_shm_id; + pixels_shm_offset = _pixels_shm_offset; + } + + void* Set( + void* cmd, GLenum _target, GLint _level, GLint _xoffset, GLint _yoffset, + GLsizei _width, GLsizei _height, GLenum _format, GLenum _type, + uint32 _pixels_shm_id, uint32 _pixels_shm_offset) { + static_cast<ValueType*>( + cmd)->Init( + _target, _level, _xoffset, _yoffset, _width, _height, _format, + _type, _pixels_shm_id, _pixels_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 level; + uint32 xoffset; + uint32 yoffset; + uint32 width; + uint32 height; + uint32 format; + uint32 type; + uint32 pixels_shm_id; + uint32 pixels_shm_offset; +}; + +COMPILE_ASSERT(sizeof(TexSubImage2D) == 44, + Sizeof_TexSubImage2D_is_not_44); +COMPILE_ASSERT(offsetof(TexSubImage2D, header) == 0, + OffsetOf_TexSubImage2D_header_not_0); +COMPILE_ASSERT(offsetof(TexSubImage2D, target) == 4, + OffsetOf_TexSubImage2D_target_not_4); +COMPILE_ASSERT(offsetof(TexSubImage2D, level) == 8, + OffsetOf_TexSubImage2D_level_not_8); +COMPILE_ASSERT(offsetof(TexSubImage2D, xoffset) == 12, + OffsetOf_TexSubImage2D_xoffset_not_12); +COMPILE_ASSERT(offsetof(TexSubImage2D, yoffset) == 16, + OffsetOf_TexSubImage2D_yoffset_not_16); +COMPILE_ASSERT(offsetof(TexSubImage2D, width) == 20, + OffsetOf_TexSubImage2D_width_not_20); +COMPILE_ASSERT(offsetof(TexSubImage2D, height) == 24, + OffsetOf_TexSubImage2D_height_not_24); +COMPILE_ASSERT(offsetof(TexSubImage2D, format) == 28, + OffsetOf_TexSubImage2D_format_not_28); +COMPILE_ASSERT(offsetof(TexSubImage2D, type) == 32, + OffsetOf_TexSubImage2D_type_not_32); +COMPILE_ASSERT(offsetof(TexSubImage2D, pixels_shm_id) == 36, + OffsetOf_TexSubImage2D_pixels_shm_id_not_36); +COMPILE_ASSERT(offsetof(TexSubImage2D, pixels_shm_offset) == 40, + OffsetOf_TexSubImage2D_pixels_shm_offset_not_40); + +struct TexSubImage2DImmediate { + typedef TexSubImage2DImmediate ValueType; + static const CommandId kCmdId = kTexSubImage2DImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeSize(uint32 size_in_bytes) { + return static_cast<uint32>( + sizeof(ValueType) + // NOLINT + RoundSizeToMultipleOfEntries(size_in_bytes)); + } + + void SetHeader(uint32 size_in_bytes) { + header.SetCmdByTotalSize<ValueType>(size_in_bytes); + } + + void Init( + GLenum _target, GLint _level, GLint _xoffset, GLint _yoffset, + GLsizei _width, GLsizei _height, GLenum _format, GLenum _type) { + uint32 total_size = 0; // TODO(gman): get correct size + SetHeader(total_size); + target = _target; + level = _level; + xoffset = _xoffset; + yoffset = _yoffset; + width = _width; + height = _height; + format = _format; + type = _type; + } + + void* Set( + void* cmd, GLenum _target, GLint _level, GLint _xoffset, GLint _yoffset, + GLsizei _width, GLsizei _height, GLenum _format, GLenum _type) { + uint32 total_size = 0; // TODO(gman): get correct size + static_cast<ValueType*>( + cmd)->Init( + _target, _level, _xoffset, _yoffset, _width, _height, _format, + _type); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, total_size); + } + + command_buffer::CommandHeader header; + uint32 target; + uint32 level; + uint32 xoffset; + uint32 yoffset; + uint32 width; + uint32 height; + uint32 format; + uint32 type; +}; + +COMPILE_ASSERT(sizeof(TexSubImage2DImmediate) == 36, + Sizeof_TexSubImage2DImmediate_is_not_36); +COMPILE_ASSERT(offsetof(TexSubImage2DImmediate, header) == 0, + OffsetOf_TexSubImage2DImmediate_header_not_0); +COMPILE_ASSERT(offsetof(TexSubImage2DImmediate, target) == 4, + OffsetOf_TexSubImage2DImmediate_target_not_4); +COMPILE_ASSERT(offsetof(TexSubImage2DImmediate, level) == 8, + OffsetOf_TexSubImage2DImmediate_level_not_8); +COMPILE_ASSERT(offsetof(TexSubImage2DImmediate, xoffset) == 12, + OffsetOf_TexSubImage2DImmediate_xoffset_not_12); +COMPILE_ASSERT(offsetof(TexSubImage2DImmediate, yoffset) == 16, + OffsetOf_TexSubImage2DImmediate_yoffset_not_16); +COMPILE_ASSERT(offsetof(TexSubImage2DImmediate, width) == 20, + OffsetOf_TexSubImage2DImmediate_width_not_20); +COMPILE_ASSERT(offsetof(TexSubImage2DImmediate, height) == 24, + OffsetOf_TexSubImage2DImmediate_height_not_24); +COMPILE_ASSERT(offsetof(TexSubImage2DImmediate, format) == 28, + OffsetOf_TexSubImage2DImmediate_format_not_28); +COMPILE_ASSERT(offsetof(TexSubImage2DImmediate, type) == 32, + OffsetOf_TexSubImage2DImmediate_type_not_32); + +struct Uniform1f { + typedef Uniform1f ValueType; + static const CommandId kCmdId = kUniform1f; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLint _location, GLfloat _x) { + SetHeader(); + location = _location; + x = _x; + } + + void* Set(void* cmd, GLint _location, GLfloat _x) { + static_cast<ValueType*>(cmd)->Init(_location, _x); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 location; + float x; +}; + +COMPILE_ASSERT(sizeof(Uniform1f) == 12, + Sizeof_Uniform1f_is_not_12); +COMPILE_ASSERT(offsetof(Uniform1f, header) == 0, + OffsetOf_Uniform1f_header_not_0); +COMPILE_ASSERT(offsetof(Uniform1f, location) == 4, + OffsetOf_Uniform1f_location_not_4); +COMPILE_ASSERT(offsetof(Uniform1f, x) == 8, + OffsetOf_Uniform1f_x_not_8); + +struct Uniform1fv { + typedef Uniform1fv ValueType; + static const CommandId kCmdId = kUniform1fv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLint _location, GLsizei _count, uint32 _v_shm_id, + uint32 _v_shm_offset) { + SetHeader(); + location = _location; + count = _count; + v_shm_id = _v_shm_id; + v_shm_offset = _v_shm_offset; + } + + void* Set( + void* cmd, GLint _location, GLsizei _count, uint32 _v_shm_id, + uint32 _v_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_location, _count, _v_shm_id, _v_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 location; + uint32 count; + uint32 v_shm_id; + uint32 v_shm_offset; +}; + +COMPILE_ASSERT(sizeof(Uniform1fv) == 20, + Sizeof_Uniform1fv_is_not_20); +COMPILE_ASSERT(offsetof(Uniform1fv, header) == 0, + OffsetOf_Uniform1fv_header_not_0); +COMPILE_ASSERT(offsetof(Uniform1fv, location) == 4, + OffsetOf_Uniform1fv_location_not_4); +COMPILE_ASSERT(offsetof(Uniform1fv, count) == 8, + OffsetOf_Uniform1fv_count_not_8); +COMPILE_ASSERT(offsetof(Uniform1fv, v_shm_id) == 12, + OffsetOf_Uniform1fv_v_shm_id_not_12); +COMPILE_ASSERT(offsetof(Uniform1fv, v_shm_offset) == 16, + OffsetOf_Uniform1fv_v_shm_offset_not_16); + +struct Uniform1fvImmediate { + typedef Uniform1fvImmediate ValueType; + static const CommandId kCmdId = kUniform1fvImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeDataSize(GLsizei count) { + return static_cast<uint32>( + sizeof(GLfloat) * 1 * count); // NOLINT + } + + static uint32 ComputeSize(GLsizei count) { + return static_cast<uint32>( + sizeof(ValueType) + ComputeDataSize(count)); // NOLINT + } + + void SetHeader(GLsizei count) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(count)); + } + + void Init(GLint _location, GLsizei _count, const GLfloat* _v) { + SetHeader(_count); + location = _location; + count = _count; + memcpy(ImmediateDataAddress(this), + _v, ComputeDataSize(_count)); + } + + void* Set(void* cmd, GLint _location, GLsizei _count, const GLfloat* _v) { + static_cast<ValueType*>(cmd)->Init(_location, _count, _v); + const uint32 size = ComputeSize(_count); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + command_buffer::CommandHeader header; + uint32 location; + uint32 count; +}; + +COMPILE_ASSERT(sizeof(Uniform1fvImmediate) == 12, + Sizeof_Uniform1fvImmediate_is_not_12); +COMPILE_ASSERT(offsetof(Uniform1fvImmediate, header) == 0, + OffsetOf_Uniform1fvImmediate_header_not_0); +COMPILE_ASSERT(offsetof(Uniform1fvImmediate, location) == 4, + OffsetOf_Uniform1fvImmediate_location_not_4); +COMPILE_ASSERT(offsetof(Uniform1fvImmediate, count) == 8, + OffsetOf_Uniform1fvImmediate_count_not_8); + +struct Uniform1i { + typedef Uniform1i ValueType; + static const CommandId kCmdId = kUniform1i; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLint _location, GLint _x) { + SetHeader(); + location = _location; + x = _x; + } + + void* Set(void* cmd, GLint _location, GLint _x) { + static_cast<ValueType*>(cmd)->Init(_location, _x); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 location; + uint32 x; +}; + +COMPILE_ASSERT(sizeof(Uniform1i) == 12, + Sizeof_Uniform1i_is_not_12); +COMPILE_ASSERT(offsetof(Uniform1i, header) == 0, + OffsetOf_Uniform1i_header_not_0); +COMPILE_ASSERT(offsetof(Uniform1i, location) == 4, + OffsetOf_Uniform1i_location_not_4); +COMPILE_ASSERT(offsetof(Uniform1i, x) == 8, + OffsetOf_Uniform1i_x_not_8); + +struct Uniform1iv { + typedef Uniform1iv ValueType; + static const CommandId kCmdId = kUniform1iv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLint _location, GLsizei _count, uint32 _v_shm_id, + uint32 _v_shm_offset) { + SetHeader(); + location = _location; + count = _count; + v_shm_id = _v_shm_id; + v_shm_offset = _v_shm_offset; + } + + void* Set( + void* cmd, GLint _location, GLsizei _count, uint32 _v_shm_id, + uint32 _v_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_location, _count, _v_shm_id, _v_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 location; + uint32 count; + uint32 v_shm_id; + uint32 v_shm_offset; +}; + +COMPILE_ASSERT(sizeof(Uniform1iv) == 20, + Sizeof_Uniform1iv_is_not_20); +COMPILE_ASSERT(offsetof(Uniform1iv, header) == 0, + OffsetOf_Uniform1iv_header_not_0); +COMPILE_ASSERT(offsetof(Uniform1iv, location) == 4, + OffsetOf_Uniform1iv_location_not_4); +COMPILE_ASSERT(offsetof(Uniform1iv, count) == 8, + OffsetOf_Uniform1iv_count_not_8); +COMPILE_ASSERT(offsetof(Uniform1iv, v_shm_id) == 12, + OffsetOf_Uniform1iv_v_shm_id_not_12); +COMPILE_ASSERT(offsetof(Uniform1iv, v_shm_offset) == 16, + OffsetOf_Uniform1iv_v_shm_offset_not_16); + +struct Uniform1ivImmediate { + typedef Uniform1ivImmediate ValueType; + static const CommandId kCmdId = kUniform1ivImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeDataSize(GLsizei count) { + return static_cast<uint32>( + sizeof(GLint) * 1 * count); // NOLINT + } + + static uint32 ComputeSize(GLsizei count) { + return static_cast<uint32>( + sizeof(ValueType) + ComputeDataSize(count)); // NOLINT + } + + void SetHeader(GLsizei count) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(count)); + } + + void Init(GLint _location, GLsizei _count, const GLint* _v) { + SetHeader(_count); + location = _location; + count = _count; + memcpy(ImmediateDataAddress(this), + _v, ComputeDataSize(_count)); + } + + void* Set(void* cmd, GLint _location, GLsizei _count, const GLint* _v) { + static_cast<ValueType*>(cmd)->Init(_location, _count, _v); + const uint32 size = ComputeSize(_count); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + command_buffer::CommandHeader header; + uint32 location; + uint32 count; +}; + +COMPILE_ASSERT(sizeof(Uniform1ivImmediate) == 12, + Sizeof_Uniform1ivImmediate_is_not_12); +COMPILE_ASSERT(offsetof(Uniform1ivImmediate, header) == 0, + OffsetOf_Uniform1ivImmediate_header_not_0); +COMPILE_ASSERT(offsetof(Uniform1ivImmediate, location) == 4, + OffsetOf_Uniform1ivImmediate_location_not_4); +COMPILE_ASSERT(offsetof(Uniform1ivImmediate, count) == 8, + OffsetOf_Uniform1ivImmediate_count_not_8); + +struct Uniform2f { + typedef Uniform2f ValueType; + static const CommandId kCmdId = kUniform2f; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLint _location, GLfloat _x, GLfloat _y) { + SetHeader(); + location = _location; + x = _x; + y = _y; + } + + void* Set(void* cmd, GLint _location, GLfloat _x, GLfloat _y) { + static_cast<ValueType*>(cmd)->Init(_location, _x, _y); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 location; + float x; + float y; +}; + +COMPILE_ASSERT(sizeof(Uniform2f) == 16, + Sizeof_Uniform2f_is_not_16); +COMPILE_ASSERT(offsetof(Uniform2f, header) == 0, + OffsetOf_Uniform2f_header_not_0); +COMPILE_ASSERT(offsetof(Uniform2f, location) == 4, + OffsetOf_Uniform2f_location_not_4); +COMPILE_ASSERT(offsetof(Uniform2f, x) == 8, + OffsetOf_Uniform2f_x_not_8); +COMPILE_ASSERT(offsetof(Uniform2f, y) == 12, + OffsetOf_Uniform2f_y_not_12); + +struct Uniform2fv { + typedef Uniform2fv ValueType; + static const CommandId kCmdId = kUniform2fv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLint _location, GLsizei _count, uint32 _v_shm_id, + uint32 _v_shm_offset) { + SetHeader(); + location = _location; + count = _count; + v_shm_id = _v_shm_id; + v_shm_offset = _v_shm_offset; + } + + void* Set( + void* cmd, GLint _location, GLsizei _count, uint32 _v_shm_id, + uint32 _v_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_location, _count, _v_shm_id, _v_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 location; + uint32 count; + uint32 v_shm_id; + uint32 v_shm_offset; +}; + +COMPILE_ASSERT(sizeof(Uniform2fv) == 20, + Sizeof_Uniform2fv_is_not_20); +COMPILE_ASSERT(offsetof(Uniform2fv, header) == 0, + OffsetOf_Uniform2fv_header_not_0); +COMPILE_ASSERT(offsetof(Uniform2fv, location) == 4, + OffsetOf_Uniform2fv_location_not_4); +COMPILE_ASSERT(offsetof(Uniform2fv, count) == 8, + OffsetOf_Uniform2fv_count_not_8); +COMPILE_ASSERT(offsetof(Uniform2fv, v_shm_id) == 12, + OffsetOf_Uniform2fv_v_shm_id_not_12); +COMPILE_ASSERT(offsetof(Uniform2fv, v_shm_offset) == 16, + OffsetOf_Uniform2fv_v_shm_offset_not_16); + +struct Uniform2fvImmediate { + typedef Uniform2fvImmediate ValueType; + static const CommandId kCmdId = kUniform2fvImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeDataSize(GLsizei count) { + return static_cast<uint32>( + sizeof(GLfloat) * 2 * count); // NOLINT + } + + static uint32 ComputeSize(GLsizei count) { + return static_cast<uint32>( + sizeof(ValueType) + ComputeDataSize(count)); // NOLINT + } + + void SetHeader(GLsizei count) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(count)); + } + + void Init(GLint _location, GLsizei _count, const GLfloat* _v) { + SetHeader(_count); + location = _location; + count = _count; + memcpy(ImmediateDataAddress(this), + _v, ComputeDataSize(_count)); + } + + void* Set(void* cmd, GLint _location, GLsizei _count, const GLfloat* _v) { + static_cast<ValueType*>(cmd)->Init(_location, _count, _v); + const uint32 size = ComputeSize(_count); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + command_buffer::CommandHeader header; + uint32 location; + uint32 count; +}; + +COMPILE_ASSERT(sizeof(Uniform2fvImmediate) == 12, + Sizeof_Uniform2fvImmediate_is_not_12); +COMPILE_ASSERT(offsetof(Uniform2fvImmediate, header) == 0, + OffsetOf_Uniform2fvImmediate_header_not_0); +COMPILE_ASSERT(offsetof(Uniform2fvImmediate, location) == 4, + OffsetOf_Uniform2fvImmediate_location_not_4); +COMPILE_ASSERT(offsetof(Uniform2fvImmediate, count) == 8, + OffsetOf_Uniform2fvImmediate_count_not_8); + +struct Uniform2i { + typedef Uniform2i ValueType; + static const CommandId kCmdId = kUniform2i; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLint _location, GLint _x, GLint _y) { + SetHeader(); + location = _location; + x = _x; + y = _y; + } + + void* Set(void* cmd, GLint _location, GLint _x, GLint _y) { + static_cast<ValueType*>(cmd)->Init(_location, _x, _y); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 location; + uint32 x; + uint32 y; +}; + +COMPILE_ASSERT(sizeof(Uniform2i) == 16, + Sizeof_Uniform2i_is_not_16); +COMPILE_ASSERT(offsetof(Uniform2i, header) == 0, + OffsetOf_Uniform2i_header_not_0); +COMPILE_ASSERT(offsetof(Uniform2i, location) == 4, + OffsetOf_Uniform2i_location_not_4); +COMPILE_ASSERT(offsetof(Uniform2i, x) == 8, + OffsetOf_Uniform2i_x_not_8); +COMPILE_ASSERT(offsetof(Uniform2i, y) == 12, + OffsetOf_Uniform2i_y_not_12); + +struct Uniform2iv { + typedef Uniform2iv ValueType; + static const CommandId kCmdId = kUniform2iv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLint _location, GLsizei _count, uint32 _v_shm_id, + uint32 _v_shm_offset) { + SetHeader(); + location = _location; + count = _count; + v_shm_id = _v_shm_id; + v_shm_offset = _v_shm_offset; + } + + void* Set( + void* cmd, GLint _location, GLsizei _count, uint32 _v_shm_id, + uint32 _v_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_location, _count, _v_shm_id, _v_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 location; + uint32 count; + uint32 v_shm_id; + uint32 v_shm_offset; +}; + +COMPILE_ASSERT(sizeof(Uniform2iv) == 20, + Sizeof_Uniform2iv_is_not_20); +COMPILE_ASSERT(offsetof(Uniform2iv, header) == 0, + OffsetOf_Uniform2iv_header_not_0); +COMPILE_ASSERT(offsetof(Uniform2iv, location) == 4, + OffsetOf_Uniform2iv_location_not_4); +COMPILE_ASSERT(offsetof(Uniform2iv, count) == 8, + OffsetOf_Uniform2iv_count_not_8); +COMPILE_ASSERT(offsetof(Uniform2iv, v_shm_id) == 12, + OffsetOf_Uniform2iv_v_shm_id_not_12); +COMPILE_ASSERT(offsetof(Uniform2iv, v_shm_offset) == 16, + OffsetOf_Uniform2iv_v_shm_offset_not_16); + +struct Uniform2ivImmediate { + typedef Uniform2ivImmediate ValueType; + static const CommandId kCmdId = kUniform2ivImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeDataSize(GLsizei count) { + return static_cast<uint32>( + sizeof(GLint) * 2 * count); // NOLINT + } + + static uint32 ComputeSize(GLsizei count) { + return static_cast<uint32>( + sizeof(ValueType) + ComputeDataSize(count)); // NOLINT + } + + void SetHeader(GLsizei count) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(count)); + } + + void Init(GLint _location, GLsizei _count, const GLint* _v) { + SetHeader(_count); + location = _location; + count = _count; + memcpy(ImmediateDataAddress(this), + _v, ComputeDataSize(_count)); + } + + void* Set(void* cmd, GLint _location, GLsizei _count, const GLint* _v) { + static_cast<ValueType*>(cmd)->Init(_location, _count, _v); + const uint32 size = ComputeSize(_count); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + command_buffer::CommandHeader header; + uint32 location; + uint32 count; +}; + +COMPILE_ASSERT(sizeof(Uniform2ivImmediate) == 12, + Sizeof_Uniform2ivImmediate_is_not_12); +COMPILE_ASSERT(offsetof(Uniform2ivImmediate, header) == 0, + OffsetOf_Uniform2ivImmediate_header_not_0); +COMPILE_ASSERT(offsetof(Uniform2ivImmediate, location) == 4, + OffsetOf_Uniform2ivImmediate_location_not_4); +COMPILE_ASSERT(offsetof(Uniform2ivImmediate, count) == 8, + OffsetOf_Uniform2ivImmediate_count_not_8); + +struct Uniform3f { + typedef Uniform3f ValueType; + static const CommandId kCmdId = kUniform3f; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLint _location, GLfloat _x, GLfloat _y, GLfloat _z) { + SetHeader(); + location = _location; + x = _x; + y = _y; + z = _z; + } + + void* Set(void* cmd, GLint _location, GLfloat _x, GLfloat _y, GLfloat _z) { + static_cast<ValueType*>(cmd)->Init(_location, _x, _y, _z); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 location; + float x; + float y; + float z; +}; + +COMPILE_ASSERT(sizeof(Uniform3f) == 20, + Sizeof_Uniform3f_is_not_20); +COMPILE_ASSERT(offsetof(Uniform3f, header) == 0, + OffsetOf_Uniform3f_header_not_0); +COMPILE_ASSERT(offsetof(Uniform3f, location) == 4, + OffsetOf_Uniform3f_location_not_4); +COMPILE_ASSERT(offsetof(Uniform3f, x) == 8, + OffsetOf_Uniform3f_x_not_8); +COMPILE_ASSERT(offsetof(Uniform3f, y) == 12, + OffsetOf_Uniform3f_y_not_12); +COMPILE_ASSERT(offsetof(Uniform3f, z) == 16, + OffsetOf_Uniform3f_z_not_16); + +struct Uniform3fv { + typedef Uniform3fv ValueType; + static const CommandId kCmdId = kUniform3fv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLint _location, GLsizei _count, uint32 _v_shm_id, + uint32 _v_shm_offset) { + SetHeader(); + location = _location; + count = _count; + v_shm_id = _v_shm_id; + v_shm_offset = _v_shm_offset; + } + + void* Set( + void* cmd, GLint _location, GLsizei _count, uint32 _v_shm_id, + uint32 _v_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_location, _count, _v_shm_id, _v_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 location; + uint32 count; + uint32 v_shm_id; + uint32 v_shm_offset; +}; + +COMPILE_ASSERT(sizeof(Uniform3fv) == 20, + Sizeof_Uniform3fv_is_not_20); +COMPILE_ASSERT(offsetof(Uniform3fv, header) == 0, + OffsetOf_Uniform3fv_header_not_0); +COMPILE_ASSERT(offsetof(Uniform3fv, location) == 4, + OffsetOf_Uniform3fv_location_not_4); +COMPILE_ASSERT(offsetof(Uniform3fv, count) == 8, + OffsetOf_Uniform3fv_count_not_8); +COMPILE_ASSERT(offsetof(Uniform3fv, v_shm_id) == 12, + OffsetOf_Uniform3fv_v_shm_id_not_12); +COMPILE_ASSERT(offsetof(Uniform3fv, v_shm_offset) == 16, + OffsetOf_Uniform3fv_v_shm_offset_not_16); + +struct Uniform3fvImmediate { + typedef Uniform3fvImmediate ValueType; + static const CommandId kCmdId = kUniform3fvImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeDataSize(GLsizei count) { + return static_cast<uint32>( + sizeof(GLfloat) * 3 * count); // NOLINT + } + + static uint32 ComputeSize(GLsizei count) { + return static_cast<uint32>( + sizeof(ValueType) + ComputeDataSize(count)); // NOLINT + } + + void SetHeader(GLsizei count) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(count)); + } + + void Init(GLint _location, GLsizei _count, const GLfloat* _v) { + SetHeader(_count); + location = _location; + count = _count; + memcpy(ImmediateDataAddress(this), + _v, ComputeDataSize(_count)); + } + + void* Set(void* cmd, GLint _location, GLsizei _count, const GLfloat* _v) { + static_cast<ValueType*>(cmd)->Init(_location, _count, _v); + const uint32 size = ComputeSize(_count); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + command_buffer::CommandHeader header; + uint32 location; + uint32 count; +}; + +COMPILE_ASSERT(sizeof(Uniform3fvImmediate) == 12, + Sizeof_Uniform3fvImmediate_is_not_12); +COMPILE_ASSERT(offsetof(Uniform3fvImmediate, header) == 0, + OffsetOf_Uniform3fvImmediate_header_not_0); +COMPILE_ASSERT(offsetof(Uniform3fvImmediate, location) == 4, + OffsetOf_Uniform3fvImmediate_location_not_4); +COMPILE_ASSERT(offsetof(Uniform3fvImmediate, count) == 8, + OffsetOf_Uniform3fvImmediate_count_not_8); + +struct Uniform3i { + typedef Uniform3i ValueType; + static const CommandId kCmdId = kUniform3i; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLint _location, GLint _x, GLint _y, GLint _z) { + SetHeader(); + location = _location; + x = _x; + y = _y; + z = _z; + } + + void* Set(void* cmd, GLint _location, GLint _x, GLint _y, GLint _z) { + static_cast<ValueType*>(cmd)->Init(_location, _x, _y, _z); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 location; + uint32 x; + uint32 y; + uint32 z; +}; + +COMPILE_ASSERT(sizeof(Uniform3i) == 20, + Sizeof_Uniform3i_is_not_20); +COMPILE_ASSERT(offsetof(Uniform3i, header) == 0, + OffsetOf_Uniform3i_header_not_0); +COMPILE_ASSERT(offsetof(Uniform3i, location) == 4, + OffsetOf_Uniform3i_location_not_4); +COMPILE_ASSERT(offsetof(Uniform3i, x) == 8, + OffsetOf_Uniform3i_x_not_8); +COMPILE_ASSERT(offsetof(Uniform3i, y) == 12, + OffsetOf_Uniform3i_y_not_12); +COMPILE_ASSERT(offsetof(Uniform3i, z) == 16, + OffsetOf_Uniform3i_z_not_16); + +struct Uniform3iv { + typedef Uniform3iv ValueType; + static const CommandId kCmdId = kUniform3iv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLint _location, GLsizei _count, uint32 _v_shm_id, + uint32 _v_shm_offset) { + SetHeader(); + location = _location; + count = _count; + v_shm_id = _v_shm_id; + v_shm_offset = _v_shm_offset; + } + + void* Set( + void* cmd, GLint _location, GLsizei _count, uint32 _v_shm_id, + uint32 _v_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_location, _count, _v_shm_id, _v_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 location; + uint32 count; + uint32 v_shm_id; + uint32 v_shm_offset; +}; + +COMPILE_ASSERT(sizeof(Uniform3iv) == 20, + Sizeof_Uniform3iv_is_not_20); +COMPILE_ASSERT(offsetof(Uniform3iv, header) == 0, + OffsetOf_Uniform3iv_header_not_0); +COMPILE_ASSERT(offsetof(Uniform3iv, location) == 4, + OffsetOf_Uniform3iv_location_not_4); +COMPILE_ASSERT(offsetof(Uniform3iv, count) == 8, + OffsetOf_Uniform3iv_count_not_8); +COMPILE_ASSERT(offsetof(Uniform3iv, v_shm_id) == 12, + OffsetOf_Uniform3iv_v_shm_id_not_12); +COMPILE_ASSERT(offsetof(Uniform3iv, v_shm_offset) == 16, + OffsetOf_Uniform3iv_v_shm_offset_not_16); + +struct Uniform3ivImmediate { + typedef Uniform3ivImmediate ValueType; + static const CommandId kCmdId = kUniform3ivImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeDataSize(GLsizei count) { + return static_cast<uint32>( + sizeof(GLint) * 3 * count); // NOLINT + } + + static uint32 ComputeSize(GLsizei count) { + return static_cast<uint32>( + sizeof(ValueType) + ComputeDataSize(count)); // NOLINT + } + + void SetHeader(GLsizei count) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(count)); + } + + void Init(GLint _location, GLsizei _count, const GLint* _v) { + SetHeader(_count); + location = _location; + count = _count; + memcpy(ImmediateDataAddress(this), + _v, ComputeDataSize(_count)); + } + + void* Set(void* cmd, GLint _location, GLsizei _count, const GLint* _v) { + static_cast<ValueType*>(cmd)->Init(_location, _count, _v); + const uint32 size = ComputeSize(_count); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + command_buffer::CommandHeader header; + uint32 location; + uint32 count; +}; + +COMPILE_ASSERT(sizeof(Uniform3ivImmediate) == 12, + Sizeof_Uniform3ivImmediate_is_not_12); +COMPILE_ASSERT(offsetof(Uniform3ivImmediate, header) == 0, + OffsetOf_Uniform3ivImmediate_header_not_0); +COMPILE_ASSERT(offsetof(Uniform3ivImmediate, location) == 4, + OffsetOf_Uniform3ivImmediate_location_not_4); +COMPILE_ASSERT(offsetof(Uniform3ivImmediate, count) == 8, + OffsetOf_Uniform3ivImmediate_count_not_8); + +struct Uniform4f { + typedef Uniform4f ValueType; + static const CommandId kCmdId = kUniform4f; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLint _location, GLfloat _x, GLfloat _y, GLfloat _z, GLfloat _w) { + SetHeader(); + location = _location; + x = _x; + y = _y; + z = _z; + w = _w; + } + + void* Set( + void* cmd, GLint _location, GLfloat _x, GLfloat _y, GLfloat _z, + GLfloat _w) { + static_cast<ValueType*>(cmd)->Init(_location, _x, _y, _z, _w); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 location; + float x; + float y; + float z; + float w; +}; + +COMPILE_ASSERT(sizeof(Uniform4f) == 24, + Sizeof_Uniform4f_is_not_24); +COMPILE_ASSERT(offsetof(Uniform4f, header) == 0, + OffsetOf_Uniform4f_header_not_0); +COMPILE_ASSERT(offsetof(Uniform4f, location) == 4, + OffsetOf_Uniform4f_location_not_4); +COMPILE_ASSERT(offsetof(Uniform4f, x) == 8, + OffsetOf_Uniform4f_x_not_8); +COMPILE_ASSERT(offsetof(Uniform4f, y) == 12, + OffsetOf_Uniform4f_y_not_12); +COMPILE_ASSERT(offsetof(Uniform4f, z) == 16, + OffsetOf_Uniform4f_z_not_16); +COMPILE_ASSERT(offsetof(Uniform4f, w) == 20, + OffsetOf_Uniform4f_w_not_20); + +struct Uniform4fv { + typedef Uniform4fv ValueType; + static const CommandId kCmdId = kUniform4fv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLint _location, GLsizei _count, uint32 _v_shm_id, + uint32 _v_shm_offset) { + SetHeader(); + location = _location; + count = _count; + v_shm_id = _v_shm_id; + v_shm_offset = _v_shm_offset; + } + + void* Set( + void* cmd, GLint _location, GLsizei _count, uint32 _v_shm_id, + uint32 _v_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_location, _count, _v_shm_id, _v_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 location; + uint32 count; + uint32 v_shm_id; + uint32 v_shm_offset; +}; + +COMPILE_ASSERT(sizeof(Uniform4fv) == 20, + Sizeof_Uniform4fv_is_not_20); +COMPILE_ASSERT(offsetof(Uniform4fv, header) == 0, + OffsetOf_Uniform4fv_header_not_0); +COMPILE_ASSERT(offsetof(Uniform4fv, location) == 4, + OffsetOf_Uniform4fv_location_not_4); +COMPILE_ASSERT(offsetof(Uniform4fv, count) == 8, + OffsetOf_Uniform4fv_count_not_8); +COMPILE_ASSERT(offsetof(Uniform4fv, v_shm_id) == 12, + OffsetOf_Uniform4fv_v_shm_id_not_12); +COMPILE_ASSERT(offsetof(Uniform4fv, v_shm_offset) == 16, + OffsetOf_Uniform4fv_v_shm_offset_not_16); + +struct Uniform4fvImmediate { + typedef Uniform4fvImmediate ValueType; + static const CommandId kCmdId = kUniform4fvImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeDataSize(GLsizei count) { + return static_cast<uint32>( + sizeof(GLfloat) * 4 * count); // NOLINT + } + + static uint32 ComputeSize(GLsizei count) { + return static_cast<uint32>( + sizeof(ValueType) + ComputeDataSize(count)); // NOLINT + } + + void SetHeader(GLsizei count) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(count)); + } + + void Init(GLint _location, GLsizei _count, const GLfloat* _v) { + SetHeader(_count); + location = _location; + count = _count; + memcpy(ImmediateDataAddress(this), + _v, ComputeDataSize(_count)); + } + + void* Set(void* cmd, GLint _location, GLsizei _count, const GLfloat* _v) { + static_cast<ValueType*>(cmd)->Init(_location, _count, _v); + const uint32 size = ComputeSize(_count); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + command_buffer::CommandHeader header; + uint32 location; + uint32 count; +}; + +COMPILE_ASSERT(sizeof(Uniform4fvImmediate) == 12, + Sizeof_Uniform4fvImmediate_is_not_12); +COMPILE_ASSERT(offsetof(Uniform4fvImmediate, header) == 0, + OffsetOf_Uniform4fvImmediate_header_not_0); +COMPILE_ASSERT(offsetof(Uniform4fvImmediate, location) == 4, + OffsetOf_Uniform4fvImmediate_location_not_4); +COMPILE_ASSERT(offsetof(Uniform4fvImmediate, count) == 8, + OffsetOf_Uniform4fvImmediate_count_not_8); + +struct Uniform4i { + typedef Uniform4i ValueType; + static const CommandId kCmdId = kUniform4i; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLint _location, GLint _x, GLint _y, GLint _z, GLint _w) { + SetHeader(); + location = _location; + x = _x; + y = _y; + z = _z; + w = _w; + } + + void* Set( + void* cmd, GLint _location, GLint _x, GLint _y, GLint _z, GLint _w) { + static_cast<ValueType*>(cmd)->Init(_location, _x, _y, _z, _w); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 location; + uint32 x; + uint32 y; + uint32 z; + uint32 w; +}; + +COMPILE_ASSERT(sizeof(Uniform4i) == 24, + Sizeof_Uniform4i_is_not_24); +COMPILE_ASSERT(offsetof(Uniform4i, header) == 0, + OffsetOf_Uniform4i_header_not_0); +COMPILE_ASSERT(offsetof(Uniform4i, location) == 4, + OffsetOf_Uniform4i_location_not_4); +COMPILE_ASSERT(offsetof(Uniform4i, x) == 8, + OffsetOf_Uniform4i_x_not_8); +COMPILE_ASSERT(offsetof(Uniform4i, y) == 12, + OffsetOf_Uniform4i_y_not_12); +COMPILE_ASSERT(offsetof(Uniform4i, z) == 16, + OffsetOf_Uniform4i_z_not_16); +COMPILE_ASSERT(offsetof(Uniform4i, w) == 20, + OffsetOf_Uniform4i_w_not_20); + +struct Uniform4iv { + typedef Uniform4iv ValueType; + static const CommandId kCmdId = kUniform4iv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLint _location, GLsizei _count, uint32 _v_shm_id, + uint32 _v_shm_offset) { + SetHeader(); + location = _location; + count = _count; + v_shm_id = _v_shm_id; + v_shm_offset = _v_shm_offset; + } + + void* Set( + void* cmd, GLint _location, GLsizei _count, uint32 _v_shm_id, + uint32 _v_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_location, _count, _v_shm_id, _v_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 location; + uint32 count; + uint32 v_shm_id; + uint32 v_shm_offset; +}; + +COMPILE_ASSERT(sizeof(Uniform4iv) == 20, + Sizeof_Uniform4iv_is_not_20); +COMPILE_ASSERT(offsetof(Uniform4iv, header) == 0, + OffsetOf_Uniform4iv_header_not_0); +COMPILE_ASSERT(offsetof(Uniform4iv, location) == 4, + OffsetOf_Uniform4iv_location_not_4); +COMPILE_ASSERT(offsetof(Uniform4iv, count) == 8, + OffsetOf_Uniform4iv_count_not_8); +COMPILE_ASSERT(offsetof(Uniform4iv, v_shm_id) == 12, + OffsetOf_Uniform4iv_v_shm_id_not_12); +COMPILE_ASSERT(offsetof(Uniform4iv, v_shm_offset) == 16, + OffsetOf_Uniform4iv_v_shm_offset_not_16); + +struct Uniform4ivImmediate { + typedef Uniform4ivImmediate ValueType; + static const CommandId kCmdId = kUniform4ivImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeDataSize(GLsizei count) { + return static_cast<uint32>( + sizeof(GLint) * 4 * count); // NOLINT + } + + static uint32 ComputeSize(GLsizei count) { + return static_cast<uint32>( + sizeof(ValueType) + ComputeDataSize(count)); // NOLINT + } + + void SetHeader(GLsizei count) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(count)); + } + + void Init(GLint _location, GLsizei _count, const GLint* _v) { + SetHeader(_count); + location = _location; + count = _count; + memcpy(ImmediateDataAddress(this), + _v, ComputeDataSize(_count)); + } + + void* Set(void* cmd, GLint _location, GLsizei _count, const GLint* _v) { + static_cast<ValueType*>(cmd)->Init(_location, _count, _v); + const uint32 size = ComputeSize(_count); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + command_buffer::CommandHeader header; + uint32 location; + uint32 count; +}; + +COMPILE_ASSERT(sizeof(Uniform4ivImmediate) == 12, + Sizeof_Uniform4ivImmediate_is_not_12); +COMPILE_ASSERT(offsetof(Uniform4ivImmediate, header) == 0, + OffsetOf_Uniform4ivImmediate_header_not_0); +COMPILE_ASSERT(offsetof(Uniform4ivImmediate, location) == 4, + OffsetOf_Uniform4ivImmediate_location_not_4); +COMPILE_ASSERT(offsetof(Uniform4ivImmediate, count) == 8, + OffsetOf_Uniform4ivImmediate_count_not_8); + +struct UniformMatrix2fv { + typedef UniformMatrix2fv ValueType; + static const CommandId kCmdId = kUniformMatrix2fv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLint _location, GLsizei _count, GLboolean _transpose, + uint32 _value_shm_id, uint32 _value_shm_offset) { + SetHeader(); + location = _location; + count = _count; + transpose = _transpose; + value_shm_id = _value_shm_id; + value_shm_offset = _value_shm_offset; + } + + void* Set( + void* cmd, GLint _location, GLsizei _count, GLboolean _transpose, + uint32 _value_shm_id, uint32 _value_shm_offset) { + static_cast<ValueType*>( + cmd)->Init( + _location, _count, _transpose, _value_shm_id, _value_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 location; + uint32 count; + uint32 transpose; + uint32 value_shm_id; + uint32 value_shm_offset; +}; + +COMPILE_ASSERT(sizeof(UniformMatrix2fv) == 24, + Sizeof_UniformMatrix2fv_is_not_24); +COMPILE_ASSERT(offsetof(UniformMatrix2fv, header) == 0, + OffsetOf_UniformMatrix2fv_header_not_0); +COMPILE_ASSERT(offsetof(UniformMatrix2fv, location) == 4, + OffsetOf_UniformMatrix2fv_location_not_4); +COMPILE_ASSERT(offsetof(UniformMatrix2fv, count) == 8, + OffsetOf_UniformMatrix2fv_count_not_8); +COMPILE_ASSERT(offsetof(UniformMatrix2fv, transpose) == 12, + OffsetOf_UniformMatrix2fv_transpose_not_12); +COMPILE_ASSERT(offsetof(UniformMatrix2fv, value_shm_id) == 16, + OffsetOf_UniformMatrix2fv_value_shm_id_not_16); +COMPILE_ASSERT(offsetof(UniformMatrix2fv, value_shm_offset) == 20, + OffsetOf_UniformMatrix2fv_value_shm_offset_not_20); + +struct UniformMatrix2fvImmediate { + typedef UniformMatrix2fvImmediate ValueType; + static const CommandId kCmdId = kUniformMatrix2fvImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeDataSize(GLsizei count) { + return static_cast<uint32>( + sizeof(GLfloat) * 4 * count); // NOLINT + } + + static uint32 ComputeSize(GLsizei count) { + return static_cast<uint32>( + sizeof(ValueType) + ComputeDataSize(count)); // NOLINT + } + + void SetHeader(GLsizei count) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(count)); + } + + void Init( + GLint _location, GLsizei _count, GLboolean _transpose, + const GLfloat* _value) { + SetHeader(_count); + location = _location; + count = _count; + transpose = _transpose; + memcpy(ImmediateDataAddress(this), + _value, ComputeDataSize(_count)); + } + + void* Set( + void* cmd, GLint _location, GLsizei _count, GLboolean _transpose, + const GLfloat* _value) { + static_cast<ValueType*>(cmd)->Init(_location, _count, _transpose, _value); + const uint32 size = ComputeSize(_count); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + command_buffer::CommandHeader header; + uint32 location; + uint32 count; + uint32 transpose; +}; + +COMPILE_ASSERT(sizeof(UniformMatrix2fvImmediate) == 16, + Sizeof_UniformMatrix2fvImmediate_is_not_16); +COMPILE_ASSERT(offsetof(UniformMatrix2fvImmediate, header) == 0, + OffsetOf_UniformMatrix2fvImmediate_header_not_0); +COMPILE_ASSERT(offsetof(UniformMatrix2fvImmediate, location) == 4, + OffsetOf_UniformMatrix2fvImmediate_location_not_4); +COMPILE_ASSERT(offsetof(UniformMatrix2fvImmediate, count) == 8, + OffsetOf_UniformMatrix2fvImmediate_count_not_8); +COMPILE_ASSERT(offsetof(UniformMatrix2fvImmediate, transpose) == 12, + OffsetOf_UniformMatrix2fvImmediate_transpose_not_12); + +struct UniformMatrix3fv { + typedef UniformMatrix3fv ValueType; + static const CommandId kCmdId = kUniformMatrix3fv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLint _location, GLsizei _count, GLboolean _transpose, + uint32 _value_shm_id, uint32 _value_shm_offset) { + SetHeader(); + location = _location; + count = _count; + transpose = _transpose; + value_shm_id = _value_shm_id; + value_shm_offset = _value_shm_offset; + } + + void* Set( + void* cmd, GLint _location, GLsizei _count, GLboolean _transpose, + uint32 _value_shm_id, uint32 _value_shm_offset) { + static_cast<ValueType*>( + cmd)->Init( + _location, _count, _transpose, _value_shm_id, _value_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 location; + uint32 count; + uint32 transpose; + uint32 value_shm_id; + uint32 value_shm_offset; +}; + +COMPILE_ASSERT(sizeof(UniformMatrix3fv) == 24, + Sizeof_UniformMatrix3fv_is_not_24); +COMPILE_ASSERT(offsetof(UniformMatrix3fv, header) == 0, + OffsetOf_UniformMatrix3fv_header_not_0); +COMPILE_ASSERT(offsetof(UniformMatrix3fv, location) == 4, + OffsetOf_UniformMatrix3fv_location_not_4); +COMPILE_ASSERT(offsetof(UniformMatrix3fv, count) == 8, + OffsetOf_UniformMatrix3fv_count_not_8); +COMPILE_ASSERT(offsetof(UniformMatrix3fv, transpose) == 12, + OffsetOf_UniformMatrix3fv_transpose_not_12); +COMPILE_ASSERT(offsetof(UniformMatrix3fv, value_shm_id) == 16, + OffsetOf_UniformMatrix3fv_value_shm_id_not_16); +COMPILE_ASSERT(offsetof(UniformMatrix3fv, value_shm_offset) == 20, + OffsetOf_UniformMatrix3fv_value_shm_offset_not_20); + +struct UniformMatrix3fvImmediate { + typedef UniformMatrix3fvImmediate ValueType; + static const CommandId kCmdId = kUniformMatrix3fvImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeDataSize(GLsizei count) { + return static_cast<uint32>( + sizeof(GLfloat) * 9 * count); // NOLINT + } + + static uint32 ComputeSize(GLsizei count) { + return static_cast<uint32>( + sizeof(ValueType) + ComputeDataSize(count)); // NOLINT + } + + void SetHeader(GLsizei count) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(count)); + } + + void Init( + GLint _location, GLsizei _count, GLboolean _transpose, + const GLfloat* _value) { + SetHeader(_count); + location = _location; + count = _count; + transpose = _transpose; + memcpy(ImmediateDataAddress(this), + _value, ComputeDataSize(_count)); + } + + void* Set( + void* cmd, GLint _location, GLsizei _count, GLboolean _transpose, + const GLfloat* _value) { + static_cast<ValueType*>(cmd)->Init(_location, _count, _transpose, _value); + const uint32 size = ComputeSize(_count); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + command_buffer::CommandHeader header; + uint32 location; + uint32 count; + uint32 transpose; +}; + +COMPILE_ASSERT(sizeof(UniformMatrix3fvImmediate) == 16, + Sizeof_UniformMatrix3fvImmediate_is_not_16); +COMPILE_ASSERT(offsetof(UniformMatrix3fvImmediate, header) == 0, + OffsetOf_UniformMatrix3fvImmediate_header_not_0); +COMPILE_ASSERT(offsetof(UniformMatrix3fvImmediate, location) == 4, + OffsetOf_UniformMatrix3fvImmediate_location_not_4); +COMPILE_ASSERT(offsetof(UniformMatrix3fvImmediate, count) == 8, + OffsetOf_UniformMatrix3fvImmediate_count_not_8); +COMPILE_ASSERT(offsetof(UniformMatrix3fvImmediate, transpose) == 12, + OffsetOf_UniformMatrix3fvImmediate_transpose_not_12); + +struct UniformMatrix4fv { + typedef UniformMatrix4fv ValueType; + static const CommandId kCmdId = kUniformMatrix4fv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLint _location, GLsizei _count, GLboolean _transpose, + uint32 _value_shm_id, uint32 _value_shm_offset) { + SetHeader(); + location = _location; + count = _count; + transpose = _transpose; + value_shm_id = _value_shm_id; + value_shm_offset = _value_shm_offset; + } + + void* Set( + void* cmd, GLint _location, GLsizei _count, GLboolean _transpose, + uint32 _value_shm_id, uint32 _value_shm_offset) { + static_cast<ValueType*>( + cmd)->Init( + _location, _count, _transpose, _value_shm_id, _value_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 location; + uint32 count; + uint32 transpose; + uint32 value_shm_id; + uint32 value_shm_offset; +}; + +COMPILE_ASSERT(sizeof(UniformMatrix4fv) == 24, + Sizeof_UniformMatrix4fv_is_not_24); +COMPILE_ASSERT(offsetof(UniformMatrix4fv, header) == 0, + OffsetOf_UniformMatrix4fv_header_not_0); +COMPILE_ASSERT(offsetof(UniformMatrix4fv, location) == 4, + OffsetOf_UniformMatrix4fv_location_not_4); +COMPILE_ASSERT(offsetof(UniformMatrix4fv, count) == 8, + OffsetOf_UniformMatrix4fv_count_not_8); +COMPILE_ASSERT(offsetof(UniformMatrix4fv, transpose) == 12, + OffsetOf_UniformMatrix4fv_transpose_not_12); +COMPILE_ASSERT(offsetof(UniformMatrix4fv, value_shm_id) == 16, + OffsetOf_UniformMatrix4fv_value_shm_id_not_16); +COMPILE_ASSERT(offsetof(UniformMatrix4fv, value_shm_offset) == 20, + OffsetOf_UniformMatrix4fv_value_shm_offset_not_20); + +struct UniformMatrix4fvImmediate { + typedef UniformMatrix4fvImmediate ValueType; + static const CommandId kCmdId = kUniformMatrix4fvImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeDataSize(GLsizei count) { + return static_cast<uint32>( + sizeof(GLfloat) * 16 * count); // NOLINT + } + + static uint32 ComputeSize(GLsizei count) { + return static_cast<uint32>( + sizeof(ValueType) + ComputeDataSize(count)); // NOLINT + } + + void SetHeader(GLsizei count) { + header.SetCmdByTotalSize<ValueType>(ComputeSize(count)); + } + + void Init( + GLint _location, GLsizei _count, GLboolean _transpose, + const GLfloat* _value) { + SetHeader(_count); + location = _location; + count = _count; + transpose = _transpose; + memcpy(ImmediateDataAddress(this), + _value, ComputeDataSize(_count)); + } + + void* Set( + void* cmd, GLint _location, GLsizei _count, GLboolean _transpose, + const GLfloat* _value) { + static_cast<ValueType*>(cmd)->Init(_location, _count, _transpose, _value); + const uint32 size = ComputeSize(_count); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + command_buffer::CommandHeader header; + uint32 location; + uint32 count; + uint32 transpose; +}; + +COMPILE_ASSERT(sizeof(UniformMatrix4fvImmediate) == 16, + Sizeof_UniformMatrix4fvImmediate_is_not_16); +COMPILE_ASSERT(offsetof(UniformMatrix4fvImmediate, header) == 0, + OffsetOf_UniformMatrix4fvImmediate_header_not_0); +COMPILE_ASSERT(offsetof(UniformMatrix4fvImmediate, location) == 4, + OffsetOf_UniformMatrix4fvImmediate_location_not_4); +COMPILE_ASSERT(offsetof(UniformMatrix4fvImmediate, count) == 8, + OffsetOf_UniformMatrix4fvImmediate_count_not_8); +COMPILE_ASSERT(offsetof(UniformMatrix4fvImmediate, transpose) == 12, + OffsetOf_UniformMatrix4fvImmediate_transpose_not_12); + +struct UseProgram { + typedef UseProgram ValueType; + static const CommandId kCmdId = kUseProgram; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLuint _program) { + SetHeader(); + program = _program; + } + + void* Set(void* cmd, GLuint _program) { + static_cast<ValueType*>(cmd)->Init(_program); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 program; +}; + +COMPILE_ASSERT(sizeof(UseProgram) == 8, + Sizeof_UseProgram_is_not_8); +COMPILE_ASSERT(offsetof(UseProgram, header) == 0, + OffsetOf_UseProgram_header_not_0); +COMPILE_ASSERT(offsetof(UseProgram, program) == 4, + OffsetOf_UseProgram_program_not_4); + +struct ValidateProgram { + typedef ValidateProgram ValueType; + static const CommandId kCmdId = kValidateProgram; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLuint _program) { + SetHeader(); + program = _program; + } + + void* Set(void* cmd, GLuint _program) { + static_cast<ValueType*>(cmd)->Init(_program); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 program; +}; + +COMPILE_ASSERT(sizeof(ValidateProgram) == 8, + Sizeof_ValidateProgram_is_not_8); +COMPILE_ASSERT(offsetof(ValidateProgram, header) == 0, + OffsetOf_ValidateProgram_header_not_0); +COMPILE_ASSERT(offsetof(ValidateProgram, program) == 4, + OffsetOf_ValidateProgram_program_not_4); + +struct VertexAttrib1f { + typedef VertexAttrib1f ValueType; + static const CommandId kCmdId = kVertexAttrib1f; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLuint _indx, GLfloat _x) { + SetHeader(); + indx = _indx; + x = _x; + } + + void* Set(void* cmd, GLuint _indx, GLfloat _x) { + static_cast<ValueType*>(cmd)->Init(_indx, _x); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 indx; + float x; +}; + +COMPILE_ASSERT(sizeof(VertexAttrib1f) == 12, + Sizeof_VertexAttrib1f_is_not_12); +COMPILE_ASSERT(offsetof(VertexAttrib1f, header) == 0, + OffsetOf_VertexAttrib1f_header_not_0); +COMPILE_ASSERT(offsetof(VertexAttrib1f, indx) == 4, + OffsetOf_VertexAttrib1f_indx_not_4); +COMPILE_ASSERT(offsetof(VertexAttrib1f, x) == 8, + OffsetOf_VertexAttrib1f_x_not_8); + +struct VertexAttrib1fv { + typedef VertexAttrib1fv ValueType; + static const CommandId kCmdId = kVertexAttrib1fv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLuint _indx, uint32 _values_shm_id, uint32 _values_shm_offset) { + SetHeader(); + indx = _indx; + values_shm_id = _values_shm_id; + values_shm_offset = _values_shm_offset; + } + + void* Set( + void* cmd, GLuint _indx, uint32 _values_shm_id, + uint32 _values_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_indx, _values_shm_id, _values_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 indx; + uint32 values_shm_id; + uint32 values_shm_offset; +}; + +COMPILE_ASSERT(sizeof(VertexAttrib1fv) == 16, + Sizeof_VertexAttrib1fv_is_not_16); +COMPILE_ASSERT(offsetof(VertexAttrib1fv, header) == 0, + OffsetOf_VertexAttrib1fv_header_not_0); +COMPILE_ASSERT(offsetof(VertexAttrib1fv, indx) == 4, + OffsetOf_VertexAttrib1fv_indx_not_4); +COMPILE_ASSERT(offsetof(VertexAttrib1fv, values_shm_id) == 8, + OffsetOf_VertexAttrib1fv_values_shm_id_not_8); +COMPILE_ASSERT(offsetof(VertexAttrib1fv, values_shm_offset) == 12, + OffsetOf_VertexAttrib1fv_values_shm_offset_not_12); + +struct VertexAttrib1fvImmediate { + typedef VertexAttrib1fvImmediate ValueType; + static const CommandId kCmdId = kVertexAttrib1fvImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeDataSize() { + return static_cast<uint32>( + sizeof(GLfloat) * 1); // NOLINT + } + + static uint32 ComputeSize() { + return static_cast<uint32>( + sizeof(ValueType) + ComputeDataSize()); // NOLINT + } + + void SetHeader() { + header.SetCmdByTotalSize<ValueType>(ComputeSize()); + } + + void Init(GLuint _indx, const GLfloat* _values) { + SetHeader(); + indx = _indx; + memcpy(ImmediateDataAddress(this), + _values, ComputeDataSize()); + } + + void* Set(void* cmd, GLuint _indx, const GLfloat* _values) { + static_cast<ValueType*>(cmd)->Init(_indx, _values); + const uint32 size = ComputeSize(); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + command_buffer::CommandHeader header; + uint32 indx; +}; + +COMPILE_ASSERT(sizeof(VertexAttrib1fvImmediate) == 8, + Sizeof_VertexAttrib1fvImmediate_is_not_8); +COMPILE_ASSERT(offsetof(VertexAttrib1fvImmediate, header) == 0, + OffsetOf_VertexAttrib1fvImmediate_header_not_0); +COMPILE_ASSERT(offsetof(VertexAttrib1fvImmediate, indx) == 4, + OffsetOf_VertexAttrib1fvImmediate_indx_not_4); + +struct VertexAttrib2f { + typedef VertexAttrib2f ValueType; + static const CommandId kCmdId = kVertexAttrib2f; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLuint _indx, GLfloat _x, GLfloat _y) { + SetHeader(); + indx = _indx; + x = _x; + y = _y; + } + + void* Set(void* cmd, GLuint _indx, GLfloat _x, GLfloat _y) { + static_cast<ValueType*>(cmd)->Init(_indx, _x, _y); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 indx; + float x; + float y; +}; + +COMPILE_ASSERT(sizeof(VertexAttrib2f) == 16, + Sizeof_VertexAttrib2f_is_not_16); +COMPILE_ASSERT(offsetof(VertexAttrib2f, header) == 0, + OffsetOf_VertexAttrib2f_header_not_0); +COMPILE_ASSERT(offsetof(VertexAttrib2f, indx) == 4, + OffsetOf_VertexAttrib2f_indx_not_4); +COMPILE_ASSERT(offsetof(VertexAttrib2f, x) == 8, + OffsetOf_VertexAttrib2f_x_not_8); +COMPILE_ASSERT(offsetof(VertexAttrib2f, y) == 12, + OffsetOf_VertexAttrib2f_y_not_12); + +struct VertexAttrib2fv { + typedef VertexAttrib2fv ValueType; + static const CommandId kCmdId = kVertexAttrib2fv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLuint _indx, uint32 _values_shm_id, uint32 _values_shm_offset) { + SetHeader(); + indx = _indx; + values_shm_id = _values_shm_id; + values_shm_offset = _values_shm_offset; + } + + void* Set( + void* cmd, GLuint _indx, uint32 _values_shm_id, + uint32 _values_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_indx, _values_shm_id, _values_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 indx; + uint32 values_shm_id; + uint32 values_shm_offset; +}; + +COMPILE_ASSERT(sizeof(VertexAttrib2fv) == 16, + Sizeof_VertexAttrib2fv_is_not_16); +COMPILE_ASSERT(offsetof(VertexAttrib2fv, header) == 0, + OffsetOf_VertexAttrib2fv_header_not_0); +COMPILE_ASSERT(offsetof(VertexAttrib2fv, indx) == 4, + OffsetOf_VertexAttrib2fv_indx_not_4); +COMPILE_ASSERT(offsetof(VertexAttrib2fv, values_shm_id) == 8, + OffsetOf_VertexAttrib2fv_values_shm_id_not_8); +COMPILE_ASSERT(offsetof(VertexAttrib2fv, values_shm_offset) == 12, + OffsetOf_VertexAttrib2fv_values_shm_offset_not_12); + +struct VertexAttrib2fvImmediate { + typedef VertexAttrib2fvImmediate ValueType; + static const CommandId kCmdId = kVertexAttrib2fvImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeDataSize() { + return static_cast<uint32>( + sizeof(GLfloat) * 2); // NOLINT + } + + static uint32 ComputeSize() { + return static_cast<uint32>( + sizeof(ValueType) + ComputeDataSize()); // NOLINT + } + + void SetHeader() { + header.SetCmdByTotalSize<ValueType>(ComputeSize()); + } + + void Init(GLuint _indx, const GLfloat* _values) { + SetHeader(); + indx = _indx; + memcpy(ImmediateDataAddress(this), + _values, ComputeDataSize()); + } + + void* Set(void* cmd, GLuint _indx, const GLfloat* _values) { + static_cast<ValueType*>(cmd)->Init(_indx, _values); + const uint32 size = ComputeSize(); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + command_buffer::CommandHeader header; + uint32 indx; +}; + +COMPILE_ASSERT(sizeof(VertexAttrib2fvImmediate) == 8, + Sizeof_VertexAttrib2fvImmediate_is_not_8); +COMPILE_ASSERT(offsetof(VertexAttrib2fvImmediate, header) == 0, + OffsetOf_VertexAttrib2fvImmediate_header_not_0); +COMPILE_ASSERT(offsetof(VertexAttrib2fvImmediate, indx) == 4, + OffsetOf_VertexAttrib2fvImmediate_indx_not_4); + +struct VertexAttrib3f { + typedef VertexAttrib3f ValueType; + static const CommandId kCmdId = kVertexAttrib3f; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLuint _indx, GLfloat _x, GLfloat _y, GLfloat _z) { + SetHeader(); + indx = _indx; + x = _x; + y = _y; + z = _z; + } + + void* Set(void* cmd, GLuint _indx, GLfloat _x, GLfloat _y, GLfloat _z) { + static_cast<ValueType*>(cmd)->Init(_indx, _x, _y, _z); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 indx; + float x; + float y; + float z; +}; + +COMPILE_ASSERT(sizeof(VertexAttrib3f) == 20, + Sizeof_VertexAttrib3f_is_not_20); +COMPILE_ASSERT(offsetof(VertexAttrib3f, header) == 0, + OffsetOf_VertexAttrib3f_header_not_0); +COMPILE_ASSERT(offsetof(VertexAttrib3f, indx) == 4, + OffsetOf_VertexAttrib3f_indx_not_4); +COMPILE_ASSERT(offsetof(VertexAttrib3f, x) == 8, + OffsetOf_VertexAttrib3f_x_not_8); +COMPILE_ASSERT(offsetof(VertexAttrib3f, y) == 12, + OffsetOf_VertexAttrib3f_y_not_12); +COMPILE_ASSERT(offsetof(VertexAttrib3f, z) == 16, + OffsetOf_VertexAttrib3f_z_not_16); + +struct VertexAttrib3fv { + typedef VertexAttrib3fv ValueType; + static const CommandId kCmdId = kVertexAttrib3fv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLuint _indx, uint32 _values_shm_id, uint32 _values_shm_offset) { + SetHeader(); + indx = _indx; + values_shm_id = _values_shm_id; + values_shm_offset = _values_shm_offset; + } + + void* Set( + void* cmd, GLuint _indx, uint32 _values_shm_id, + uint32 _values_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_indx, _values_shm_id, _values_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 indx; + uint32 values_shm_id; + uint32 values_shm_offset; +}; + +COMPILE_ASSERT(sizeof(VertexAttrib3fv) == 16, + Sizeof_VertexAttrib3fv_is_not_16); +COMPILE_ASSERT(offsetof(VertexAttrib3fv, header) == 0, + OffsetOf_VertexAttrib3fv_header_not_0); +COMPILE_ASSERT(offsetof(VertexAttrib3fv, indx) == 4, + OffsetOf_VertexAttrib3fv_indx_not_4); +COMPILE_ASSERT(offsetof(VertexAttrib3fv, values_shm_id) == 8, + OffsetOf_VertexAttrib3fv_values_shm_id_not_8); +COMPILE_ASSERT(offsetof(VertexAttrib3fv, values_shm_offset) == 12, + OffsetOf_VertexAttrib3fv_values_shm_offset_not_12); + +struct VertexAttrib3fvImmediate { + typedef VertexAttrib3fvImmediate ValueType; + static const CommandId kCmdId = kVertexAttrib3fvImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeDataSize() { + return static_cast<uint32>( + sizeof(GLfloat) * 3); // NOLINT + } + + static uint32 ComputeSize() { + return static_cast<uint32>( + sizeof(ValueType) + ComputeDataSize()); // NOLINT + } + + void SetHeader() { + header.SetCmdByTotalSize<ValueType>(ComputeSize()); + } + + void Init(GLuint _indx, const GLfloat* _values) { + SetHeader(); + indx = _indx; + memcpy(ImmediateDataAddress(this), + _values, ComputeDataSize()); + } + + void* Set(void* cmd, GLuint _indx, const GLfloat* _values) { + static_cast<ValueType*>(cmd)->Init(_indx, _values); + const uint32 size = ComputeSize(); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + command_buffer::CommandHeader header; + uint32 indx; +}; + +COMPILE_ASSERT(sizeof(VertexAttrib3fvImmediate) == 8, + Sizeof_VertexAttrib3fvImmediate_is_not_8); +COMPILE_ASSERT(offsetof(VertexAttrib3fvImmediate, header) == 0, + OffsetOf_VertexAttrib3fvImmediate_header_not_0); +COMPILE_ASSERT(offsetof(VertexAttrib3fvImmediate, indx) == 4, + OffsetOf_VertexAttrib3fvImmediate_indx_not_4); + +struct VertexAttrib4f { + typedef VertexAttrib4f ValueType; + static const CommandId kCmdId = kVertexAttrib4f; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLuint _indx, GLfloat _x, GLfloat _y, GLfloat _z, GLfloat _w) { + SetHeader(); + indx = _indx; + x = _x; + y = _y; + z = _z; + w = _w; + } + + void* Set( + void* cmd, GLuint _indx, GLfloat _x, GLfloat _y, GLfloat _z, + GLfloat _w) { + static_cast<ValueType*>(cmd)->Init(_indx, _x, _y, _z, _w); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 indx; + float x; + float y; + float z; + float w; +}; + +COMPILE_ASSERT(sizeof(VertexAttrib4f) == 24, + Sizeof_VertexAttrib4f_is_not_24); +COMPILE_ASSERT(offsetof(VertexAttrib4f, header) == 0, + OffsetOf_VertexAttrib4f_header_not_0); +COMPILE_ASSERT(offsetof(VertexAttrib4f, indx) == 4, + OffsetOf_VertexAttrib4f_indx_not_4); +COMPILE_ASSERT(offsetof(VertexAttrib4f, x) == 8, + OffsetOf_VertexAttrib4f_x_not_8); +COMPILE_ASSERT(offsetof(VertexAttrib4f, y) == 12, + OffsetOf_VertexAttrib4f_y_not_12); +COMPILE_ASSERT(offsetof(VertexAttrib4f, z) == 16, + OffsetOf_VertexAttrib4f_z_not_16); +COMPILE_ASSERT(offsetof(VertexAttrib4f, w) == 20, + OffsetOf_VertexAttrib4f_w_not_20); + +struct VertexAttrib4fv { + typedef VertexAttrib4fv ValueType; + static const CommandId kCmdId = kVertexAttrib4fv; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLuint _indx, uint32 _values_shm_id, uint32 _values_shm_offset) { + SetHeader(); + indx = _indx; + values_shm_id = _values_shm_id; + values_shm_offset = _values_shm_offset; + } + + void* Set( + void* cmd, GLuint _indx, uint32 _values_shm_id, + uint32 _values_shm_offset) { + static_cast<ValueType*>( + cmd)->Init(_indx, _values_shm_id, _values_shm_offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 indx; + uint32 values_shm_id; + uint32 values_shm_offset; +}; + +COMPILE_ASSERT(sizeof(VertexAttrib4fv) == 16, + Sizeof_VertexAttrib4fv_is_not_16); +COMPILE_ASSERT(offsetof(VertexAttrib4fv, header) == 0, + OffsetOf_VertexAttrib4fv_header_not_0); +COMPILE_ASSERT(offsetof(VertexAttrib4fv, indx) == 4, + OffsetOf_VertexAttrib4fv_indx_not_4); +COMPILE_ASSERT(offsetof(VertexAttrib4fv, values_shm_id) == 8, + OffsetOf_VertexAttrib4fv_values_shm_id_not_8); +COMPILE_ASSERT(offsetof(VertexAttrib4fv, values_shm_offset) == 12, + OffsetOf_VertexAttrib4fv_values_shm_offset_not_12); + +struct VertexAttrib4fvImmediate { + typedef VertexAttrib4fvImmediate ValueType; + static const CommandId kCmdId = kVertexAttrib4fvImmediate; + static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN; + + static uint32 ComputeDataSize() { + return static_cast<uint32>( + sizeof(GLfloat) * 4); // NOLINT + } + + static uint32 ComputeSize() { + return static_cast<uint32>( + sizeof(ValueType) + ComputeDataSize()); // NOLINT + } + + void SetHeader() { + header.SetCmdByTotalSize<ValueType>(ComputeSize()); + } + + void Init(GLuint _indx, const GLfloat* _values) { + SetHeader(); + indx = _indx; + memcpy(ImmediateDataAddress(this), + _values, ComputeDataSize()); + } + + void* Set(void* cmd, GLuint _indx, const GLfloat* _values) { + static_cast<ValueType*>(cmd)->Init(_indx, _values); + const uint32 size = ComputeSize(); + return NextImmediateCmdAddressTotalSize<ValueType>(cmd, size); + } + + command_buffer::CommandHeader header; + uint32 indx; +}; + +COMPILE_ASSERT(sizeof(VertexAttrib4fvImmediate) == 8, + Sizeof_VertexAttrib4fvImmediate_is_not_8); +COMPILE_ASSERT(offsetof(VertexAttrib4fvImmediate, header) == 0, + OffsetOf_VertexAttrib4fvImmediate_header_not_0); +COMPILE_ASSERT(offsetof(VertexAttrib4fvImmediate, indx) == 4, + OffsetOf_VertexAttrib4fvImmediate_indx_not_4); + +struct VertexAttribPointer { + typedef VertexAttribPointer ValueType; + static const CommandId kCmdId = kVertexAttribPointer; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init( + GLuint _indx, GLint _size, GLenum _type, GLboolean _normalized, + GLsizei _stride, GLuint _offset) { + SetHeader(); + indx = _indx; + size = _size; + type = _type; + normalized = _normalized; + stride = _stride; + offset = _offset; + } + + void* Set( + void* cmd, GLuint _indx, GLint _size, GLenum _type, GLboolean _normalized, + GLsizei _stride, GLuint _offset) { + static_cast<ValueType*>( + cmd)->Init(_indx, _size, _type, _normalized, _stride, _offset); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 indx; + uint32 size; + uint32 type; + uint32 normalized; + uint32 stride; + uint32 offset; +}; + +COMPILE_ASSERT(sizeof(VertexAttribPointer) == 28, + Sizeof_VertexAttribPointer_is_not_28); +COMPILE_ASSERT(offsetof(VertexAttribPointer, header) == 0, + OffsetOf_VertexAttribPointer_header_not_0); +COMPILE_ASSERT(offsetof(VertexAttribPointer, indx) == 4, + OffsetOf_VertexAttribPointer_indx_not_4); +COMPILE_ASSERT(offsetof(VertexAttribPointer, size) == 8, + OffsetOf_VertexAttribPointer_size_not_8); +COMPILE_ASSERT(offsetof(VertexAttribPointer, type) == 12, + OffsetOf_VertexAttribPointer_type_not_12); +COMPILE_ASSERT(offsetof(VertexAttribPointer, normalized) == 16, + OffsetOf_VertexAttribPointer_normalized_not_16); +COMPILE_ASSERT(offsetof(VertexAttribPointer, stride) == 20, + OffsetOf_VertexAttribPointer_stride_not_20); +COMPILE_ASSERT(offsetof(VertexAttribPointer, offset) == 24, + OffsetOf_VertexAttribPointer_offset_not_24); + +struct Viewport { + typedef Viewport ValueType; + static const CommandId kCmdId = kViewport; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init(GLint _x, GLint _y, GLsizei _width, GLsizei _height) { + SetHeader(); + x = _x; + y = _y; + width = _width; + height = _height; + } + + void* Set(void* cmd, GLint _x, GLint _y, GLsizei _width, GLsizei _height) { + static_cast<ValueType*>(cmd)->Init(_x, _y, _width, _height); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; + uint32 x; + uint32 y; + uint32 width; + uint32 height; +}; + +COMPILE_ASSERT(sizeof(Viewport) == 20, + Sizeof_Viewport_is_not_20); +COMPILE_ASSERT(offsetof(Viewport, header) == 0, + OffsetOf_Viewport_header_not_0); +COMPILE_ASSERT(offsetof(Viewport, x) == 4, + OffsetOf_Viewport_x_not_4); +COMPILE_ASSERT(offsetof(Viewport, y) == 8, + OffsetOf_Viewport_y_not_8); +COMPILE_ASSERT(offsetof(Viewport, width) == 12, + OffsetOf_Viewport_width_not_12); +COMPILE_ASSERT(offsetof(Viewport, height) == 16, + OffsetOf_Viewport_height_not_16); + +struct SwapBuffers { + typedef SwapBuffers ValueType; + static const CommandId kCmdId = kSwapBuffers; + static const cmd::ArgFlags kArgFlags = cmd::kFixed; + + static uint32 ComputeSize() { + return static_cast<uint32>(sizeof(ValueType)); // NOLINT + } + + void SetHeader() { + header.SetCmd<ValueType>(); + } + + void Init() { + SetHeader(); + } + + void* Set(void* cmd) { + static_cast<ValueType*>(cmd)->Init(); + return NextCmdAddress<ValueType>(cmd); + } + + command_buffer::CommandHeader header; +}; + +COMPILE_ASSERT(sizeof(SwapBuffers) == 4, + Sizeof_SwapBuffers_is_not_4); +COMPILE_ASSERT(offsetof(SwapBuffers, header) == 0, + OffsetOf_SwapBuffers_header_not_0); + +#pragma pack(pop) + diff --git a/gpu/command_buffer/common/gles2_cmd_format_test.cc b/gpu/command_buffer/common/gles2_cmd_format_test.cc new file mode 100644 index 0000000..c699a1d --- /dev/null +++ b/gpu/command_buffer/common/gles2_cmd_format_test.cc @@ -0,0 +1,17 @@ +// Copyright (c) 2006-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 contains unit tests for gles2 commmands + +#include "testing/gtest/include/gtest/gtest.h" +#include "gpu/command_buffer/common/gles2_cmd_format.h" + +namespace command_buffer { +namespace gles2 { + +#include "gpu/command_buffer/common/gles2_cmd_format_test_autogen.h" + +} // namespace gles2 +} // namespace command_buffer + diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h new file mode 100644 index 0000000..b914e07 --- /dev/null +++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h @@ -0,0 +1,2758 @@ +// This file is auto-generated. DO NOT EDIT! + +// This file contains unit tests for gles2 commmands +// It is included by gles2_cmd_format_test.cc + +TEST(GLES2FormatTest, ActiveTexture) { + ActiveTexture cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11)); + EXPECT_EQ(ActiveTexture::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.texture); +} + +TEST(GLES2FormatTest, AttachShader) { + AttachShader cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<GLuint>(12)); + EXPECT_EQ(AttachShader::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<GLuint>(12), cmd.shader); +} + +TEST(GLES2FormatTest, BindAttribLocation) { + BindAttribLocation cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<GLuint>(12), + static_cast<uint32>(13), + static_cast<uint32>(14), + static_cast<uint32>(15)); + EXPECT_EQ(BindAttribLocation::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<GLuint>(12), cmd.index); + EXPECT_EQ(static_cast<uint32>(13), cmd.name_shm_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.name_shm_offset); + EXPECT_EQ(static_cast<uint32>(15), cmd.data_size); +} + +TEST(GLES2FormatTest, BindAttribLocationImmediate) { + int8 buf[256] = { 0, }; + BindAttribLocationImmediate& cmd = + *static_cast<BindAttribLocationImmediate*>(static_cast<void*>(&buf)); + static const char* const test_str = "test string"; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<GLuint>(12), + test_str); + EXPECT_EQ(BindAttribLocationImmediate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd) + // NOLINT + RoundSizeToMultipleOfEntries(strlen(test_str)), + cmd.header.size * 4); + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<GLuint>(12), cmd.index); + // TODO(gman): check that string got copied. +} + +TEST(GLES2FormatTest, BindBuffer) { + BindBuffer cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLuint>(12)); + EXPECT_EQ(BindBuffer::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLuint>(12), cmd.buffer); +} + +TEST(GLES2FormatTest, BindFramebuffer) { + BindFramebuffer cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLuint>(12)); + EXPECT_EQ(BindFramebuffer::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLuint>(12), cmd.framebuffer); +} + +TEST(GLES2FormatTest, BindRenderbuffer) { + BindRenderbuffer cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLuint>(12)); + EXPECT_EQ(BindRenderbuffer::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLuint>(12), cmd.renderbuffer); +} + +TEST(GLES2FormatTest, BindTexture) { + BindTexture cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLuint>(12)); + EXPECT_EQ(BindTexture::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLuint>(12), cmd.texture); +} + +TEST(GLES2FormatTest, BlendColor) { + BlendColor cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLclampf>(11), + static_cast<GLclampf>(12), + static_cast<GLclampf>(13), + static_cast<GLclampf>(14)); + EXPECT_EQ(BlendColor::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLclampf>(11), cmd.red); + EXPECT_EQ(static_cast<GLclampf>(12), cmd.green); + EXPECT_EQ(static_cast<GLclampf>(13), cmd.blue); + EXPECT_EQ(static_cast<GLclampf>(14), cmd.alpha); +} + +TEST(GLES2FormatTest, BlendEquation) { + BlendEquation cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11)); + EXPECT_EQ(BlendEquation::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.mode); +} + +TEST(GLES2FormatTest, BlendEquationSeparate) { + BlendEquationSeparate cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLenum>(12)); + EXPECT_EQ(BlendEquationSeparate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.modeRGB); + EXPECT_EQ(static_cast<GLenum>(12), cmd.modeAlpha); +} + +TEST(GLES2FormatTest, BlendFunc) { + BlendFunc cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLenum>(12)); + EXPECT_EQ(BlendFunc::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.sfactor); + EXPECT_EQ(static_cast<GLenum>(12), cmd.dfactor); +} + +TEST(GLES2FormatTest, BlendFuncSeparate) { + BlendFuncSeparate cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLenum>(12), + static_cast<GLenum>(13), + static_cast<GLenum>(14)); + EXPECT_EQ(BlendFuncSeparate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.srcRGB); + EXPECT_EQ(static_cast<GLenum>(12), cmd.dstRGB); + EXPECT_EQ(static_cast<GLenum>(13), cmd.srcAlpha); + EXPECT_EQ(static_cast<GLenum>(14), cmd.dstAlpha); +} + +TEST(GLES2FormatTest, BufferData) { + BufferData cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLsizeiptr>(12), + static_cast<uint32>(13), + static_cast<uint32>(14), + static_cast<GLenum>(15)); + EXPECT_EQ(BufferData::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLsizeiptr>(12), cmd.size); + EXPECT_EQ(static_cast<uint32>(13), cmd.data_shm_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.data_shm_offset); + EXPECT_EQ(static_cast<GLenum>(15), cmd.usage); +} + +// TODO(gman): Implement test for BufferDataImmediate +TEST(GLES2FormatTest, BufferSubData) { + BufferSubData cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLintptr>(12), + static_cast<GLsizeiptr>(13), + static_cast<uint32>(14), + static_cast<uint32>(15)); + EXPECT_EQ(BufferSubData::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLintptr>(12), cmd.offset); + EXPECT_EQ(static_cast<GLsizeiptr>(13), cmd.size); + EXPECT_EQ(static_cast<uint32>(14), cmd.data_shm_id); + EXPECT_EQ(static_cast<uint32>(15), cmd.data_shm_offset); +} + +// TODO(gman): Implement test for BufferSubDataImmediate +TEST(GLES2FormatTest, CheckFramebufferStatus) { + CheckFramebufferStatus cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11)); + EXPECT_EQ(CheckFramebufferStatus::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); +} + +TEST(GLES2FormatTest, Clear) { + Clear cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLbitfield>(11)); + EXPECT_EQ(Clear::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLbitfield>(11), cmd.mask); +} + +TEST(GLES2FormatTest, ClearColor) { + ClearColor cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLclampf>(11), + static_cast<GLclampf>(12), + static_cast<GLclampf>(13), + static_cast<GLclampf>(14)); + EXPECT_EQ(ClearColor::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLclampf>(11), cmd.red); + EXPECT_EQ(static_cast<GLclampf>(12), cmd.green); + EXPECT_EQ(static_cast<GLclampf>(13), cmd.blue); + EXPECT_EQ(static_cast<GLclampf>(14), cmd.alpha); +} + +TEST(GLES2FormatTest, ClearDepthf) { + ClearDepthf cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLclampf>(11)); + EXPECT_EQ(ClearDepthf::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLclampf>(11), cmd.depth); +} + +TEST(GLES2FormatTest, ClearStencil) { + ClearStencil cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(11)); + EXPECT_EQ(ClearStencil::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(11), cmd.s); +} + +TEST(GLES2FormatTest, ColorMask) { + ColorMask cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLboolean>(11), + static_cast<GLboolean>(12), + static_cast<GLboolean>(13), + static_cast<GLboolean>(14)); + EXPECT_EQ(ColorMask::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLboolean>(11), cmd.red); + EXPECT_EQ(static_cast<GLboolean>(12), cmd.green); + EXPECT_EQ(static_cast<GLboolean>(13), cmd.blue); + EXPECT_EQ(static_cast<GLboolean>(14), cmd.alpha); +} + +TEST(GLES2FormatTest, CompileShader) { + CompileShader cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11)); + EXPECT_EQ(CompileShader::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.shader); +} + +TEST(GLES2FormatTest, CompressedTexImage2D) { + CompressedTexImage2D cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLint>(12), + static_cast<GLenum>(13), + static_cast<GLsizei>(14), + static_cast<GLsizei>(15), + static_cast<GLint>(16), + static_cast<GLsizei>(17), + static_cast<uint32>(18), + static_cast<uint32>(19)); + EXPECT_EQ(CompressedTexImage2D::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLint>(12), cmd.level); + EXPECT_EQ(static_cast<GLenum>(13), cmd.internalformat); + EXPECT_EQ(static_cast<GLsizei>(14), cmd.width); + EXPECT_EQ(static_cast<GLsizei>(15), cmd.height); + EXPECT_EQ(static_cast<GLint>(16), cmd.border); + EXPECT_EQ(static_cast<GLsizei>(17), cmd.imageSize); + EXPECT_EQ(static_cast<uint32>(18), cmd.data_shm_id); + EXPECT_EQ(static_cast<uint32>(19), cmd.data_shm_offset); +} + +// TODO(gman): Implement test for CompressedTexImage2DImmediate +TEST(GLES2FormatTest, CompressedTexSubImage2D) { + CompressedTexSubImage2D cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLint>(12), + static_cast<GLint>(13), + static_cast<GLint>(14), + static_cast<GLsizei>(15), + static_cast<GLsizei>(16), + static_cast<GLenum>(17), + static_cast<GLsizei>(18), + static_cast<uint32>(19), + static_cast<uint32>(20)); + EXPECT_EQ(CompressedTexSubImage2D::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLint>(12), cmd.level); + EXPECT_EQ(static_cast<GLint>(13), cmd.xoffset); + EXPECT_EQ(static_cast<GLint>(14), cmd.yoffset); + EXPECT_EQ(static_cast<GLsizei>(15), cmd.width); + EXPECT_EQ(static_cast<GLsizei>(16), cmd.height); + EXPECT_EQ(static_cast<GLenum>(17), cmd.format); + EXPECT_EQ(static_cast<GLsizei>(18), cmd.imageSize); + EXPECT_EQ(static_cast<uint32>(19), cmd.data_shm_id); + EXPECT_EQ(static_cast<uint32>(20), cmd.data_shm_offset); +} + +// TODO(gman): Implement test for CompressedTexSubImage2DImmediate +TEST(GLES2FormatTest, CopyTexImage2D) { + CopyTexImage2D cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLint>(12), + static_cast<GLenum>(13), + static_cast<GLint>(14), + static_cast<GLint>(15), + static_cast<GLsizei>(16), + static_cast<GLsizei>(17), + static_cast<GLint>(18)); + EXPECT_EQ(CopyTexImage2D::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLint>(12), cmd.level); + EXPECT_EQ(static_cast<GLenum>(13), cmd.internalformat); + EXPECT_EQ(static_cast<GLint>(14), cmd.x); + EXPECT_EQ(static_cast<GLint>(15), cmd.y); + EXPECT_EQ(static_cast<GLsizei>(16), cmd.width); + EXPECT_EQ(static_cast<GLsizei>(17), cmd.height); + EXPECT_EQ(static_cast<GLint>(18), cmd.border); +} + +TEST(GLES2FormatTest, CopyTexSubImage2D) { + CopyTexSubImage2D cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLint>(12), + static_cast<GLint>(13), + static_cast<GLint>(14), + static_cast<GLint>(15), + static_cast<GLint>(16), + static_cast<GLsizei>(17), + static_cast<GLsizei>(18)); + EXPECT_EQ(CopyTexSubImage2D::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLint>(12), cmd.level); + EXPECT_EQ(static_cast<GLint>(13), cmd.xoffset); + EXPECT_EQ(static_cast<GLint>(14), cmd.yoffset); + EXPECT_EQ(static_cast<GLint>(15), cmd.x); + EXPECT_EQ(static_cast<GLint>(16), cmd.y); + EXPECT_EQ(static_cast<GLsizei>(17), cmd.width); + EXPECT_EQ(static_cast<GLsizei>(18), cmd.height); +} + +TEST(GLES2FormatTest, CreateProgram) { + CreateProgram cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<uint32>(11)); + EXPECT_EQ(CreateProgram::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<uint32>(11), cmd.client_id); +} + +TEST(GLES2FormatTest, CreateShader) { + CreateShader cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<uint32>(12)); + EXPECT_EQ(CreateShader::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.type); + EXPECT_EQ(static_cast<uint32>(12), cmd.client_id); +} + +TEST(GLES2FormatTest, CullFace) { + CullFace cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11)); + EXPECT_EQ(CullFace::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.mode); +} + +TEST(GLES2FormatTest, DeleteBuffers) { + DeleteBuffers cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLsizei>(11), + static_cast<uint32>(12), + static_cast<uint32>(13)); + EXPECT_EQ(DeleteBuffers::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLsizei>(11), cmd.n); + EXPECT_EQ(static_cast<uint32>(12), cmd.buffers_shm_id); + EXPECT_EQ(static_cast<uint32>(13), cmd.buffers_shm_offset); +} + +TEST(GLES2FormatTest, DeleteBuffersImmediate) { + static GLuint ids[] = { 12, 23, 34, }; + int8 buf[256] = { 0, }; + DeleteBuffersImmediate& cmd = + *static_cast<DeleteBuffersImmediate*>(static_cast<void*>(&buf)); + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLsizei>(11), + ids); + EXPECT_EQ(DeleteBuffersImmediate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd) + + RoundSizeToMultipleOfEntries(cmd.n * 4), + cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLsizei>(11), cmd.n); + // TODO(gman): Check that ids were inserted; +} + +TEST(GLES2FormatTest, DeleteFramebuffers) { + DeleteFramebuffers cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLsizei>(11), + static_cast<uint32>(12), + static_cast<uint32>(13)); + EXPECT_EQ(DeleteFramebuffers::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLsizei>(11), cmd.n); + EXPECT_EQ(static_cast<uint32>(12), cmd.framebuffers_shm_id); + EXPECT_EQ(static_cast<uint32>(13), cmd.framebuffers_shm_offset); +} + +TEST(GLES2FormatTest, DeleteFramebuffersImmediate) { + static GLuint ids[] = { 12, 23, 34, }; + int8 buf[256] = { 0, }; + DeleteFramebuffersImmediate& cmd = + *static_cast<DeleteFramebuffersImmediate*>(static_cast<void*>(&buf)); + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLsizei>(11), + ids); + EXPECT_EQ(DeleteFramebuffersImmediate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd) + + RoundSizeToMultipleOfEntries(cmd.n * 4), + cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLsizei>(11), cmd.n); + // TODO(gman): Check that ids were inserted; +} + +TEST(GLES2FormatTest, DeleteProgram) { + DeleteProgram cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11)); + EXPECT_EQ(DeleteProgram::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); +} + +TEST(GLES2FormatTest, DeleteRenderbuffers) { + DeleteRenderbuffers cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLsizei>(11), + static_cast<uint32>(12), + static_cast<uint32>(13)); + EXPECT_EQ(DeleteRenderbuffers::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLsizei>(11), cmd.n); + EXPECT_EQ(static_cast<uint32>(12), cmd.renderbuffers_shm_id); + EXPECT_EQ(static_cast<uint32>(13), cmd.renderbuffers_shm_offset); +} + +TEST(GLES2FormatTest, DeleteRenderbuffersImmediate) { + static GLuint ids[] = { 12, 23, 34, }; + int8 buf[256] = { 0, }; + DeleteRenderbuffersImmediate& cmd = + *static_cast<DeleteRenderbuffersImmediate*>(static_cast<void*>(&buf)); + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLsizei>(11), + ids); + EXPECT_EQ(DeleteRenderbuffersImmediate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd) + + RoundSizeToMultipleOfEntries(cmd.n * 4), + cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLsizei>(11), cmd.n); + // TODO(gman): Check that ids were inserted; +} + +TEST(GLES2FormatTest, DeleteShader) { + DeleteShader cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11)); + EXPECT_EQ(DeleteShader::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.shader); +} + +TEST(GLES2FormatTest, DeleteTextures) { + DeleteTextures cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLsizei>(11), + static_cast<uint32>(12), + static_cast<uint32>(13)); + EXPECT_EQ(DeleteTextures::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLsizei>(11), cmd.n); + EXPECT_EQ(static_cast<uint32>(12), cmd.textures_shm_id); + EXPECT_EQ(static_cast<uint32>(13), cmd.textures_shm_offset); +} + +TEST(GLES2FormatTest, DeleteTexturesImmediate) { + static GLuint ids[] = { 12, 23, 34, }; + int8 buf[256] = { 0, }; + DeleteTexturesImmediate& cmd = + *static_cast<DeleteTexturesImmediate*>(static_cast<void*>(&buf)); + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLsizei>(11), + ids); + EXPECT_EQ(DeleteTexturesImmediate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd) + + RoundSizeToMultipleOfEntries(cmd.n * 4), + cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLsizei>(11), cmd.n); + // TODO(gman): Check that ids were inserted; +} + +TEST(GLES2FormatTest, DepthFunc) { + DepthFunc cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11)); + EXPECT_EQ(DepthFunc::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.func); +} + +TEST(GLES2FormatTest, DepthMask) { + DepthMask cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLboolean>(11)); + EXPECT_EQ(DepthMask::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLboolean>(11), cmd.flag); +} + +TEST(GLES2FormatTest, DepthRangef) { + DepthRangef cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLclampf>(11), + static_cast<GLclampf>(12)); + EXPECT_EQ(DepthRangef::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLclampf>(11), cmd.zNear); + EXPECT_EQ(static_cast<GLclampf>(12), cmd.zFar); +} + +TEST(GLES2FormatTest, DetachShader) { + DetachShader cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<GLuint>(12)); + EXPECT_EQ(DetachShader::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<GLuint>(12), cmd.shader); +} + +TEST(GLES2FormatTest, Disable) { + Disable cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11)); + EXPECT_EQ(Disable::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.cap); +} + +TEST(GLES2FormatTest, DisableVertexAttribArray) { + DisableVertexAttribArray cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11)); + EXPECT_EQ(DisableVertexAttribArray::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.index); +} + +TEST(GLES2FormatTest, DrawArrays) { + DrawArrays cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLint>(12), + static_cast<GLsizei>(13)); + EXPECT_EQ(DrawArrays::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.mode); + EXPECT_EQ(static_cast<GLint>(12), cmd.first); + EXPECT_EQ(static_cast<GLsizei>(13), cmd.count); +} + +TEST(GLES2FormatTest, DrawElements) { + DrawElements cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLsizei>(12), + static_cast<GLenum>(13), + static_cast<GLuint>(14)); + EXPECT_EQ(DrawElements::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.mode); + EXPECT_EQ(static_cast<GLsizei>(12), cmd.count); + EXPECT_EQ(static_cast<GLenum>(13), cmd.type); + EXPECT_EQ(static_cast<GLuint>(14), cmd.index_offset); +} + +TEST(GLES2FormatTest, Enable) { + Enable cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11)); + EXPECT_EQ(Enable::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.cap); +} + +TEST(GLES2FormatTest, EnableVertexAttribArray) { + EnableVertexAttribArray cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11)); + EXPECT_EQ(EnableVertexAttribArray::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.index); +} + +TEST(GLES2FormatTest, Finish) { + Finish cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd); + EXPECT_EQ(Finish::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT +} + +TEST(GLES2FormatTest, Flush) { + Flush cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd); + EXPECT_EQ(Flush::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT +} + +TEST(GLES2FormatTest, FramebufferRenderbuffer) { + FramebufferRenderbuffer cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLenum>(12), + static_cast<GLenum>(13), + static_cast<GLuint>(14)); + EXPECT_EQ(FramebufferRenderbuffer::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLenum>(12), cmd.attachment); + EXPECT_EQ(static_cast<GLenum>(13), cmd.renderbuffertarget); + EXPECT_EQ(static_cast<GLuint>(14), cmd.renderbuffer); +} + +TEST(GLES2FormatTest, FramebufferTexture2D) { + FramebufferTexture2D cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLenum>(12), + static_cast<GLenum>(13), + static_cast<GLuint>(14), + static_cast<GLint>(15)); + EXPECT_EQ(FramebufferTexture2D::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLenum>(12), cmd.attachment); + EXPECT_EQ(static_cast<GLenum>(13), cmd.textarget); + EXPECT_EQ(static_cast<GLuint>(14), cmd.texture); + EXPECT_EQ(static_cast<GLint>(15), cmd.level); +} + +TEST(GLES2FormatTest, FrontFace) { + FrontFace cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11)); + EXPECT_EQ(FrontFace::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.mode); +} + +TEST(GLES2FormatTest, GenBuffers) { + GenBuffers cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLsizei>(11), + static_cast<uint32>(12), + static_cast<uint32>(13)); + EXPECT_EQ(GenBuffers::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLsizei>(11), cmd.n); + EXPECT_EQ(static_cast<uint32>(12), cmd.buffers_shm_id); + EXPECT_EQ(static_cast<uint32>(13), cmd.buffers_shm_offset); +} + +TEST(GLES2FormatTest, GenBuffersImmediate) { + static GLuint ids[] = { 12, 23, 34, }; + int8 buf[256] = { 0, }; + GenBuffersImmediate& cmd = + *static_cast<GenBuffersImmediate*>(static_cast<void*>(&buf)); + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLsizei>(11), + ids); + EXPECT_EQ(GenBuffersImmediate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd) + + RoundSizeToMultipleOfEntries(cmd.n * 4), + cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLsizei>(11), cmd.n); + // TODO(gman): Check that ids were inserted; +} + +TEST(GLES2FormatTest, GenerateMipmap) { + GenerateMipmap cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11)); + EXPECT_EQ(GenerateMipmap::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); +} + +TEST(GLES2FormatTest, GenFramebuffers) { + GenFramebuffers cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLsizei>(11), + static_cast<uint32>(12), + static_cast<uint32>(13)); + EXPECT_EQ(GenFramebuffers::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLsizei>(11), cmd.n); + EXPECT_EQ(static_cast<uint32>(12), cmd.framebuffers_shm_id); + EXPECT_EQ(static_cast<uint32>(13), cmd.framebuffers_shm_offset); +} + +TEST(GLES2FormatTest, GenFramebuffersImmediate) { + static GLuint ids[] = { 12, 23, 34, }; + int8 buf[256] = { 0, }; + GenFramebuffersImmediate& cmd = + *static_cast<GenFramebuffersImmediate*>(static_cast<void*>(&buf)); + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLsizei>(11), + ids); + EXPECT_EQ(GenFramebuffersImmediate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd) + + RoundSizeToMultipleOfEntries(cmd.n * 4), + cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLsizei>(11), cmd.n); + // TODO(gman): Check that ids were inserted; +} + +TEST(GLES2FormatTest, GenRenderbuffers) { + GenRenderbuffers cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLsizei>(11), + static_cast<uint32>(12), + static_cast<uint32>(13)); + EXPECT_EQ(GenRenderbuffers::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLsizei>(11), cmd.n); + EXPECT_EQ(static_cast<uint32>(12), cmd.renderbuffers_shm_id); + EXPECT_EQ(static_cast<uint32>(13), cmd.renderbuffers_shm_offset); +} + +TEST(GLES2FormatTest, GenRenderbuffersImmediate) { + static GLuint ids[] = { 12, 23, 34, }; + int8 buf[256] = { 0, }; + GenRenderbuffersImmediate& cmd = + *static_cast<GenRenderbuffersImmediate*>(static_cast<void*>(&buf)); + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLsizei>(11), + ids); + EXPECT_EQ(GenRenderbuffersImmediate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd) + + RoundSizeToMultipleOfEntries(cmd.n * 4), + cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLsizei>(11), cmd.n); + // TODO(gman): Check that ids were inserted; +} + +TEST(GLES2FormatTest, GenTextures) { + GenTextures cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLsizei>(11), + static_cast<uint32>(12), + static_cast<uint32>(13)); + EXPECT_EQ(GenTextures::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLsizei>(11), cmd.n); + EXPECT_EQ(static_cast<uint32>(12), cmd.textures_shm_id); + EXPECT_EQ(static_cast<uint32>(13), cmd.textures_shm_offset); +} + +TEST(GLES2FormatTest, GenTexturesImmediate) { + static GLuint ids[] = { 12, 23, 34, }; + int8 buf[256] = { 0, }; + GenTexturesImmediate& cmd = + *static_cast<GenTexturesImmediate*>(static_cast<void*>(&buf)); + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLsizei>(11), + ids); + EXPECT_EQ(GenTexturesImmediate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd) + + RoundSizeToMultipleOfEntries(cmd.n * 4), + cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLsizei>(11), cmd.n); + // TODO(gman): Check that ids were inserted; +} + +TEST(GLES2FormatTest, GetActiveAttrib) { + GetActiveAttrib cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<GLuint>(12), + static_cast<GLsizei>(13), + static_cast<uint32>(14), + static_cast<uint32>(15), + static_cast<uint32>(16), + static_cast<uint32>(17), + static_cast<uint32>(18), + static_cast<uint32>(19), + static_cast<uint32>(20), + static_cast<uint32>(21)); + EXPECT_EQ(GetActiveAttrib::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<GLuint>(12), cmd.index); + EXPECT_EQ(static_cast<GLsizei>(13), cmd.bufsize); + EXPECT_EQ(static_cast<uint32>(14), cmd.length_shm_id); + EXPECT_EQ(static_cast<uint32>(15), cmd.length_shm_offset); + EXPECT_EQ(static_cast<uint32>(16), cmd.size_shm_id); + EXPECT_EQ(static_cast<uint32>(17), cmd.size_shm_offset); + EXPECT_EQ(static_cast<uint32>(18), cmd.type_shm_id); + EXPECT_EQ(static_cast<uint32>(19), cmd.type_shm_offset); + EXPECT_EQ(static_cast<uint32>(20), cmd.name_shm_id); + EXPECT_EQ(static_cast<uint32>(21), cmd.name_shm_offset); +} + +TEST(GLES2FormatTest, GetActiveUniform) { + GetActiveUniform cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<GLuint>(12), + static_cast<GLsizei>(13), + static_cast<uint32>(14), + static_cast<uint32>(15), + static_cast<uint32>(16), + static_cast<uint32>(17), + static_cast<uint32>(18), + static_cast<uint32>(19), + static_cast<uint32>(20), + static_cast<uint32>(21)); + EXPECT_EQ(GetActiveUniform::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<GLuint>(12), cmd.index); + EXPECT_EQ(static_cast<GLsizei>(13), cmd.bufsize); + EXPECT_EQ(static_cast<uint32>(14), cmd.length_shm_id); + EXPECT_EQ(static_cast<uint32>(15), cmd.length_shm_offset); + EXPECT_EQ(static_cast<uint32>(16), cmd.size_shm_id); + EXPECT_EQ(static_cast<uint32>(17), cmd.size_shm_offset); + EXPECT_EQ(static_cast<uint32>(18), cmd.type_shm_id); + EXPECT_EQ(static_cast<uint32>(19), cmd.type_shm_offset); + EXPECT_EQ(static_cast<uint32>(20), cmd.name_shm_id); + EXPECT_EQ(static_cast<uint32>(21), cmd.name_shm_offset); +} + +TEST(GLES2FormatTest, GetAttachedShaders) { + GetAttachedShaders cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<GLsizei>(12), + static_cast<uint32>(13), + static_cast<uint32>(14), + static_cast<uint32>(15), + static_cast<uint32>(16)); + EXPECT_EQ(GetAttachedShaders::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<GLsizei>(12), cmd.maxcount); + EXPECT_EQ(static_cast<uint32>(13), cmd.count_shm_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.count_shm_offset); + EXPECT_EQ(static_cast<uint32>(15), cmd.shaders_shm_id); + EXPECT_EQ(static_cast<uint32>(16), cmd.shaders_shm_offset); +} + +TEST(GLES2FormatTest, GetAttribLocation) { + GetAttribLocation cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<uint32>(12), + static_cast<uint32>(13), + static_cast<uint32>(14)); + EXPECT_EQ(GetAttribLocation::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<uint32>(12), cmd.name_shm_id); + EXPECT_EQ(static_cast<uint32>(13), cmd.name_shm_offset); + EXPECT_EQ(static_cast<uint32>(14), cmd.data_size); +} + +TEST(GLES2FormatTest, GetAttribLocationImmediate) { + int8 buf[256] = { 0, }; + GetAttribLocationImmediate& cmd = + *static_cast<GetAttribLocationImmediate*>(static_cast<void*>(&buf)); + static const char* const test_str = "test string"; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + test_str); + EXPECT_EQ(GetAttribLocationImmediate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd) + // NOLINT + RoundSizeToMultipleOfEntries(strlen(test_str)), + cmd.header.size * 4); + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + // TODO(gman): check that string got copied. +} + +TEST(GLES2FormatTest, GetBooleanv) { + GetBooleanv cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<uint32>(12), + static_cast<uint32>(13)); + EXPECT_EQ(GetBooleanv::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.pname); + EXPECT_EQ(static_cast<uint32>(12), cmd.params_shm_id); + EXPECT_EQ(static_cast<uint32>(13), cmd.params_shm_offset); +} + +TEST(GLES2FormatTest, GetBufferParameteriv) { + GetBufferParameteriv cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLenum>(12), + static_cast<uint32>(13), + static_cast<uint32>(14)); + EXPECT_EQ(GetBufferParameteriv::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLenum>(12), cmd.pname); + EXPECT_EQ(static_cast<uint32>(13), cmd.params_shm_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.params_shm_offset); +} + +TEST(GLES2FormatTest, GetError) { + GetError cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<uint32>(11), + static_cast<uint32>(12)); + EXPECT_EQ(GetError::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<uint32>(11), cmd.result_shm_id); + EXPECT_EQ(static_cast<uint32>(12), cmd.result_shm_offset); +} + +TEST(GLES2FormatTest, GetFloatv) { + GetFloatv cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<uint32>(12), + static_cast<uint32>(13)); + EXPECT_EQ(GetFloatv::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.pname); + EXPECT_EQ(static_cast<uint32>(12), cmd.params_shm_id); + EXPECT_EQ(static_cast<uint32>(13), cmd.params_shm_offset); +} + +TEST(GLES2FormatTest, GetFramebufferAttachmentParameteriv) { + GetFramebufferAttachmentParameteriv cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLenum>(12), + static_cast<GLenum>(13), + static_cast<uint32>(14), + static_cast<uint32>(15)); + EXPECT_EQ(GetFramebufferAttachmentParameteriv::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLenum>(12), cmd.attachment); + EXPECT_EQ(static_cast<GLenum>(13), cmd.pname); + EXPECT_EQ(static_cast<uint32>(14), cmd.params_shm_id); + EXPECT_EQ(static_cast<uint32>(15), cmd.params_shm_offset); +} + +TEST(GLES2FormatTest, GetIntegerv) { + GetIntegerv cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<uint32>(12), + static_cast<uint32>(13)); + EXPECT_EQ(GetIntegerv::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.pname); + EXPECT_EQ(static_cast<uint32>(12), cmd.params_shm_id); + EXPECT_EQ(static_cast<uint32>(13), cmd.params_shm_offset); +} + +TEST(GLES2FormatTest, GetProgramiv) { + GetProgramiv cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<GLenum>(12), + static_cast<uint32>(13), + static_cast<uint32>(14)); + EXPECT_EQ(GetProgramiv::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<GLenum>(12), cmd.pname); + EXPECT_EQ(static_cast<uint32>(13), cmd.params_shm_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.params_shm_offset); +} + +TEST(GLES2FormatTest, GetProgramInfoLog) { + GetProgramInfoLog cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<GLsizei>(12), + static_cast<uint32>(13), + static_cast<uint32>(14), + static_cast<uint32>(15), + static_cast<uint32>(16)); + EXPECT_EQ(GetProgramInfoLog::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<GLsizei>(12), cmd.bufsize); + EXPECT_EQ(static_cast<uint32>(13), cmd.length_shm_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.length_shm_offset); + EXPECT_EQ(static_cast<uint32>(15), cmd.infolog_shm_id); + EXPECT_EQ(static_cast<uint32>(16), cmd.infolog_shm_offset); +} + +TEST(GLES2FormatTest, GetRenderbufferParameteriv) { + GetRenderbufferParameteriv cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLenum>(12), + static_cast<uint32>(13), + static_cast<uint32>(14)); + EXPECT_EQ(GetRenderbufferParameteriv::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLenum>(12), cmd.pname); + EXPECT_EQ(static_cast<uint32>(13), cmd.params_shm_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.params_shm_offset); +} + +TEST(GLES2FormatTest, GetShaderiv) { + GetShaderiv cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<GLenum>(12), + static_cast<uint32>(13), + static_cast<uint32>(14)); + EXPECT_EQ(GetShaderiv::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.shader); + EXPECT_EQ(static_cast<GLenum>(12), cmd.pname); + EXPECT_EQ(static_cast<uint32>(13), cmd.params_shm_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.params_shm_offset); +} + +TEST(GLES2FormatTest, GetShaderInfoLog) { + GetShaderInfoLog cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<GLsizei>(12), + static_cast<uint32>(13), + static_cast<uint32>(14), + static_cast<uint32>(15), + static_cast<uint32>(16)); + EXPECT_EQ(GetShaderInfoLog::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.shader); + EXPECT_EQ(static_cast<GLsizei>(12), cmd.bufsize); + EXPECT_EQ(static_cast<uint32>(13), cmd.length_shm_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.length_shm_offset); + EXPECT_EQ(static_cast<uint32>(15), cmd.infolog_shm_id); + EXPECT_EQ(static_cast<uint32>(16), cmd.infolog_shm_offset); +} + +TEST(GLES2FormatTest, GetShaderPrecisionFormat) { + GetShaderPrecisionFormat cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLenum>(12), + static_cast<uint32>(13), + static_cast<uint32>(14), + static_cast<uint32>(15), + static_cast<uint32>(16)); + EXPECT_EQ(GetShaderPrecisionFormat::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.shadertype); + EXPECT_EQ(static_cast<GLenum>(12), cmd.precisiontype); + EXPECT_EQ(static_cast<uint32>(13), cmd.range_shm_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.range_shm_offset); + EXPECT_EQ(static_cast<uint32>(15), cmd.precision_shm_id); + EXPECT_EQ(static_cast<uint32>(16), cmd.precision_shm_offset); +} + +TEST(GLES2FormatTest, GetShaderSource) { + GetShaderSource cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<GLsizei>(12), + static_cast<uint32>(13), + static_cast<uint32>(14), + static_cast<uint32>(15), + static_cast<uint32>(16)); + EXPECT_EQ(GetShaderSource::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.shader); + EXPECT_EQ(static_cast<GLsizei>(12), cmd.bufsize); + EXPECT_EQ(static_cast<uint32>(13), cmd.length_shm_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.length_shm_offset); + EXPECT_EQ(static_cast<uint32>(15), cmd.source_shm_id); + EXPECT_EQ(static_cast<uint32>(16), cmd.source_shm_offset); +} + +TEST(GLES2FormatTest, GetString) { + GetString cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11)); + EXPECT_EQ(GetString::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.name); +} + +TEST(GLES2FormatTest, GetTexParameterfv) { + GetTexParameterfv cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLenum>(12), + static_cast<uint32>(13), + static_cast<uint32>(14)); + EXPECT_EQ(GetTexParameterfv::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLenum>(12), cmd.pname); + EXPECT_EQ(static_cast<uint32>(13), cmd.params_shm_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.params_shm_offset); +} + +TEST(GLES2FormatTest, GetTexParameteriv) { + GetTexParameteriv cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLenum>(12), + static_cast<uint32>(13), + static_cast<uint32>(14)); + EXPECT_EQ(GetTexParameteriv::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLenum>(12), cmd.pname); + EXPECT_EQ(static_cast<uint32>(13), cmd.params_shm_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.params_shm_offset); +} + +TEST(GLES2FormatTest, GetUniformfv) { + GetUniformfv cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<GLint>(12), + static_cast<uint32>(13), + static_cast<uint32>(14)); + EXPECT_EQ(GetUniformfv::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<GLint>(12), cmd.location); + EXPECT_EQ(static_cast<uint32>(13), cmd.params_shm_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.params_shm_offset); +} + +TEST(GLES2FormatTest, GetUniformiv) { + GetUniformiv cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<GLint>(12), + static_cast<uint32>(13), + static_cast<uint32>(14)); + EXPECT_EQ(GetUniformiv::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<GLint>(12), cmd.location); + EXPECT_EQ(static_cast<uint32>(13), cmd.params_shm_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.params_shm_offset); +} + +TEST(GLES2FormatTest, GetUniformLocation) { + GetUniformLocation cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<uint32>(12), + static_cast<uint32>(13), + static_cast<uint32>(14)); + EXPECT_EQ(GetUniformLocation::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<uint32>(12), cmd.name_shm_id); + EXPECT_EQ(static_cast<uint32>(13), cmd.name_shm_offset); + EXPECT_EQ(static_cast<uint32>(14), cmd.data_size); +} + +TEST(GLES2FormatTest, GetUniformLocationImmediate) { + int8 buf[256] = { 0, }; + GetUniformLocationImmediate& cmd = + *static_cast<GetUniformLocationImmediate*>(static_cast<void*>(&buf)); + static const char* const test_str = "test string"; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + test_str); + EXPECT_EQ(GetUniformLocationImmediate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd) + // NOLINT + RoundSizeToMultipleOfEntries(strlen(test_str)), + cmd.header.size * 4); + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + // TODO(gman): check that string got copied. +} + +TEST(GLES2FormatTest, GetVertexAttribfv) { + GetVertexAttribfv cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<GLenum>(12), + static_cast<uint32>(13), + static_cast<uint32>(14)); + EXPECT_EQ(GetVertexAttribfv::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.index); + EXPECT_EQ(static_cast<GLenum>(12), cmd.pname); + EXPECT_EQ(static_cast<uint32>(13), cmd.params_shm_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.params_shm_offset); +} + +TEST(GLES2FormatTest, GetVertexAttribiv) { + GetVertexAttribiv cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<GLenum>(12), + static_cast<uint32>(13), + static_cast<uint32>(14)); + EXPECT_EQ(GetVertexAttribiv::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.index); + EXPECT_EQ(static_cast<GLenum>(12), cmd.pname); + EXPECT_EQ(static_cast<uint32>(13), cmd.params_shm_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.params_shm_offset); +} + +TEST(GLES2FormatTest, GetVertexAttribPointerv) { + GetVertexAttribPointerv cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<GLenum>(12), + static_cast<uint32>(13), + static_cast<uint32>(14)); + EXPECT_EQ(GetVertexAttribPointerv::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.index); + EXPECT_EQ(static_cast<GLenum>(12), cmd.pname); + EXPECT_EQ(static_cast<uint32>(13), cmd.pointer_shm_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.pointer_shm_offset); +} + +TEST(GLES2FormatTest, Hint) { + Hint cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLenum>(12)); + EXPECT_EQ(Hint::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLenum>(12), cmd.mode); +} + +TEST(GLES2FormatTest, IsBuffer) { + IsBuffer cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<uint32>(12), + static_cast<uint32>(13)); + EXPECT_EQ(IsBuffer::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.buffer); + EXPECT_EQ(static_cast<uint32>(12), cmd.result_shm_id); + EXPECT_EQ(static_cast<uint32>(13), cmd.result_shm_offset); +} + +TEST(GLES2FormatTest, IsEnabled) { + IsEnabled cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<uint32>(12), + static_cast<uint32>(13)); + EXPECT_EQ(IsEnabled::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.cap); + EXPECT_EQ(static_cast<uint32>(12), cmd.result_shm_id); + EXPECT_EQ(static_cast<uint32>(13), cmd.result_shm_offset); +} + +TEST(GLES2FormatTest, IsFramebuffer) { + IsFramebuffer cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<uint32>(12), + static_cast<uint32>(13)); + EXPECT_EQ(IsFramebuffer::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.framebuffer); + EXPECT_EQ(static_cast<uint32>(12), cmd.result_shm_id); + EXPECT_EQ(static_cast<uint32>(13), cmd.result_shm_offset); +} + +TEST(GLES2FormatTest, IsProgram) { + IsProgram cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<uint32>(12), + static_cast<uint32>(13)); + EXPECT_EQ(IsProgram::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); + EXPECT_EQ(static_cast<uint32>(12), cmd.result_shm_id); + EXPECT_EQ(static_cast<uint32>(13), cmd.result_shm_offset); +} + +TEST(GLES2FormatTest, IsRenderbuffer) { + IsRenderbuffer cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<uint32>(12), + static_cast<uint32>(13)); + EXPECT_EQ(IsRenderbuffer::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.renderbuffer); + EXPECT_EQ(static_cast<uint32>(12), cmd.result_shm_id); + EXPECT_EQ(static_cast<uint32>(13), cmd.result_shm_offset); +} + +TEST(GLES2FormatTest, IsShader) { + IsShader cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<uint32>(12), + static_cast<uint32>(13)); + EXPECT_EQ(IsShader::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.shader); + EXPECT_EQ(static_cast<uint32>(12), cmd.result_shm_id); + EXPECT_EQ(static_cast<uint32>(13), cmd.result_shm_offset); +} + +TEST(GLES2FormatTest, IsTexture) { + IsTexture cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<uint32>(12), + static_cast<uint32>(13)); + EXPECT_EQ(IsTexture::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.texture); + EXPECT_EQ(static_cast<uint32>(12), cmd.result_shm_id); + EXPECT_EQ(static_cast<uint32>(13), cmd.result_shm_offset); +} + +TEST(GLES2FormatTest, LineWidth) { + LineWidth cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLfloat>(11)); + EXPECT_EQ(LineWidth::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLfloat>(11), cmd.width); +} + +TEST(GLES2FormatTest, LinkProgram) { + LinkProgram cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11)); + EXPECT_EQ(LinkProgram::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); +} + +TEST(GLES2FormatTest, PixelStorei) { + PixelStorei cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLint>(12)); + EXPECT_EQ(PixelStorei::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.pname); + EXPECT_EQ(static_cast<GLint>(12), cmd.param); +} + +TEST(GLES2FormatTest, PolygonOffset) { + PolygonOffset cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLfloat>(11), + static_cast<GLfloat>(12)); + EXPECT_EQ(PolygonOffset::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLfloat>(11), cmd.factor); + EXPECT_EQ(static_cast<GLfloat>(12), cmd.units); +} + +TEST(GLES2FormatTest, ReadPixels) { + ReadPixels cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(11), + static_cast<GLint>(12), + static_cast<GLsizei>(13), + static_cast<GLsizei>(14), + static_cast<GLenum>(15), + static_cast<GLenum>(16), + static_cast<uint32>(17), + static_cast<uint32>(18)); + EXPECT_EQ(ReadPixels::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(11), cmd.x); + EXPECT_EQ(static_cast<GLint>(12), cmd.y); + EXPECT_EQ(static_cast<GLsizei>(13), cmd.width); + EXPECT_EQ(static_cast<GLsizei>(14), cmd.height); + EXPECT_EQ(static_cast<GLenum>(15), cmd.format); + EXPECT_EQ(static_cast<GLenum>(16), cmd.type); + EXPECT_EQ(static_cast<uint32>(17), cmd.pixels_shm_id); + EXPECT_EQ(static_cast<uint32>(18), cmd.pixels_shm_offset); +} + +TEST(GLES2FormatTest, RenderbufferStorage) { + RenderbufferStorage cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLenum>(12), + static_cast<GLsizei>(13), + static_cast<GLsizei>(14)); + EXPECT_EQ(RenderbufferStorage::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLenum>(12), cmd.internalformat); + EXPECT_EQ(static_cast<GLsizei>(13), cmd.width); + EXPECT_EQ(static_cast<GLsizei>(14), cmd.height); +} + +TEST(GLES2FormatTest, SampleCoverage) { + SampleCoverage cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLclampf>(11), + static_cast<GLboolean>(12)); + EXPECT_EQ(SampleCoverage::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLclampf>(11), cmd.value); + EXPECT_EQ(static_cast<GLboolean>(12), cmd.invert); +} + +TEST(GLES2FormatTest, Scissor) { + Scissor cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(11), + static_cast<GLint>(12), + static_cast<GLsizei>(13), + static_cast<GLsizei>(14)); + EXPECT_EQ(Scissor::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(11), cmd.x); + EXPECT_EQ(static_cast<GLint>(12), cmd.y); + EXPECT_EQ(static_cast<GLsizei>(13), cmd.width); + EXPECT_EQ(static_cast<GLsizei>(14), cmd.height); +} + +TEST(GLES2FormatTest, ShaderSource) { + ShaderSource cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<GLsizei>(12), + static_cast<uint32>(13), + static_cast<uint32>(14), + static_cast<uint32>(15)); + EXPECT_EQ(ShaderSource::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.shader); + EXPECT_EQ(static_cast<GLsizei>(12), cmd.count); + EXPECT_EQ(static_cast<uint32>(13), cmd.data_shm_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.data_shm_offset); + EXPECT_EQ(static_cast<uint32>(15), cmd.data_size); +} + +// TODO(gman): Implement test for ShaderSourceImmediate +TEST(GLES2FormatTest, StencilFunc) { + StencilFunc cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLint>(12), + static_cast<GLuint>(13)); + EXPECT_EQ(StencilFunc::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.func); + EXPECT_EQ(static_cast<GLint>(12), cmd.ref); + EXPECT_EQ(static_cast<GLuint>(13), cmd.mask); +} + +TEST(GLES2FormatTest, StencilFuncSeparate) { + StencilFuncSeparate cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLenum>(12), + static_cast<GLint>(13), + static_cast<GLuint>(14)); + EXPECT_EQ(StencilFuncSeparate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.face); + EXPECT_EQ(static_cast<GLenum>(12), cmd.func); + EXPECT_EQ(static_cast<GLint>(13), cmd.ref); + EXPECT_EQ(static_cast<GLuint>(14), cmd.mask); +} + +TEST(GLES2FormatTest, StencilMask) { + StencilMask cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11)); + EXPECT_EQ(StencilMask::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.mask); +} + +TEST(GLES2FormatTest, StencilMaskSeparate) { + StencilMaskSeparate cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLuint>(12)); + EXPECT_EQ(StencilMaskSeparate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.face); + EXPECT_EQ(static_cast<GLuint>(12), cmd.mask); +} + +TEST(GLES2FormatTest, StencilOp) { + StencilOp cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLenum>(12), + static_cast<GLenum>(13)); + EXPECT_EQ(StencilOp::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.fail); + EXPECT_EQ(static_cast<GLenum>(12), cmd.zfail); + EXPECT_EQ(static_cast<GLenum>(13), cmd.zpass); +} + +TEST(GLES2FormatTest, StencilOpSeparate) { + StencilOpSeparate cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLenum>(12), + static_cast<GLenum>(13), + static_cast<GLenum>(14)); + EXPECT_EQ(StencilOpSeparate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.face); + EXPECT_EQ(static_cast<GLenum>(12), cmd.fail); + EXPECT_EQ(static_cast<GLenum>(13), cmd.zfail); + EXPECT_EQ(static_cast<GLenum>(14), cmd.zpass); +} + +TEST(GLES2FormatTest, TexImage2D) { + TexImage2D cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLint>(12), + static_cast<GLint>(13), + static_cast<GLsizei>(14), + static_cast<GLsizei>(15), + static_cast<GLint>(16), + static_cast<GLenum>(17), + static_cast<GLenum>(18), + static_cast<uint32>(19), + static_cast<uint32>(20)); + EXPECT_EQ(TexImage2D::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLint>(12), cmd.level); + EXPECT_EQ(static_cast<GLint>(13), cmd.internalformat); + EXPECT_EQ(static_cast<GLsizei>(14), cmd.width); + EXPECT_EQ(static_cast<GLsizei>(15), cmd.height); + EXPECT_EQ(static_cast<GLint>(16), cmd.border); + EXPECT_EQ(static_cast<GLenum>(17), cmd.format); + EXPECT_EQ(static_cast<GLenum>(18), cmd.type); + EXPECT_EQ(static_cast<uint32>(19), cmd.pixels_shm_id); + EXPECT_EQ(static_cast<uint32>(20), cmd.pixels_shm_offset); +} + +// TODO(gman): Implement test for TexImage2DImmediate +TEST(GLES2FormatTest, TexParameterf) { + TexParameterf cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLenum>(12), + static_cast<GLfloat>(13)); + EXPECT_EQ(TexParameterf::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLenum>(12), cmd.pname); + EXPECT_EQ(static_cast<GLfloat>(13), cmd.param); +} + +TEST(GLES2FormatTest, TexParameterfv) { + TexParameterfv cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLenum>(12), + static_cast<uint32>(13), + static_cast<uint32>(14)); + EXPECT_EQ(TexParameterfv::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLenum>(12), cmd.pname); + EXPECT_EQ(static_cast<uint32>(13), cmd.params_shm_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.params_shm_offset); +} + +TEST(GLES2FormatTest, TexParameterfvImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLfloat data[] = { + static_cast<GLfloat>(kSomeBaseValueToTestWith + 0), + }; + int8 buf[256] = { 0, }; + TexParameterfvImmediate& cmd = + *static_cast<TexParameterfvImmediate*>(static_cast<void*>(&buf)); + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLenum>(12), + data); + EXPECT_EQ(TexParameterfvImmediate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd) + + RoundSizeToMultipleOfEntries(sizeof(data)), + cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLenum>(12), cmd.pname); + // TODO(gman): Check that data was inserted; +} + +TEST(GLES2FormatTest, TexParameteri) { + TexParameteri cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLenum>(12), + static_cast<GLint>(13)); + EXPECT_EQ(TexParameteri::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLenum>(12), cmd.pname); + EXPECT_EQ(static_cast<GLint>(13), cmd.param); +} + +TEST(GLES2FormatTest, TexParameteriv) { + TexParameteriv cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLenum>(12), + static_cast<uint32>(13), + static_cast<uint32>(14)); + EXPECT_EQ(TexParameteriv::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLenum>(12), cmd.pname); + EXPECT_EQ(static_cast<uint32>(13), cmd.params_shm_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.params_shm_offset); +} + +TEST(GLES2FormatTest, TexParameterivImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLint data[] = { + static_cast<GLint>(kSomeBaseValueToTestWith + 0), + }; + int8 buf[256] = { 0, }; + TexParameterivImmediate& cmd = + *static_cast<TexParameterivImmediate*>(static_cast<void*>(&buf)); + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLenum>(12), + data); + EXPECT_EQ(TexParameterivImmediate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd) + + RoundSizeToMultipleOfEntries(sizeof(data)), + cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLenum>(12), cmd.pname); + // TODO(gman): Check that data was inserted; +} + +TEST(GLES2FormatTest, TexSubImage2D) { + TexSubImage2D cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLenum>(11), + static_cast<GLint>(12), + static_cast<GLint>(13), + static_cast<GLint>(14), + static_cast<GLsizei>(15), + static_cast<GLsizei>(16), + static_cast<GLenum>(17), + static_cast<GLenum>(18), + static_cast<uint32>(19), + static_cast<uint32>(20)); + EXPECT_EQ(TexSubImage2D::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLenum>(11), cmd.target); + EXPECT_EQ(static_cast<GLint>(12), cmd.level); + EXPECT_EQ(static_cast<GLint>(13), cmd.xoffset); + EXPECT_EQ(static_cast<GLint>(14), cmd.yoffset); + EXPECT_EQ(static_cast<GLsizei>(15), cmd.width); + EXPECT_EQ(static_cast<GLsizei>(16), cmd.height); + EXPECT_EQ(static_cast<GLenum>(17), cmd.format); + EXPECT_EQ(static_cast<GLenum>(18), cmd.type); + EXPECT_EQ(static_cast<uint32>(19), cmd.pixels_shm_id); + EXPECT_EQ(static_cast<uint32>(20), cmd.pixels_shm_offset); +} + +// TODO(gman): Implement test for TexSubImage2DImmediate +TEST(GLES2FormatTest, Uniform1f) { + Uniform1f cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(11), + static_cast<GLfloat>(12)); + EXPECT_EQ(Uniform1f::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(11), cmd.location); + EXPECT_EQ(static_cast<GLfloat>(12), cmd.x); +} + +TEST(GLES2FormatTest, Uniform1fv) { + Uniform1fv cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(11), + static_cast<GLsizei>(12), + static_cast<uint32>(13), + static_cast<uint32>(14)); + EXPECT_EQ(Uniform1fv::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(11), cmd.location); + EXPECT_EQ(static_cast<GLsizei>(12), cmd.count); + EXPECT_EQ(static_cast<uint32>(13), cmd.v_shm_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.v_shm_offset); +} + +TEST(GLES2FormatTest, Uniform1fvImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLfloat data[] = { + static_cast<GLfloat>(kSomeBaseValueToTestWith + 0), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 1), + }; + int8 buf[256] = { 0, }; + Uniform1fvImmediate& cmd = + *static_cast<Uniform1fvImmediate*>(static_cast<void*>(&buf)); + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(1), + static_cast<GLsizei>(2), + data); + EXPECT_EQ(Uniform1fvImmediate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd) + + RoundSizeToMultipleOfEntries(sizeof(data)), + cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(1), cmd.location); + EXPECT_EQ(static_cast<GLsizei>(2), cmd.count); + // TODO(gman): Check that data was inserted; +} + +TEST(GLES2FormatTest, Uniform1i) { + Uniform1i cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(11), + static_cast<GLint>(12)); + EXPECT_EQ(Uniform1i::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(11), cmd.location); + EXPECT_EQ(static_cast<GLint>(12), cmd.x); +} + +TEST(GLES2FormatTest, Uniform1iv) { + Uniform1iv cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(11), + static_cast<GLsizei>(12), + static_cast<uint32>(13), + static_cast<uint32>(14)); + EXPECT_EQ(Uniform1iv::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(11), cmd.location); + EXPECT_EQ(static_cast<GLsizei>(12), cmd.count); + EXPECT_EQ(static_cast<uint32>(13), cmd.v_shm_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.v_shm_offset); +} + +TEST(GLES2FormatTest, Uniform1ivImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLint data[] = { + static_cast<GLint>(kSomeBaseValueToTestWith + 0), + static_cast<GLint>(kSomeBaseValueToTestWith + 1), + }; + int8 buf[256] = { 0, }; + Uniform1ivImmediate& cmd = + *static_cast<Uniform1ivImmediate*>(static_cast<void*>(&buf)); + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(1), + static_cast<GLsizei>(2), + data); + EXPECT_EQ(Uniform1ivImmediate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd) + + RoundSizeToMultipleOfEntries(sizeof(data)), + cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(1), cmd.location); + EXPECT_EQ(static_cast<GLsizei>(2), cmd.count); + // TODO(gman): Check that data was inserted; +} + +TEST(GLES2FormatTest, Uniform2f) { + Uniform2f cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(11), + static_cast<GLfloat>(12), + static_cast<GLfloat>(13)); + EXPECT_EQ(Uniform2f::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(11), cmd.location); + EXPECT_EQ(static_cast<GLfloat>(12), cmd.x); + EXPECT_EQ(static_cast<GLfloat>(13), cmd.y); +} + +TEST(GLES2FormatTest, Uniform2fv) { + Uniform2fv cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(11), + static_cast<GLsizei>(12), + static_cast<uint32>(13), + static_cast<uint32>(14)); + EXPECT_EQ(Uniform2fv::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(11), cmd.location); + EXPECT_EQ(static_cast<GLsizei>(12), cmd.count); + EXPECT_EQ(static_cast<uint32>(13), cmd.v_shm_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.v_shm_offset); +} + +TEST(GLES2FormatTest, Uniform2fvImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLfloat data[] = { + static_cast<GLfloat>(kSomeBaseValueToTestWith + 0), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 1), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 2), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 3), + }; + int8 buf[256] = { 0, }; + Uniform2fvImmediate& cmd = + *static_cast<Uniform2fvImmediate*>(static_cast<void*>(&buf)); + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(1), + static_cast<GLsizei>(2), + data); + EXPECT_EQ(Uniform2fvImmediate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd) + + RoundSizeToMultipleOfEntries(sizeof(data)), + cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(1), cmd.location); + EXPECT_EQ(static_cast<GLsizei>(2), cmd.count); + // TODO(gman): Check that data was inserted; +} + +TEST(GLES2FormatTest, Uniform2i) { + Uniform2i cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(11), + static_cast<GLint>(12), + static_cast<GLint>(13)); + EXPECT_EQ(Uniform2i::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(11), cmd.location); + EXPECT_EQ(static_cast<GLint>(12), cmd.x); + EXPECT_EQ(static_cast<GLint>(13), cmd.y); +} + +TEST(GLES2FormatTest, Uniform2iv) { + Uniform2iv cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(11), + static_cast<GLsizei>(12), + static_cast<uint32>(13), + static_cast<uint32>(14)); + EXPECT_EQ(Uniform2iv::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(11), cmd.location); + EXPECT_EQ(static_cast<GLsizei>(12), cmd.count); + EXPECT_EQ(static_cast<uint32>(13), cmd.v_shm_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.v_shm_offset); +} + +TEST(GLES2FormatTest, Uniform2ivImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLint data[] = { + static_cast<GLint>(kSomeBaseValueToTestWith + 0), + static_cast<GLint>(kSomeBaseValueToTestWith + 1), + static_cast<GLint>(kSomeBaseValueToTestWith + 2), + static_cast<GLint>(kSomeBaseValueToTestWith + 3), + }; + int8 buf[256] = { 0, }; + Uniform2ivImmediate& cmd = + *static_cast<Uniform2ivImmediate*>(static_cast<void*>(&buf)); + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(1), + static_cast<GLsizei>(2), + data); + EXPECT_EQ(Uniform2ivImmediate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd) + + RoundSizeToMultipleOfEntries(sizeof(data)), + cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(1), cmd.location); + EXPECT_EQ(static_cast<GLsizei>(2), cmd.count); + // TODO(gman): Check that data was inserted; +} + +TEST(GLES2FormatTest, Uniform3f) { + Uniform3f cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(11), + static_cast<GLfloat>(12), + static_cast<GLfloat>(13), + static_cast<GLfloat>(14)); + EXPECT_EQ(Uniform3f::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(11), cmd.location); + EXPECT_EQ(static_cast<GLfloat>(12), cmd.x); + EXPECT_EQ(static_cast<GLfloat>(13), cmd.y); + EXPECT_EQ(static_cast<GLfloat>(14), cmd.z); +} + +TEST(GLES2FormatTest, Uniform3fv) { + Uniform3fv cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(11), + static_cast<GLsizei>(12), + static_cast<uint32>(13), + static_cast<uint32>(14)); + EXPECT_EQ(Uniform3fv::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(11), cmd.location); + EXPECT_EQ(static_cast<GLsizei>(12), cmd.count); + EXPECT_EQ(static_cast<uint32>(13), cmd.v_shm_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.v_shm_offset); +} + +TEST(GLES2FormatTest, Uniform3fvImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLfloat data[] = { + static_cast<GLfloat>(kSomeBaseValueToTestWith + 0), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 1), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 2), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 3), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 4), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 5), + }; + int8 buf[256] = { 0, }; + Uniform3fvImmediate& cmd = + *static_cast<Uniform3fvImmediate*>(static_cast<void*>(&buf)); + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(1), + static_cast<GLsizei>(2), + data); + EXPECT_EQ(Uniform3fvImmediate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd) + + RoundSizeToMultipleOfEntries(sizeof(data)), + cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(1), cmd.location); + EXPECT_EQ(static_cast<GLsizei>(2), cmd.count); + // TODO(gman): Check that data was inserted; +} + +TEST(GLES2FormatTest, Uniform3i) { + Uniform3i cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(11), + static_cast<GLint>(12), + static_cast<GLint>(13), + static_cast<GLint>(14)); + EXPECT_EQ(Uniform3i::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(11), cmd.location); + EXPECT_EQ(static_cast<GLint>(12), cmd.x); + EXPECT_EQ(static_cast<GLint>(13), cmd.y); + EXPECT_EQ(static_cast<GLint>(14), cmd.z); +} + +TEST(GLES2FormatTest, Uniform3iv) { + Uniform3iv cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(11), + static_cast<GLsizei>(12), + static_cast<uint32>(13), + static_cast<uint32>(14)); + EXPECT_EQ(Uniform3iv::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(11), cmd.location); + EXPECT_EQ(static_cast<GLsizei>(12), cmd.count); + EXPECT_EQ(static_cast<uint32>(13), cmd.v_shm_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.v_shm_offset); +} + +TEST(GLES2FormatTest, Uniform3ivImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLint data[] = { + static_cast<GLint>(kSomeBaseValueToTestWith + 0), + static_cast<GLint>(kSomeBaseValueToTestWith + 1), + static_cast<GLint>(kSomeBaseValueToTestWith + 2), + static_cast<GLint>(kSomeBaseValueToTestWith + 3), + static_cast<GLint>(kSomeBaseValueToTestWith + 4), + static_cast<GLint>(kSomeBaseValueToTestWith + 5), + }; + int8 buf[256] = { 0, }; + Uniform3ivImmediate& cmd = + *static_cast<Uniform3ivImmediate*>(static_cast<void*>(&buf)); + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(1), + static_cast<GLsizei>(2), + data); + EXPECT_EQ(Uniform3ivImmediate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd) + + RoundSizeToMultipleOfEntries(sizeof(data)), + cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(1), cmd.location); + EXPECT_EQ(static_cast<GLsizei>(2), cmd.count); + // TODO(gman): Check that data was inserted; +} + +TEST(GLES2FormatTest, Uniform4f) { + Uniform4f cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(11), + static_cast<GLfloat>(12), + static_cast<GLfloat>(13), + static_cast<GLfloat>(14), + static_cast<GLfloat>(15)); + EXPECT_EQ(Uniform4f::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(11), cmd.location); + EXPECT_EQ(static_cast<GLfloat>(12), cmd.x); + EXPECT_EQ(static_cast<GLfloat>(13), cmd.y); + EXPECT_EQ(static_cast<GLfloat>(14), cmd.z); + EXPECT_EQ(static_cast<GLfloat>(15), cmd.w); +} + +TEST(GLES2FormatTest, Uniform4fv) { + Uniform4fv cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(11), + static_cast<GLsizei>(12), + static_cast<uint32>(13), + static_cast<uint32>(14)); + EXPECT_EQ(Uniform4fv::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(11), cmd.location); + EXPECT_EQ(static_cast<GLsizei>(12), cmd.count); + EXPECT_EQ(static_cast<uint32>(13), cmd.v_shm_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.v_shm_offset); +} + +TEST(GLES2FormatTest, Uniform4fvImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLfloat data[] = { + static_cast<GLfloat>(kSomeBaseValueToTestWith + 0), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 1), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 2), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 3), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 4), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 5), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 6), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 7), + }; + int8 buf[256] = { 0, }; + Uniform4fvImmediate& cmd = + *static_cast<Uniform4fvImmediate*>(static_cast<void*>(&buf)); + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(1), + static_cast<GLsizei>(2), + data); + EXPECT_EQ(Uniform4fvImmediate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd) + + RoundSizeToMultipleOfEntries(sizeof(data)), + cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(1), cmd.location); + EXPECT_EQ(static_cast<GLsizei>(2), cmd.count); + // TODO(gman): Check that data was inserted; +} + +TEST(GLES2FormatTest, Uniform4i) { + Uniform4i cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(11), + static_cast<GLint>(12), + static_cast<GLint>(13), + static_cast<GLint>(14), + static_cast<GLint>(15)); + EXPECT_EQ(Uniform4i::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(11), cmd.location); + EXPECT_EQ(static_cast<GLint>(12), cmd.x); + EXPECT_EQ(static_cast<GLint>(13), cmd.y); + EXPECT_EQ(static_cast<GLint>(14), cmd.z); + EXPECT_EQ(static_cast<GLint>(15), cmd.w); +} + +TEST(GLES2FormatTest, Uniform4iv) { + Uniform4iv cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(11), + static_cast<GLsizei>(12), + static_cast<uint32>(13), + static_cast<uint32>(14)); + EXPECT_EQ(Uniform4iv::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(11), cmd.location); + EXPECT_EQ(static_cast<GLsizei>(12), cmd.count); + EXPECT_EQ(static_cast<uint32>(13), cmd.v_shm_id); + EXPECT_EQ(static_cast<uint32>(14), cmd.v_shm_offset); +} + +TEST(GLES2FormatTest, Uniform4ivImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLint data[] = { + static_cast<GLint>(kSomeBaseValueToTestWith + 0), + static_cast<GLint>(kSomeBaseValueToTestWith + 1), + static_cast<GLint>(kSomeBaseValueToTestWith + 2), + static_cast<GLint>(kSomeBaseValueToTestWith + 3), + static_cast<GLint>(kSomeBaseValueToTestWith + 4), + static_cast<GLint>(kSomeBaseValueToTestWith + 5), + static_cast<GLint>(kSomeBaseValueToTestWith + 6), + static_cast<GLint>(kSomeBaseValueToTestWith + 7), + }; + int8 buf[256] = { 0, }; + Uniform4ivImmediate& cmd = + *static_cast<Uniform4ivImmediate*>(static_cast<void*>(&buf)); + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(1), + static_cast<GLsizei>(2), + data); + EXPECT_EQ(Uniform4ivImmediate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd) + + RoundSizeToMultipleOfEntries(sizeof(data)), + cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(1), cmd.location); + EXPECT_EQ(static_cast<GLsizei>(2), cmd.count); + // TODO(gman): Check that data was inserted; +} + +TEST(GLES2FormatTest, UniformMatrix2fv) { + UniformMatrix2fv cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(11), + static_cast<GLsizei>(12), + static_cast<GLboolean>(13), + static_cast<uint32>(14), + static_cast<uint32>(15)); + EXPECT_EQ(UniformMatrix2fv::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(11), cmd.location); + EXPECT_EQ(static_cast<GLsizei>(12), cmd.count); + EXPECT_EQ(static_cast<GLboolean>(13), cmd.transpose); + EXPECT_EQ(static_cast<uint32>(14), cmd.value_shm_id); + EXPECT_EQ(static_cast<uint32>(15), cmd.value_shm_offset); +} + +TEST(GLES2FormatTest, UniformMatrix2fvImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLfloat data[] = { + static_cast<GLfloat>(kSomeBaseValueToTestWith + 0), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 1), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 2), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 3), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 4), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 5), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 6), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 7), + }; + int8 buf[256] = { 0, }; + UniformMatrix2fvImmediate& cmd = + *static_cast<UniformMatrix2fvImmediate*>(static_cast<void*>(&buf)); + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(1), + static_cast<GLsizei>(2), + static_cast<GLboolean>(3), + data); + EXPECT_EQ(UniformMatrix2fvImmediate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd) + + RoundSizeToMultipleOfEntries(sizeof(data)), + cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(1), cmd.location); + EXPECT_EQ(static_cast<GLsizei>(2), cmd.count); + EXPECT_EQ(static_cast<GLboolean>(3), cmd.transpose); + // TODO(gman): Check that data was inserted; +} + +TEST(GLES2FormatTest, UniformMatrix3fv) { + UniformMatrix3fv cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(11), + static_cast<GLsizei>(12), + static_cast<GLboolean>(13), + static_cast<uint32>(14), + static_cast<uint32>(15)); + EXPECT_EQ(UniformMatrix3fv::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(11), cmd.location); + EXPECT_EQ(static_cast<GLsizei>(12), cmd.count); + EXPECT_EQ(static_cast<GLboolean>(13), cmd.transpose); + EXPECT_EQ(static_cast<uint32>(14), cmd.value_shm_id); + EXPECT_EQ(static_cast<uint32>(15), cmd.value_shm_offset); +} + +TEST(GLES2FormatTest, UniformMatrix3fvImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLfloat data[] = { + static_cast<GLfloat>(kSomeBaseValueToTestWith + 0), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 1), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 2), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 3), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 4), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 5), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 6), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 7), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 8), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 9), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 10), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 11), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 12), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 13), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 14), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 15), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 16), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 17), + }; + int8 buf[256] = { 0, }; + UniformMatrix3fvImmediate& cmd = + *static_cast<UniformMatrix3fvImmediate*>(static_cast<void*>(&buf)); + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(1), + static_cast<GLsizei>(2), + static_cast<GLboolean>(3), + data); + EXPECT_EQ(UniformMatrix3fvImmediate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd) + + RoundSizeToMultipleOfEntries(sizeof(data)), + cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(1), cmd.location); + EXPECT_EQ(static_cast<GLsizei>(2), cmd.count); + EXPECT_EQ(static_cast<GLboolean>(3), cmd.transpose); + // TODO(gman): Check that data was inserted; +} + +TEST(GLES2FormatTest, UniformMatrix4fv) { + UniformMatrix4fv cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(11), + static_cast<GLsizei>(12), + static_cast<GLboolean>(13), + static_cast<uint32>(14), + static_cast<uint32>(15)); + EXPECT_EQ(UniformMatrix4fv::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(11), cmd.location); + EXPECT_EQ(static_cast<GLsizei>(12), cmd.count); + EXPECT_EQ(static_cast<GLboolean>(13), cmd.transpose); + EXPECT_EQ(static_cast<uint32>(14), cmd.value_shm_id); + EXPECT_EQ(static_cast<uint32>(15), cmd.value_shm_offset); +} + +TEST(GLES2FormatTest, UniformMatrix4fvImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLfloat data[] = { + static_cast<GLfloat>(kSomeBaseValueToTestWith + 0), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 1), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 2), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 3), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 4), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 5), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 6), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 7), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 8), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 9), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 10), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 11), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 12), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 13), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 14), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 15), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 16), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 17), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 18), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 19), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 20), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 21), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 22), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 23), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 24), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 25), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 26), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 27), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 28), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 29), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 30), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 31), + }; + int8 buf[256] = { 0, }; + UniformMatrix4fvImmediate& cmd = + *static_cast<UniformMatrix4fvImmediate*>(static_cast<void*>(&buf)); + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(1), + static_cast<GLsizei>(2), + static_cast<GLboolean>(3), + data); + EXPECT_EQ(UniformMatrix4fvImmediate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd) + + RoundSizeToMultipleOfEntries(sizeof(data)), + cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(1), cmd.location); + EXPECT_EQ(static_cast<GLsizei>(2), cmd.count); + EXPECT_EQ(static_cast<GLboolean>(3), cmd.transpose); + // TODO(gman): Check that data was inserted; +} + +TEST(GLES2FormatTest, UseProgram) { + UseProgram cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11)); + EXPECT_EQ(UseProgram::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); +} + +TEST(GLES2FormatTest, ValidateProgram) { + ValidateProgram cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11)); + EXPECT_EQ(ValidateProgram::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.program); +} + +TEST(GLES2FormatTest, VertexAttrib1f) { + VertexAttrib1f cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<GLfloat>(12)); + EXPECT_EQ(VertexAttrib1f::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.indx); + EXPECT_EQ(static_cast<GLfloat>(12), cmd.x); +} + +TEST(GLES2FormatTest, VertexAttrib1fv) { + VertexAttrib1fv cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<uint32>(12), + static_cast<uint32>(13)); + EXPECT_EQ(VertexAttrib1fv::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.indx); + EXPECT_EQ(static_cast<uint32>(12), cmd.values_shm_id); + EXPECT_EQ(static_cast<uint32>(13), cmd.values_shm_offset); +} + +TEST(GLES2FormatTest, VertexAttrib1fvImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLfloat data[] = { + static_cast<GLfloat>(kSomeBaseValueToTestWith + 0), + }; + int8 buf[256] = { 0, }; + VertexAttrib1fvImmediate& cmd = + *static_cast<VertexAttrib1fvImmediate*>(static_cast<void*>(&buf)); + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + data); + EXPECT_EQ(VertexAttrib1fvImmediate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd) + + RoundSizeToMultipleOfEntries(sizeof(data)), + cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.indx); + // TODO(gman): Check that data was inserted; +} + +TEST(GLES2FormatTest, VertexAttrib2f) { + VertexAttrib2f cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<GLfloat>(12), + static_cast<GLfloat>(13)); + EXPECT_EQ(VertexAttrib2f::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.indx); + EXPECT_EQ(static_cast<GLfloat>(12), cmd.x); + EXPECT_EQ(static_cast<GLfloat>(13), cmd.y); +} + +TEST(GLES2FormatTest, VertexAttrib2fv) { + VertexAttrib2fv cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<uint32>(12), + static_cast<uint32>(13)); + EXPECT_EQ(VertexAttrib2fv::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.indx); + EXPECT_EQ(static_cast<uint32>(12), cmd.values_shm_id); + EXPECT_EQ(static_cast<uint32>(13), cmd.values_shm_offset); +} + +TEST(GLES2FormatTest, VertexAttrib2fvImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLfloat data[] = { + static_cast<GLfloat>(kSomeBaseValueToTestWith + 0), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 1), + }; + int8 buf[256] = { 0, }; + VertexAttrib2fvImmediate& cmd = + *static_cast<VertexAttrib2fvImmediate*>(static_cast<void*>(&buf)); + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + data); + EXPECT_EQ(VertexAttrib2fvImmediate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd) + + RoundSizeToMultipleOfEntries(sizeof(data)), + cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.indx); + // TODO(gman): Check that data was inserted; +} + +TEST(GLES2FormatTest, VertexAttrib3f) { + VertexAttrib3f cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<GLfloat>(12), + static_cast<GLfloat>(13), + static_cast<GLfloat>(14)); + EXPECT_EQ(VertexAttrib3f::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.indx); + EXPECT_EQ(static_cast<GLfloat>(12), cmd.x); + EXPECT_EQ(static_cast<GLfloat>(13), cmd.y); + EXPECT_EQ(static_cast<GLfloat>(14), cmd.z); +} + +TEST(GLES2FormatTest, VertexAttrib3fv) { + VertexAttrib3fv cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<uint32>(12), + static_cast<uint32>(13)); + EXPECT_EQ(VertexAttrib3fv::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.indx); + EXPECT_EQ(static_cast<uint32>(12), cmd.values_shm_id); + EXPECT_EQ(static_cast<uint32>(13), cmd.values_shm_offset); +} + +TEST(GLES2FormatTest, VertexAttrib3fvImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLfloat data[] = { + static_cast<GLfloat>(kSomeBaseValueToTestWith + 0), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 1), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 2), + }; + int8 buf[256] = { 0, }; + VertexAttrib3fvImmediate& cmd = + *static_cast<VertexAttrib3fvImmediate*>(static_cast<void*>(&buf)); + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + data); + EXPECT_EQ(VertexAttrib3fvImmediate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd) + + RoundSizeToMultipleOfEntries(sizeof(data)), + cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.indx); + // TODO(gman): Check that data was inserted; +} + +TEST(GLES2FormatTest, VertexAttrib4f) { + VertexAttrib4f cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<GLfloat>(12), + static_cast<GLfloat>(13), + static_cast<GLfloat>(14), + static_cast<GLfloat>(15)); + EXPECT_EQ(VertexAttrib4f::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.indx); + EXPECT_EQ(static_cast<GLfloat>(12), cmd.x); + EXPECT_EQ(static_cast<GLfloat>(13), cmd.y); + EXPECT_EQ(static_cast<GLfloat>(14), cmd.z); + EXPECT_EQ(static_cast<GLfloat>(15), cmd.w); +} + +TEST(GLES2FormatTest, VertexAttrib4fv) { + VertexAttrib4fv cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<uint32>(12), + static_cast<uint32>(13)); + EXPECT_EQ(VertexAttrib4fv::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.indx); + EXPECT_EQ(static_cast<uint32>(12), cmd.values_shm_id); + EXPECT_EQ(static_cast<uint32>(13), cmd.values_shm_offset); +} + +TEST(GLES2FormatTest, VertexAttrib4fvImmediate) { + const int kSomeBaseValueToTestWith = 51; + static GLfloat data[] = { + static_cast<GLfloat>(kSomeBaseValueToTestWith + 0), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 1), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 2), + static_cast<GLfloat>(kSomeBaseValueToTestWith + 3), + }; + int8 buf[256] = { 0, }; + VertexAttrib4fvImmediate& cmd = + *static_cast<VertexAttrib4fvImmediate*>(static_cast<void*>(&buf)); + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + data); + EXPECT_EQ(VertexAttrib4fvImmediate::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd) + + RoundSizeToMultipleOfEntries(sizeof(data)), + cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.indx); + // TODO(gman): Check that data was inserted; +} + +TEST(GLES2FormatTest, VertexAttribPointer) { + VertexAttribPointer cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLuint>(11), + static_cast<GLint>(12), + static_cast<GLenum>(13), + static_cast<GLboolean>(14), + static_cast<GLsizei>(15), + static_cast<GLuint>(16)); + EXPECT_EQ(VertexAttribPointer::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLuint>(11), cmd.indx); + EXPECT_EQ(static_cast<GLint>(12), cmd.size); + EXPECT_EQ(static_cast<GLenum>(13), cmd.type); + EXPECT_EQ(static_cast<GLboolean>(14), cmd.normalized); + EXPECT_EQ(static_cast<GLsizei>(15), cmd.stride); + EXPECT_EQ(static_cast<GLuint>(16), cmd.offset); +} + +TEST(GLES2FormatTest, Viewport) { + Viewport cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd, + static_cast<GLint>(11), + static_cast<GLint>(12), + static_cast<GLsizei>(13), + static_cast<GLsizei>(14)); + EXPECT_EQ(Viewport::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT + EXPECT_EQ(static_cast<GLint>(11), cmd.x); + EXPECT_EQ(static_cast<GLint>(12), cmd.y); + EXPECT_EQ(static_cast<GLsizei>(13), cmd.width); + EXPECT_EQ(static_cast<GLsizei>(14), cmd.height); +} + +TEST(GLES2FormatTest, SwapBuffers) { + SwapBuffers cmd = { 0, }; + void* next_cmd = cmd.Set( + &cmd); + EXPECT_EQ(SwapBuffers::kCmdId, cmd.header.command); + EXPECT_EQ(sizeof(cmd), cmd.header.size * 4); // NOLINT +} + diff --git a/gpu/command_buffer/common/gles2_cmd_id_test.cc b/gpu/command_buffer/common/gles2_cmd_id_test.cc new file mode 100644 index 0000000..4094cfb --- /dev/null +++ b/gpu/command_buffer/common/gles2_cmd_id_test.cc @@ -0,0 +1,372 @@ + +// Copyright (c) 2006-2008 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 contains unit tests for gles2 commmand ids + +#include "testing/gtest/include/gtest/gtest.h" +#include "gpu/command_buffer/common/gles2_cmd_format.h" + +namespace command_buffer { +namespace gles2 { + +// *** These IDs MUST NOT CHANGE!!! *** +// Changing them will break all client programs. +TEST(GLES2CommandIdTest, CommandIdsMatch) { + COMPILE_ASSERT(ActiveTexture::kCmdId == 1024, + GLES2_ActiveTexture_kCmdId_mismatch); + COMPILE_ASSERT(AttachShader::kCmdId == 1025, + GLES2_AttachShader_kCmdId_mismatch); + COMPILE_ASSERT(BindAttribLocation::kCmdId == 1026, + GLES2_BindAttribLocation_kCmdId_mismatch); + COMPILE_ASSERT(BindAttribLocationImmediate::kCmdId == 1027, + GLES2_BindAttribLocationImmediate_kCmdId_mismatch); + COMPILE_ASSERT(BindBuffer::kCmdId == 1028, + GLES2_BindBuffer_kCmdId_mismatch); + COMPILE_ASSERT(BindFramebuffer::kCmdId == 1029, + GLES2_BindFramebuffer_kCmdId_mismatch); + COMPILE_ASSERT(BindRenderbuffer::kCmdId == 1030, + GLES2_BindRenderbuffer_kCmdId_mismatch); + COMPILE_ASSERT(BindTexture::kCmdId == 1031, + GLES2_BindTexture_kCmdId_mismatch); + COMPILE_ASSERT(BlendColor::kCmdId == 1032, + GLES2_BlendColor_kCmdId_mismatch); + COMPILE_ASSERT(BlendEquation::kCmdId == 1033, + GLES2_BlendEquation_kCmdId_mismatch); + COMPILE_ASSERT(BlendEquationSeparate::kCmdId == 1034, + GLES2_BlendEquationSeparate_kCmdId_mismatch); + COMPILE_ASSERT(BlendFunc::kCmdId == 1035, + GLES2_BlendFunc_kCmdId_mismatch); + COMPILE_ASSERT(BlendFuncSeparate::kCmdId == 1036, + GLES2_BlendFuncSeparate_kCmdId_mismatch); + COMPILE_ASSERT(BufferData::kCmdId == 1037, + GLES2_BufferData_kCmdId_mismatch); + COMPILE_ASSERT(BufferDataImmediate::kCmdId == 1038, + GLES2_BufferDataImmediate_kCmdId_mismatch); + COMPILE_ASSERT(BufferSubData::kCmdId == 1039, + GLES2_BufferSubData_kCmdId_mismatch); + COMPILE_ASSERT(BufferSubDataImmediate::kCmdId == 1040, + GLES2_BufferSubDataImmediate_kCmdId_mismatch); + COMPILE_ASSERT(CheckFramebufferStatus::kCmdId == 1041, + GLES2_CheckFramebufferStatus_kCmdId_mismatch); + COMPILE_ASSERT(Clear::kCmdId == 1042, + GLES2_Clear_kCmdId_mismatch); + COMPILE_ASSERT(ClearColor::kCmdId == 1043, + GLES2_ClearColor_kCmdId_mismatch); + COMPILE_ASSERT(ClearDepthf::kCmdId == 1044, + GLES2_ClearDepthf_kCmdId_mismatch); + COMPILE_ASSERT(ClearStencil::kCmdId == 1045, + GLES2_ClearStencil_kCmdId_mismatch); + COMPILE_ASSERT(ColorMask::kCmdId == 1046, + GLES2_ColorMask_kCmdId_mismatch); + COMPILE_ASSERT(CompileShader::kCmdId == 1047, + GLES2_CompileShader_kCmdId_mismatch); + COMPILE_ASSERT(CompressedTexImage2D::kCmdId == 1048, + GLES2_CompressedTexImage2D_kCmdId_mismatch); + COMPILE_ASSERT(CompressedTexImage2DImmediate::kCmdId == 1049, + GLES2_CompressedTexImage2DImmediate_kCmdId_mismatch); + COMPILE_ASSERT(CompressedTexSubImage2D::kCmdId == 1050, + GLES2_CompressedTexSubImage2D_kCmdId_mismatch); + COMPILE_ASSERT(CompressedTexSubImage2DImmediate::kCmdId == 1051, + GLES2_CompressedTexSubImage2DImmediate_kCmdId_mismatch); + COMPILE_ASSERT(CopyTexImage2D::kCmdId == 1052, + GLES2_CopyTexImage2D_kCmdId_mismatch); + COMPILE_ASSERT(CopyTexSubImage2D::kCmdId == 1053, + GLES2_CopyTexSubImage2D_kCmdId_mismatch); + COMPILE_ASSERT(CreateProgram::kCmdId == 1054, + GLES2_CreateProgram_kCmdId_mismatch); + COMPILE_ASSERT(CreateShader::kCmdId == 1055, + GLES2_CreateShader_kCmdId_mismatch); + COMPILE_ASSERT(CullFace::kCmdId == 1056, + GLES2_CullFace_kCmdId_mismatch); + COMPILE_ASSERT(DeleteBuffers::kCmdId == 1057, + GLES2_DeleteBuffers_kCmdId_mismatch); + COMPILE_ASSERT(DeleteBuffersImmediate::kCmdId == 1058, + GLES2_DeleteBuffersImmediate_kCmdId_mismatch); + COMPILE_ASSERT(DeleteFramebuffers::kCmdId == 1059, + GLES2_DeleteFramebuffers_kCmdId_mismatch); + COMPILE_ASSERT(DeleteFramebuffersImmediate::kCmdId == 1060, + GLES2_DeleteFramebuffersImmediate_kCmdId_mismatch); + COMPILE_ASSERT(DeleteProgram::kCmdId == 1061, + GLES2_DeleteProgram_kCmdId_mismatch); + COMPILE_ASSERT(DeleteRenderbuffers::kCmdId == 1062, + GLES2_DeleteRenderbuffers_kCmdId_mismatch); + COMPILE_ASSERT(DeleteRenderbuffersImmediate::kCmdId == 1063, + GLES2_DeleteRenderbuffersImmediate_kCmdId_mismatch); + COMPILE_ASSERT(DeleteShader::kCmdId == 1064, + GLES2_DeleteShader_kCmdId_mismatch); + COMPILE_ASSERT(DeleteTextures::kCmdId == 1065, + GLES2_DeleteTextures_kCmdId_mismatch); + COMPILE_ASSERT(DeleteTexturesImmediate::kCmdId == 1066, + GLES2_DeleteTexturesImmediate_kCmdId_mismatch); + COMPILE_ASSERT(DepthFunc::kCmdId == 1067, + GLES2_DepthFunc_kCmdId_mismatch); + COMPILE_ASSERT(DepthMask::kCmdId == 1068, + GLES2_DepthMask_kCmdId_mismatch); + COMPILE_ASSERT(DepthRangef::kCmdId == 1069, + GLES2_DepthRangef_kCmdId_mismatch); + COMPILE_ASSERT(DetachShader::kCmdId == 1070, + GLES2_DetachShader_kCmdId_mismatch); + COMPILE_ASSERT(Disable::kCmdId == 1071, + GLES2_Disable_kCmdId_mismatch); + COMPILE_ASSERT(DisableVertexAttribArray::kCmdId == 1072, + GLES2_DisableVertexAttribArray_kCmdId_mismatch); + COMPILE_ASSERT(DrawArrays::kCmdId == 1073, + GLES2_DrawArrays_kCmdId_mismatch); + COMPILE_ASSERT(DrawElements::kCmdId == 1074, + GLES2_DrawElements_kCmdId_mismatch); + COMPILE_ASSERT(Enable::kCmdId == 1075, + GLES2_Enable_kCmdId_mismatch); + COMPILE_ASSERT(EnableVertexAttribArray::kCmdId == 1076, + GLES2_EnableVertexAttribArray_kCmdId_mismatch); + COMPILE_ASSERT(Finish::kCmdId == 1077, + GLES2_Finish_kCmdId_mismatch); + COMPILE_ASSERT(Flush::kCmdId == 1078, + GLES2_Flush_kCmdId_mismatch); + COMPILE_ASSERT(FramebufferRenderbuffer::kCmdId == 1079, + GLES2_FramebufferRenderbuffer_kCmdId_mismatch); + COMPILE_ASSERT(FramebufferTexture2D::kCmdId == 1080, + GLES2_FramebufferTexture2D_kCmdId_mismatch); + COMPILE_ASSERT(FrontFace::kCmdId == 1081, + GLES2_FrontFace_kCmdId_mismatch); + COMPILE_ASSERT(GenBuffers::kCmdId == 1082, + GLES2_GenBuffers_kCmdId_mismatch); + COMPILE_ASSERT(GenBuffersImmediate::kCmdId == 1083, + GLES2_GenBuffersImmediate_kCmdId_mismatch); + COMPILE_ASSERT(GenerateMipmap::kCmdId == 1084, + GLES2_GenerateMipmap_kCmdId_mismatch); + COMPILE_ASSERT(GenFramebuffers::kCmdId == 1085, + GLES2_GenFramebuffers_kCmdId_mismatch); + COMPILE_ASSERT(GenFramebuffersImmediate::kCmdId == 1086, + GLES2_GenFramebuffersImmediate_kCmdId_mismatch); + COMPILE_ASSERT(GenRenderbuffers::kCmdId == 1087, + GLES2_GenRenderbuffers_kCmdId_mismatch); + COMPILE_ASSERT(GenRenderbuffersImmediate::kCmdId == 1088, + GLES2_GenRenderbuffersImmediate_kCmdId_mismatch); + COMPILE_ASSERT(GenTextures::kCmdId == 1089, + GLES2_GenTextures_kCmdId_mismatch); + COMPILE_ASSERT(GenTexturesImmediate::kCmdId == 1090, + GLES2_GenTexturesImmediate_kCmdId_mismatch); + COMPILE_ASSERT(GetActiveAttrib::kCmdId == 1091, + GLES2_GetActiveAttrib_kCmdId_mismatch); + COMPILE_ASSERT(GetActiveUniform::kCmdId == 1092, + GLES2_GetActiveUniform_kCmdId_mismatch); + COMPILE_ASSERT(GetAttachedShaders::kCmdId == 1093, + GLES2_GetAttachedShaders_kCmdId_mismatch); + COMPILE_ASSERT(GetAttribLocation::kCmdId == 1094, + GLES2_GetAttribLocation_kCmdId_mismatch); + COMPILE_ASSERT(GetAttribLocationImmediate::kCmdId == 1095, + GLES2_GetAttribLocationImmediate_kCmdId_mismatch); + COMPILE_ASSERT(GetBooleanv::kCmdId == 1096, + GLES2_GetBooleanv_kCmdId_mismatch); + COMPILE_ASSERT(GetBufferParameteriv::kCmdId == 1097, + GLES2_GetBufferParameteriv_kCmdId_mismatch); + COMPILE_ASSERT(GetError::kCmdId == 1098, + GLES2_GetError_kCmdId_mismatch); + COMPILE_ASSERT(GetFloatv::kCmdId == 1099, + GLES2_GetFloatv_kCmdId_mismatch); + COMPILE_ASSERT(GetFramebufferAttachmentParameteriv::kCmdId == 1100, + GLES2_GetFramebufferAttachmentParameteriv_kCmdId_mismatch); + COMPILE_ASSERT(GetIntegerv::kCmdId == 1101, + GLES2_GetIntegerv_kCmdId_mismatch); + COMPILE_ASSERT(GetProgramiv::kCmdId == 1102, + GLES2_GetProgramiv_kCmdId_mismatch); + COMPILE_ASSERT(GetProgramInfoLog::kCmdId == 1103, + GLES2_GetProgramInfoLog_kCmdId_mismatch); + COMPILE_ASSERT(GetRenderbufferParameteriv::kCmdId == 1104, + GLES2_GetRenderbufferParameteriv_kCmdId_mismatch); + COMPILE_ASSERT(GetShaderiv::kCmdId == 1105, + GLES2_GetShaderiv_kCmdId_mismatch); + COMPILE_ASSERT(GetShaderInfoLog::kCmdId == 1106, + GLES2_GetShaderInfoLog_kCmdId_mismatch); + COMPILE_ASSERT(GetShaderPrecisionFormat::kCmdId == 1107, + GLES2_GetShaderPrecisionFormat_kCmdId_mismatch); + COMPILE_ASSERT(GetShaderSource::kCmdId == 1108, + GLES2_GetShaderSource_kCmdId_mismatch); + COMPILE_ASSERT(GetString::kCmdId == 1109, + GLES2_GetString_kCmdId_mismatch); + COMPILE_ASSERT(GetTexParameterfv::kCmdId == 1110, + GLES2_GetTexParameterfv_kCmdId_mismatch); + COMPILE_ASSERT(GetTexParameteriv::kCmdId == 1111, + GLES2_GetTexParameteriv_kCmdId_mismatch); + COMPILE_ASSERT(GetUniformfv::kCmdId == 1112, + GLES2_GetUniformfv_kCmdId_mismatch); + COMPILE_ASSERT(GetUniformiv::kCmdId == 1113, + GLES2_GetUniformiv_kCmdId_mismatch); + COMPILE_ASSERT(GetUniformLocation::kCmdId == 1114, + GLES2_GetUniformLocation_kCmdId_mismatch); + COMPILE_ASSERT(GetUniformLocationImmediate::kCmdId == 1115, + GLES2_GetUniformLocationImmediate_kCmdId_mismatch); + COMPILE_ASSERT(GetVertexAttribfv::kCmdId == 1116, + GLES2_GetVertexAttribfv_kCmdId_mismatch); + COMPILE_ASSERT(GetVertexAttribiv::kCmdId == 1117, + GLES2_GetVertexAttribiv_kCmdId_mismatch); + COMPILE_ASSERT(GetVertexAttribPointerv::kCmdId == 1118, + GLES2_GetVertexAttribPointerv_kCmdId_mismatch); + COMPILE_ASSERT(Hint::kCmdId == 1119, + GLES2_Hint_kCmdId_mismatch); + COMPILE_ASSERT(IsBuffer::kCmdId == 1120, + GLES2_IsBuffer_kCmdId_mismatch); + COMPILE_ASSERT(IsEnabled::kCmdId == 1121, + GLES2_IsEnabled_kCmdId_mismatch); + COMPILE_ASSERT(IsFramebuffer::kCmdId == 1122, + GLES2_IsFramebuffer_kCmdId_mismatch); + COMPILE_ASSERT(IsProgram::kCmdId == 1123, + GLES2_IsProgram_kCmdId_mismatch); + COMPILE_ASSERT(IsRenderbuffer::kCmdId == 1124, + GLES2_IsRenderbuffer_kCmdId_mismatch); + COMPILE_ASSERT(IsShader::kCmdId == 1125, + GLES2_IsShader_kCmdId_mismatch); + COMPILE_ASSERT(IsTexture::kCmdId == 1126, + GLES2_IsTexture_kCmdId_mismatch); + COMPILE_ASSERT(LineWidth::kCmdId == 1127, + GLES2_LineWidth_kCmdId_mismatch); + COMPILE_ASSERT(LinkProgram::kCmdId == 1128, + GLES2_LinkProgram_kCmdId_mismatch); + COMPILE_ASSERT(PixelStorei::kCmdId == 1129, + GLES2_PixelStorei_kCmdId_mismatch); + COMPILE_ASSERT(PolygonOffset::kCmdId == 1130, + GLES2_PolygonOffset_kCmdId_mismatch); + COMPILE_ASSERT(ReadPixels::kCmdId == 1131, + GLES2_ReadPixels_kCmdId_mismatch); + COMPILE_ASSERT(RenderbufferStorage::kCmdId == 1132, + GLES2_RenderbufferStorage_kCmdId_mismatch); + COMPILE_ASSERT(SampleCoverage::kCmdId == 1133, + GLES2_SampleCoverage_kCmdId_mismatch); + COMPILE_ASSERT(Scissor::kCmdId == 1134, + GLES2_Scissor_kCmdId_mismatch); + COMPILE_ASSERT(ShaderSource::kCmdId == 1135, + GLES2_ShaderSource_kCmdId_mismatch); + COMPILE_ASSERT(ShaderSourceImmediate::kCmdId == 1136, + GLES2_ShaderSourceImmediate_kCmdId_mismatch); + COMPILE_ASSERT(StencilFunc::kCmdId == 1137, + GLES2_StencilFunc_kCmdId_mismatch); + COMPILE_ASSERT(StencilFuncSeparate::kCmdId == 1138, + GLES2_StencilFuncSeparate_kCmdId_mismatch); + COMPILE_ASSERT(StencilMask::kCmdId == 1139, + GLES2_StencilMask_kCmdId_mismatch); + COMPILE_ASSERT(StencilMaskSeparate::kCmdId == 1140, + GLES2_StencilMaskSeparate_kCmdId_mismatch); + COMPILE_ASSERT(StencilOp::kCmdId == 1141, + GLES2_StencilOp_kCmdId_mismatch); + COMPILE_ASSERT(StencilOpSeparate::kCmdId == 1142, + GLES2_StencilOpSeparate_kCmdId_mismatch); + COMPILE_ASSERT(TexImage2D::kCmdId == 1143, + GLES2_TexImage2D_kCmdId_mismatch); + COMPILE_ASSERT(TexImage2DImmediate::kCmdId == 1144, + GLES2_TexImage2DImmediate_kCmdId_mismatch); + COMPILE_ASSERT(TexParameterf::kCmdId == 1145, + GLES2_TexParameterf_kCmdId_mismatch); + COMPILE_ASSERT(TexParameterfv::kCmdId == 1146, + GLES2_TexParameterfv_kCmdId_mismatch); + COMPILE_ASSERT(TexParameterfvImmediate::kCmdId == 1147, + GLES2_TexParameterfvImmediate_kCmdId_mismatch); + COMPILE_ASSERT(TexParameteri::kCmdId == 1148, + GLES2_TexParameteri_kCmdId_mismatch); + COMPILE_ASSERT(TexParameteriv::kCmdId == 1149, + GLES2_TexParameteriv_kCmdId_mismatch); + COMPILE_ASSERT(TexParameterivImmediate::kCmdId == 1150, + GLES2_TexParameterivImmediate_kCmdId_mismatch); + COMPILE_ASSERT(TexSubImage2D::kCmdId == 1151, + GLES2_TexSubImage2D_kCmdId_mismatch); + COMPILE_ASSERT(TexSubImage2DImmediate::kCmdId == 1152, + GLES2_TexSubImage2DImmediate_kCmdId_mismatch); + COMPILE_ASSERT(Uniform1f::kCmdId == 1153, + GLES2_Uniform1f_kCmdId_mismatch); + COMPILE_ASSERT(Uniform1fv::kCmdId == 1154, + GLES2_Uniform1fv_kCmdId_mismatch); + COMPILE_ASSERT(Uniform1fvImmediate::kCmdId == 1155, + GLES2_Uniform1fvImmediate_kCmdId_mismatch); + COMPILE_ASSERT(Uniform1i::kCmdId == 1156, + GLES2_Uniform1i_kCmdId_mismatch); + COMPILE_ASSERT(Uniform1iv::kCmdId == 1157, + GLES2_Uniform1iv_kCmdId_mismatch); + COMPILE_ASSERT(Uniform1ivImmediate::kCmdId == 1158, + GLES2_Uniform1ivImmediate_kCmdId_mismatch); + COMPILE_ASSERT(Uniform2f::kCmdId == 1159, + GLES2_Uniform2f_kCmdId_mismatch); + COMPILE_ASSERT(Uniform2fv::kCmdId == 1160, + GLES2_Uniform2fv_kCmdId_mismatch); + COMPILE_ASSERT(Uniform2fvImmediate::kCmdId == 1161, + GLES2_Uniform2fvImmediate_kCmdId_mismatch); + COMPILE_ASSERT(Uniform2i::kCmdId == 1162, + GLES2_Uniform2i_kCmdId_mismatch); + COMPILE_ASSERT(Uniform2iv::kCmdId == 1163, + GLES2_Uniform2iv_kCmdId_mismatch); + COMPILE_ASSERT(Uniform2ivImmediate::kCmdId == 1164, + GLES2_Uniform2ivImmediate_kCmdId_mismatch); + COMPILE_ASSERT(Uniform3f::kCmdId == 1165, + GLES2_Uniform3f_kCmdId_mismatch); + COMPILE_ASSERT(Uniform3fv::kCmdId == 1166, + GLES2_Uniform3fv_kCmdId_mismatch); + COMPILE_ASSERT(Uniform3fvImmediate::kCmdId == 1167, + GLES2_Uniform3fvImmediate_kCmdId_mismatch); + COMPILE_ASSERT(Uniform3i::kCmdId == 1168, + GLES2_Uniform3i_kCmdId_mismatch); + COMPILE_ASSERT(Uniform3iv::kCmdId == 1169, + GLES2_Uniform3iv_kCmdId_mismatch); + COMPILE_ASSERT(Uniform3ivImmediate::kCmdId == 1170, + GLES2_Uniform3ivImmediate_kCmdId_mismatch); + COMPILE_ASSERT(Uniform4f::kCmdId == 1171, + GLES2_Uniform4f_kCmdId_mismatch); + COMPILE_ASSERT(Uniform4fv::kCmdId == 1172, + GLES2_Uniform4fv_kCmdId_mismatch); + COMPILE_ASSERT(Uniform4fvImmediate::kCmdId == 1173, + GLES2_Uniform4fvImmediate_kCmdId_mismatch); + COMPILE_ASSERT(Uniform4i::kCmdId == 1174, + GLES2_Uniform4i_kCmdId_mismatch); + COMPILE_ASSERT(Uniform4iv::kCmdId == 1175, + GLES2_Uniform4iv_kCmdId_mismatch); + COMPILE_ASSERT(Uniform4ivImmediate::kCmdId == 1176, + GLES2_Uniform4ivImmediate_kCmdId_mismatch); + COMPILE_ASSERT(UniformMatrix2fv::kCmdId == 1177, + GLES2_UniformMatrix2fv_kCmdId_mismatch); + COMPILE_ASSERT(UniformMatrix2fvImmediate::kCmdId == 1178, + GLES2_UniformMatrix2fvImmediate_kCmdId_mismatch); + COMPILE_ASSERT(UniformMatrix3fv::kCmdId == 1179, + GLES2_UniformMatrix3fv_kCmdId_mismatch); + COMPILE_ASSERT(UniformMatrix3fvImmediate::kCmdId == 1180, + GLES2_UniformMatrix3fvImmediate_kCmdId_mismatch); + COMPILE_ASSERT(UniformMatrix4fv::kCmdId == 1181, + GLES2_UniformMatrix4fv_kCmdId_mismatch); + COMPILE_ASSERT(UniformMatrix4fvImmediate::kCmdId == 1182, + GLES2_UniformMatrix4fvImmediate_kCmdId_mismatch); + COMPILE_ASSERT(UseProgram::kCmdId == 1183, + GLES2_UseProgram_kCmdId_mismatch); + COMPILE_ASSERT(ValidateProgram::kCmdId == 1184, + GLES2_ValidateProgram_kCmdId_mismatch); + COMPILE_ASSERT(VertexAttrib1f::kCmdId == 1185, + GLES2_VertexAttrib1f_kCmdId_mismatch); + COMPILE_ASSERT(VertexAttrib1fv::kCmdId == 1186, + GLES2_VertexAttrib1fv_kCmdId_mismatch); + COMPILE_ASSERT(VertexAttrib1fvImmediate::kCmdId == 1187, + GLES2_VertexAttrib1fvImmediate_kCmdId_mismatch); + COMPILE_ASSERT(VertexAttrib2f::kCmdId == 1188, + GLES2_VertexAttrib2f_kCmdId_mismatch); + COMPILE_ASSERT(VertexAttrib2fv::kCmdId == 1189, + GLES2_VertexAttrib2fv_kCmdId_mismatch); + COMPILE_ASSERT(VertexAttrib2fvImmediate::kCmdId == 1190, + GLES2_VertexAttrib2fvImmediate_kCmdId_mismatch); + COMPILE_ASSERT(VertexAttrib3f::kCmdId == 1191, + GLES2_VertexAttrib3f_kCmdId_mismatch); + COMPILE_ASSERT(VertexAttrib3fv::kCmdId == 1192, + GLES2_VertexAttrib3fv_kCmdId_mismatch); + COMPILE_ASSERT(VertexAttrib3fvImmediate::kCmdId == 1193, + GLES2_VertexAttrib3fvImmediate_kCmdId_mismatch); + COMPILE_ASSERT(VertexAttrib4f::kCmdId == 1194, + GLES2_VertexAttrib4f_kCmdId_mismatch); + COMPILE_ASSERT(VertexAttrib4fv::kCmdId == 1195, + GLES2_VertexAttrib4fv_kCmdId_mismatch); + COMPILE_ASSERT(VertexAttrib4fvImmediate::kCmdId == 1196, + GLES2_VertexAttrib4fvImmediate_kCmdId_mismatch); + COMPILE_ASSERT(VertexAttribPointer::kCmdId == 1197, + GLES2_VertexAttribPointer_kCmdId_mismatch); + COMPILE_ASSERT(Viewport::kCmdId == 1198, + GLES2_Viewport_kCmdId_mismatch); + COMPILE_ASSERT(SwapBuffers::kCmdId == 1199, + GLES2_SwapBuffers_kCmdId_mismatch); +} +} // namespace gles2 +} // namespace command_buffer + diff --git a/gpu/command_buffer/common/gles2_cmd_ids.h b/gpu/command_buffer/common/gles2_cmd_ids.h new file mode 100644 index 0000000..130fce9 --- /dev/null +++ b/gpu/command_buffer/common/gles2_cmd_ids.h @@ -0,0 +1,23 @@ +// Copyright (c) 2006-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 defines the GLES2 command buffer commands. + +#ifndef GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_IDS_H +#define GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_IDS_H + +#include "gpu/command_buffer/common/cmd_buffer_common.h" + +namespace command_buffer { +namespace gles2 { + +#include "gpu/command_buffer/common/gles2_cmd_ids_autogen.h" + +const char* GetCommandName(CommandId command_id); + +} // namespace gles2 +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_IDS_H + diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h new file mode 100644 index 0000000..9e9d5c6 --- /dev/null +++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h @@ -0,0 +1,188 @@ +// This file is auto-generated. DO NOT EDIT! + +#define GLES2_COMMAND_LIST(OP) \ + OP(ActiveTexture) /* 1024 */ \ + OP(AttachShader) /* 1025 */ \ + OP(BindAttribLocation) /* 1026 */ \ + OP(BindAttribLocationImmediate) /* 1027 */ \ + OP(BindBuffer) /* 1028 */ \ + OP(BindFramebuffer) /* 1029 */ \ + OP(BindRenderbuffer) /* 1030 */ \ + OP(BindTexture) /* 1031 */ \ + OP(BlendColor) /* 1032 */ \ + OP(BlendEquation) /* 1033 */ \ + OP(BlendEquationSeparate) /* 1034 */ \ + OP(BlendFunc) /* 1035 */ \ + OP(BlendFuncSeparate) /* 1036 */ \ + OP(BufferData) /* 1037 */ \ + OP(BufferDataImmediate) /* 1038 */ \ + OP(BufferSubData) /* 1039 */ \ + OP(BufferSubDataImmediate) /* 1040 */ \ + OP(CheckFramebufferStatus) /* 1041 */ \ + OP(Clear) /* 1042 */ \ + OP(ClearColor) /* 1043 */ \ + OP(ClearDepthf) /* 1044 */ \ + OP(ClearStencil) /* 1045 */ \ + OP(ColorMask) /* 1046 */ \ + OP(CompileShader) /* 1047 */ \ + OP(CompressedTexImage2D) /* 1048 */ \ + OP(CompressedTexImage2DImmediate) /* 1049 */ \ + OP(CompressedTexSubImage2D) /* 1050 */ \ + OP(CompressedTexSubImage2DImmediate) /* 1051 */ \ + OP(CopyTexImage2D) /* 1052 */ \ + OP(CopyTexSubImage2D) /* 1053 */ \ + OP(CreateProgram) /* 1054 */ \ + OP(CreateShader) /* 1055 */ \ + OP(CullFace) /* 1056 */ \ + OP(DeleteBuffers) /* 1057 */ \ + OP(DeleteBuffersImmediate) /* 1058 */ \ + OP(DeleteFramebuffers) /* 1059 */ \ + OP(DeleteFramebuffersImmediate) /* 1060 */ \ + OP(DeleteProgram) /* 1061 */ \ + OP(DeleteRenderbuffers) /* 1062 */ \ + OP(DeleteRenderbuffersImmediate) /* 1063 */ \ + OP(DeleteShader) /* 1064 */ \ + OP(DeleteTextures) /* 1065 */ \ + OP(DeleteTexturesImmediate) /* 1066 */ \ + OP(DepthFunc) /* 1067 */ \ + OP(DepthMask) /* 1068 */ \ + OP(DepthRangef) /* 1069 */ \ + OP(DetachShader) /* 1070 */ \ + OP(Disable) /* 1071 */ \ + OP(DisableVertexAttribArray) /* 1072 */ \ + OP(DrawArrays) /* 1073 */ \ + OP(DrawElements) /* 1074 */ \ + OP(Enable) /* 1075 */ \ + OP(EnableVertexAttribArray) /* 1076 */ \ + OP(Finish) /* 1077 */ \ + OP(Flush) /* 1078 */ \ + OP(FramebufferRenderbuffer) /* 1079 */ \ + OP(FramebufferTexture2D) /* 1080 */ \ + OP(FrontFace) /* 1081 */ \ + OP(GenBuffers) /* 1082 */ \ + OP(GenBuffersImmediate) /* 1083 */ \ + OP(GenerateMipmap) /* 1084 */ \ + OP(GenFramebuffers) /* 1085 */ \ + OP(GenFramebuffersImmediate) /* 1086 */ \ + OP(GenRenderbuffers) /* 1087 */ \ + OP(GenRenderbuffersImmediate) /* 1088 */ \ + OP(GenTextures) /* 1089 */ \ + OP(GenTexturesImmediate) /* 1090 */ \ + OP(GetActiveAttrib) /* 1091 */ \ + OP(GetActiveUniform) /* 1092 */ \ + OP(GetAttachedShaders) /* 1093 */ \ + OP(GetAttribLocation) /* 1094 */ \ + OP(GetAttribLocationImmediate) /* 1095 */ \ + OP(GetBooleanv) /* 1096 */ \ + OP(GetBufferParameteriv) /* 1097 */ \ + OP(GetError) /* 1098 */ \ + OP(GetFloatv) /* 1099 */ \ + OP(GetFramebufferAttachmentParameteriv) /* 1100 */ \ + OP(GetIntegerv) /* 1101 */ \ + OP(GetProgramiv) /* 1102 */ \ + OP(GetProgramInfoLog) /* 1103 */ \ + OP(GetRenderbufferParameteriv) /* 1104 */ \ + OP(GetShaderiv) /* 1105 */ \ + OP(GetShaderInfoLog) /* 1106 */ \ + OP(GetShaderPrecisionFormat) /* 1107 */ \ + OP(GetShaderSource) /* 1108 */ \ + OP(GetString) /* 1109 */ \ + OP(GetTexParameterfv) /* 1110 */ \ + OP(GetTexParameteriv) /* 1111 */ \ + OP(GetUniformfv) /* 1112 */ \ + OP(GetUniformiv) /* 1113 */ \ + OP(GetUniformLocation) /* 1114 */ \ + OP(GetUniformLocationImmediate) /* 1115 */ \ + OP(GetVertexAttribfv) /* 1116 */ \ + OP(GetVertexAttribiv) /* 1117 */ \ + OP(GetVertexAttribPointerv) /* 1118 */ \ + OP(Hint) /* 1119 */ \ + OP(IsBuffer) /* 1120 */ \ + OP(IsEnabled) /* 1121 */ \ + OP(IsFramebuffer) /* 1122 */ \ + OP(IsProgram) /* 1123 */ \ + OP(IsRenderbuffer) /* 1124 */ \ + OP(IsShader) /* 1125 */ \ + OP(IsTexture) /* 1126 */ \ + OP(LineWidth) /* 1127 */ \ + OP(LinkProgram) /* 1128 */ \ + OP(PixelStorei) /* 1129 */ \ + OP(PolygonOffset) /* 1130 */ \ + OP(ReadPixels) /* 1131 */ \ + OP(RenderbufferStorage) /* 1132 */ \ + OP(SampleCoverage) /* 1133 */ \ + OP(Scissor) /* 1134 */ \ + OP(ShaderSource) /* 1135 */ \ + OP(ShaderSourceImmediate) /* 1136 */ \ + OP(StencilFunc) /* 1137 */ \ + OP(StencilFuncSeparate) /* 1138 */ \ + OP(StencilMask) /* 1139 */ \ + OP(StencilMaskSeparate) /* 1140 */ \ + OP(StencilOp) /* 1141 */ \ + OP(StencilOpSeparate) /* 1142 */ \ + OP(TexImage2D) /* 1143 */ \ + OP(TexImage2DImmediate) /* 1144 */ \ + OP(TexParameterf) /* 1145 */ \ + OP(TexParameterfv) /* 1146 */ \ + OP(TexParameterfvImmediate) /* 1147 */ \ + OP(TexParameteri) /* 1148 */ \ + OP(TexParameteriv) /* 1149 */ \ + OP(TexParameterivImmediate) /* 1150 */ \ + OP(TexSubImage2D) /* 1151 */ \ + OP(TexSubImage2DImmediate) /* 1152 */ \ + OP(Uniform1f) /* 1153 */ \ + OP(Uniform1fv) /* 1154 */ \ + OP(Uniform1fvImmediate) /* 1155 */ \ + OP(Uniform1i) /* 1156 */ \ + OP(Uniform1iv) /* 1157 */ \ + OP(Uniform1ivImmediate) /* 1158 */ \ + OP(Uniform2f) /* 1159 */ \ + OP(Uniform2fv) /* 1160 */ \ + OP(Uniform2fvImmediate) /* 1161 */ \ + OP(Uniform2i) /* 1162 */ \ + OP(Uniform2iv) /* 1163 */ \ + OP(Uniform2ivImmediate) /* 1164 */ \ + OP(Uniform3f) /* 1165 */ \ + OP(Uniform3fv) /* 1166 */ \ + OP(Uniform3fvImmediate) /* 1167 */ \ + OP(Uniform3i) /* 1168 */ \ + OP(Uniform3iv) /* 1169 */ \ + OP(Uniform3ivImmediate) /* 1170 */ \ + OP(Uniform4f) /* 1171 */ \ + OP(Uniform4fv) /* 1172 */ \ + OP(Uniform4fvImmediate) /* 1173 */ \ + OP(Uniform4i) /* 1174 */ \ + OP(Uniform4iv) /* 1175 */ \ + OP(Uniform4ivImmediate) /* 1176 */ \ + OP(UniformMatrix2fv) /* 1177 */ \ + OP(UniformMatrix2fvImmediate) /* 1178 */ \ + OP(UniformMatrix3fv) /* 1179 */ \ + OP(UniformMatrix3fvImmediate) /* 1180 */ \ + OP(UniformMatrix4fv) /* 1181 */ \ + OP(UniformMatrix4fvImmediate) /* 1182 */ \ + OP(UseProgram) /* 1183 */ \ + OP(ValidateProgram) /* 1184 */ \ + OP(VertexAttrib1f) /* 1185 */ \ + OP(VertexAttrib1fv) /* 1186 */ \ + OP(VertexAttrib1fvImmediate) /* 1187 */ \ + OP(VertexAttrib2f) /* 1188 */ \ + OP(VertexAttrib2fv) /* 1189 */ \ + OP(VertexAttrib2fvImmediate) /* 1190 */ \ + OP(VertexAttrib3f) /* 1191 */ \ + OP(VertexAttrib3fv) /* 1192 */ \ + OP(VertexAttrib3fvImmediate) /* 1193 */ \ + OP(VertexAttrib4f) /* 1194 */ \ + OP(VertexAttrib4fv) /* 1195 */ \ + OP(VertexAttrib4fvImmediate) /* 1196 */ \ + OP(VertexAttribPointer) /* 1197 */ \ + OP(Viewport) /* 1198 */ \ + OP(SwapBuffers) /* 1199 */ \ + +enum CommandId { + kStartPoint = cmd::kLastCommonId, // All GLES2 commands start after this. +#define GLES2_CMD_OP(name) k ## name, + GLES2_COMMAND_LIST(GLES2_CMD_OP) +#undef GLES2_CMD_OP + kNumCommands +}; + diff --git a/gpu/command_buffer/common/gles2_cmd_utils.cc b/gpu/command_buffer/common/gles2_cmd_utils.cc new file mode 100644 index 0000000..9b0c20b --- /dev/null +++ b/gpu/command_buffer/common/gles2_cmd_utils.cc @@ -0,0 +1,347 @@ +// Copyright (c) 2006-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 is here so other GLES2 related files can have a common set of +// includes where appropriate. + +#include "gpu/command_buffer/common/gles2_cmd_utils.h" +#include "gpu/command_buffer/common/gles2_cmd_format.h" + +namespace command_buffer { +namespace gles2 { + +int GLES2Util::GLGetNumValuesReturned(int id) const { + switch (id) { + // -- glGetBooleanv, glGetFloatv, glGetIntergerv + case GL_ACTIVE_TEXTURE: + return 1; + case GL_ALIASED_LINE_WIDTH_RANGE: + return 2; + case GL_ALIASED_POINT_SIZE_RANGE: + return 1; + case GL_ALPHA_BITS: + return 1; + case GL_ARRAY_BUFFER_BINDING: + return 1; + case GL_BLEND: + return 1; + case GL_BLEND_COLOR: + return 4; + case GL_BLEND_DST_ALPHA: + return 1; + case GL_BLEND_DST_RGB: + return 1; + case GL_BLEND_EQUATION_ALPHA: + return 1; + case GL_BLEND_EQUATION_RGB: + return 1; + case GL_BLEND_SRC_ALPHA: + return 1; + case GL_BLEND_SRC_RGB: + return 1; + case GL_BLUE_BITS: + return 1; + case GL_COLOR_CLEAR_VALUE: + return 4; + case GL_COLOR_WRITEMASK: + return 4; + case GL_COMPRESSED_TEXTURE_FORMATS: + return num_compressed_texture_formats_; + case GL_CULL_FACE: + return 1; + case GL_CULL_FACE_MODE: + return 1; + case GL_CURRENT_PROGRAM: + return 1; + case GL_DEPTH_BITS: + return 1; + case GL_DEPTH_CLEAR_VALUE: + return 1; + case GL_DEPTH_FUNC: + return 1; + case GL_DEPTH_RANGE: + return 2; + case GL_DEPTH_TEST: + return 1; + case GL_DEPTH_WRITEMASK: + return 1; + case GL_DITHER: + return 1; + case GL_ELEMENT_ARRAY_BUFFER_BINDING: + return 1; + case GL_FRAMEBUFFER_BINDING: + return 1; + case GL_FRONT_FACE: + return 1; + case GL_GENERATE_MIPMAP_HINT: + return 1; + case GL_GREEN_BITS: + return 1; + case GL_IMPLEMENTATION_COLOR_READ_FORMAT: + return 1; + case GL_IMPLEMENTATION_COLOR_READ_TYPE: + return 1; + case GL_LINE_WIDTH: + return 1; + case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: + return 1; + case GL_MAX_CUBE_MAP_TEXTURE_SIZE: + return 1; + case GL_MAX_FRAGMENT_UNIFORM_VECTORS: + return 1; + case GL_MAX_RENDERBUFFER_SIZE: + return 1; + case GL_MAX_TEXTURE_IMAGE_UNITS: + return 1; + case GL_MAX_TEXTURE_SIZE: + return 1; + case GL_MAX_VARYING_VECTORS: + return 1; + case GL_MAX_VERTEX_ATTRIBS: + return 1; + case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: + return 1; + case GL_MAX_VERTEX_UNIFORM_VECTORS: + return 1; + case GL_MAX_VIEWPORT_DIMS: + return 2; + case GL_NUM_COMPRESSED_TEXTURE_FORMATS: + return 1; + case GL_PACK_ALIGNMENT: + return 1; + case GL_POLYGON_OFFSET_FACTOR: + return 1; + case GL_POLYGON_OFFSET_FILL: + return 1; + case GL_POLYGON_OFFSET_UNITS: + return 1; + case GL_RED_BITS: + return 1; + case GL_RENDERBUFFER_BINDING: + return 1; + case GL_SAMPLE_BUFFERS: + return 1; + case GL_SAMPLE_COVERAGE_INVERT: + return 1; + case GL_SAMPLE_COVERAGE_VALUE: + return 1; + case GL_SAMPLES: + return 1; + case GL_SCISSOR_BOX: + return 4; + case GL_SCISSOR_TEST: + return 1; + case GL_SHADER_COMPILER: + return 1; + case GL_STENCIL_BACK_FAIL: + return 1; + case GL_STENCIL_BACK_FUNC: + return 1; + case GL_STENCIL_BACK_PASS_DEPTH_FAIL: + return 1; + case GL_STENCIL_BACK_PASS_DEPTH_PASS: + return 1; + case GL_STENCIL_BACK_REF: + return 1; + case GL_STENCIL_BACK_VALUE_MASK: + return 1; + case GL_STENCIL_BACK_WRITEMASK: + return 1; + case GL_STENCIL_BITS: + return 1; + case GL_STENCIL_CLEAR_VALUE: + return 1; + case GL_STENCIL_FAIL: + return 1; + case GL_STENCIL_FUNC: + return 1; + case GL_STENCIL_PASS_DEPTH_FAIL: + return 1; + case GL_STENCIL_PASS_DEPTH_PASS: + return 1; + case GL_STENCIL_REF: + return 1; + case GL_STENCIL_TEST: + return 1; + case GL_STENCIL_VALUE_MASK: + return 1; + case GL_STENCIL_WRITEMASK: + return 1; + case GL_SUBPIXEL_BITS: + return 1; + case GL_TEXTURE_BINDING_2D: + return 1; + case GL_TEXTURE_BINDING_CUBE_MAP: + return 1; + case GL_UNPACK_ALIGNMENT: + return 1; + case GL_VIEWPORT: + return 4; + + // -- glGetBufferParameteriv + case GL_BUFFER_SIZE: + return 1; + case GL_BUFFER_USAGE: + return 1; + + // -- glGetFramebufferAttachmentParameteriv + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: + return 1; + case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: + return 1; + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: + return 1; + case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: + return 1; + + // -- glGetFramebufferAttachmentParameteriv + case GL_DELETE_STATUS: + return 1; + case GL_LINK_STATUS: + return 1; + case GL_VALIDATE_STATUS: + return 1; + case GL_INFO_LOG_LENGTH: + return 1; + case GL_ATTACHED_SHADERS: + return 1; + case GL_ACTIVE_ATTRIBUTES: + return 1; + case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: + return 1; + case GL_ACTIVE_UNIFORMS: + return 1; + case GL_ACTIVE_UNIFORM_MAX_LENGTH: + return 1; + + + // -- glGetRenderbufferAttachmentParameteriv + case GL_RENDERBUFFER_WIDTH: + return 1; + case GL_RENDERBUFFER_HEIGHT: + return 1; + case GL_RENDERBUFFER_INTERNAL_FORMAT: + return 1; + case GL_RENDERBUFFER_RED_SIZE: + return 1; + case GL_RENDERBUFFER_GREEN_SIZE: + return 1; + case GL_RENDERBUFFER_BLUE_SIZE: + return 1; + case GL_RENDERBUFFER_ALPHA_SIZE: + return 1; + case GL_RENDERBUFFER_DEPTH_SIZE: + return 1; + case GL_RENDERBUFFER_STENCIL_SIZE: + return 1; + + // -- glGetShaderiv + case GL_SHADER_TYPE: + return 1; + // Already defined under glGetFramebufferAttachemntParameteriv. + // case GL_DELETE_STATUS: + // return 1; + case GL_COMPILE_STATUS: + return 1; + // Already defined under glGetFramebufferAttachemntParameteriv. + // case GL_INFO_LOG_LENGTH: + // return 1; + case GL_SHADER_SOURCE_LENGTH: + return 1; + + // -- glGetTexParameterfv, glGetTexParameteriv + case GL_TEXTURE_MAG_FILTER: + return 1; + case GL_TEXTURE_MIN_FILTER: + return 1; + case GL_TEXTURE_WRAP_S: + return 1; + case GL_TEXTURE_WRAP_T: + return 1; + + // -- glGetVertexAttribfv, glGetVertexAttribiv + case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: + return 1; + case GL_VERTEX_ATTRIB_ARRAY_ENABLED: + return 1; + case GL_VERTEX_ATTRIB_ARRAY_SIZE: + return 1; + case GL_VERTEX_ATTRIB_ARRAY_STRIDE: + return 1; + case GL_VERTEX_ATTRIB_ARRAY_TYPE: + return 1; + case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: + return 1; + case GL_CURRENT_VERTEX_ATTRIB: + return 4; + + // bad enum + default: + return 0; + } +} + +namespace { + +// Return the number of elements per group of a specified format. +int ElementsPerGroup(int format, int type) { + switch (type) { + case GL_UNSIGNED_SHORT_5_6_5: + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_5_5_5_1: + return 1; + default: + break; + } + + switch (format) { + case GL_RGB: + return 3; + case GL_LUMINANCE_ALPHA: + return 2; + case GL_RGBA: + return 4; + case GL_ALPHA: + case GL_LUMINANCE: + return 1; + default: + return 0; + } +} + +// Return the number of bytes per element, based on the element type. +int BytesPerElement(int type) { + switch (type) { + case GL_UNSIGNED_SHORT: + case GL_SHORT: + case GL_UNSIGNED_SHORT_5_6_5: + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_5_5_5_1: + return 2; + case GL_UNSIGNED_BYTE: + case GL_BYTE: + return 1; + default: + return 0; + } +} + +} // anonymous namespace + +// Returns the amount of data glTexImage2D or glTexSubImage2D will access. +uint32 GLES2Util::ComputeImageDataSize( + int width, int height, int format, int type, int unpack_alignment) { + uint32 bytes_per_group = BytesPerElement(ElementsPerGroup(format, type)); + uint32 row_size = width * bytes_per_group; + if (height > 1) { + uint32 padded_row_size = ((row_size + unpack_alignment - 1) / + unpack_alignment) * unpack_alignment; + return height - 1 * padded_row_size + row_size; + } + return height * row_size; +} + +} // namespace gles2 +} // namespace command_buffer + diff --git a/gpu/command_buffer/common/gles2_cmd_utils.h b/gpu/command_buffer/common/gles2_cmd_utils.h new file mode 100644 index 0000000..9674a30 --- /dev/null +++ b/gpu/command_buffer/common/gles2_cmd_utils.h @@ -0,0 +1,41 @@ +// Copyright (c) 2006-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 is here so other GLES2 related files can have a common set of +// includes where appropriate. + +#ifndef GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_UTILS_H +#define GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_UTILS_H + +#include "base/basictypes.h" +#include "gpu/command_buffer/common/types.h" + +namespace command_buffer { +namespace gles2 { + +// Utilties for GLES2 support. +class GLES2Util { + public: + explicit GLES2Util( + int num_compressed_texture_formats) + : num_compressed_texture_formats_(num_compressed_texture_formats) { + } + + // Gets the number of values a particular id will return when a glGet + // function is called. If 0 is returned the id is invalid. + int GLGetNumValuesReturned(int id) const; + + // Computes the size of image data for TexImage2D and TexSubImage2D. + static uint32 ComputeImageDataSize( + int width, int height, int format, int type, int unpack_alignment); + + private: + int num_compressed_texture_formats_; +}; + +} // namespace gles2 +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_UTILS_H + diff --git a/gpu/command_buffer/common/logging.h b/gpu/command_buffer/common/logging.h new file mode 100644 index 0000000..a9bbad8 --- /dev/null +++ b/gpu/command_buffer/common/logging.h @@ -0,0 +1,67 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file abstracts differences in logging between NaCl and host +// environment. + +#ifndef GPU_COMMAND_BUFFER_COMMON_CROSS_LOGGING_H_ +#define GPU_COMMAND_BUFFER_COMMON_CROSS_LOGGING_H_ + +#ifndef __native_client__ +#include "base/logging.h" +#else +#include <sstream> + +// TODO: implement logging through nacl's debug service runtime if +// available. +#define CHECK(X) do {} while (0) +#define CHECK_EQ(X, Y) do {} while (0) +#define CHECK_NE(X, Y) do {} while (0) +#define CHECK_GT(X, Y) do {} while (0) +#define CHECK_GE(X, Y) do {} while (0) +#define CHECK_LT(X, Y) do {} while (0) +#define CHECK_LE(X, Y) do {} while (0) + +#define DCHECK(X) do {} while (0) +#define DCHECK_EQ(X, Y) do {} while (0) +#define DCHECK_NE(X, Y) do {} while (0) +#define DCHECK_GT(X, Y) do {} while (0) +#define DCHECK_GE(X, Y) do {} while (0) +#define DCHECK_LT(X, Y) do {} while (0) +#define DCHECK_LE(X, Y) do {} while (0) + +#define LOG(LEVEL) if (0) std::ostringstream() +#define DLOG(LEVEL) if (0) std::ostringstream() + +#endif + +#endif // GPU_COMMAND_BUFFER_COMMON_CROSS_LOGGING_H_ diff --git a/gpu/command_buffer/common/resource.cc b/gpu/command_buffer/common/resource.cc new file mode 100644 index 0000000..f3b75ec --- /dev/null +++ b/gpu/command_buffer/common/resource.cc @@ -0,0 +1,120 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the implementation of the helper functions for resources. + +#include "gpu/command_buffer/common/resource.h" + +namespace command_buffer { + +namespace texture { + +// Gets the number of bytes per block for a given format. +unsigned int GetBytesPerBlock(Format format) { + switch (format) { + case kXRGB8: + case kARGB8: + case kR32F: + return 4; + case kABGR16F: + return 8; + case kABGR32F: + return 16; + case kDXT1: + return 8; + default: + // TODO(petersont): Add DXT3/5 support. + LOG(FATAL) << "Invalid format"; + return 1; + } +} + +// Gets the width of a block for a given format. +unsigned int GetBlockSizeX(Format format) { + switch (format) { + case kXRGB8: + case kARGB8: + case kABGR16F: + case kR32F: + case kABGR32F: + return 1; + case kDXT1: + return 4; + default: + // TODO(petersont): Add DXT3/5 support. + LOG(FATAL) << "Invalid format"; + return 1; + } +} + +// Gets the height of a block for a given format. +unsigned int GetBlockSizeY(Format format) { + // NOTE: currently only supported formats use square blocks. + return GetBlockSizeX(format); +} + +} // namespace texture + +namespace effect_param { + +// Gets the size of the data of a given parameter type. +unsigned int GetDataSize(DataType type) { + switch (type) { + case kUnknown: + return 0; + case kFloat1: + return sizeof(float); // NOLINT + case kFloat2: + return sizeof(float) * 2; // NOLINT + case kFloat3: + return sizeof(float) * 3; // NOLINT + case kFloat4: + return sizeof(float) * 4; // NOLINT + case kMatrix4: + return sizeof(float) * 16; // NOLINT + case kInt: + return sizeof(int); // NOLINT + case kBool: + return sizeof(bool); // NOLINT + case kSampler: + return sizeof(ResourceId); // NOLINT + case kTexture: + return sizeof(ResourceId); // NOLINT + default: + LOG(FATAL) << "Invalid type."; + return 0; + } +} + +} // namespace effect_param + +} // namespace command_buffer diff --git a/gpu/command_buffer/common/resource.h b/gpu/command_buffer/common/resource.h new file mode 100644 index 0000000..01de6a1 --- /dev/null +++ b/gpu/command_buffer/common/resource.h @@ -0,0 +1,229 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains definitions for resource flags, enums, and helper +// functions. + +#ifndef GPU_COMMAND_BUFFER_COMMON_CROSS_RESOURCE_H_ +#define GPU_COMMAND_BUFFER_COMMON_CROSS_RESOURCE_H_ + +#include <algorithm> +#include "base/basictypes.h" +#include "base/scoped_ptr.h" +#include "gpu/command_buffer/common/types.h" +#include "gpu/command_buffer/common/logging.h" + +namespace command_buffer { + +// A resource ID, key to the resource maps. +typedef uint32 ResourceId; +// Invalid resource ID. +static const ResourceId kInvalidResource = 0xffffffffU; + +namespace vertex_buffer { +// Vertex buffer flags. +enum Flags { + kNone = 0x00, + kDynamic = 0x01, // This vertex buffer is dynamic and is expected to have + // its data updated often. +}; +} // namespace vertex_buffer + +namespace index_buffer { +// Index buffer flags. +enum Flags { + kNone = 0x00, + kDynamic = 0x01, // This index buffer is dynamic and is expected to have + // its data updated often. + kIndex32Bit = 0x02, // Indices contained in this index buffer are 32 bits + // (unsigned int) instead of 16 bit (unsigned short). +}; +} // namespace index_buffer + +namespace vertex_struct { +// Semantics for input data. +enum Semantic { + kUnknownSemantic = -1, + kPosition = 0, + kNormal, + kColor, + kTexCoord, + kNumSemantics +}; + +// Input data types. +enum Type { + kFloat1, + kFloat2, + kFloat3, + kFloat4, + kUChar4N, + kNumTypes +}; +} // namespace vertex_struct + +namespace effect_param { +enum DataType { + kUnknown, // A parameter exists in the effect, but the type is not + // representable (e.g. MATRIX3x4). + kFloat1, + kFloat2, + kFloat3, + kFloat4, + kMatrix4, + kInt, + kBool, + kSampler, + kTexture, + kNumTypes, + kMake32Bit = 0x7fffffff, +}; +COMPILE_ASSERT(sizeof(DataType) == 4, DataType_should_be_32_bits); + +// Gets the size of the data of a particular type. +unsigned int GetDataSize(DataType type); + +// Structure describing a parameter, filled in by the +// GAPIInterface::GetParamDesc call. +struct Desc { + Uint32 size; // the total memory size needed for the complete + // description. + Uint32 name_offset; // the offset of the parameter name, relative to + // the beginning of the structure. May be 0 if the + // name doesn't fit into the memory buffer. + Uint32 name_size; // the size of the parameter name, including the + // terminating nul character. Will always be set + // even if the name doesn't fit into the buffer. + Uint32 semantic_offset; // the offset of the parameter semantic, relative + // to the beginning of the structure. May be 0 if + // the semantic doesn't fit into the memory + // buffer. + Uint32 semantic_size; // the size of the parameter semantic, including + // the terminating nul character. Will always be + // set even if the semantic doesn't fit into the + // buffer. + Uint32 num_elements; // the number of entries if the parameter is an array + // 0 otherwise. + DataType data_type; // the data type of the parameter. + Uint32 data_size; // the size of the parameter data, in bytes. +}; +} // namespace effect_param + +namespace effect_stream { +struct Desc { + Desc() + : semantic(vertex_struct::kUnknownSemantic), + semantic_index(0) {} + Desc(Uint32 semantic, Uint32 semantic_index) + : semantic(semantic), + semantic_index(semantic_index) {} + Uint32 semantic; // the semantic type + Uint32 semantic_index; +}; +} // namespace effect_stream + +namespace texture { +// Texture flags. +enum Flags { + kNone = 0x00, + kDynamic = 0x01, // This texture is dynamic and is expected to have + // its data updated often. +}; + +// Texel formats. +enum Format { + kUnknown, + kXRGB8, + kARGB8, + kABGR16F, + kR32F, + kABGR32F, + kDXT1 +}; + +// Texture type. +enum Type { + kTexture2d, + kTexture3d, + kTextureCube, +}; + +// Cube map face. +enum Face { + kFacePositiveX, + kFaceNegativeX, + kFacePositiveY, + kFaceNegativeY, + kFacePositiveZ, + kFaceNegativeZ, + kFaceNone = kFacePositiveX, // For non-cube maps. +}; + +// Gets the number of bytes per block for a given texture format. For most +// texture formats, a block is 1x1 texels, but DXT* formats have 4x4 blocks. +unsigned int GetBytesPerBlock(Format format); +// Gets the x dimension of a texel block for a given texture format. For most +// texture formats, a block is 1x1 texels, but DXT* formats have 4x4 blocks. +unsigned int GetBlockSizeX(Format format); +// Gets the y dimension of a texel block for a given texture format. For most +// texture formats, a block is 1x1 texels, but DXT* formats have 4x4 blocks. +unsigned int GetBlockSizeY(Format format); +// Gets the dimension of a mipmap level given the dimension of the base +// level. Every mipmap level is half the size of the previous level, rounding +// down. +inline unsigned int GetMipMapDimension(unsigned int base, + unsigned int level) { + DCHECK_GT(base, 0U); + return std::max(1U, base >> level); +} +} // namespace texture + +namespace sampler { +enum AddressingMode { + kWrap, + kMirrorRepeat, + kClampToEdge, + kClampToBorder, + kNumAddressingMode +}; + +enum FilteringMode { + kNone, + kPoint, + kLinear, + kNumFilteringMode +}; +} // namespace sampler + +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_COMMON_CROSS_RESOURCE_H_ diff --git a/gpu/command_buffer/common/types.h b/gpu/command_buffer/common/types.h new file mode 100644 index 0000000..daa01cb --- /dev/null +++ b/gpu/command_buffer/common/types.h @@ -0,0 +1,60 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains cross-platform basic type definitions + +#ifndef GPU_COMMAND_BUFFER_COMMON_CROSS_TYPES_H_ +#define GPU_COMMAND_BUFFER_COMMON_CROSS_TYPES_H_ + +#include <build/build_config.h> +#if !defined(COMPILER_MSVC) +#include <stdint.h> +#endif +#include <string> + +namespace command_buffer { +#if defined(COMPILER_MSVC) +typedef short Int16; +typedef unsigned short Uint16; +typedef int Int32; +typedef unsigned int Uint32; +#else +typedef int16_t Int16; +typedef uint16_t Uint16; +typedef int32_t Int32; +typedef uint32_t Uint32; +#endif + +typedef std::string String; +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_COMMON_CROSS_TYPES_H_ diff --git a/gpu/command_buffer/service/cmd_buffer_engine.h b/gpu/command_buffer/service/cmd_buffer_engine.h new file mode 100644 index 0000000..74ad649 --- /dev/null +++ b/gpu/command_buffer/service/cmd_buffer_engine.h @@ -0,0 +1,70 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file defines the CommandBufferEngine class, providing the main loop for +// the service, exposing the RPC API, managing the command parser. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_CROSS_CMD_BUFFER_ENGINE_H_ +#define GPU_COMMAND_BUFFER_SERVICE_CROSS_CMD_BUFFER_ENGINE_H_ + +#include "base/basictypes.h" + +namespace command_buffer { + +class CommandBufferEngine { + public: + CommandBufferEngine() { + } + + virtual ~CommandBufferEngine() { + } + + // Gets the base address of a registered shared memory buffer. + // Parameters: + // shm_id: the identifier for the shared memory buffer. + virtual void *GetSharedMemoryAddress(int32 shm_id) = 0; + + // Gets the size of a registered shared memory buffer. + // Parameters: + // shm_id: the identifier for the shared memory buffer. + virtual size_t GetSharedMemorySize(int32 shm_id) = 0; + + // Sets the token value. + virtual void set_token(int32 token) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(CommandBufferEngine); +}; + +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_SERVICE_CROSS_CMD_BUFFER_ENGINE_H_ diff --git a/gpu/command_buffer/service/cmd_parser.cc b/gpu/command_buffer/service/cmd_parser.cc new file mode 100644 index 0000000..019e7b2 --- /dev/null +++ b/gpu/command_buffer/service/cmd_parser.cc @@ -0,0 +1,110 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the implementation of the command parser. + +#include "gpu/command_buffer/service/precompile.h" +#include "gpu/command_buffer/service/cmd_parser.h" + +namespace command_buffer { + +CommandParser::CommandParser(void *shm_address, + size_t shm_size, + ptrdiff_t offset, + size_t size, + CommandBufferOffset start_get, + AsyncAPIInterface *handler) + : get_(start_get), + put_(start_get), + handler_(handler) { + // check proper alignments. + DCHECK_EQ(0, (reinterpret_cast<intptr_t>(shm_address)) % 4); + DCHECK_EQ(0, offset % 4); + DCHECK_EQ(0u, size % 4); + // check that the command buffer fits into the memory buffer. + DCHECK_GE(shm_size, offset + size); + char * buffer_begin = static_cast<char *>(shm_address) + offset; + buffer_ = reinterpret_cast<CommandBufferEntry *>(buffer_begin); + entry_count_ = size / 4; +} + +// Process one command, reading the header from the command buffer, and +// forwarding the command index and the arguments to the handler. +// Note that: +// - validation needs to happen on a copy of the data (to avoid race +// conditions). This function only validates the header, leaving the arguments +// validation to the handler, so it can pass a reference to them. +// - get_ is modified *after* the command has been executed. +parse_error::ParseError CommandParser::ProcessCommand() { + CommandBufferOffset get = get_; + if (get == put_) return parse_error::kParseNoError; + + CommandHeader header = buffer_[get].value_header; + if (header.size == 0) { + DLOG(INFO) << "Error: zero sized command in command buffer"; + return parse_error::kParseInvalidSize; + } + + if (header.size + get > entry_count_) { + DLOG(INFO) << "Error: get offset out of bounds"; + return parse_error::kParseOutOfBounds; + } + + parse_error::ParseError result = handler_->DoCommand( + header.command, header.size - 1, buffer_ + get); + // TODO(gman): If you want to log errors this is the best place to catch them. + // It seems like we need an official way to turn on a debug mode and + // get these errors. + if (result != parse_error::kParseNoError) { + ReportError(header.command, result); + } + get_ = (get + header.size) % entry_count_; + return result; +} + +void CommandParser::ReportError(unsigned int command_id, + parse_error::ParseError result) { + DLOG(INFO) << "Error: " << result << " for Command " + << handler_->GetCommandName(command_id); +} + +// Processes all the commands, while the buffer is not empty. Stop if an error +// is encountered. +parse_error::ParseError CommandParser::ProcessAllCommands() { + while (!IsEmpty()) { + parse_error::ParseError error = ProcessCommand(); + if (error) return error; + } + return parse_error::kParseNoError; +} + +} // namespace command_buffer diff --git a/gpu/command_buffer/service/cmd_parser.h b/gpu/command_buffer/service/cmd_parser.h new file mode 100644 index 0000000..2209cf8 --- /dev/null +++ b/gpu/command_buffer/service/cmd_parser.h @@ -0,0 +1,115 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the command parser class. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_CROSS_CMD_PARSER_H_ +#define GPU_COMMAND_BUFFER_SERVICE_CROSS_CMD_PARSER_H_ + +#include "gpu/command_buffer/common/constants.h" +#include "gpu/command_buffer/common/cmd_buffer_common.h" + +namespace command_buffer { + +class AsyncAPIInterface; + +// Command parser class. This class parses commands from a shared memory +// buffer, to implement some asynchronous RPC mechanism. +class CommandParser { + public: + CommandParser(void *shm_address, + size_t shm_size, + ptrdiff_t offset, + size_t size, + CommandBufferOffset start_get, + AsyncAPIInterface *handler); + + // Gets the "get" pointer. The get pointer is an index into the command + // buffer considered as an array of CommandBufferEntry. + CommandBufferOffset get() const { return get_; } + + // Sets the "put" pointer. The put pointer is an index into the command + // buffer considered as an array of CommandBufferEntry. + void set_put(CommandBufferOffset put) { put_ = put; } + + // Gets the "put" pointer. The put pointer is an index into the command + // buffer considered as an array of CommandBufferEntry. + CommandBufferOffset put() const { return put_; } + + // Checks whether there are commands to process. + bool IsEmpty() const { return put_ == get_; } + + // Processes one command, updating the get pointer. This will return an error + // if there are no commands in the buffer. + parse_error::ParseError ProcessCommand(); + + // Processes all commands until get == put. + parse_error::ParseError ProcessAllCommands(); + + // Reports an error. + void ReportError(unsigned int command_id, parse_error::ParseError result); + + private: + CommandBufferOffset get_; + CommandBufferOffset put_; + CommandBufferEntry *buffer_; + size_t entry_count_; + AsyncAPIInterface *handler_; +}; + +// This class defines the interface for an asynchronous API handler, that +// is responsible for de-multiplexing commands and their arguments. +class AsyncAPIInterface { + public: + AsyncAPIInterface() {} + virtual ~AsyncAPIInterface() {} + + // Executes a command. + // Parameters: + // command: the command index. + // arg_count: the number of CommandBufferEntry arguments. + // cmd_data: the command data. + // Returns: + // parse_error::NO_ERROR if no error was found, one of + // parse_error::ParseError otherwise. + virtual parse_error::ParseError DoCommand( + unsigned int command, + unsigned int arg_count, + const void* cmd_data) = 0; + + // Returns a name for a command. Useful for logging / debuging. + virtual const char* GetCommandName(unsigned int command_id) const = 0; +}; + +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_SERVICE_CROSS_CMD_PARSER_H_ diff --git a/gpu/command_buffer/service/cmd_parser_test.cc b/gpu/command_buffer/service/cmd_parser_test.cc new file mode 100644 index 0000000..347eef2 --- /dev/null +++ b/gpu/command_buffer/service/cmd_parser_test.cc @@ -0,0 +1,316 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// Tests for the command parser. + +#include "gpu/command_buffer/service/precompile.h" + +#include "base/scoped_ptr.h" +#include "gpu/command_buffer/service/cmd_parser.h" +#include "gpu/command_buffer/service/mocks.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace command_buffer { + +using testing::Return; +using testing::Mock; +using testing::Truly; +using testing::Sequence; +using testing::_; + +// Test fixture for CommandParser test - Creates a mock AsyncAPIInterface, and +// a fixed size memory buffer. Also provides a simple API to create a +// CommandParser. +class CommandParserTest : public testing::Test { + protected: + virtual void SetUp() { + api_mock_.reset(new AsyncAPIMock); + buffer_entry_count_ = 20; + buffer_.reset(new CommandBufferEntry[buffer_entry_count_]); + } + virtual void TearDown() {} + + // Adds a DoCommand expectation in the mock. + void AddDoCommandExpect(parse_error::ParseError _return, + unsigned int command, + unsigned int arg_count, + CommandBufferEntry *args) { + EXPECT_CALL(*api_mock(), DoCommand(command, arg_count, + Truly(AsyncAPIMock::IsArgs(arg_count, args)))) + .InSequence(sequence_) + .WillOnce(Return(_return)); + } + + // Creates a parser, with a buffer of the specified size (in entries). + CommandParser *MakeParser(unsigned int entry_count) { + size_t shm_size = buffer_entry_count_ * + sizeof(CommandBufferEntry); // NOLINT + size_t command_buffer_size = entry_count * + sizeof(CommandBufferEntry); // NOLINT + DCHECK_LE(command_buffer_size, shm_size); + return new CommandParser(buffer(), + shm_size, + 0, + command_buffer_size, + 0, + api_mock()); + } + + unsigned int buffer_entry_count() { return 20; } + AsyncAPIMock *api_mock() { return api_mock_.get(); } + CommandBufferEntry *buffer() { return buffer_.get(); } + private: + unsigned int buffer_entry_count_; + scoped_ptr<AsyncAPIMock> api_mock_; + scoped_array<CommandBufferEntry> buffer_; + Sequence sequence_; +}; + +// Tests initialization conditions. +TEST_F(CommandParserTest, TestInit) { + scoped_ptr<CommandParser> parser(MakeParser(10)); + EXPECT_EQ(0u, parser->get()); + EXPECT_EQ(0u, parser->put()); + EXPECT_TRUE(parser->IsEmpty()); +} + +// Tests simple commands. +TEST_F(CommandParserTest, TestSimple) { + scoped_ptr<CommandParser> parser(MakeParser(10)); + CommandBufferOffset put = parser->put(); + CommandHeader header; + + // add a single command, no args + header.size = 1; + header.command = 123; + buffer()[put++].value_header = header; + + parser->set_put(put); + EXPECT_EQ(put, parser->put()); + + AddDoCommandExpect(parse_error::kParseNoError, 123, 0, NULL); + EXPECT_EQ(parse_error::kParseNoError, parser->ProcessCommand()); + EXPECT_EQ(put, parser->get()); + Mock::VerifyAndClearExpectations(api_mock()); + + // add a single command, 2 args + header.size = 3; + header.command = 456; + buffer()[put++].value_header = header; + buffer()[put++].value_int32 = 2134; + buffer()[put++].value_float = 1.f; + + parser->set_put(put); + EXPECT_EQ(put, parser->put()); + + CommandBufferEntry param_array[2]; + param_array[0].value_int32 = 2134; + param_array[1].value_float = 1.f; + AddDoCommandExpect(parse_error::kParseNoError, 456, 2, param_array); + EXPECT_EQ(parse_error::kParseNoError, parser->ProcessCommand()); + EXPECT_EQ(put, parser->get()); + Mock::VerifyAndClearExpectations(api_mock()); +} + +// Tests having multiple commands in the buffer. +TEST_F(CommandParserTest, TestMultipleCommands) { + scoped_ptr<CommandParser> parser(MakeParser(10)); + CommandBufferOffset put = parser->put(); + CommandHeader header; + + // add 2 commands, test with single ProcessCommand() + header.size = 2; + header.command = 789; + buffer()[put++].value_header = header; + buffer()[put++].value_int32 = 5151; + + CommandBufferOffset put_cmd2 = put; + header.size = 2; + header.command = 2121; + buffer()[put++].value_header = header; + buffer()[put++].value_int32 = 3434; + + parser->set_put(put); + EXPECT_EQ(put, parser->put()); + + CommandBufferEntry param_array[2]; + param_array[0].value_int32 = 5151; + AddDoCommandExpect(parse_error::kParseNoError, 789, 1, param_array); + param_array[1].value_int32 = 3434; + AddDoCommandExpect(parse_error::kParseNoError, 2121, 1, + param_array+1); + + EXPECT_EQ(parse_error::kParseNoError, parser->ProcessCommand()); + EXPECT_EQ(put_cmd2, parser->get()); + EXPECT_EQ(parse_error::kParseNoError, parser->ProcessCommand()); + EXPECT_EQ(put, parser->get()); + Mock::VerifyAndClearExpectations(api_mock()); + + // add 2 commands again, test with ProcessAllCommands() + header.size = 2; + header.command = 4545; + buffer()[put++].value_header = header; + buffer()[put++].value_int32 = 5656; + + header.size = 2; + header.command = 6767; + buffer()[put++].value_header = header; + buffer()[put++].value_int32 = 7878; + + parser->set_put(put); + EXPECT_EQ(put, parser->put()); + + param_array[0].value_int32 = 5656; + AddDoCommandExpect(parse_error::kParseNoError, 4545, 1, param_array); + param_array[1].value_int32 = 7878; + AddDoCommandExpect(parse_error::kParseNoError, 6767, 1, + param_array+1); + + EXPECT_EQ(parse_error::kParseNoError, parser->ProcessAllCommands()); + EXPECT_EQ(put, parser->get()); + Mock::VerifyAndClearExpectations(api_mock()); +} + +// Tests that the parser will wrap correctly at the end of the buffer. +TEST_F(CommandParserTest, TestWrap) { + scoped_ptr<CommandParser> parser(MakeParser(5)); + CommandBufferOffset put = parser->put(); + CommandHeader header; + + // add 3 commands with no args (1 word each) + for (unsigned int i = 0; i < 3; ++i) { + header.size = 1; + header.command = i; + buffer()[put++].value_header = header; + AddDoCommandExpect(parse_error::kParseNoError, i, 0, NULL); + } + parser->set_put(put); + EXPECT_EQ(put, parser->put()); + EXPECT_EQ(parse_error::kParseNoError, parser->ProcessAllCommands()); + EXPECT_EQ(put, parser->get()); + Mock::VerifyAndClearExpectations(api_mock()); + + // add 1 command with 1 arg (2 words). That should put us at the end of the + // buffer. + header.size = 2; + header.command = 3; + buffer()[put++].value_header = header; + buffer()[put++].value_int32 = 5; + CommandBufferEntry param; + param.value_int32 = 5; + AddDoCommandExpect(parse_error::kParseNoError, 3, 1, ¶m); + + DCHECK_EQ(5u, put); + put = 0; + parser->set_put(put); + EXPECT_EQ(put, parser->put()); + EXPECT_EQ(parse_error::kParseNoError, parser->ProcessAllCommands()); + EXPECT_EQ(put, parser->get()); + Mock::VerifyAndClearExpectations(api_mock()); + + // add 1 command with 1 arg (2 words). + header.size = 2; + header.command = 4; + buffer()[put++].value_header = header; + buffer()[put++].value_int32 = 6; + param.value_int32 = 6; + AddDoCommandExpect(parse_error::kParseNoError, 4, 1, ¶m); + parser->set_put(put); + EXPECT_EQ(put, parser->put()); + EXPECT_EQ(parse_error::kParseNoError, parser->ProcessAllCommands()); + EXPECT_EQ(put, parser->get()); + Mock::VerifyAndClearExpectations(api_mock()); +} + +// Tests error conditions. +TEST_F(CommandParserTest, TestError) { + scoped_ptr<CommandParser> parser(MakeParser(5)); + CommandBufferOffset put = parser->put(); + CommandHeader header; + + // Generate a command with size 0. + header.size = 0; + header.command = 3; + buffer()[put++].value_header = header; + + parser->set_put(put); + EXPECT_EQ(put, parser->put()); + EXPECT_EQ(parse_error::kParseInvalidSize, + parser->ProcessAllCommands()); + // check that no DoCommand call was made. + Mock::VerifyAndClearExpectations(api_mock()); + + parser.reset(MakeParser(5)); + put = parser->put(); + + // Generate a command with size 6, extends beyond the end of the buffer. + header.size = 6; + header.command = 3; + buffer()[put++].value_header = header; + + parser->set_put(put); + EXPECT_EQ(put, parser->put()); + EXPECT_EQ(parse_error::kParseOutOfBounds, + parser->ProcessAllCommands()); + // check that no DoCommand call was made. + Mock::VerifyAndClearExpectations(api_mock()); + + parser.reset(MakeParser(5)); + put = parser->put(); + + // Generates 2 commands. + header.size = 1; + header.command = 3; + buffer()[put++].value_header = header; + CommandBufferOffset put_post_fail = put; + header.size = 1; + header.command = 4; + buffer()[put++].value_header = header; + + parser->set_put(put); + EXPECT_EQ(put, parser->put()); + // have the first command fail to parse. + AddDoCommandExpect(parse_error::kParseUnknownCommand, 3, 0, NULL); + EXPECT_EQ(parse_error::kParseUnknownCommand, + parser->ProcessAllCommands()); + // check that only one command was executed, and that get reflects that + // correctly. + EXPECT_EQ(put_post_fail, parser->get()); + Mock::VerifyAndClearExpectations(api_mock()); + // make the second one succeed, and check that the parser recovered fine. + AddDoCommandExpect(parse_error::kParseNoError, 4, 0, NULL); + EXPECT_EQ(parse_error::kParseNoError, parser->ProcessAllCommands()); + EXPECT_EQ(put, parser->get()); + Mock::VerifyAndClearExpectations(api_mock()); +} + +} // namespace command_buffer diff --git a/gpu/command_buffer/service/command_buffer_service.cc b/gpu/command_buffer/service/command_buffer_service.cc new file mode 100644 index 0000000..1ab2a9b --- /dev/null +++ b/gpu/command_buffer/service/command_buffer_service.cc @@ -0,0 +1,159 @@ +// Copyright (c) 2006-2008 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/command_buffer_service.h" + +using ::base::SharedMemory; + +namespace command_buffer { + +CommandBufferService::CommandBufferService() + : size_(0), + get_offset_(0), + put_offset_(0), + token_(0), + parse_error_(0), + error_status_(false) { + // Element zero is always NULL. + registered_objects_.push_back(linked_ptr<SharedMemory>()); +} + +CommandBufferService::~CommandBufferService() { +} + +bool CommandBufferService::Initialize(::base::SharedMemory* ring_buffer) { + DCHECK(ring_buffer); + + // Fail if already initialized. + if (ring_buffer_.get()) + return false; + + size_t size_in_bytes = ring_buffer->max_size(); + size_ = size_in_bytes / sizeof(int32); + ring_buffer_.reset(ring_buffer); + + return true; +} + +SharedMemory* CommandBufferService::GetRingBuffer() { + return ring_buffer_.get(); +} + +int32 CommandBufferService::GetSize() { + return size_; +} + +int32 CommandBufferService::SyncOffsets(int32 put_offset) { + if (put_offset < 0 || put_offset >= size_) + return -1; + + put_offset_ = put_offset; + + if (put_offset_change_callback_.get()) { + put_offset_change_callback_->Run(); + } + + return get_offset_; +} + +int32 CommandBufferService::GetGetOffset() { + return get_offset_; +} + +void CommandBufferService::SetGetOffset(int32 get_offset) { + DCHECK(get_offset >= 0 && get_offset < size_); + get_offset_ = get_offset; +} + +int32 CommandBufferService::GetPutOffset() { + return put_offset_; +} + +void CommandBufferService::SetPutOffsetChangeCallback( + Callback0::Type* callback) { + put_offset_change_callback_.reset(callback); +} + +int32 CommandBufferService::CreateTransferBuffer(size_t size) { + linked_ptr<SharedMemory> buffer(new SharedMemory); + if (!buffer->Create(std::wstring(), false, false, size)) + return -1; + + if (unused_registered_object_elements_.empty()) { + // Check we haven't exceeded the range that fits in a 32-bit integer. + int32 handle = static_cast<int32>(registered_objects_.size()); + if (handle != registered_objects_.size()) + return -1; + + registered_objects_.push_back(buffer); + return handle; + } + + int32 handle = *unused_registered_object_elements_.begin(); + unused_registered_object_elements_.erase( + unused_registered_object_elements_.begin()); + DCHECK(!registered_objects_[handle].get()); + registered_objects_[handle] = buffer; + return handle; +} + +void CommandBufferService::DestroyTransferBuffer(int32 handle) { + if (handle <= 0) + return; + + if (static_cast<size_t>(handle) >= registered_objects_.size()) + return; + + registered_objects_[handle].reset(); + unused_registered_object_elements_.insert(handle); + + // Remove all null objects from the end of the vector. This allows the vector + // to shrink when, for example, all objects are unregistered. Note that this + // loop never removes element zero, which is always NULL. + while (registered_objects_.size() > 1 && !registered_objects_.back().get()) { + registered_objects_.pop_back(); + unused_registered_object_elements_.erase( + static_cast<int32>(registered_objects_.size())); + } +} + +::base::SharedMemory* CommandBufferService::GetTransferBuffer(int32 handle) { + if (handle < 0) + return NULL; + + if (static_cast<size_t>(handle) >= registered_objects_.size()) + return NULL; + + return registered_objects_[handle].get(); +} + +int32 CommandBufferService::GetToken() { + return token_; +} + +void CommandBufferService::SetToken(int32 token) { + token_ = token; +} + +int32 CommandBufferService::ResetParseError() { + int32 last_error = parse_error_; + parse_error_ = 0; + return last_error; +} + +void CommandBufferService::SetParseError(int32 parse_error) { + if (parse_error_ == 0) { + parse_error_ = parse_error; + } +} + +bool CommandBufferService::GetErrorStatus() { + return error_status_; +} + +void CommandBufferService::RaiseErrorStatus() { + error_status_ = true; +} + +} // namespace command_buffer diff --git a/gpu/command_buffer/service/command_buffer_service.h b/gpu/command_buffer/service/command_buffer_service.h new file mode 100644 index 0000000..d6da953 --- /dev/null +++ b/gpu/command_buffer/service/command_buffer_service.h @@ -0,0 +1,93 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_COMMAND_BUFFER_H_ +#define GPU_COMMAND_BUFFER_SERVICE_COMMAND_BUFFER_H_ + +#include <set> +#include <vector> + +#include "base/linked_ptr.h" +#include "base/scoped_ptr.h" +#include "base/shared_memory.h" +#include "base/task.h" +#include "gpu/command_buffer/common/command_buffer.h" +#include "gpu/np_utils/default_np_object.h" +#include "gpu/np_utils/np_dispatcher.h" + +namespace command_buffer { + +// An NPObject that implements a shared memory command buffer and a synchronous +// API to manage the put and get pointers. +class CommandBufferService : public CommandBuffer { + public: + CommandBufferService(); + virtual ~CommandBufferService(); + + // Overrides CommandBuffer. + virtual bool Initialize(::base::SharedMemory* ring_buffer); + + // Overrides CommandBuffer. + virtual ::base::SharedMemory* GetRingBuffer(); + + virtual int32 GetSize(); + + // Overrides CommandBuffer. + virtual int32 SyncOffsets(int32 put_offset); + + // Overrides CommandBuffer. + virtual int32 GetGetOffset(); + + // Overrides CommandBuffer. + virtual void SetGetOffset(int32 get_offset); + + // Overrides CommandBuffer. + virtual int32 GetPutOffset(); + + // Overrides CommandBuffer. + virtual void SetPutOffsetChangeCallback(Callback0::Type* callback); + + // Overrides CommandBuffer. + virtual int32 CreateTransferBuffer(size_t size); + + // Overrides CommandBuffer. + virtual void DestroyTransferBuffer(int32 id); + + // Overrides CommandBuffer. + virtual ::base::SharedMemory* GetTransferBuffer(int32 handle); + + // Overrides CommandBuffer. + virtual int32 GetToken(); + + // Overrides CommandBuffer. + virtual void SetToken(int32 token); + + // Overrides CommandBuffer. + virtual int32 ResetParseError(); + + // Overrides CommandBuffer. + virtual void SetParseError(int32 parse_error); + + // Overrides CommandBuffer. + virtual bool GetErrorStatus(); + + // Overrides CommandBuffer. + virtual void RaiseErrorStatus(); + + private: + scoped_ptr< ::base::SharedMemory> ring_buffer_; + int32 size_; + int32 get_offset_; + int32 put_offset_; + scoped_ptr<Callback0::Type> put_offset_change_callback_; + std::vector<linked_ptr< ::base::SharedMemory> > registered_objects_; + std::set<int32> unused_registered_object_elements_; + int32 token_; + int32 parse_error_; + bool error_status_; +}; + +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_SERVICE_COMMAND_BUFFER_H_ diff --git a/gpu/command_buffer/service/command_buffer_service_unittest.cc b/gpu/command_buffer/service/command_buffer_service_unittest.cc new file mode 100644 index 0000000..2f9c1fb --- /dev/null +++ b/gpu/command_buffer/service/command_buffer_service_unittest.cc @@ -0,0 +1,185 @@ +// Copyright (c) 2006-2008 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 "base/thread.h" +#include "gpu/command_buffer/service/command_buffer_service.h" +#include "gpu/np_utils/np_browser_mock.h" +#include "gpu/np_utils/dynamic_np_object.h" +#include "gpu/np_utils/np_object_mock.h" +#include "gpu/np_utils/np_object_pointer.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/gmock/include/gmock/gmock.h" + +using base::SharedMemory; +using np_utils::NPCreateObject; +using np_utils::NPObjectPointer; +using testing::_; +using testing::DoAll; +using testing::Return; +using testing::SetArgumentPointee; +using testing::StrictMock; + +namespace command_buffer { + +class CommandBufferServiceTest : public testing::Test { + protected: + virtual void SetUp() { + command_buffer_.reset(new CommandBufferService); + } + + np_utils::MockNPBrowser mock_browser_; + scoped_ptr<CommandBufferService> command_buffer_; +}; + +TEST_F(CommandBufferServiceTest, NullRingBufferByDefault) { + EXPECT_TRUE(NULL == command_buffer_->GetRingBuffer()); +} + +TEST_F(CommandBufferServiceTest, InitializesCommandBuffer) { + SharedMemory* ring_buffer = new SharedMemory; + EXPECT_TRUE(ring_buffer->Create(std::wstring(), false, false, 1024)); + EXPECT_TRUE(command_buffer_->Initialize(ring_buffer)); + EXPECT_TRUE(ring_buffer == command_buffer_->GetRingBuffer()); + EXPECT_EQ(256, command_buffer_->GetSize()); +} + +TEST_F(CommandBufferServiceTest, InitializeFailsSecondTime) { + SharedMemory* ring_buffer = new SharedMemory; + EXPECT_TRUE(command_buffer_->Initialize(ring_buffer)); + EXPECT_FALSE(command_buffer_->Initialize(ring_buffer)); +} + +TEST_F(CommandBufferServiceTest, GetAndPutOffsetsDefaultToZero) { + EXPECT_EQ(0, command_buffer_->GetGetOffset()); + EXPECT_EQ(0, command_buffer_->GetPutOffset()); +} + +class MockCallback : public CallbackRunner<Tuple0> { + public: + MOCK_METHOD1(RunWithParams, void(const Tuple0&)); +}; + +TEST_F(CommandBufferServiceTest, CanSyncGetAndPutOffset) { + SharedMemory* ring_buffer = new SharedMemory; + ring_buffer->Create(std::wstring(), false, false, 1024); + + EXPECT_TRUE(command_buffer_->Initialize(ring_buffer)); + + StrictMock<MockCallback>* put_offset_change_callback = + new StrictMock<MockCallback>; + command_buffer_->SetPutOffsetChangeCallback(put_offset_change_callback); + + EXPECT_CALL(*put_offset_change_callback, RunWithParams(_)); + EXPECT_EQ(0, command_buffer_->SyncOffsets(2)); + EXPECT_EQ(2, command_buffer_->GetPutOffset()); + + EXPECT_CALL(*put_offset_change_callback, RunWithParams(_)); + EXPECT_EQ(0, command_buffer_->SyncOffsets(4)); + EXPECT_EQ(4, command_buffer_->GetPutOffset()); + + command_buffer_->SetGetOffset(2); + EXPECT_EQ(2, command_buffer_->GetGetOffset()); + EXPECT_CALL(*put_offset_change_callback, RunWithParams(_)); + EXPECT_EQ(2, command_buffer_->SyncOffsets(6)); + + EXPECT_EQ(-1, command_buffer_->SyncOffsets(-1)); + EXPECT_EQ(-1, command_buffer_->SyncOffsets(1024)); +} + +TEST_F(CommandBufferServiceTest, ZeroHandleMapsToNull) { + EXPECT_TRUE(NULL == command_buffer_->GetTransferBuffer(0)); +} + +TEST_F(CommandBufferServiceTest, NegativeHandleMapsToNull) { + EXPECT_TRUE(NULL == command_buffer_->GetTransferBuffer(-1)); +} + +TEST_F(CommandBufferServiceTest, OutOfRangeHandleMapsToNull) { + EXPECT_TRUE(NULL == command_buffer_->GetTransferBuffer(1)); +} + +TEST_F(CommandBufferServiceTest, CanCreateTransferBuffers) { + int32 handle = command_buffer_->CreateTransferBuffer(1024); + EXPECT_EQ(1, handle); + SharedMemory* buffer = command_buffer_->GetTransferBuffer(handle); + ASSERT_TRUE(NULL != buffer); + EXPECT_EQ(1024, buffer->max_size()); +} + +TEST_F(CommandBufferServiceTest, CreateTransferBufferReturnsDistinctHandles) { + EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024)); +} + +TEST_F(CommandBufferServiceTest, + CreateTransferBufferReusesUnregisteredHandles) { + EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024)); + EXPECT_EQ(2, command_buffer_->CreateTransferBuffer(1024)); + command_buffer_->DestroyTransferBuffer(1); + EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024)); + EXPECT_EQ(3, command_buffer_->CreateTransferBuffer(1024)); +} + +TEST_F(CommandBufferServiceTest, CannotUnregisterHandleZero) { + command_buffer_->DestroyTransferBuffer(0); + EXPECT_TRUE(NULL == command_buffer_->GetTransferBuffer(0)); + EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024)); +} + +TEST_F(CommandBufferServiceTest, CannotUnregisterNegativeHandles) { + command_buffer_->DestroyTransferBuffer(-1); + EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024)); +} + +TEST_F(CommandBufferServiceTest, CannotUnregisterUnregisteredHandles) { + command_buffer_->DestroyTransferBuffer(1); + EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024)); +} + +// Testing this case specifically because there is an optimization that takes +// a different code path in this case. +TEST_F(CommandBufferServiceTest, UnregistersLastRegisteredHandle) { + EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024)); + command_buffer_->DestroyTransferBuffer(1); + EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024)); +} + +// Testing this case specifically because there is an optimization that takes +// a different code path in this case. +TEST_F(CommandBufferServiceTest, UnregistersTwoLastRegisteredHandles) { + EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024)); + EXPECT_EQ(2, command_buffer_->CreateTransferBuffer(1024)); + command_buffer_->DestroyTransferBuffer(2); + command_buffer_->DestroyTransferBuffer(1); + EXPECT_EQ(1, command_buffer_->CreateTransferBuffer(1024)); +} + +TEST_F(CommandBufferServiceTest, DefaultTokenIsZero) { + EXPECT_EQ(0, command_buffer_->GetToken()); +} + +TEST_F(CommandBufferServiceTest, CanSetToken) { + command_buffer_->SetToken(7); + EXPECT_EQ(7, command_buffer_->GetToken()); +} + +TEST_F(CommandBufferServiceTest, DefaultParseErrorIsNoError) { + EXPECT_EQ(0, command_buffer_->ResetParseError()); +} + +TEST_F(CommandBufferServiceTest, CanSetAndResetParseError) { + command_buffer_->SetParseError(1); + EXPECT_EQ(1, command_buffer_->ResetParseError()); + EXPECT_EQ(0, command_buffer_->ResetParseError()); +} + +TEST_F(CommandBufferServiceTest, DefaultErrorStatusIsFalse) { + EXPECT_FALSE(command_buffer_->GetErrorStatus()); +} + +TEST_F(CommandBufferServiceTest, CanRaiseErrorStatus) { + command_buffer_->RaiseErrorStatus(); + EXPECT_TRUE(command_buffer_->GetErrorStatus()); +} + +} // namespace command_buffer diff --git a/gpu/command_buffer/service/common_decoder.cc b/gpu/command_buffer/service/common_decoder.cc new file mode 100644 index 0000000..22bf445 --- /dev/null +++ b/gpu/command_buffer/service/common_decoder.cc @@ -0,0 +1,122 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "gpu/command_buffer/service/precompile.h" +#include "gpu/command_buffer/service/common_decoder.h" +#include "gpu/command_buffer/service/cmd_buffer_engine.h" + +namespace command_buffer { + +void* CommonDecoder::GetAddressAndCheckSize(unsigned int shm_id, + unsigned int offset, + unsigned int size) { + void* shm_addr = engine_->GetSharedMemoryAddress(shm_id); + if (!shm_addr) return NULL; + size_t shm_size = engine_->GetSharedMemorySize(shm_id); + unsigned int end = offset + size; + if (end > shm_size || end < offset) { + return NULL; + } + return static_cast<int8 *>(shm_addr) + offset; +} + +const char* CommonDecoder::GetCommonCommandName( + cmd::CommandId command_id) const { + return cmd::GetCommandName(command_id); +} + +namespace { + +// A struct to hold info about each command. +struct CommandInfo { + int arg_flags; // How to handle the arguments for this command + int arg_count; // How many arguments are expected for this command. +}; + +// A table of CommandInfo for all the commands. +const CommandInfo g_command_info[] = { + #define COMMON_COMMAND_BUFFER_CMD_OP(name) { \ + cmd::name::kArgFlags, \ + sizeof(cmd::name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */ \ + + COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP) + + #undef COMMON_COMMAND_BUFFER_CMD_OP +}; + +} // anonymous namespace. + +// Decode command with its arguments, and call the corresponding method. +// Note: args is a pointer to the command buffer. As such, it could be changed +// by a (malicious) client at any time, so if validation has to happen, it +// should operate on a copy of them. +parse_error::ParseError CommonDecoder::DoCommonCommand( + unsigned int command, + unsigned int arg_count, + const void* cmd_data) { + if (command < arraysize(g_command_info)) { + const CommandInfo& info = g_command_info[command]; + 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)) { + switch (command) { + #define COMMON_COMMAND_BUFFER_CMD_OP(name) \ + case cmd::name::kCmdId: \ + return Handle ## name( \ + arg_count, \ + *static_cast<const cmd::name*>(cmd_data)); \ + + COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP) + + #undef COMMON_COMMAND_BUFFER_CMD_OP + } + } else { + return parse_error::kParseInvalidArguments; + } + } + return DoCommonCommand(command, arg_count, cmd_data); + return parse_error::kParseUnknownCommand; +} + +parse_error::ParseError CommonDecoder::HandleNoop( + uint32 arg_count, + const cmd::Noop& args) { + return parse_error::kParseNoError; +} + +parse_error::ParseError CommonDecoder::HandleSetToken( + uint32 arg_count, + const cmd::SetToken& args) { + engine_->set_token(args.token); + return parse_error::kParseNoError; +} + +} // namespace command_buffer diff --git a/gpu/command_buffer/service/common_decoder.h b/gpu/command_buffer/service/common_decoder.h new file mode 100644 index 0000000..25d1dbe --- /dev/null +++ b/gpu/command_buffer/service/common_decoder.h @@ -0,0 +1,107 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GPU_COMMAND_BUFFER_SERVICE_CROSS_COMMON_DECODER_H_ +#define GPU_COMMAND_BUFFER_SERVICE_CROSS_COMMON_DECODER_H_ + +#include "gpu/command_buffer/service/cmd_parser.h" + +namespace command_buffer { + +class CommandBufferEngine; + +// This class is a helper base class for implementing the common parts of the +// o3d/gl2 command buffer decoder. +class CommonDecoder : public AsyncAPIInterface { + public: + typedef parse_error::ParseError ParseError; + + CommonDecoder() : engine_(NULL) { + } + virtual ~CommonDecoder() { + } + + // Sets the engine, to get shared memory buffers from, and to set the token + // to. + void set_engine(CommandBufferEngine* engine) { + engine_ = engine; + } + + protected: + // Executes a common command. + // Parameters: + // command: the command index. + // arg_count: the number of CommandBufferEntry arguments. + // cmd_data: the command data. + // Returns: + // parse_error::NO_ERROR if no error was found, one of + // parse_error::ParseError otherwise. + parse_error::ParseError DoCommonCommand( + unsigned int command, + unsigned int arg_count, + const void* cmd_data); + + // Gets the address of shared memory data, given a shared memory ID and an + // offset. Also checks that the size is consistent with the shared memory + // size. + // Parameters: + // shm_id: the id of the shared memory buffer. + // offset: the offset of the data in the shared memory buffer. + // size: the size of the data. + // Returns: + // NULL if shm_id isn't a valid shared memory buffer ID or if the size + // check fails. Return a pointer to the data otherwise. + void* GetAddressAndCheckSize(unsigned int shm_id, + unsigned int offset, + unsigned int size); + + // Gets an name for a common command. + const char* GetCommonCommandName(cmd::CommandId command_id) const; + + private: + // Generate a member function prototype for each command in an automated and + // typesafe way. + #define COMMON_COMMAND_BUFFER_CMD_OP(name) \ + parse_error::ParseError Handle ## name( \ + unsigned int arg_count, \ + const cmd::name& args); \ + + COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP) + + #undef COMMON_COMMAND_BUFFER_CMD_OP + + CommandBufferEngine* engine_; +}; + +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_SERVICE_CROSS_COMMON_DECODER_H_ + diff --git a/gpu/command_buffer/service/gl_utils.h b/gpu/command_buffer/service/gl_utils.h new file mode 100644 index 0000000..b9c10f5 --- /dev/null +++ b/gpu/command_buffer/service/gl_utils.h @@ -0,0 +1,58 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file includes all the necessary GL headers and implements some useful +// utilities. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_GL_UTILS_H_ +#define GPU_COMMAND_BUFFER_SERVICE_GL_UTILS_H_ + +#include <GL/glew.h> +#if defined(OS_WIN) +#include <GL/wglew.h> +#endif +#include <build/build_config.h> + +#define GL_GLEXT_PROTOTYPES + +// Define this for extra GL error debugging (slower). +// #define GL_ERROR_DEBUGGING +#ifdef GL_ERROR_DEBUGGING +#define CHECK_GL_ERROR() do { \ + GLenum gl_error = glGetError(); \ + LOG_IF(ERROR, gl_error != GL_NO_ERROR) << "GL Error :" << gl_error; \ + } while (0) +#else // GL_ERROR_DEBUGGING +#define CHECK_GL_ERROR() void(0) +#endif // GL_ERROR_DEBUGGING + +#endif // GPU_COMMAND_BUFFER_SERVICE_GL_UTILS_H_ diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc new file mode 100644 index 0000000..159c5c5 --- /dev/null +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -0,0 +1,950 @@ +// Copyright (c) 2006-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 <vector> +#include <string> +#include <map> +#include <build/build_config.h> +#include "base/scoped_ptr.h" +#define GLES2_GPU_SERVICE 1 +#include "gpu/command_buffer/common/gles2_cmd_format.h" +#include "gpu/command_buffer/common/gles2_cmd_utils.h" +#include "gpu/command_buffer/service/cmd_buffer_engine.h" +#include "gpu/command_buffer/service/gl_utils.h" +#include "gpu/command_buffer/service/gles2_cmd_decoder.h" + +namespace command_buffer { +namespace gles2 { + +namespace { + +// Returns the address of the first byte after a struct. +template <typename T> +const void* AddressAfterStruct(const T& pod) { + return reinterpret_cast<const uint8*>(&pod) + sizeof(pod); +} + +// Returns the address of the frst byte after the struct. +template <typename RETURN_TYPE, typename COMMAND_TYPE> +RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod) { + return static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))); +} + +// Returns the size in bytes of the data of an Immediate command, a command with +// its data inline in the command buffer. +template <typename T> +unsigned int ImmediateDataSize(uint32 arg_count) { + return static_cast<unsigned int>( + (arg_count + 1 - ComputeNumEntries(sizeof(T))) * + sizeof(CommandBufferEntry)); // NOLINT +} + +// Checks if there is enough immediate data. +template<typename T> +bool CheckImmediateDataSize( + unsigned int arg_count, + GLuint count, + size_t size, + unsigned int elements_per_unit) { + return ImmediateDataSize<T>(arg_count) == count * size * elements_per_unit; +} + +// A struct to hold info about each command. +struct CommandInfo { + int arg_flags; // How to handle the arguments for this command + int arg_count; // How many arguments are expected for this command. +}; + +// A table of CommandInfo for all the commands. +const CommandInfo g_command_info[] = { + #define GLES2_CMD_OP(name) { \ + name::kArgFlags, \ + sizeof(name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */ \ + + GLES2_COMMAND_LIST(GLES2_CMD_OP) + + #undef GLES2_CMD_OP +}; + +// These commands convert from c calls to local os calls. +void GLGenBuffersHelper(GLsizei n, GLuint* ids) { + glGenBuffersARB(n, ids); +} + +void GLGenFramebuffersHelper(GLsizei n, GLuint* ids) { + glGenFramebuffersEXT(n, ids); +} + +void GLGenRenderbuffersHelper(GLsizei n, GLuint* ids) { + glGenRenderbuffersEXT(n, ids); +} + +void GLGenTexturesHelper(GLsizei n, GLuint* ids) { + glGenTextures(n, ids); +} + +void GLDeleteBuffersHelper(GLsizei n, GLuint* ids) { + glDeleteBuffersARB(n, ids); +} + +void GLDeleteFramebuffersHelper(GLsizei n, GLuint* ids) { + glDeleteFramebuffersEXT(n, ids); +} + +void GLDeleteRenderbuffersHelper(GLsizei n, GLuint* ids) { + glDeleteRenderbuffersEXT(n, ids); +} + +void GLDeleteTexturesHelper(GLsizei n, GLuint* ids) { + glDeleteTextures(n, ids); +} + +namespace GLErrorBit { +enum GLErrorBit { + kNoError = 0, + kInvalidEnum, + kInvalidValue, + kInvalidOperation, + kOutOfMemory, + kInvalidFrameBufferOperation, +}; +} + +uint32 GLErrorToErrorBit(GLenum error) { + switch(error) { + case GL_INVALID_ENUM: + return GLErrorBit::kInvalidEnum; + case GL_INVALID_VALUE: + return GLErrorBit::kInvalidValue; + case GL_INVALID_OPERATION: + return GLErrorBit::kInvalidOperation; + case GL_OUT_OF_MEMORY: + return GLErrorBit::kOutOfMemory; + case GL_INVALID_FRAMEBUFFER_OPERATION: + return GLErrorBit::kInvalidFrameBufferOperation; + default: + DCHECK(false); + return GLErrorBit::kNoError; + } +} + +GLenum GLErrorBitToGLError(uint32 error_bit) { + switch(error_bit) { + case GLErrorBit::kInvalidEnum: + return GL_INVALID_ENUM; + case GLErrorBit::kInvalidValue: + return GL_INVALID_VALUE; + case GLErrorBit::kInvalidOperation: + return GL_INVALID_OPERATION; + case GLErrorBit::kOutOfMemory: + return GL_OUT_OF_MEMORY; + case GLErrorBit::kInvalidFrameBufferOperation: + return GL_INVALID_FRAMEBUFFER_OPERATION; + default: + DCHECK(false); + return GL_NO_ERROR; + } +} + +} // anonymous namespace. + +GLES2Decoder::GLES2Decoder() +#ifdef OS_LINUX + : window_(NULL) { +#endif +#ifdef OS_WIN + : hwnd_(NULL) { +#endif +} + +// This class maps one set of ids to another. +class IdMap { + public: + // Maps a client_id to a service_id. Return false if the client_id or + // service_id are already mapped to something else. + bool AddMapping(GLuint client_id, GLuint service_id); + + // Unmaps a pair of ids. Returns false if the pair were not previously mapped. + bool RemoveMapping(GLuint client_id, GLuint service_id); + + // Gets the corresponding service_id for the given client_id. + // Returns false if there is no corresponding service_id. + bool GetServiceId(GLuint client_id, GLuint* service_id); + + // Gets the corresponding client_id for the given service_id. + // Returns false if there is no corresponding client_id. + bool GetClientId(GLuint service_id, GLuint* client_id); + + private: + // TODO(gman): Replace with faster implementation. + typedef std::map<GLuint, GLuint> MapType; + MapType id_map_; +}; + +bool IdMap::AddMapping(GLuint client_id, GLuint service_id) { + std::pair<MapType::iterator, bool> result = id_map_.insert( + std::make_pair(client_id, service_id)); + return result.second; +} + +bool IdMap::RemoveMapping(GLuint client_id, GLuint service_id) { + MapType::iterator iter = id_map_.find(client_id); + if (iter != id_map_.end() && iter->second == service_id) { + id_map_.erase(iter); + return true; + } + return false; +} + +bool IdMap::GetServiceId(GLuint client_id, GLuint* service_id) { + DCHECK(service_id); + MapType::iterator iter = id_map_.find(client_id); + if (iter != id_map_.end()) { + *service_id = iter->second; + return true; + } + return false; +} + +bool IdMap::GetClientId(GLuint service_id, GLuint* client_id) { + DCHECK(client_id); + MapType::iterator end(id_map_.end()); + for (MapType::iterator iter(id_map_.begin()); + iter != end; + ++iter) { + if (iter->second == service_id) { + *client_id = iter->first; + return true; + } + } + return false; +} + +// This class implements GLES2Decoder so we don't have to expose all the GLES2 +// cmd stuff to outside this class. +class GLES2DecoderImpl : public GLES2Decoder { + public: + GLES2DecoderImpl(); + + // Overridden from AsyncAPIInterface. + virtual ParseError DoCommand(unsigned int command, + unsigned int arg_count, + const void* args); + + // Overridden from AsyncAPIInterface. + virtual const char* GetCommandName(unsigned int command_id) const; + + // Overridden from GLES2Decoder. + virtual bool Initialize(); + + // Overridden from GLES2Decoder. + virtual void Destroy(); + + private: + bool InitPlatformSpecific(); + bool InitGlew(); + + // Typed version of GetAddressAndCheckSize. + template <typename T> + T GetSharedMemoryAs(unsigned int shm_id, unsigned int offset, + unsigned int size) { + return static_cast<T>(GetAddressAndCheckSize(shm_id, offset, size)); + } + + // Template to help call glGenXXX functions. + template <void gl_gen_function(GLsizei, GLuint*)> + bool GenGLObjects(GLsizei n, const GLuint* client_ids) { + // TODO(gman): Verify client ids are unused. + scoped_array<GLuint>temp(new GLuint[n]); + gl_gen_function(n, temp.get()); + // TODO(gman): check for success before copying results. + for (GLsizei ii = 0; ii < n; ++ii) { + if (!id_map_.AddMapping(client_ids[ii], temp[ii])) { + // TODO(gman): fail. + } + } + return true; + } + + // Template to help call glDeleteXXX functions. + template <void gl_delete_function(GLsizei, GLuint*)> + bool DeleteGLObjects(GLsizei n, const GLuint* client_ids) { + scoped_array<GLuint>temp(new GLuint[n]); + // TODO(gman): check for success before copying results. + for (GLsizei ii = 0; ii < n; ++ii) { + if (id_map_.GetServiceId(client_ids[ii], &temp[ii])) { + id_map_.RemoveMapping(client_ids[ii], temp[ii]); + } else { + temp[ii] = 0; + } + } + gl_delete_function(n, temp.get()); + return true; + } + + // Wrapper for glCreateProgram + void CreateProgramHelper(GLuint client_id); + + // Wrapper for glCreateShader + void CreateShaderHelper(GLenum type, GLuint client_id); + + // Wrapper for glBindBuffer since we need to track the current targets. + void DoBindBuffer(GLenum target, GLuint buffer); + + // Wrapper for glDeleteProgram. + void DoDeleteProgram(GLuint program); + + // Wrapper for glDeleteShader. + void DoDeleteShader(GLuint shader); + + // Swaps the buffers (copies/renders to the current window). + void DoSwapBuffers(); + + // Gets the GLError through our wrapper. + GLenum GetGLError(); + + // Sets our wrapper for the GLError. + void SetGLError(GLenum error); + + // Generate a member function prototype for each command in an automated and + // typesafe way. + #define GLES2_CMD_OP(name) \ + ParseError Handle ## name( \ + unsigned int arg_count, \ + const gles2::name& args); \ + + GLES2_COMMAND_LIST(GLES2_CMD_OP) + + #undef GLES2_CMD_OP + + // Current GL error bits. + uint32 error_bits_; + + // Map of client ids to GL ids. + IdMap id_map_; + + // Util to help with GL. + GLES2Util util_; + + // pack alignment as last set by glPixelStorei + GLint pack_alignment_; + + // unpack alignment as last set by glPixelStorei + GLint unpack_alignment_; + + // The currently bound array buffer. If this is 0 it is illegal to call + // glVertexAttribPointer. + GLuint bound_array_buffer_; + + // The currently bound element array buffer. If this is 0 it is illegal + // to call glDrawElements. + GLuint bound_element_array_buffer_; + +#if defined(OS_WIN) + HDC device_context_; + HGLRC gl_context_; +#endif + + bool anti_aliased_; + + DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl); +}; + +GLES2Decoder* GLES2Decoder::Create() { + return new GLES2DecoderImpl(); +} + +GLES2DecoderImpl::GLES2DecoderImpl() + : GLES2Decoder(), + error_bits_(0), + util_(0), // TODO(gman): Set to actual num compress texture formats. + pack_alignment_(4), + unpack_alignment_(4), + bound_array_buffer_(0), + bound_element_array_buffer_(0), +#ifdef OS_WIN + device_context_(NULL), + gl_context_(NULL), +#endif + anti_aliased_(false) { +} + +bool GLES2DecoderImpl::Initialize() { + if (!InitPlatformSpecific()) + return false; + if (!InitGlew()) + return false; + CHECK_GL_ERROR(); + + //glBindFramebuffer(0, 0); + return true; +} + +#if defined(OS_WIN) +namespace { + +const PIXELFORMATDESCRIPTOR kPixelFormatDescriptor = { + sizeof(kPixelFormatDescriptor), // Size of structure. + 1, // Default version. + PFD_DRAW_TO_WINDOW | // Window drawing support. + PFD_SUPPORT_OPENGL | // OpenGL support. + PFD_DOUBLEBUFFER, // Double buffering support (not stereo). + PFD_TYPE_RGBA, // RGBA color mode (not indexed). + 24, // 24 bit color mode. + 0, 0, 0, 0, 0, 0, // Don't set RGB bits & shifts. + 8, 0, // 8 bit alpha + 0, // No accumulation buffer. + 0, 0, 0, 0, // Ignore accumulation bits. + 24, // 24 bit z-buffer size. + 8, // 8-bit stencil buffer. + 0, // No aux buffer. + PFD_MAIN_PLANE, // Main drawing plane (not overlay). + 0, // Reserved. + 0, 0, 0, // Layer masks ignored. +}; + +LRESULT CALLBACK IntermediateWindowProc(HWND window, + UINT message, + WPARAM w_param, + LPARAM l_param) { + return ::DefWindowProc(window, message, w_param, l_param); +} + +// Helper routine that returns the highest quality pixel format supported on +// the current platform. Returns true upon success. +bool GetWindowsPixelFormat(HWND window, + bool anti_aliased, + int* pixel_format) { + // We must initialize a GL context before we can determine the multi-sampling + // supported on the current hardware, so we create an intermediate window + // and context here. + HINSTANCE module_handle; + if (!::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT | + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, + reinterpret_cast<wchar_t*>(IntermediateWindowProc), + &module_handle)) { + return false; + } + + WNDCLASS intermediate_class; + intermediate_class.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; + intermediate_class.lpfnWndProc = IntermediateWindowProc; + intermediate_class.cbClsExtra = 0; + intermediate_class.cbWndExtra = 0; + intermediate_class.hInstance = module_handle; + intermediate_class.hIcon = LoadIcon(NULL, IDI_APPLICATION); + intermediate_class.hCursor = LoadCursor(NULL, IDC_ARROW); + intermediate_class.hbrBackground = NULL; + intermediate_class.lpszMenuName = NULL; + intermediate_class.lpszClassName = L"Intermediate GL Window"; + + ATOM class_registration = ::RegisterClass(&intermediate_class); + if (!class_registration) { + return false; + } + + HWND intermediate_window = ::CreateWindow( + reinterpret_cast<wchar_t*>(class_registration), + L"", + WS_OVERLAPPEDWINDOW, + 0, 0, + CW_USEDEFAULT, CW_USEDEFAULT, + NULL, + NULL, + NULL, + NULL); + + if (!intermediate_window) { + ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration), + module_handle); + return false; + } + + HDC intermediate_dc = ::GetDC(intermediate_window); + int format_index = ::ChoosePixelFormat(intermediate_dc, + &kPixelFormatDescriptor); + if (format_index == 0) { + DLOG(ERROR) << "Unable to get the pixel format for GL context."; + ::ReleaseDC(intermediate_window, intermediate_dc); + ::DestroyWindow(intermediate_window); + ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration), + module_handle); + return false; + } + if (!::SetPixelFormat(intermediate_dc, format_index, + &kPixelFormatDescriptor)) { + DLOG(ERROR) << "Unable to set the pixel format for GL context."; + ::ReleaseDC(intermediate_window, intermediate_dc); + ::DestroyWindow(intermediate_window); + ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration), + module_handle); + return false; + } + + // Store the pixel format without multisampling. + *pixel_format = format_index; + HGLRC gl_context = ::wglCreateContext(intermediate_dc); + if (::wglMakeCurrent(intermediate_dc, gl_context)) { + // GL context was successfully created and applied to the window's DC. + // Startup GLEW, the GL extensions wrangler. + GLenum glew_error = ::glewInit(); + if (glew_error == GLEW_OK) { + DLOG(INFO) << "Initialized GLEW " << ::glewGetString(GLEW_VERSION); + } else { + DLOG(ERROR) << "Unable to initialise GLEW : " + << ::glewGetErrorString(glew_error); + ::wglMakeCurrent(intermediate_dc, NULL); + ::wglDeleteContext(gl_context); + ::ReleaseDC(intermediate_window, intermediate_dc); + ::DestroyWindow(intermediate_window); + ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration), + module_handle); + return false; + } + + // If the multi-sample extensions are present, query the api to determine + // the pixel format. + if (anti_aliased && WGLEW_ARB_pixel_format && WGLEW_ARB_multisample) { + int pixel_attributes[] = { + WGL_SAMPLES_ARB, 4, + WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, + WGL_SUPPORT_OPENGL_ARB, GL_TRUE, + WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB, + WGL_COLOR_BITS_ARB, 24, + WGL_ALPHA_BITS_ARB, 8, + WGL_DEPTH_BITS_ARB, 24, + WGL_STENCIL_BITS_ARB, 8, + WGL_DOUBLE_BUFFER_ARB, GL_TRUE, + WGL_SAMPLE_BUFFERS_ARB, GL_TRUE, + 0, 0}; + + float pixel_attributes_f[] = {0, 0}; + int msaa_pixel_format; + unsigned int num_formats; + + // Query for the highest sampling rate supported, starting at 4x. + static const int kSampleCount[] = {4, 2}; + static const int kNumSamples = 2; + for (int sample = 0; sample < kNumSamples; ++sample) { + pixel_attributes[1] = kSampleCount[sample]; + if (GL_TRUE == ::wglChoosePixelFormatARB(intermediate_dc, + pixel_attributes, + pixel_attributes_f, + 1, + &msaa_pixel_format, + &num_formats)) { + *pixel_format = msaa_pixel_format; + break; + } + } + } + } + + ::wglMakeCurrent(intermediate_dc, NULL); + ::wglDeleteContext(gl_context); + ::ReleaseDC(intermediate_window, intermediate_dc); + ::DestroyWindow(intermediate_window); + ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration), + module_handle); + return true; +} + +} // anonymous namespace +#endif + +bool GLES2DecoderImpl::InitPlatformSpecific() { +#if defined(OS_WIN) + device_context_ = ::GetDC(hwnd()); + + int pixel_format; + + if (!GetWindowsPixelFormat(hwnd(), + anti_aliased_, + &pixel_format)) { + DLOG(ERROR) << "Unable to determine optimal pixel format for GL context."; + return false; + } + + if (!::SetPixelFormat(device_context_, pixel_format, + &kPixelFormatDescriptor)) { + DLOG(ERROR) << "Unable to set the pixel format for GL context."; + return false; + } + + gl_context_ = ::wglCreateContext(device_context_); + if (!gl_context_) { + DLOG(ERROR) << "Failed to create GL context."; + return false; + } + + if (!::wglMakeCurrent(device_context_, gl_context_)) { + DLOG(ERROR) << "Unable to make gl context current."; + return false; + } +#elif defined(OS_LINUX) + DCHECK(window()); + if (!window()->Initialize()) + return false; + if (!window()->MakeCurrent()) + return false; +#endif + + return true; +} + +bool GLES2DecoderImpl::InitGlew() { + DLOG(INFO) << "Initializing GL and GLEW for GLES2Decoder."; + + GLenum glew_error = glewInit(); + if (glew_error != GLEW_OK) { + DLOG(ERROR) << "Unable to initialise GLEW : " + << ::glewGetErrorString(glew_error); + return false; + } + + // Check to see that we can use the OpenGL vertex attribute APIs + // TODO(petersont): Return false if this check fails, but because some + // Intel hardware does not support OpenGL 2.0, yet does support all of the + // extensions we require, we only log an error. A future CL should change + // this check to ensure that all of the extension strings we require are + // present. + if (!GLEW_VERSION_2_0) { + DLOG(ERROR) << "GL drivers do not have OpenGL 2.0 functionality."; + } + + bool extensions_found = true; + if (!GLEW_ARB_vertex_buffer_object) { + // NOTE: Linux NVidia drivers claim to support OpenGL 2.0 when using + // indirect rendering (e.g. remote X), but it is actually lying. The + // ARB_vertex_buffer_object functions silently no-op (!) when using + // indirect rendering, leading to crashes. Fortunately, in that case, the + // driver claims to not support ARB_vertex_buffer_object, so fail in that + // case. + DLOG(ERROR) << "GL drivers do not support vertex buffer objects."; + extensions_found = false; + } + if (!GLEW_EXT_framebuffer_object) { + DLOG(ERROR) << "GL drivers do not support framebuffer objects."; + extensions_found = false; + } + // Check for necessary extensions + if (!GLEW_VERSION_2_0 && !GLEW_EXT_stencil_two_side) { + DLOG(ERROR) << "Two sided stencil extension missing."; + extensions_found = false; + } + if (!GLEW_VERSION_1_4 && !GLEW_EXT_blend_func_separate) { + DLOG(ERROR) <<"Separate blend func extension missing."; + extensions_found = false; + } + if (!GLEW_VERSION_2_0 && !GLEW_EXT_blend_equation_separate) { + DLOG(ERROR) << "Separate blend function extension missing."; + extensions_found = false; + } + if (!extensions_found) + return false; + + return true; +} + +void GLES2DecoderImpl::Destroy() { +#ifdef OS_LINUX + DCHECK(window()); + window()->Destroy(); +#endif +} + +const char* GLES2DecoderImpl::GetCommandName(unsigned int command_id) const { + if (command_id > kStartPoint && command_id < kNumCommands) { + return gles2::GetCommandName(static_cast<CommandId>(command_id)); + } + return GetCommonCommandName(static_cast<cmd::CommandId>(command_id)); +} + +// Decode command with its arguments, and call the corresponding GL function. +// Note: args is a pointer to the command buffer. As such, it could be changed +// by a (malicious) client at any time, so if validation has to happen, it +// should operate on a copy of them. +parse_error::ParseError GLES2DecoderImpl::DoCommand( + unsigned int command, + unsigned int arg_count, + const void* cmd_data) { + unsigned int command_index = command - kStartPoint - 1; + if (command_index < arraysize(g_command_info)) { + const CommandInfo& info = g_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)) { + switch (command) { + #define GLES2_CMD_OP(name) \ + case name::kCmdId: \ + return Handle ## name( \ + arg_count, \ + *static_cast<const name*>(cmd_data)); \ + + GLES2_COMMAND_LIST(GLES2_CMD_OP) + + #undef GLES2_CMD_OP + } + } else { + return parse_error::kParseInvalidArguments; + } + } + return DoCommonCommand(command, arg_count, cmd_data); +} + +} // namespace gles2 +} // namespace command_buffer + +// This is included so the compiler will make these inline. +#include "gpu/command_buffer/service/gles2_cmd_decoder_validate.h" + +namespace command_buffer { +namespace gles2 { + +void GLES2DecoderImpl::CreateProgramHelper(GLuint client_id) { + // TODO(gman): verify client_id is unused. + GLuint service_id = glCreateProgram(); + if (service_id) { + id_map_.AddMapping(client_id, service_id); + } +} + +void GLES2DecoderImpl::CreateShaderHelper(GLenum type, GLuint client_id) { + // TODO(gman): verify client_id is unused. + GLuint service_id = glCreateShader(type); + if (service_id) { + id_map_.AddMapping(client_id, service_id); + } +} + +void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint buffer) { + switch (target) { + case GL_ARRAY_BUFFER: + bound_array_buffer_ = buffer; + break; + case GL_ELEMENT_ARRAY_BUFFER: + bound_element_array_buffer_ = buffer; + break; + default: + break; + } + glBindBuffer(target, buffer); +} + +void GLES2DecoderImpl::DoDeleteProgram(GLuint program) { + GLuint service_id; + if (id_map_.GetServiceId(program, &service_id)) { + glDeleteProgram(service_id); + id_map_.RemoveMapping(program, service_id); + } +} + +void GLES2DecoderImpl::DoDeleteShader(GLuint shader) { + GLuint service_id; + if (id_map_.GetServiceId(shader, &service_id)) { + glDeleteProgram(service_id); + id_map_.RemoveMapping(shader, service_id); + } +} + +// 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 + ::SwapBuffers(device_context_); +#endif + +#ifdef OS_LINUX + DCHECK(window()); + window()->SwapBuffers(); +#endif +} + +GLenum GLES2DecoderImpl::GetGLError() { + // Check the GL error first, then our wrapped error. + GLenum error = glGetError(); + if (error == GL_NO_ERROR && error_bits_ != 0) { + uint32 mask = 1; + while (mask) { + if ((error_bits_ & mask) != 0) { + error = GLErrorBitToGLError(mask); + break; + } + } + } + + if (error != GL_NO_ERROR) { + // There was an error, clear the corresponding wrapped error. + error_bits_ &= ~GLErrorToErrorBit(error); + } + return error; +} + +void GLES2DecoderImpl::SetGLError(GLenum error) { + error_bits_ |= GLErrorToErrorBit(error); +} + +parse_error::ParseError GLES2DecoderImpl::HandleDrawElements( + unsigned int arg_count, const gles2::DrawElements& c) { + if (bound_element_array_buffer_ != 0) { + GLenum mode = c.mode; + GLsizei count = c.count; + GLenum type = c.type; + const GLvoid* indices = reinterpret_cast<const GLvoid*>(c.index_offset); + glDrawElements(mode, count, type, indices); + } else { + SetGLError(GL_INVALID_VALUE); + } + return parse_error::kParseNoError; +} + +namespace { + +// Calls glShaderSource for the various versions of the ShaderSource command. +// Assumes that data / data_size points to a piece of memory that is in range +// of whatever context it came from (shared memory, immediate memory, bucket +// memory.) +parse_error::ParseError ShaderSourceHelper( + GLuint shader, GLsizei count, const char* data, uint32 data_size) { + std::vector<std::string> strings(count); + scoped_array<const char*> string_pointers(new const char* [count]); + + const uint32* ends = reinterpret_cast<const uint32*>(data); + uint32 start_offset = count * sizeof(*ends); + if (start_offset > data_size) { + return parse_error::kParseOutOfBounds; + } + for (GLsizei ii = 0; ii < count; ++ii) { + uint32 end_offset = ends[ii]; + if (end_offset > data_size || end_offset < start_offset) { + return parse_error::kParseOutOfBounds; + } + strings[ii] = std::string(data + start_offset, end_offset - start_offset); + string_pointers[ii] = strings[ii].c_str(); + } + + glShaderSource(shader, count, string_pointers.get(), NULL); + return parse_error::kParseNoError; +} + +} // anonymous namespace. + +parse_error::ParseError GLES2DecoderImpl::HandleShaderSource( + unsigned int arg_count, const gles2::ShaderSource& c) { + GLuint shader = c.shader; + GLsizei count = c.count; + uint32 data_size = c.data_size; + const char** data = GetSharedMemoryAs<const char**>( + c.data_shm_id, c.data_shm_offset, data_size); + parse_error::ParseError result = + ValidateShaderSource(this, arg_count, shader, count, data, NULL); + if (result != parse_error::kParseNoError) { + return result; + } + return ShaderSourceHelper( + shader, count, reinterpret_cast<const char*>(data), data_size); +} + +parse_error::ParseError GLES2DecoderImpl::HandleShaderSourceImmediate( + unsigned int arg_count, const gles2::ShaderSourceImmediate& c) { + GLuint shader = c.shader; + GLsizei count = c.count; + uint32 data_size = c.data_size; + // TODO(gman): need to check that data_size is in range for arg_count. + const char** data = GetImmediateDataAs<const char**>(c); + parse_error::ParseError result = + ValidateShaderSourceImmediate( + this, arg_count, shader, count, data, NULL); + if (result != parse_error::kParseNoError) { + return result; + } + return ShaderSourceHelper( + shader, count, reinterpret_cast<const char*>(data), data_size); +} + +parse_error::ParseError GLES2DecoderImpl::HandleVertexAttribPointer( + unsigned int arg_count, const gles2::VertexAttribPointer& c) { + if (bound_array_buffer_ != 0) { + GLuint indx = c.indx; + GLint size = c.size; + GLenum type = c.type; + GLboolean normalized = c.normalized; + GLsizei stride = c.stride; + GLuint offset = c.offset; + const void* ptr = reinterpret_cast<const void*>(c.offset); + parse_error::ParseError result = + ValidateVertexAttribPointer( + this, arg_count, indx, size, type, normalized, stride, ptr); + if (result != parse_error::kParseNoError) { + return result; + } + glVertexAttribPointer(indx, size, type, normalized, stride, ptr); + } else { + SetGLError(GL_INVALID_VALUE); + } + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleReadPixels( + unsigned int arg_count, const gles2::ReadPixels& c) { + // TODO(gman): Implement. + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandlePixelStorei( + unsigned int arg_count, const gles2::PixelStorei& c) { + // TODO(gman): Implement. + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGetVertexAttribPointerv( + unsigned int arg_count, const gles2::GetVertexAttribPointerv& c) { + // TODO(gman): Implement. + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGetUniformiv( + unsigned int arg_count, const gles2::GetUniformiv& c) { + // TODO(gman): Implement. + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGetUniformfv( + unsigned int arg_count, const gles2::GetUniformfv& c) { + // TODO(gman): Implement. + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGetShaderPrecisionFormat( + unsigned int arg_count, const gles2::GetShaderPrecisionFormat& c) { + // TODO(gman): Implement. + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGetAttachedShaders( + unsigned int arg_count, const gles2::GetAttachedShaders& c) { + // TODO(gman): Implement. + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGetActiveUniform( + unsigned int arg_count, const gles2::GetActiveUniform& c) { + // TODO(gman): Implement. + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGetActiveAttrib( + unsigned int arg_count, const gles2::GetActiveAttrib& c) { + // TODO(gman): Implement. + return parse_error::kParseNoError; +} + +// Include the auto-generated part of this file. We split this because it means +// we can easily edit the non-auto generated parts right here in this file +// instead of having to edit some template or the code generator. +#include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" + +} // namespace gles2 +} // namespace command_buffer + diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.h b/gpu/command_buffer/service/gles2_cmd_decoder.h new file mode 100644 index 0000000..10387c6 --- /dev/null +++ b/gpu/command_buffer/service/gles2_cmd_decoder.h @@ -0,0 +1,74 @@ +// Copyright (c) 2006-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 contains the GLES2Decoder class. + +#ifndef O3D_COMMAND_BUFFER_SERVICE_CROSS_GLES2_CMD_DECODER_H +#define O3D_COMMAND_BUFFER_SERVICE_CROSS_GLES2_CMD_DECODER_H + +#include <build/build_config.h> +#ifdef OS_WIN +#include <windows.h> +#endif +#include "gpu/command_buffer/service/common_decoder.h" + +namespace command_buffer { +namespace gles2 { + +// This class implements the AsyncAPIInterface interface, decoding GLES2 +// commands and calling GL. +class GLES2Decoder : public CommonDecoder { + public: + typedef parse_error::ParseError ParseError; + + // Creates a decoder. + static GLES2Decoder* Create(); + + virtual ~GLES2Decoder() { + } + +#if defined(OS_LINUX) + void set_window_wrapper(XWindowWrapper *window) { + window_ = window; + } + XWindowWrapper* window() const { + return window_; + } +#elif defined(OS_WIN) + void set_hwnd(HWND hwnd) { + hwnd_ = hwnd; + } + + HWND hwnd() const { + return hwnd_; + } +#endif + + // Initializes the graphics context. + // Returns: + // true if successful. + virtual bool Initialize() = 0; + + // Destroys the graphics context. + virtual void Destroy() = 0; + + protected: + GLES2Decoder(); + + private: +#if defined(OS_LINUX) + XWindowWrapper *window_; +#elif defined(OS_WIN) + // Handle to the GL device. + HWND hwnd_; +#endif + + DISALLOW_COPY_AND_ASSIGN(GLES2Decoder); +}; + +} // namespace gles2 +} // namespace command_buffer + +#endif // O3D_COMMAND_BUFFER_SERVICE_CROSS_GLES2_CMD_DECODER_H + diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h new file mode 100644 index 0000000..1a247fd --- /dev/null +++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h @@ -0,0 +1,2610 @@ +// This file is auto-generated. DO NOT EDIT! + +// It is included by gles2_cmd_decoder.cc + +parse_error::ParseError GLES2DecoderImpl::HandleActiveTexture( + unsigned int arg_count, const gles2::ActiveTexture& c) { + GLenum texture = static_cast<GLenum>(c.texture); + parse_error::ParseError result = + ValidateActiveTexture(this, arg_count, texture); + if (result != parse_error::kParseNoError) { + return result; + } + glActiveTexture(texture); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleAttachShader( + unsigned int arg_count, const gles2::AttachShader& c) { + GLuint program; + if (!id_map_.GetServiceId(c.program, &program)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + GLuint shader; + if (!id_map_.GetServiceId(c.shader, &shader)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + parse_error::ParseError result = + ValidateAttachShader(this, arg_count, program, shader); + if (result != parse_error::kParseNoError) { + return result; + } + glAttachShader(program, shader); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleBindAttribLocation( + unsigned int arg_count, const gles2::BindAttribLocation& c) { + GLuint program; + if (!id_map_.GetServiceId(c.program, &program)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + GLuint index = static_cast<GLuint>(c.index); + uint32 name_size = c.data_size; + const char* name = GetSharedMemoryAs<const char*>( + c.name_shm_id, c.name_shm_offset, name_size); + parse_error::ParseError result = + ValidateBindAttribLocation(this, arg_count, program, index, name); + if (result != parse_error::kParseNoError) { + return result; + } + String name_str(name, name_size); + glBindAttribLocation(program, index, name_str.c_str()); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleBindAttribLocationImmediate( + unsigned int arg_count, const gles2::BindAttribLocationImmediate& c) { + GLuint program; + if (!id_map_.GetServiceId(c.program, &program)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + GLuint index = static_cast<GLuint>(c.index); + uint32 name_size = c.data_size; + const char* name = GetImmediateDataAs<const char*>(c); + // TODO(gman): Make sure validate checks arg_count + // covers data_size. + parse_error::ParseError result = + ValidateBindAttribLocationImmediate( + this, arg_count, program, index, name); + if (result != parse_error::kParseNoError) { + return result; + } + String name_str(name, name_size); + glBindAttribLocation(program, index, name_str.c_str()); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleBindBuffer( + unsigned int arg_count, const gles2::BindBuffer& c) { + GLenum target = static_cast<GLenum>(c.target); + GLuint buffer; + if (!id_map_.GetServiceId(c.buffer, &buffer)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + parse_error::ParseError result = + ValidateBindBuffer(this, arg_count, target, buffer); + if (result != parse_error::kParseNoError) { + return result; + } + DoBindBuffer(target, buffer); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleBindFramebuffer( + unsigned int arg_count, const gles2::BindFramebuffer& c) { + GLenum target = static_cast<GLenum>(c.target); + GLuint framebuffer; + if (!id_map_.GetServiceId(c.framebuffer, &framebuffer)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + parse_error::ParseError result = + ValidateBindFramebuffer(this, arg_count, target, framebuffer); + if (result != parse_error::kParseNoError) { + return result; + } + glBindFramebufferEXT(target, framebuffer); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleBindRenderbuffer( + unsigned int arg_count, const gles2::BindRenderbuffer& c) { + GLenum target = static_cast<GLenum>(c.target); + GLuint renderbuffer; + if (!id_map_.GetServiceId(c.renderbuffer, &renderbuffer)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + parse_error::ParseError result = + ValidateBindRenderbuffer(this, arg_count, target, renderbuffer); + if (result != parse_error::kParseNoError) { + return result; + } + glBindRenderbufferEXT(target, renderbuffer); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleBindTexture( + unsigned int arg_count, const gles2::BindTexture& c) { + GLenum target = static_cast<GLenum>(c.target); + GLuint texture; + if (!id_map_.GetServiceId(c.texture, &texture)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + parse_error::ParseError result = + ValidateBindTexture(this, arg_count, target, texture); + if (result != parse_error::kParseNoError) { + return result; + } + glBindTexture(target, texture); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleBlendColor( + unsigned int arg_count, const gles2::BlendColor& c) { + GLclampf red = static_cast<GLclampf>(c.red); + GLclampf green = static_cast<GLclampf>(c.green); + GLclampf blue = static_cast<GLclampf>(c.blue); + GLclampf alpha = static_cast<GLclampf>(c.alpha); + parse_error::ParseError result = + ValidateBlendColor(this, arg_count, red, green, blue, alpha); + if (result != parse_error::kParseNoError) { + return result; + } + glBlendColor(red, green, blue, alpha); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleBlendEquation( + unsigned int arg_count, const gles2::BlendEquation& c) { + GLenum mode = static_cast<GLenum>(c.mode); + parse_error::ParseError result = + ValidateBlendEquation(this, arg_count, mode); + if (result != parse_error::kParseNoError) { + return result; + } + glBlendEquation(mode); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleBlendEquationSeparate( + unsigned int arg_count, const gles2::BlendEquationSeparate& c) { + GLenum modeRGB = static_cast<GLenum>(c.modeRGB); + GLenum modeAlpha = static_cast<GLenum>(c.modeAlpha); + parse_error::ParseError result = + ValidateBlendEquationSeparate(this, arg_count, modeRGB, modeAlpha); + if (result != parse_error::kParseNoError) { + return result; + } + glBlendEquationSeparate(modeRGB, modeAlpha); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleBlendFunc( + unsigned int arg_count, const gles2::BlendFunc& c) { + GLenum sfactor = static_cast<GLenum>(c.sfactor); + GLenum dfactor = static_cast<GLenum>(c.dfactor); + parse_error::ParseError result = + ValidateBlendFunc(this, arg_count, sfactor, dfactor); + if (result != parse_error::kParseNoError) { + return result; + } + glBlendFunc(sfactor, dfactor); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleBlendFuncSeparate( + unsigned int arg_count, const gles2::BlendFuncSeparate& c) { + GLenum srcRGB = static_cast<GLenum>(c.srcRGB); + GLenum dstRGB = static_cast<GLenum>(c.dstRGB); + GLenum srcAlpha = static_cast<GLenum>(c.srcAlpha); + GLenum dstAlpha = static_cast<GLenum>(c.dstAlpha); + parse_error::ParseError result = + ValidateBlendFuncSeparate( + this, arg_count, srcRGB, dstRGB, srcAlpha, dstAlpha); + if (result != parse_error::kParseNoError) { + return result; + } + glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleBufferData( + unsigned int arg_count, const gles2::BufferData& c) { + 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); + uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset); + GLenum usage = static_cast<GLenum>(c.usage); + uint32 data_size = size; + const void* data = GetSharedMemoryAs<const void*>( + data_shm_id, data_shm_offset, data_size); + parse_error::ParseError result = + ValidateBufferData(this, arg_count, target, size, data, usage); + if (result != parse_error::kParseNoError) { + return result; + } + glBufferData(target, size, data, usage); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleBufferDataImmediate( + unsigned int arg_count, const gles2::BufferDataImmediate& c) { + GLenum target = static_cast<GLenum>(c.target); + GLsizeiptr size = static_cast<GLsizeiptr>(c.size); + const void* data = GetImmediateDataAs<const void*>(c); + GLenum usage = static_cast<GLenum>(c.usage); + // Immediate version. + parse_error::ParseError result = + ValidateBufferDataImmediate(this, arg_count, target, size, data, usage); + if (result != parse_error::kParseNoError) { + return result; + } + glBufferData(target, size, data, usage); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleBufferSubData( + unsigned int arg_count, const gles2::BufferSubData& c) { + GLenum target = static_cast<GLenum>(c.target); + GLintptr offset = static_cast<GLintptr>(c.offset); + GLsizeiptr size = static_cast<GLsizeiptr>(c.size); + uint32 data_shm_id = static_cast<uint32>(c.data_shm_id); + uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset); + uint32 data_size = size; + const void* data = GetSharedMemoryAs<const void*>( + data_shm_id, data_shm_offset, data_size); + parse_error::ParseError result = + ValidateBufferSubData(this, arg_count, target, offset, size, data); + if (result != parse_error::kParseNoError) { + return result; + } + glBufferSubData(target, offset, size, data); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleBufferSubDataImmediate( + unsigned int arg_count, const gles2::BufferSubDataImmediate& c) { + GLenum target = static_cast<GLenum>(c.target); + GLintptr offset = static_cast<GLintptr>(c.offset); + GLsizeiptr size = static_cast<GLsizeiptr>(c.size); + const void* data = GetImmediateDataAs<const void*>(c); + // Immediate version. + parse_error::ParseError result = + ValidateBufferSubDataImmediate( + this, arg_count, target, offset, size, data); + if (result != parse_error::kParseNoError) { + return result; + } + glBufferSubData(target, offset, size, data); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleCheckFramebufferStatus( + unsigned int arg_count, const gles2::CheckFramebufferStatus& c) { + GLenum target = static_cast<GLenum>(c.target); + parse_error::ParseError result = + ValidateCheckFramebufferStatus(this, arg_count, target); + if (result != parse_error::kParseNoError) { + return result; + } + glCheckFramebufferStatusEXT(target); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleClear( + unsigned int arg_count, const gles2::Clear& c) { + GLbitfield mask = static_cast<GLbitfield>(c.mask); + parse_error::ParseError result = + ValidateClear(this, arg_count, mask); + if (result != parse_error::kParseNoError) { + return result; + } + glClear(mask); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleClearColor( + unsigned int arg_count, const gles2::ClearColor& c) { + GLclampf red = static_cast<GLclampf>(c.red); + GLclampf green = static_cast<GLclampf>(c.green); + GLclampf blue = static_cast<GLclampf>(c.blue); + GLclampf alpha = static_cast<GLclampf>(c.alpha); + parse_error::ParseError result = + ValidateClearColor(this, arg_count, red, green, blue, alpha); + if (result != parse_error::kParseNoError) { + return result; + } + glClearColor(red, green, blue, alpha); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleClearDepthf( + unsigned int arg_count, const gles2::ClearDepthf& c) { + GLclampf depth = static_cast<GLclampf>(c.depth); + parse_error::ParseError result = + ValidateClearDepthf(this, arg_count, depth); + if (result != parse_error::kParseNoError) { + return result; + } + glClearDepth(depth); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleClearStencil( + unsigned int arg_count, const gles2::ClearStencil& c) { + GLint s = static_cast<GLint>(c.s); + parse_error::ParseError result = + ValidateClearStencil(this, arg_count, s); + if (result != parse_error::kParseNoError) { + return result; + } + glClearStencil(s); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleColorMask( + unsigned int arg_count, const gles2::ColorMask& c) { + GLboolean red = static_cast<GLboolean>(c.red); + GLboolean green = static_cast<GLboolean>(c.green); + GLboolean blue = static_cast<GLboolean>(c.blue); + GLboolean alpha = static_cast<GLboolean>(c.alpha); + parse_error::ParseError result = + ValidateColorMask(this, arg_count, red, green, blue, alpha); + if (result != parse_error::kParseNoError) { + return result; + } + glColorMask(red, green, blue, alpha); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleCompileShader( + unsigned int arg_count, const gles2::CompileShader& c) { + GLuint shader; + if (!id_map_.GetServiceId(c.shader, &shader)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + parse_error::ParseError result = + ValidateCompileShader(this, arg_count, shader); + if (result != parse_error::kParseNoError) { + return result; + } + glCompileShader(shader); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleCompressedTexImage2D( + unsigned int arg_count, const gles2::CompressedTexImage2D& c) { + GLenum target = static_cast<GLenum>(c.target); + GLint level = static_cast<GLint>(c.level); + GLenum internalformat = static_cast<GLenum>(c.internalformat); + GLsizei width = static_cast<GLsizei>(c.width); + GLsizei height = static_cast<GLsizei>(c.height); + GLint border = static_cast<GLint>(c.border); + GLsizei imageSize = static_cast<GLsizei>(c.imageSize); + uint32 data_shm_id = static_cast<uint32>(c.data_shm_id); + uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset); + uint32 data_size = imageSize; + const void* data = GetSharedMemoryAs<const void*>( + data_shm_id, data_shm_offset, data_size); + parse_error::ParseError result = + ValidateCompressedTexImage2D( + this, arg_count, target, level, internalformat, width, height, border, + imageSize, data); + if (result != parse_error::kParseNoError) { + return result; + } + glCompressedTexImage2D( + target, level, internalformat, width, height, border, imageSize, data); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleCompressedTexImage2DImmediate( + unsigned int arg_count, const gles2::CompressedTexImage2DImmediate& c) { + GLenum target = static_cast<GLenum>(c.target); + GLint level = static_cast<GLint>(c.level); + GLenum internalformat = static_cast<GLenum>(c.internalformat); + GLsizei width = static_cast<GLsizei>(c.width); + GLsizei height = static_cast<GLsizei>(c.height); + GLint border = static_cast<GLint>(c.border); + GLsizei imageSize = static_cast<GLsizei>(c.imageSize); + const void* data = GetImmediateDataAs<const void*>(c); + // Immediate version. + parse_error::ParseError result = + ValidateCompressedTexImage2DImmediate( + this, arg_count, target, level, internalformat, width, height, border, + imageSize, data); + if (result != parse_error::kParseNoError) { + return result; + } + glCompressedTexImage2D( + target, level, internalformat, width, height, border, imageSize, data); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleCompressedTexSubImage2D( + unsigned int arg_count, const gles2::CompressedTexSubImage2D& c) { + GLenum target = static_cast<GLenum>(c.target); + GLint level = static_cast<GLint>(c.level); + GLint xoffset = static_cast<GLint>(c.xoffset); + GLint yoffset = static_cast<GLint>(c.yoffset); + GLsizei width = static_cast<GLsizei>(c.width); + GLsizei height = static_cast<GLsizei>(c.height); + GLenum format = static_cast<GLenum>(c.format); + GLsizei imageSize = static_cast<GLsizei>(c.imageSize); + uint32 data_shm_id = static_cast<uint32>(c.data_shm_id); + uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset); + uint32 data_size = imageSize; + const void* data = GetSharedMemoryAs<const void*>( + data_shm_id, data_shm_offset, data_size); + parse_error::ParseError result = + ValidateCompressedTexSubImage2D( + this, arg_count, target, level, xoffset, yoffset, width, height, + format, imageSize, data); + if (result != parse_error::kParseNoError) { + return result; + } + glCompressedTexSubImage2D( + target, level, xoffset, yoffset, width, height, format, imageSize, data); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleCompressedTexSubImage2DImmediate( + + unsigned int arg_count, const gles2::CompressedTexSubImage2DImmediate& c) { + GLenum target = static_cast<GLenum>(c.target); + GLint level = static_cast<GLint>(c.level); + GLint xoffset = static_cast<GLint>(c.xoffset); + GLint yoffset = static_cast<GLint>(c.yoffset); + GLsizei width = static_cast<GLsizei>(c.width); + GLsizei height = static_cast<GLsizei>(c.height); + GLenum format = static_cast<GLenum>(c.format); + GLsizei imageSize = static_cast<GLsizei>(c.imageSize); + const void* data = GetImmediateDataAs<const void*>(c); + // Immediate version. + parse_error::ParseError result = + ValidateCompressedTexSubImage2DImmediate( + this, arg_count, target, level, xoffset, yoffset, width, height, + format, imageSize, data); + if (result != parse_error::kParseNoError) { + return result; + } + glCompressedTexSubImage2D( + target, level, xoffset, yoffset, width, height, format, imageSize, data); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleCopyTexImage2D( + unsigned int arg_count, const gles2::CopyTexImage2D& c) { + GLenum target = static_cast<GLenum>(c.target); + GLint level = static_cast<GLint>(c.level); + GLenum internalformat = static_cast<GLenum>(c.internalformat); + GLint x = static_cast<GLint>(c.x); + GLint y = static_cast<GLint>(c.y); + GLsizei width = static_cast<GLsizei>(c.width); + GLsizei height = static_cast<GLsizei>(c.height); + GLint border = static_cast<GLint>(c.border); + parse_error::ParseError result = + ValidateCopyTexImage2D( + this, arg_count, target, level, internalformat, x, y, width, height, + border); + if (result != parse_error::kParseNoError) { + return result; + } + glCopyTexImage2D(target, level, internalformat, x, y, width, height, border); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleCopyTexSubImage2D( + unsigned int arg_count, const gles2::CopyTexSubImage2D& c) { + GLenum target = static_cast<GLenum>(c.target); + GLint level = static_cast<GLint>(c.level); + GLint xoffset = static_cast<GLint>(c.xoffset); + GLint yoffset = static_cast<GLint>(c.yoffset); + GLint x = static_cast<GLint>(c.x); + GLint y = static_cast<GLint>(c.y); + GLsizei width = static_cast<GLsizei>(c.width); + GLsizei height = static_cast<GLsizei>(c.height); + parse_error::ParseError result = + ValidateCopyTexSubImage2D( + this, arg_count, target, level, xoffset, yoffset, x, y, width, + height); + if (result != parse_error::kParseNoError) { + return result; + } + glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleCreateProgram( + unsigned int arg_count, const gles2::CreateProgram& c) { + uint32 client_id = c.client_id; + parse_error::ParseError result = + ValidateCreateProgram(this, arg_count); + if (result != parse_error::kParseNoError) { + return result; + } + CreateProgramHelper(client_id); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleCreateShader( + unsigned int arg_count, const gles2::CreateShader& c) { + GLenum type = static_cast<GLenum>(c.type); + uint32 client_id = c.client_id; + parse_error::ParseError result = + ValidateCreateShader(this, arg_count, type); + if (result != parse_error::kParseNoError) { + return result; + } + CreateShaderHelper(type, client_id); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleCullFace( + unsigned int arg_count, const gles2::CullFace& c) { + GLenum mode = static_cast<GLenum>(c.mode); + parse_error::ParseError result = + ValidateCullFace(this, arg_count, mode); + if (result != parse_error::kParseNoError) { + return result; + } + glCullFace(mode); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleDeleteBuffers( + unsigned int arg_count, const gles2::DeleteBuffers& c) { + GLsizei n = static_cast<GLsizei>(c.n); + const GLuint* buffers = GetSharedMemoryAs<const GLuint*>( + c.buffers_shm_id, c.buffers_shm_offset, 0 /* TODO(gman): size */); + parse_error::ParseError result = + ValidateDeleteBuffers(this, arg_count, n, buffers); + if (result != parse_error::kParseNoError) { + return result; + } + DeleteGLObjects<GLDeleteBuffersHelper>(n, buffers); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleDeleteBuffersImmediate( + unsigned int arg_count, const gles2::DeleteBuffersImmediate& c) { + GLsizei n = static_cast<GLsizei>(c.n); + const GLuint* buffers = GetImmediateDataAs<const GLuint*>(c); + parse_error::ParseError result = + ValidateDeleteBuffersImmediate(this, arg_count, n, buffers); + if (result != parse_error::kParseNoError) { + return result; + } + DeleteGLObjects<GLDeleteBuffersHelper>(n, buffers); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleDeleteFramebuffers( + unsigned int arg_count, const gles2::DeleteFramebuffers& c) { + GLsizei n = static_cast<GLsizei>(c.n); + const GLuint* framebuffers = GetSharedMemoryAs<const GLuint*>( + c.framebuffers_shm_id, c.framebuffers_shm_offset, 0 /* TODO( + gman): size */); + parse_error::ParseError result = + ValidateDeleteFramebuffers(this, arg_count, n, framebuffers); + if (result != parse_error::kParseNoError) { + return result; + } + DeleteGLObjects<GLDeleteFramebuffersHelper>(n, framebuffers); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleDeleteFramebuffersImmediate( + unsigned int arg_count, const gles2::DeleteFramebuffersImmediate& c) { + GLsizei n = static_cast<GLsizei>(c.n); + const GLuint* framebuffers = GetImmediateDataAs<const GLuint*>(c); + parse_error::ParseError result = + ValidateDeleteFramebuffersImmediate(this, arg_count, n, framebuffers); + if (result != parse_error::kParseNoError) { + return result; + } + DeleteGLObjects<GLDeleteFramebuffersHelper>(n, framebuffers); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleDeleteProgram( + unsigned int arg_count, const gles2::DeleteProgram& c) { + GLuint program; + if (!id_map_.GetServiceId(c.program, &program)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + parse_error::ParseError result = + ValidateDeleteProgram(this, arg_count, program); + if (result != parse_error::kParseNoError) { + return result; + } + DoDeleteProgram(program); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleDeleteRenderbuffers( + unsigned int arg_count, const gles2::DeleteRenderbuffers& c) { + GLsizei n = static_cast<GLsizei>(c.n); + const GLuint* renderbuffers = GetSharedMemoryAs<const GLuint*>( + c.renderbuffers_shm_id, c.renderbuffers_shm_offset, 0 /* TODO( + gman): size */); + parse_error::ParseError result = + ValidateDeleteRenderbuffers(this, arg_count, n, renderbuffers); + if (result != parse_error::kParseNoError) { + return result; + } + DeleteGLObjects<GLDeleteRenderbuffersHelper>(n, renderbuffers); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleDeleteRenderbuffersImmediate( + unsigned int arg_count, const gles2::DeleteRenderbuffersImmediate& c) { + GLsizei n = static_cast<GLsizei>(c.n); + const GLuint* renderbuffers = GetImmediateDataAs<const GLuint*>(c); + parse_error::ParseError result = + ValidateDeleteRenderbuffersImmediate(this, arg_count, n, renderbuffers); + if (result != parse_error::kParseNoError) { + return result; + } + DeleteGLObjects<GLDeleteRenderbuffersHelper>(n, renderbuffers); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleDeleteShader( + unsigned int arg_count, const gles2::DeleteShader& c) { + GLuint shader; + if (!id_map_.GetServiceId(c.shader, &shader)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + parse_error::ParseError result = + ValidateDeleteShader(this, arg_count, shader); + if (result != parse_error::kParseNoError) { + return result; + } + DoDeleteShader(shader); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleDeleteTextures( + unsigned int arg_count, const gles2::DeleteTextures& c) { + GLsizei n = static_cast<GLsizei>(c.n); + const GLuint* textures = GetSharedMemoryAs<const GLuint*>( + c.textures_shm_id, c.textures_shm_offset, 0 /* TODO(gman): size */); + parse_error::ParseError result = + ValidateDeleteTextures(this, arg_count, n, textures); + if (result != parse_error::kParseNoError) { + return result; + } + DeleteGLObjects<GLDeleteTexturesHelper>(n, textures); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleDeleteTexturesImmediate( + unsigned int arg_count, const gles2::DeleteTexturesImmediate& c) { + GLsizei n = static_cast<GLsizei>(c.n); + const GLuint* textures = GetImmediateDataAs<const GLuint*>(c); + parse_error::ParseError result = + ValidateDeleteTexturesImmediate(this, arg_count, n, textures); + if (result != parse_error::kParseNoError) { + return result; + } + DeleteGLObjects<GLDeleteTexturesHelper>(n, textures); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleDepthFunc( + unsigned int arg_count, const gles2::DepthFunc& c) { + GLenum func = static_cast<GLenum>(c.func); + parse_error::ParseError result = + ValidateDepthFunc(this, arg_count, func); + if (result != parse_error::kParseNoError) { + return result; + } + glDepthFunc(func); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleDepthMask( + unsigned int arg_count, const gles2::DepthMask& c) { + GLboolean flag = static_cast<GLboolean>(c.flag); + parse_error::ParseError result = + ValidateDepthMask(this, arg_count, flag); + if (result != parse_error::kParseNoError) { + return result; + } + glDepthMask(flag); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleDepthRangef( + unsigned int arg_count, const gles2::DepthRangef& c) { + GLclampf zNear = static_cast<GLclampf>(c.zNear); + GLclampf zFar = static_cast<GLclampf>(c.zFar); + parse_error::ParseError result = + ValidateDepthRangef(this, arg_count, zNear, zFar); + if (result != parse_error::kParseNoError) { + return result; + } + glDepthRange(zNear, zFar); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleDetachShader( + unsigned int arg_count, const gles2::DetachShader& c) { + GLuint program; + if (!id_map_.GetServiceId(c.program, &program)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + GLuint shader; + if (!id_map_.GetServiceId(c.shader, &shader)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + parse_error::ParseError result = + ValidateDetachShader(this, arg_count, program, shader); + if (result != parse_error::kParseNoError) { + return result; + } + glDetachShader(program, shader); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleDisable( + unsigned int arg_count, const gles2::Disable& c) { + GLenum cap = static_cast<GLenum>(c.cap); + parse_error::ParseError result = + ValidateDisable(this, arg_count, cap); + if (result != parse_error::kParseNoError) { + return result; + } + glDisable(cap); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleDisableVertexAttribArray( + unsigned int arg_count, const gles2::DisableVertexAttribArray& c) { + GLuint index = static_cast<GLuint>(c.index); + parse_error::ParseError result = + ValidateDisableVertexAttribArray(this, arg_count, index); + if (result != parse_error::kParseNoError) { + return result; + } + glDisableVertexAttribArray(index); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleDrawArrays( + unsigned int arg_count, const gles2::DrawArrays& c) { + GLenum mode = static_cast<GLenum>(c.mode); + GLint first = static_cast<GLint>(c.first); + GLsizei count = static_cast<GLsizei>(c.count); + parse_error::ParseError result = + ValidateDrawArrays(this, arg_count, mode, first, count); + if (result != parse_error::kParseNoError) { + return result; + } + glDrawArrays(mode, first, count); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleEnable( + unsigned int arg_count, const gles2::Enable& c) { + GLenum cap = static_cast<GLenum>(c.cap); + parse_error::ParseError result = + ValidateEnable(this, arg_count, cap); + if (result != parse_error::kParseNoError) { + return result; + } + glEnable(cap); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleEnableVertexAttribArray( + unsigned int arg_count, const gles2::EnableVertexAttribArray& c) { + GLuint index = static_cast<GLuint>(c.index); + parse_error::ParseError result = + ValidateEnableVertexAttribArray(this, arg_count, index); + if (result != parse_error::kParseNoError) { + return result; + } + glEnableVertexAttribArray(index); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleFinish( + unsigned int arg_count, const gles2::Finish& c) { + parse_error::ParseError result = + ValidateFinish(this, arg_count); + if (result != parse_error::kParseNoError) { + return result; + } + glFinish(); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleFlush( + unsigned int arg_count, const gles2::Flush& c) { + parse_error::ParseError result = + ValidateFlush(this, arg_count); + if (result != parse_error::kParseNoError) { + return result; + } + glFlush(); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleFramebufferRenderbuffer( + unsigned int arg_count, const gles2::FramebufferRenderbuffer& c) { + GLenum target = static_cast<GLenum>(c.target); + GLenum attachment = static_cast<GLenum>(c.attachment); + GLenum renderbuffertarget = static_cast<GLenum>(c.renderbuffertarget); + GLuint renderbuffer; + if (!id_map_.GetServiceId(c.renderbuffer, &renderbuffer)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + parse_error::ParseError result = + ValidateFramebufferRenderbuffer( + this, arg_count, target, attachment, renderbuffertarget, + renderbuffer); + if (result != parse_error::kParseNoError) { + return result; + } + glFramebufferRenderbufferEXT( + target, attachment, renderbuffertarget, renderbuffer); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleFramebufferTexture2D( + unsigned int arg_count, const gles2::FramebufferTexture2D& c) { + GLenum target = static_cast<GLenum>(c.target); + GLenum attachment = static_cast<GLenum>(c.attachment); + GLenum textarget = static_cast<GLenum>(c.textarget); + GLuint texture; + if (!id_map_.GetServiceId(c.texture, &texture)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + GLint level = static_cast<GLint>(c.level); + parse_error::ParseError result = + ValidateFramebufferTexture2D( + this, arg_count, target, attachment, textarget, texture, level); + if (result != parse_error::kParseNoError) { + return result; + } + glFramebufferTexture2DEXT(target, attachment, textarget, texture, level); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleFrontFace( + unsigned int arg_count, const gles2::FrontFace& c) { + GLenum mode = static_cast<GLenum>(c.mode); + parse_error::ParseError result = + ValidateFrontFace(this, arg_count, mode); + if (result != parse_error::kParseNoError) { + return result; + } + glFrontFace(mode); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGenBuffers( + unsigned int arg_count, const gles2::GenBuffers& c) { + GLsizei n = static_cast<GLsizei>(c.n); + GLuint* buffers = GetSharedMemoryAs<GLuint*>( + c.buffers_shm_id, c.buffers_shm_offset, 0 /* TODO(gman): size */); + parse_error::ParseError result = + ValidateGenBuffers(this, arg_count, n, buffers); + if (result != parse_error::kParseNoError) { + return result; + } + GenGLObjects<GLGenBuffersHelper>(n, buffers); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGenBuffersImmediate( + unsigned int arg_count, const gles2::GenBuffersImmediate& c) { + GLsizei n = static_cast<GLsizei>(c.n); + GLuint* buffers = GetImmediateDataAs<GLuint*>(c); + parse_error::ParseError result = + ValidateGenBuffersImmediate(this, arg_count, n, buffers); + if (result != parse_error::kParseNoError) { + return result; + } + GenGLObjects<GLGenBuffersHelper>(n, buffers); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGenerateMipmap( + unsigned int arg_count, const gles2::GenerateMipmap& c) { + GLenum target = static_cast<GLenum>(c.target); + parse_error::ParseError result = + ValidateGenerateMipmap(this, arg_count, target); + if (result != parse_error::kParseNoError) { + return result; + } + glGenerateMipmapEXT(target); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGenFramebuffers( + unsigned int arg_count, const gles2::GenFramebuffers& c) { + GLsizei n = static_cast<GLsizei>(c.n); + GLuint* framebuffers = GetSharedMemoryAs<GLuint*>( + c.framebuffers_shm_id, c.framebuffers_shm_offset, 0 /* TODO( + gman): size */); + parse_error::ParseError result = + ValidateGenFramebuffers(this, arg_count, n, framebuffers); + if (result != parse_error::kParseNoError) { + return result; + } + GenGLObjects<GLGenFramebuffersHelper>(n, framebuffers); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGenFramebuffersImmediate( + unsigned int arg_count, const gles2::GenFramebuffersImmediate& c) { + GLsizei n = static_cast<GLsizei>(c.n); + GLuint* framebuffers = GetImmediateDataAs<GLuint*>(c); + parse_error::ParseError result = + ValidateGenFramebuffersImmediate(this, arg_count, n, framebuffers); + if (result != parse_error::kParseNoError) { + return result; + } + GenGLObjects<GLGenFramebuffersHelper>(n, framebuffers); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGenRenderbuffers( + unsigned int arg_count, const gles2::GenRenderbuffers& c) { + GLsizei n = static_cast<GLsizei>(c.n); + GLuint* renderbuffers = GetSharedMemoryAs<GLuint*>( + c.renderbuffers_shm_id, c.renderbuffers_shm_offset, 0 /* TODO( + gman): size */); + parse_error::ParseError result = + ValidateGenRenderbuffers(this, arg_count, n, renderbuffers); + if (result != parse_error::kParseNoError) { + return result; + } + GenGLObjects<GLGenRenderbuffersHelper>(n, renderbuffers); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGenRenderbuffersImmediate( + unsigned int arg_count, const gles2::GenRenderbuffersImmediate& c) { + GLsizei n = static_cast<GLsizei>(c.n); + GLuint* renderbuffers = GetImmediateDataAs<GLuint*>(c); + parse_error::ParseError result = + ValidateGenRenderbuffersImmediate(this, arg_count, n, renderbuffers); + if (result != parse_error::kParseNoError) { + return result; + } + GenGLObjects<GLGenRenderbuffersHelper>(n, renderbuffers); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGenTextures( + unsigned int arg_count, const gles2::GenTextures& c) { + GLsizei n = static_cast<GLsizei>(c.n); + GLuint* textures = GetSharedMemoryAs<GLuint*>( + c.textures_shm_id, c.textures_shm_offset, 0 /* TODO(gman): size */); + parse_error::ParseError result = + ValidateGenTextures(this, arg_count, n, textures); + if (result != parse_error::kParseNoError) { + return result; + } + GenGLObjects<GLGenTexturesHelper>(n, textures); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGenTexturesImmediate( + unsigned int arg_count, const gles2::GenTexturesImmediate& c) { + GLsizei n = static_cast<GLsizei>(c.n); + GLuint* textures = GetImmediateDataAs<GLuint*>(c); + parse_error::ParseError result = + ValidateGenTexturesImmediate(this, arg_count, n, textures); + if (result != parse_error::kParseNoError) { + return result; + } + GenGLObjects<GLGenTexturesHelper>(n, textures); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGetAttribLocation( + unsigned int arg_count, const gles2::GetAttribLocation& c) { + GLuint program; + if (!id_map_.GetServiceId(c.program, &program)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + uint32 name_size = c.data_size; + const char* name = GetSharedMemoryAs<const char*>( + c.name_shm_id, c.name_shm_offset, name_size); + parse_error::ParseError result = + ValidateGetAttribLocation(this, arg_count, program, name); + if (result != parse_error::kParseNoError) { + return result; + } + String name_str(name, name_size); + GLint location = glGetAttribLocation(program, name_str.c_str()); + DCHECK(false); // TODO: return result. + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGetAttribLocationImmediate( + unsigned int arg_count, const gles2::GetAttribLocationImmediate& c) { + GLuint program; + if (!id_map_.GetServiceId(c.program, &program)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + uint32 name_size = c.data_size; + const char* name = GetImmediateDataAs<const char*>(c); + // TODO(gman): Make sure validate checks arg_count + // covers data_size. + parse_error::ParseError result = + ValidateGetAttribLocationImmediate(this, arg_count, program, name); + if (result != parse_error::kParseNoError) { + return result; + } + String name_str(name, name_size); + GLint location = glGetAttribLocation(program, name_str.c_str()); + DCHECK(false); // TODO: return result. + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGetBooleanv( + unsigned int arg_count, const gles2::GetBooleanv& c) { + GLenum pname = static_cast<GLenum>(c.pname); + GLboolean* params; + GLsizei num_values = util_.GLGetNumValuesReturned(pname); + uint32 params_size = num_values * sizeof(*params); + params = GetSharedMemoryAs<GLboolean*>( + c.params_shm_id, c.params_shm_offset, params_size); + parse_error::ParseError result = + ValidateGetBooleanv(this, arg_count, pname, params); + if (result != parse_error::kParseNoError) { + return result; + } + glGetBooleanv(pname, params); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGetBufferParameteriv( + unsigned int arg_count, const gles2::GetBufferParameteriv& c) { + GLenum target = static_cast<GLenum>(c.target); + GLenum pname = static_cast<GLenum>(c.pname); + GLint* params; + GLsizei num_values = util_.GLGetNumValuesReturned(pname); + uint32 params_size = num_values * sizeof(*params); + params = GetSharedMemoryAs<GLint*>( + c.params_shm_id, c.params_shm_offset, params_size); + parse_error::ParseError result = + ValidateGetBufferParameteriv(this, arg_count, target, pname, params); + if (result != parse_error::kParseNoError) { + return result; + } + glGetBufferParameteriv(target, pname, params); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGetError( + unsigned int arg_count, const gles2::GetError& c) { + GLenum* result_dst = GetSharedMemoryAs<GLenum*>( + c.result_shm_id, c.result_shm_offset, sizeof(*result_dst)); + parse_error::ParseError result = + ValidateGetError(this, arg_count); + if (result != parse_error::kParseNoError) { + return result; + } + *result_dst = glGetError(); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGetFloatv( + unsigned int arg_count, const gles2::GetFloatv& c) { + GLenum pname = static_cast<GLenum>(c.pname); + GLfloat* params; + GLsizei num_values = util_.GLGetNumValuesReturned(pname); + uint32 params_size = num_values * sizeof(*params); + params = GetSharedMemoryAs<GLfloat*>( + c.params_shm_id, c.params_shm_offset, params_size); + parse_error::ParseError result = + ValidateGetFloatv(this, arg_count, pname, params); + if (result != parse_error::kParseNoError) { + return result; + } + glGetFloatv(pname, params); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGetFramebufferAttachmentParameteriv( + + unsigned int arg_count, + const gles2::GetFramebufferAttachmentParameteriv& c) { + GLenum target = static_cast<GLenum>(c.target); + GLenum attachment = static_cast<GLenum>(c.attachment); + GLenum pname = static_cast<GLenum>(c.pname); + GLint* params; + GLsizei num_values = util_.GLGetNumValuesReturned(pname); + uint32 params_size = num_values * sizeof(*params); + params = GetSharedMemoryAs<GLint*>( + c.params_shm_id, c.params_shm_offset, params_size); + parse_error::ParseError result = + ValidateGetFramebufferAttachmentParameteriv( + this, arg_count, target, attachment, pname, params); + if (result != parse_error::kParseNoError) { + return result; + } + glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, params); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGetIntegerv( + unsigned int arg_count, const gles2::GetIntegerv& c) { + GLenum pname = static_cast<GLenum>(c.pname); + GLint* params; + GLsizei num_values = util_.GLGetNumValuesReturned(pname); + uint32 params_size = num_values * sizeof(*params); + params = GetSharedMemoryAs<GLint*>( + c.params_shm_id, c.params_shm_offset, params_size); + parse_error::ParseError result = + ValidateGetIntegerv(this, arg_count, pname, params); + if (result != parse_error::kParseNoError) { + return result; + } + glGetIntegerv(pname, params); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGetProgramiv( + unsigned int arg_count, const gles2::GetProgramiv& c) { + GLuint program; + if (!id_map_.GetServiceId(c.program, &program)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + GLenum pname = static_cast<GLenum>(c.pname); + GLint* params; + GLsizei num_values = util_.GLGetNumValuesReturned(pname); + uint32 params_size = num_values * sizeof(*params); + params = GetSharedMemoryAs<GLint*>( + c.params_shm_id, c.params_shm_offset, params_size); + parse_error::ParseError result = + ValidateGetProgramiv(this, arg_count, program, pname, params); + if (result != parse_error::kParseNoError) { + return result; + } + glGetProgramiv(program, pname, params); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGetProgramInfoLog( + unsigned int arg_count, const gles2::GetProgramInfoLog& c) { + GLuint program; + if (!id_map_.GetServiceId(c.program, &program)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + GLsizei bufsize = static_cast<GLsizei>(c.bufsize); + GLsizei* length = GetSharedMemoryAs<GLsizei*>( + c.length_shm_id, c.length_shm_offset, 0 /* TODO(gman): size */); + char* infolog = GetSharedMemoryAs<char*>( + c.infolog_shm_id, c.infolog_shm_offset, 0 /* TODO(gman): size */); + parse_error::ParseError result = + ValidateGetProgramInfoLog( + this, arg_count, program, bufsize, length, infolog); + if (result != parse_error::kParseNoError) { + return result; + } + glGetProgramInfoLog(program, bufsize, length, infolog); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGetRenderbufferParameteriv( + unsigned int arg_count, const gles2::GetRenderbufferParameteriv& c) { + GLenum target = static_cast<GLenum>(c.target); + GLenum pname = static_cast<GLenum>(c.pname); + GLint* params; + GLsizei num_values = util_.GLGetNumValuesReturned(pname); + uint32 params_size = num_values * sizeof(*params); + params = GetSharedMemoryAs<GLint*>( + c.params_shm_id, c.params_shm_offset, params_size); + parse_error::ParseError result = + ValidateGetRenderbufferParameteriv( + this, arg_count, target, pname, params); + if (result != parse_error::kParseNoError) { + return result; + } + glGetRenderbufferParameterivEXT(target, pname, params); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGetShaderiv( + unsigned int arg_count, const gles2::GetShaderiv& c) { + GLuint shader; + if (!id_map_.GetServiceId(c.shader, &shader)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + GLenum pname = static_cast<GLenum>(c.pname); + GLint* params; + GLsizei num_values = util_.GLGetNumValuesReturned(pname); + uint32 params_size = num_values * sizeof(*params); + params = GetSharedMemoryAs<GLint*>( + c.params_shm_id, c.params_shm_offset, params_size); + parse_error::ParseError result = + ValidateGetShaderiv(this, arg_count, shader, pname, params); + if (result != parse_error::kParseNoError) { + return result; + } + glGetShaderiv(shader, pname, params); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGetShaderInfoLog( + unsigned int arg_count, const gles2::GetShaderInfoLog& c) { + GLuint shader; + if (!id_map_.GetServiceId(c.shader, &shader)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + GLsizei bufsize = static_cast<GLsizei>(c.bufsize); + GLsizei* length = GetSharedMemoryAs<GLsizei*>( + c.length_shm_id, c.length_shm_offset, 0 /* TODO(gman): size */); + char* infolog = GetSharedMemoryAs<char*>( + c.infolog_shm_id, c.infolog_shm_offset, 0 /* TODO(gman): size */); + parse_error::ParseError result = + ValidateGetShaderInfoLog( + this, arg_count, shader, bufsize, length, infolog); + if (result != parse_error::kParseNoError) { + return result; + } + glGetShaderInfoLog(shader, bufsize, length, infolog); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGetShaderSource( + unsigned int arg_count, const gles2::GetShaderSource& c) { + GLuint shader; + if (!id_map_.GetServiceId(c.shader, &shader)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + GLsizei bufsize = static_cast<GLsizei>(c.bufsize); + GLsizei* length = GetSharedMemoryAs<GLsizei*>( + c.length_shm_id, c.length_shm_offset, 0 /* TODO(gman): size */); + char* source = GetSharedMemoryAs<char*>( + c.source_shm_id, c.source_shm_offset, 0 /* TODO(gman): size */); + parse_error::ParseError result = + ValidateGetShaderSource( + this, arg_count, shader, bufsize, length, source); + if (result != parse_error::kParseNoError) { + return result; + } + glGetShaderSource(shader, bufsize, length, source); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGetString( + unsigned int arg_count, const gles2::GetString& c) { + GLenum name = static_cast<GLenum>(c.name); + parse_error::ParseError result = + ValidateGetString(this, arg_count, name); + if (result != parse_error::kParseNoError) { + return result; + } + glGetString(name); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGetTexParameterfv( + unsigned int arg_count, const gles2::GetTexParameterfv& c) { + GLenum target = static_cast<GLenum>(c.target); + GLenum pname = static_cast<GLenum>(c.pname); + GLfloat* params; + GLsizei num_values = util_.GLGetNumValuesReturned(pname); + uint32 params_size = num_values * sizeof(*params); + params = GetSharedMemoryAs<GLfloat*>( + c.params_shm_id, c.params_shm_offset, params_size); + parse_error::ParseError result = + ValidateGetTexParameterfv(this, arg_count, target, pname, params); + if (result != parse_error::kParseNoError) { + return result; + } + glGetTexParameterfv(target, pname, params); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGetTexParameteriv( + unsigned int arg_count, const gles2::GetTexParameteriv& c) { + GLenum target = static_cast<GLenum>(c.target); + GLenum pname = static_cast<GLenum>(c.pname); + GLint* params; + GLsizei num_values = util_.GLGetNumValuesReturned(pname); + uint32 params_size = num_values * sizeof(*params); + params = GetSharedMemoryAs<GLint*>( + c.params_shm_id, c.params_shm_offset, params_size); + parse_error::ParseError result = + ValidateGetTexParameteriv(this, arg_count, target, pname, params); + if (result != parse_error::kParseNoError) { + return result; + } + glGetTexParameteriv(target, pname, params); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGetUniformLocation( + unsigned int arg_count, const gles2::GetUniformLocation& c) { + GLuint program; + if (!id_map_.GetServiceId(c.program, &program)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + uint32 name_size = c.data_size; + const char* name = GetSharedMemoryAs<const char*>( + c.name_shm_id, c.name_shm_offset, name_size); + parse_error::ParseError result = + ValidateGetUniformLocation(this, arg_count, program, name); + if (result != parse_error::kParseNoError) { + return result; + } + String name_str(name, name_size); + GLint location = glGetUniformLocation(program, name_str.c_str()); + DCHECK(false); // TODO: return result. + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGetUniformLocationImmediate( + unsigned int arg_count, const gles2::GetUniformLocationImmediate& c) { + GLuint program; + if (!id_map_.GetServiceId(c.program, &program)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + uint32 name_size = c.data_size; + const char* name = GetImmediateDataAs<const char*>(c); + // TODO(gman): Make sure validate checks arg_count + // covers data_size. + parse_error::ParseError result = + ValidateGetUniformLocationImmediate(this, arg_count, program, name); + if (result != parse_error::kParseNoError) { + return result; + } + String name_str(name, name_size); + GLint location = glGetUniformLocation(program, name_str.c_str()); + DCHECK(false); // TODO: return result. + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGetVertexAttribfv( + unsigned int arg_count, const gles2::GetVertexAttribfv& c) { + GLuint index = static_cast<GLuint>(c.index); + GLenum pname = static_cast<GLenum>(c.pname); + GLfloat* params; + GLsizei num_values = util_.GLGetNumValuesReturned(pname); + uint32 params_size = num_values * sizeof(*params); + params = GetSharedMemoryAs<GLfloat*>( + c.params_shm_id, c.params_shm_offset, params_size); + parse_error::ParseError result = + ValidateGetVertexAttribfv(this, arg_count, index, pname, params); + if (result != parse_error::kParseNoError) { + return result; + } + glGetVertexAttribfv(index, pname, params); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleGetVertexAttribiv( + unsigned int arg_count, const gles2::GetVertexAttribiv& c) { + GLuint index = static_cast<GLuint>(c.index); + GLenum pname = static_cast<GLenum>(c.pname); + GLint* params; + GLsizei num_values = util_.GLGetNumValuesReturned(pname); + uint32 params_size = num_values * sizeof(*params); + params = GetSharedMemoryAs<GLint*>( + c.params_shm_id, c.params_shm_offset, params_size); + parse_error::ParseError result = + ValidateGetVertexAttribiv(this, arg_count, index, pname, params); + if (result != parse_error::kParseNoError) { + return result; + } + glGetVertexAttribiv(index, pname, params); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleHint( + unsigned int arg_count, const gles2::Hint& c) { + GLenum target = static_cast<GLenum>(c.target); + GLenum mode = static_cast<GLenum>(c.mode); + parse_error::ParseError result = + ValidateHint(this, arg_count, target, mode); + if (result != parse_error::kParseNoError) { + return result; + } + glHint(target, mode); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleIsBuffer( + unsigned int arg_count, const gles2::IsBuffer& c) { + GLuint buffer; + if (!id_map_.GetServiceId(c.buffer, &buffer)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + GLboolean* result_dst = GetSharedMemoryAs<GLboolean*>( + c.result_shm_id, c.result_shm_offset, sizeof(*result_dst)); + parse_error::ParseError result = + ValidateIsBuffer(this, arg_count, buffer); + if (result != parse_error::kParseNoError) { + return result; + } + *result_dst = glIsBuffer(buffer); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleIsEnabled( + unsigned int arg_count, const gles2::IsEnabled& c) { + GLenum cap = static_cast<GLenum>(c.cap); + GLboolean* result_dst = GetSharedMemoryAs<GLboolean*>( + c.result_shm_id, c.result_shm_offset, sizeof(*result_dst)); + parse_error::ParseError result = + ValidateIsEnabled(this, arg_count, cap); + if (result != parse_error::kParseNoError) { + return result; + } + *result_dst = glIsEnabled(cap); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleIsFramebuffer( + unsigned int arg_count, const gles2::IsFramebuffer& c) { + GLuint framebuffer; + if (!id_map_.GetServiceId(c.framebuffer, &framebuffer)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + GLboolean* result_dst = GetSharedMemoryAs<GLboolean*>( + c.result_shm_id, c.result_shm_offset, sizeof(*result_dst)); + parse_error::ParseError result = + ValidateIsFramebuffer(this, arg_count, framebuffer); + if (result != parse_error::kParseNoError) { + return result; + } + *result_dst = glIsFramebufferEXT(framebuffer); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleIsProgram( + unsigned int arg_count, const gles2::IsProgram& c) { + GLuint program; + if (!id_map_.GetServiceId(c.program, &program)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + GLboolean* result_dst = GetSharedMemoryAs<GLboolean*>( + c.result_shm_id, c.result_shm_offset, sizeof(*result_dst)); + parse_error::ParseError result = + ValidateIsProgram(this, arg_count, program); + if (result != parse_error::kParseNoError) { + return result; + } + *result_dst = glIsProgram(program); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleIsRenderbuffer( + unsigned int arg_count, const gles2::IsRenderbuffer& c) { + GLuint renderbuffer; + if (!id_map_.GetServiceId(c.renderbuffer, &renderbuffer)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + GLboolean* result_dst = GetSharedMemoryAs<GLboolean*>( + c.result_shm_id, c.result_shm_offset, sizeof(*result_dst)); + parse_error::ParseError result = + ValidateIsRenderbuffer(this, arg_count, renderbuffer); + if (result != parse_error::kParseNoError) { + return result; + } + *result_dst = glIsRenderbufferEXT(renderbuffer); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleIsShader( + unsigned int arg_count, const gles2::IsShader& c) { + GLuint shader; + if (!id_map_.GetServiceId(c.shader, &shader)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + GLboolean* result_dst = GetSharedMemoryAs<GLboolean*>( + c.result_shm_id, c.result_shm_offset, sizeof(*result_dst)); + parse_error::ParseError result = + ValidateIsShader(this, arg_count, shader); + if (result != parse_error::kParseNoError) { + return result; + } + *result_dst = glIsShader(shader); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleIsTexture( + unsigned int arg_count, const gles2::IsTexture& c) { + GLuint texture; + if (!id_map_.GetServiceId(c.texture, &texture)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + GLboolean* result_dst = GetSharedMemoryAs<GLboolean*>( + c.result_shm_id, c.result_shm_offset, sizeof(*result_dst)); + parse_error::ParseError result = + ValidateIsTexture(this, arg_count, texture); + if (result != parse_error::kParseNoError) { + return result; + } + *result_dst = glIsTexture(texture); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleLineWidth( + unsigned int arg_count, const gles2::LineWidth& c) { + GLfloat width = static_cast<GLfloat>(c.width); + parse_error::ParseError result = + ValidateLineWidth(this, arg_count, width); + if (result != parse_error::kParseNoError) { + return result; + } + glLineWidth(width); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleLinkProgram( + unsigned int arg_count, const gles2::LinkProgram& c) { + GLuint program; + if (!id_map_.GetServiceId(c.program, &program)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + parse_error::ParseError result = + ValidateLinkProgram(this, arg_count, program); + if (result != parse_error::kParseNoError) { + return result; + } + glLinkProgram(program); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandlePolygonOffset( + unsigned int arg_count, const gles2::PolygonOffset& c) { + GLfloat factor = static_cast<GLfloat>(c.factor); + GLfloat units = static_cast<GLfloat>(c.units); + parse_error::ParseError result = + ValidatePolygonOffset(this, arg_count, factor, units); + if (result != parse_error::kParseNoError) { + return result; + } + glPolygonOffset(factor, units); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleRenderbufferStorage( + unsigned int arg_count, const gles2::RenderbufferStorage& c) { + GLenum target = static_cast<GLenum>(c.target); + GLenum internalformat = static_cast<GLenum>(c.internalformat); + GLsizei width = static_cast<GLsizei>(c.width); + GLsizei height = static_cast<GLsizei>(c.height); + parse_error::ParseError result = + ValidateRenderbufferStorage( + this, arg_count, target, internalformat, width, height); + if (result != parse_error::kParseNoError) { + return result; + } + glRenderbufferStorageEXT(target, internalformat, width, height); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleSampleCoverage( + unsigned int arg_count, const gles2::SampleCoverage& c) { + GLclampf value = static_cast<GLclampf>(c.value); + GLboolean invert = static_cast<GLboolean>(c.invert); + parse_error::ParseError result = + ValidateSampleCoverage(this, arg_count, value, invert); + if (result != parse_error::kParseNoError) { + return result; + } + glSampleCoverage(value, invert); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleScissor( + unsigned int arg_count, const gles2::Scissor& c) { + GLint x = static_cast<GLint>(c.x); + GLint y = static_cast<GLint>(c.y); + GLsizei width = static_cast<GLsizei>(c.width); + GLsizei height = static_cast<GLsizei>(c.height); + parse_error::ParseError result = + ValidateScissor(this, arg_count, x, y, width, height); + if (result != parse_error::kParseNoError) { + return result; + } + glScissor(x, y, width, height); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleStencilFunc( + unsigned int arg_count, const gles2::StencilFunc& c) { + GLenum func = static_cast<GLenum>(c.func); + GLint ref = static_cast<GLint>(c.ref); + GLuint mask = static_cast<GLuint>(c.mask); + parse_error::ParseError result = + ValidateStencilFunc(this, arg_count, func, ref, mask); + if (result != parse_error::kParseNoError) { + return result; + } + glStencilFunc(func, ref, mask); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleStencilFuncSeparate( + unsigned int arg_count, const gles2::StencilFuncSeparate& c) { + GLenum face = static_cast<GLenum>(c.face); + GLenum func = static_cast<GLenum>(c.func); + GLint ref = static_cast<GLint>(c.ref); + GLuint mask = static_cast<GLuint>(c.mask); + parse_error::ParseError result = + ValidateStencilFuncSeparate(this, arg_count, face, func, ref, mask); + if (result != parse_error::kParseNoError) { + return result; + } + glStencilFuncSeparate(face, func, ref, mask); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleStencilMask( + unsigned int arg_count, const gles2::StencilMask& c) { + GLuint mask = static_cast<GLuint>(c.mask); + parse_error::ParseError result = + ValidateStencilMask(this, arg_count, mask); + if (result != parse_error::kParseNoError) { + return result; + } + glStencilMask(mask); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleStencilMaskSeparate( + unsigned int arg_count, const gles2::StencilMaskSeparate& c) { + GLenum face = static_cast<GLenum>(c.face); + GLuint mask = static_cast<GLuint>(c.mask); + parse_error::ParseError result = + ValidateStencilMaskSeparate(this, arg_count, face, mask); + if (result != parse_error::kParseNoError) { + return result; + } + glStencilMaskSeparate(face, mask); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleStencilOp( + unsigned int arg_count, const gles2::StencilOp& c) { + GLenum fail = static_cast<GLenum>(c.fail); + GLenum zfail = static_cast<GLenum>(c.zfail); + GLenum zpass = static_cast<GLenum>(c.zpass); + parse_error::ParseError result = + ValidateStencilOp(this, arg_count, fail, zfail, zpass); + if (result != parse_error::kParseNoError) { + return result; + } + glStencilOp(fail, zfail, zpass); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleStencilOpSeparate( + unsigned int arg_count, const gles2::StencilOpSeparate& c) { + GLenum face = static_cast<GLenum>(c.face); + GLenum fail = static_cast<GLenum>(c.fail); + GLenum zfail = static_cast<GLenum>(c.zfail); + GLenum zpass = static_cast<GLenum>(c.zpass); + parse_error::ParseError result = + ValidateStencilOpSeparate(this, arg_count, face, fail, zfail, zpass); + if (result != parse_error::kParseNoError) { + return result; + } + glStencilOpSeparate(face, fail, zfail, zpass); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleTexImage2D( + unsigned int arg_count, const gles2::TexImage2D& c) { + GLenum target = static_cast<GLenum>(c.target); + GLint level = static_cast<GLint>(c.level); + GLint internalformat = static_cast<GLint>(c.internalformat); + GLsizei width = static_cast<GLsizei>(c.width); + GLsizei height = static_cast<GLsizei>(c.height); + GLint border = static_cast<GLint>(c.border); + GLenum format = static_cast<GLenum>(c.format); + GLenum type = static_cast<GLenum>(c.type); + uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id); + uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset); + uint32 pixels_size = GLES2Util::ComputeImageDataSize( + width, height, format, type, unpack_alignment_); + const void* pixels = GetSharedMemoryAs<const void*>( + pixels_shm_id, pixels_shm_offset, pixels_size); + parse_error::ParseError result = + ValidateTexImage2D( + this, arg_count, target, level, internalformat, width, height, border, + format, type, pixels); + if (result != parse_error::kParseNoError) { + return result; + } + glTexImage2D( + target, level, internalformat, width, height, border, format, type, + pixels); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleTexImage2DImmediate( + unsigned int arg_count, const gles2::TexImage2DImmediate& c) { + GLenum target = static_cast<GLenum>(c.target); + GLint level = static_cast<GLint>(c.level); + GLint internalformat = static_cast<GLint>(c.internalformat); + GLsizei width = static_cast<GLsizei>(c.width); + GLsizei height = static_cast<GLsizei>(c.height); + GLint border = static_cast<GLint>(c.border); + GLenum format = static_cast<GLenum>(c.format); + GLenum type = static_cast<GLenum>(c.type); + const void* pixels = GetImmediateDataAs<const void*>(c); + // Immediate version. + parse_error::ParseError result = + ValidateTexImage2DImmediate( + this, arg_count, target, level, internalformat, width, height, border, + format, type, pixels); + if (result != parse_error::kParseNoError) { + return result; + } + glTexImage2D( + target, level, internalformat, width, height, border, format, type, + pixels); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleTexParameterf( + unsigned int arg_count, const gles2::TexParameterf& c) { + GLenum target = static_cast<GLenum>(c.target); + GLenum pname = static_cast<GLenum>(c.pname); + GLfloat param = static_cast<GLfloat>(c.param); + parse_error::ParseError result = + ValidateTexParameterf(this, arg_count, target, pname, param); + if (result != parse_error::kParseNoError) { + return result; + } + glTexParameterf(target, pname, param); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleTexParameterfv( + unsigned int arg_count, const gles2::TexParameterfv& c) { + GLenum target = static_cast<GLenum>(c.target); + GLenum pname = static_cast<GLenum>(c.pname); + const GLfloat* params = GetSharedMemoryAs<const GLfloat*>( + c.params_shm_id, c.params_shm_offset, 0 /* TODO(gman): size */); + parse_error::ParseError result = + ValidateTexParameterfv(this, arg_count, target, pname, params); + if (result != parse_error::kParseNoError) { + return result; + } + glTexParameterfv(target, pname, params); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleTexParameterfvImmediate( + unsigned int arg_count, const gles2::TexParameterfvImmediate& c) { + GLenum target = static_cast<GLenum>(c.target); + GLenum pname = static_cast<GLenum>(c.pname); + const GLfloat* params = GetImmediateDataAs<const GLfloat*>(c); + // Immediate version. + parse_error::ParseError result = + ValidateTexParameterfvImmediate(this, arg_count, target, pname, params); + if (result != parse_error::kParseNoError) { + return result; + } + glTexParameterfv(target, pname, params); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleTexParameteri( + unsigned int arg_count, const gles2::TexParameteri& c) { + GLenum target = static_cast<GLenum>(c.target); + GLenum pname = static_cast<GLenum>(c.pname); + GLint param = static_cast<GLint>(c.param); + parse_error::ParseError result = + ValidateTexParameteri(this, arg_count, target, pname, param); + if (result != parse_error::kParseNoError) { + return result; + } + glTexParameteri(target, pname, param); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleTexParameteriv( + unsigned int arg_count, const gles2::TexParameteriv& c) { + GLenum target = static_cast<GLenum>(c.target); + GLenum pname = static_cast<GLenum>(c.pname); + const GLint* params = GetSharedMemoryAs<const GLint*>( + c.params_shm_id, c.params_shm_offset, 0 /* TODO(gman): size */); + parse_error::ParseError result = + ValidateTexParameteriv(this, arg_count, target, pname, params); + if (result != parse_error::kParseNoError) { + return result; + } + glTexParameteriv(target, pname, params); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleTexParameterivImmediate( + unsigned int arg_count, const gles2::TexParameterivImmediate& c) { + GLenum target = static_cast<GLenum>(c.target); + GLenum pname = static_cast<GLenum>(c.pname); + const GLint* params = GetImmediateDataAs<const GLint*>(c); + // Immediate version. + parse_error::ParseError result = + ValidateTexParameterivImmediate(this, arg_count, target, pname, params); + if (result != parse_error::kParseNoError) { + return result; + } + glTexParameteriv(target, pname, params); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleTexSubImage2D( + unsigned int arg_count, const gles2::TexSubImage2D& c) { + GLenum target = static_cast<GLenum>(c.target); + GLint level = static_cast<GLint>(c.level); + GLint xoffset = static_cast<GLint>(c.xoffset); + GLint yoffset = static_cast<GLint>(c.yoffset); + GLsizei width = static_cast<GLsizei>(c.width); + GLsizei height = static_cast<GLsizei>(c.height); + GLenum format = static_cast<GLenum>(c.format); + GLenum type = static_cast<GLenum>(c.type); + uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id); + uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset); + uint32 pixels_size = GLES2Util::ComputeImageDataSize( + width, height, format, type, unpack_alignment_); + const void* pixels = GetSharedMemoryAs<const void*>( + pixels_shm_id, pixels_shm_offset, pixels_size); + parse_error::ParseError result = + ValidateTexSubImage2D( + this, arg_count, target, level, xoffset, yoffset, width, height, + format, type, pixels); + if (result != parse_error::kParseNoError) { + return result; + } + glTexSubImage2D( + target, level, xoffset, yoffset, width, height, format, type, pixels); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleTexSubImage2DImmediate( + unsigned int arg_count, const gles2::TexSubImage2DImmediate& c) { + GLenum target = static_cast<GLenum>(c.target); + GLint level = static_cast<GLint>(c.level); + GLint xoffset = static_cast<GLint>(c.xoffset); + GLint yoffset = static_cast<GLint>(c.yoffset); + GLsizei width = static_cast<GLsizei>(c.width); + GLsizei height = static_cast<GLsizei>(c.height); + GLenum format = static_cast<GLenum>(c.format); + GLenum type = static_cast<GLenum>(c.type); + const void* pixels = GetImmediateDataAs<const void*>(c); + // Immediate version. + parse_error::ParseError result = + ValidateTexSubImage2DImmediate( + this, arg_count, target, level, xoffset, yoffset, width, height, + format, type, pixels); + if (result != parse_error::kParseNoError) { + return result; + } + glTexSubImage2D( + target, level, xoffset, yoffset, width, height, format, type, pixels); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleUniform1f( + unsigned int arg_count, const gles2::Uniform1f& c) { + GLint location = static_cast<GLint>(c.location); + GLfloat x = static_cast<GLfloat>(c.x); + parse_error::ParseError result = + ValidateUniform1f(this, arg_count, location, x); + if (result != parse_error::kParseNoError) { + return result; + } + glUniform1f(location, x); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleUniform1fv( + unsigned int arg_count, const gles2::Uniform1fv& c) { + GLint location = static_cast<GLint>(c.location); + GLsizei count = static_cast<GLsizei>(c.count); + const GLfloat* v = GetSharedMemoryAs<const GLfloat*>( + c.v_shm_id, c.v_shm_offset, 0 /* TODO(gman): size */); + parse_error::ParseError result = + ValidateUniform1fv(this, arg_count, location, count, v); + if (result != parse_error::kParseNoError) { + return result; + } + glUniform1fv(location, count, v); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleUniform1fvImmediate( + unsigned int arg_count, const gles2::Uniform1fvImmediate& c) { + GLint location = static_cast<GLint>(c.location); + GLsizei count = static_cast<GLsizei>(c.count); + const GLfloat* v = GetImmediateDataAs<const GLfloat*>(c); + // Immediate version. + parse_error::ParseError result = + ValidateUniform1fvImmediate(this, arg_count, location, count, v); + if (result != parse_error::kParseNoError) { + return result; + } + glUniform1fv(location, count, v); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleUniform1i( + unsigned int arg_count, const gles2::Uniform1i& c) { + GLint location = static_cast<GLint>(c.location); + GLint x = static_cast<GLint>(c.x); + parse_error::ParseError result = + ValidateUniform1i(this, arg_count, location, x); + if (result != parse_error::kParseNoError) { + return result; + } + glUniform1i(location, x); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleUniform1iv( + unsigned int arg_count, const gles2::Uniform1iv& c) { + GLint location = static_cast<GLint>(c.location); + GLsizei count = static_cast<GLsizei>(c.count); + const GLint* v = GetSharedMemoryAs<const GLint*>( + c.v_shm_id, c.v_shm_offset, 0 /* TODO(gman): size */); + parse_error::ParseError result = + ValidateUniform1iv(this, arg_count, location, count, v); + if (result != parse_error::kParseNoError) { + return result; + } + glUniform1iv(location, count, v); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleUniform1ivImmediate( + unsigned int arg_count, const gles2::Uniform1ivImmediate& c) { + GLint location = static_cast<GLint>(c.location); + GLsizei count = static_cast<GLsizei>(c.count); + const GLint* v = GetImmediateDataAs<const GLint*>(c); + // Immediate version. + parse_error::ParseError result = + ValidateUniform1ivImmediate(this, arg_count, location, count, v); + if (result != parse_error::kParseNoError) { + return result; + } + glUniform1iv(location, count, v); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleUniform2f( + unsigned int arg_count, const gles2::Uniform2f& c) { + GLint location = static_cast<GLint>(c.location); + GLfloat x = static_cast<GLfloat>(c.x); + GLfloat y = static_cast<GLfloat>(c.y); + parse_error::ParseError result = + ValidateUniform2f(this, arg_count, location, x, y); + if (result != parse_error::kParseNoError) { + return result; + } + glUniform2f(location, x, y); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleUniform2fv( + unsigned int arg_count, const gles2::Uniform2fv& c) { + GLint location = static_cast<GLint>(c.location); + GLsizei count = static_cast<GLsizei>(c.count); + const GLfloat* v = GetSharedMemoryAs<const GLfloat*>( + c.v_shm_id, c.v_shm_offset, 0 /* TODO(gman): size */); + parse_error::ParseError result = + ValidateUniform2fv(this, arg_count, location, count, v); + if (result != parse_error::kParseNoError) { + return result; + } + glUniform2fv(location, count, v); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleUniform2fvImmediate( + unsigned int arg_count, const gles2::Uniform2fvImmediate& c) { + GLint location = static_cast<GLint>(c.location); + GLsizei count = static_cast<GLsizei>(c.count); + const GLfloat* v = GetImmediateDataAs<const GLfloat*>(c); + // Immediate version. + parse_error::ParseError result = + ValidateUniform2fvImmediate(this, arg_count, location, count, v); + if (result != parse_error::kParseNoError) { + return result; + } + glUniform2fv(location, count, v); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleUniform2i( + unsigned int arg_count, const gles2::Uniform2i& c) { + GLint location = static_cast<GLint>(c.location); + GLint x = static_cast<GLint>(c.x); + GLint y = static_cast<GLint>(c.y); + parse_error::ParseError result = + ValidateUniform2i(this, arg_count, location, x, y); + if (result != parse_error::kParseNoError) { + return result; + } + glUniform2i(location, x, y); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleUniform2iv( + unsigned int arg_count, const gles2::Uniform2iv& c) { + GLint location = static_cast<GLint>(c.location); + GLsizei count = static_cast<GLsizei>(c.count); + const GLint* v = GetSharedMemoryAs<const GLint*>( + c.v_shm_id, c.v_shm_offset, 0 /* TODO(gman): size */); + parse_error::ParseError result = + ValidateUniform2iv(this, arg_count, location, count, v); + if (result != parse_error::kParseNoError) { + return result; + } + glUniform2iv(location, count, v); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleUniform2ivImmediate( + unsigned int arg_count, const gles2::Uniform2ivImmediate& c) { + GLint location = static_cast<GLint>(c.location); + GLsizei count = static_cast<GLsizei>(c.count); + const GLint* v = GetImmediateDataAs<const GLint*>(c); + // Immediate version. + parse_error::ParseError result = + ValidateUniform2ivImmediate(this, arg_count, location, count, v); + if (result != parse_error::kParseNoError) { + return result; + } + glUniform2iv(location, count, v); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleUniform3f( + unsigned int arg_count, const gles2::Uniform3f& c) { + GLint location = static_cast<GLint>(c.location); + GLfloat x = static_cast<GLfloat>(c.x); + GLfloat y = static_cast<GLfloat>(c.y); + GLfloat z = static_cast<GLfloat>(c.z); + parse_error::ParseError result = + ValidateUniform3f(this, arg_count, location, x, y, z); + if (result != parse_error::kParseNoError) { + return result; + } + glUniform3f(location, x, y, z); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleUniform3fv( + unsigned int arg_count, const gles2::Uniform3fv& c) { + GLint location = static_cast<GLint>(c.location); + GLsizei count = static_cast<GLsizei>(c.count); + const GLfloat* v = GetSharedMemoryAs<const GLfloat*>( + c.v_shm_id, c.v_shm_offset, 0 /* TODO(gman): size */); + parse_error::ParseError result = + ValidateUniform3fv(this, arg_count, location, count, v); + if (result != parse_error::kParseNoError) { + return result; + } + glUniform3fv(location, count, v); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleUniform3fvImmediate( + unsigned int arg_count, const gles2::Uniform3fvImmediate& c) { + GLint location = static_cast<GLint>(c.location); + GLsizei count = static_cast<GLsizei>(c.count); + const GLfloat* v = GetImmediateDataAs<const GLfloat*>(c); + // Immediate version. + parse_error::ParseError result = + ValidateUniform3fvImmediate(this, arg_count, location, count, v); + if (result != parse_error::kParseNoError) { + return result; + } + glUniform3fv(location, count, v); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleUniform3i( + unsigned int arg_count, const gles2::Uniform3i& c) { + GLint location = static_cast<GLint>(c.location); + GLint x = static_cast<GLint>(c.x); + GLint y = static_cast<GLint>(c.y); + GLint z = static_cast<GLint>(c.z); + parse_error::ParseError result = + ValidateUniform3i(this, arg_count, location, x, y, z); + if (result != parse_error::kParseNoError) { + return result; + } + glUniform3i(location, x, y, z); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleUniform3iv( + unsigned int arg_count, const gles2::Uniform3iv& c) { + GLint location = static_cast<GLint>(c.location); + GLsizei count = static_cast<GLsizei>(c.count); + const GLint* v = GetSharedMemoryAs<const GLint*>( + c.v_shm_id, c.v_shm_offset, 0 /* TODO(gman): size */); + parse_error::ParseError result = + ValidateUniform3iv(this, arg_count, location, count, v); + if (result != parse_error::kParseNoError) { + return result; + } + glUniform3iv(location, count, v); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleUniform3ivImmediate( + unsigned int arg_count, const gles2::Uniform3ivImmediate& c) { + GLint location = static_cast<GLint>(c.location); + GLsizei count = static_cast<GLsizei>(c.count); + const GLint* v = GetImmediateDataAs<const GLint*>(c); + // Immediate version. + parse_error::ParseError result = + ValidateUniform3ivImmediate(this, arg_count, location, count, v); + if (result != parse_error::kParseNoError) { + return result; + } + glUniform3iv(location, count, v); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleUniform4f( + unsigned int arg_count, const gles2::Uniform4f& c) { + GLint location = static_cast<GLint>(c.location); + GLfloat x = static_cast<GLfloat>(c.x); + GLfloat y = static_cast<GLfloat>(c.y); + GLfloat z = static_cast<GLfloat>(c.z); + GLfloat w = static_cast<GLfloat>(c.w); + parse_error::ParseError result = + ValidateUniform4f(this, arg_count, location, x, y, z, w); + if (result != parse_error::kParseNoError) { + return result; + } + glUniform4f(location, x, y, z, w); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleUniform4fv( + unsigned int arg_count, const gles2::Uniform4fv& c) { + GLint location = static_cast<GLint>(c.location); + GLsizei count = static_cast<GLsizei>(c.count); + const GLfloat* v = GetSharedMemoryAs<const GLfloat*>( + c.v_shm_id, c.v_shm_offset, 0 /* TODO(gman): size */); + parse_error::ParseError result = + ValidateUniform4fv(this, arg_count, location, count, v); + if (result != parse_error::kParseNoError) { + return result; + } + glUniform4fv(location, count, v); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleUniform4fvImmediate( + unsigned int arg_count, const gles2::Uniform4fvImmediate& c) { + GLint location = static_cast<GLint>(c.location); + GLsizei count = static_cast<GLsizei>(c.count); + const GLfloat* v = GetImmediateDataAs<const GLfloat*>(c); + // Immediate version. + parse_error::ParseError result = + ValidateUniform4fvImmediate(this, arg_count, location, count, v); + if (result != parse_error::kParseNoError) { + return result; + } + glUniform4fv(location, count, v); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleUniform4i( + unsigned int arg_count, const gles2::Uniform4i& c) { + GLint location = static_cast<GLint>(c.location); + GLint x = static_cast<GLint>(c.x); + GLint y = static_cast<GLint>(c.y); + GLint z = static_cast<GLint>(c.z); + GLint w = static_cast<GLint>(c.w); + parse_error::ParseError result = + ValidateUniform4i(this, arg_count, location, x, y, z, w); + if (result != parse_error::kParseNoError) { + return result; + } + glUniform4i(location, x, y, z, w); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleUniform4iv( + unsigned int arg_count, const gles2::Uniform4iv& c) { + GLint location = static_cast<GLint>(c.location); + GLsizei count = static_cast<GLsizei>(c.count); + const GLint* v = GetSharedMemoryAs<const GLint*>( + c.v_shm_id, c.v_shm_offset, 0 /* TODO(gman): size */); + parse_error::ParseError result = + ValidateUniform4iv(this, arg_count, location, count, v); + if (result != parse_error::kParseNoError) { + return result; + } + glUniform4iv(location, count, v); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleUniform4ivImmediate( + unsigned int arg_count, const gles2::Uniform4ivImmediate& c) { + GLint location = static_cast<GLint>(c.location); + GLsizei count = static_cast<GLsizei>(c.count); + const GLint* v = GetImmediateDataAs<const GLint*>(c); + // Immediate version. + parse_error::ParseError result = + ValidateUniform4ivImmediate(this, arg_count, location, count, v); + if (result != parse_error::kParseNoError) { + return result; + } + glUniform4iv(location, count, v); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleUniformMatrix2fv( + unsigned int arg_count, const gles2::UniformMatrix2fv& c) { + GLint location = static_cast<GLint>(c.location); + GLsizei count = static_cast<GLsizei>(c.count); + GLboolean transpose = static_cast<GLboolean>(c.transpose); + const GLfloat* value = GetSharedMemoryAs<const GLfloat*>( + c.value_shm_id, c.value_shm_offset, 0 /* TODO(gman): size */); + parse_error::ParseError result = + ValidateUniformMatrix2fv( + this, arg_count, location, count, transpose, value); + if (result != parse_error::kParseNoError) { + return result; + } + glUniformMatrix2fv(location, count, transpose, value); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleUniformMatrix2fvImmediate( + unsigned int arg_count, const gles2::UniformMatrix2fvImmediate& c) { + GLint location = static_cast<GLint>(c.location); + GLsizei count = static_cast<GLsizei>(c.count); + GLboolean transpose = static_cast<GLboolean>(c.transpose); + const GLfloat* value = GetImmediateDataAs<const GLfloat*>(c); + // Immediate version. + parse_error::ParseError result = + ValidateUniformMatrix2fvImmediate( + this, arg_count, location, count, transpose, value); + if (result != parse_error::kParseNoError) { + return result; + } + glUniformMatrix2fv(location, count, transpose, value); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleUniformMatrix3fv( + unsigned int arg_count, const gles2::UniformMatrix3fv& c) { + GLint location = static_cast<GLint>(c.location); + GLsizei count = static_cast<GLsizei>(c.count); + GLboolean transpose = static_cast<GLboolean>(c.transpose); + const GLfloat* value = GetSharedMemoryAs<const GLfloat*>( + c.value_shm_id, c.value_shm_offset, 0 /* TODO(gman): size */); + parse_error::ParseError result = + ValidateUniformMatrix3fv( + this, arg_count, location, count, transpose, value); + if (result != parse_error::kParseNoError) { + return result; + } + glUniformMatrix3fv(location, count, transpose, value); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleUniformMatrix3fvImmediate( + unsigned int arg_count, const gles2::UniformMatrix3fvImmediate& c) { + GLint location = static_cast<GLint>(c.location); + GLsizei count = static_cast<GLsizei>(c.count); + GLboolean transpose = static_cast<GLboolean>(c.transpose); + const GLfloat* value = GetImmediateDataAs<const GLfloat*>(c); + // Immediate version. + parse_error::ParseError result = + ValidateUniformMatrix3fvImmediate( + this, arg_count, location, count, transpose, value); + if (result != parse_error::kParseNoError) { + return result; + } + glUniformMatrix3fv(location, count, transpose, value); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleUniformMatrix4fv( + unsigned int arg_count, const gles2::UniformMatrix4fv& c) { + GLint location = static_cast<GLint>(c.location); + GLsizei count = static_cast<GLsizei>(c.count); + GLboolean transpose = static_cast<GLboolean>(c.transpose); + const GLfloat* value = GetSharedMemoryAs<const GLfloat*>( + c.value_shm_id, c.value_shm_offset, 0 /* TODO(gman): size */); + parse_error::ParseError result = + ValidateUniformMatrix4fv( + this, arg_count, location, count, transpose, value); + if (result != parse_error::kParseNoError) { + return result; + } + glUniformMatrix4fv(location, count, transpose, value); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleUniformMatrix4fvImmediate( + unsigned int arg_count, const gles2::UniformMatrix4fvImmediate& c) { + GLint location = static_cast<GLint>(c.location); + GLsizei count = static_cast<GLsizei>(c.count); + GLboolean transpose = static_cast<GLboolean>(c.transpose); + const GLfloat* value = GetImmediateDataAs<const GLfloat*>(c); + // Immediate version. + parse_error::ParseError result = + ValidateUniformMatrix4fvImmediate( + this, arg_count, location, count, transpose, value); + if (result != parse_error::kParseNoError) { + return result; + } + glUniformMatrix4fv(location, count, transpose, value); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleUseProgram( + unsigned int arg_count, const gles2::UseProgram& c) { + GLuint program; + if (!id_map_.GetServiceId(c.program, &program)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + parse_error::ParseError result = + ValidateUseProgram(this, arg_count, program); + if (result != parse_error::kParseNoError) { + return result; + } + glUseProgram(program); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleValidateProgram( + unsigned int arg_count, const gles2::ValidateProgram& c) { + GLuint program; + if (!id_map_.GetServiceId(c.program, &program)) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + parse_error::ParseError result = + ValidateValidateProgram(this, arg_count, program); + if (result != parse_error::kParseNoError) { + return result; + } + glValidateProgram(program); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleVertexAttrib1f( + unsigned int arg_count, const gles2::VertexAttrib1f& c) { + GLuint indx = static_cast<GLuint>(c.indx); + GLfloat x = static_cast<GLfloat>(c.x); + parse_error::ParseError result = + ValidateVertexAttrib1f(this, arg_count, indx, x); + if (result != parse_error::kParseNoError) { + return result; + } + glVertexAttrib1f(indx, x); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleVertexAttrib1fv( + unsigned int arg_count, const gles2::VertexAttrib1fv& c) { + GLuint indx = static_cast<GLuint>(c.indx); + const GLfloat* values = GetSharedMemoryAs<const GLfloat*>( + c.values_shm_id, c.values_shm_offset, 0 /* TODO(gman): size */); + parse_error::ParseError result = + ValidateVertexAttrib1fv(this, arg_count, indx, values); + if (result != parse_error::kParseNoError) { + return result; + } + glVertexAttrib1fv(indx, values); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleVertexAttrib1fvImmediate( + unsigned int arg_count, const gles2::VertexAttrib1fvImmediate& c) { + GLuint indx = static_cast<GLuint>(c.indx); + const GLfloat* values = GetImmediateDataAs<const GLfloat*>(c); + // Immediate version. + parse_error::ParseError result = + ValidateVertexAttrib1fvImmediate(this, arg_count, indx, values); + if (result != parse_error::kParseNoError) { + return result; + } + glVertexAttrib1fv(indx, values); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleVertexAttrib2f( + unsigned int arg_count, const gles2::VertexAttrib2f& c) { + GLuint indx = static_cast<GLuint>(c.indx); + GLfloat x = static_cast<GLfloat>(c.x); + GLfloat y = static_cast<GLfloat>(c.y); + parse_error::ParseError result = + ValidateVertexAttrib2f(this, arg_count, indx, x, y); + if (result != parse_error::kParseNoError) { + return result; + } + glVertexAttrib2f(indx, x, y); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleVertexAttrib2fv( + unsigned int arg_count, const gles2::VertexAttrib2fv& c) { + GLuint indx = static_cast<GLuint>(c.indx); + const GLfloat* values = GetSharedMemoryAs<const GLfloat*>( + c.values_shm_id, c.values_shm_offset, 0 /* TODO(gman): size */); + parse_error::ParseError result = + ValidateVertexAttrib2fv(this, arg_count, indx, values); + if (result != parse_error::kParseNoError) { + return result; + } + glVertexAttrib2fv(indx, values); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleVertexAttrib2fvImmediate( + unsigned int arg_count, const gles2::VertexAttrib2fvImmediate& c) { + GLuint indx = static_cast<GLuint>(c.indx); + const GLfloat* values = GetImmediateDataAs<const GLfloat*>(c); + // Immediate version. + parse_error::ParseError result = + ValidateVertexAttrib2fvImmediate(this, arg_count, indx, values); + if (result != parse_error::kParseNoError) { + return result; + } + glVertexAttrib2fv(indx, values); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleVertexAttrib3f( + unsigned int arg_count, const gles2::VertexAttrib3f& c) { + GLuint indx = static_cast<GLuint>(c.indx); + GLfloat x = static_cast<GLfloat>(c.x); + GLfloat y = static_cast<GLfloat>(c.y); + GLfloat z = static_cast<GLfloat>(c.z); + parse_error::ParseError result = + ValidateVertexAttrib3f(this, arg_count, indx, x, y, z); + if (result != parse_error::kParseNoError) { + return result; + } + glVertexAttrib3f(indx, x, y, z); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleVertexAttrib3fv( + unsigned int arg_count, const gles2::VertexAttrib3fv& c) { + GLuint indx = static_cast<GLuint>(c.indx); + const GLfloat* values = GetSharedMemoryAs<const GLfloat*>( + c.values_shm_id, c.values_shm_offset, 0 /* TODO(gman): size */); + parse_error::ParseError result = + ValidateVertexAttrib3fv(this, arg_count, indx, values); + if (result != parse_error::kParseNoError) { + return result; + } + glVertexAttrib3fv(indx, values); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleVertexAttrib3fvImmediate( + unsigned int arg_count, const gles2::VertexAttrib3fvImmediate& c) { + GLuint indx = static_cast<GLuint>(c.indx); + const GLfloat* values = GetImmediateDataAs<const GLfloat*>(c); + // Immediate version. + parse_error::ParseError result = + ValidateVertexAttrib3fvImmediate(this, arg_count, indx, values); + if (result != parse_error::kParseNoError) { + return result; + } + glVertexAttrib3fv(indx, values); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleVertexAttrib4f( + unsigned int arg_count, const gles2::VertexAttrib4f& c) { + GLuint indx = static_cast<GLuint>(c.indx); + GLfloat x = static_cast<GLfloat>(c.x); + GLfloat y = static_cast<GLfloat>(c.y); + GLfloat z = static_cast<GLfloat>(c.z); + GLfloat w = static_cast<GLfloat>(c.w); + parse_error::ParseError result = + ValidateVertexAttrib4f(this, arg_count, indx, x, y, z, w); + if (result != parse_error::kParseNoError) { + return result; + } + glVertexAttrib4f(indx, x, y, z, w); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleVertexAttrib4fv( + unsigned int arg_count, const gles2::VertexAttrib4fv& c) { + GLuint indx = static_cast<GLuint>(c.indx); + const GLfloat* values = GetSharedMemoryAs<const GLfloat*>( + c.values_shm_id, c.values_shm_offset, 0 /* TODO(gman): size */); + parse_error::ParseError result = + ValidateVertexAttrib4fv(this, arg_count, indx, values); + if (result != parse_error::kParseNoError) { + return result; + } + glVertexAttrib4fv(indx, values); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleVertexAttrib4fvImmediate( + unsigned int arg_count, const gles2::VertexAttrib4fvImmediate& c) { + GLuint indx = static_cast<GLuint>(c.indx); + const GLfloat* values = GetImmediateDataAs<const GLfloat*>(c); + // Immediate version. + parse_error::ParseError result = + ValidateVertexAttrib4fvImmediate(this, arg_count, indx, values); + if (result != parse_error::kParseNoError) { + return result; + } + glVertexAttrib4fv(indx, values); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleViewport( + unsigned int arg_count, const gles2::Viewport& c) { + GLint x = static_cast<GLint>(c.x); + GLint y = static_cast<GLint>(c.y); + GLsizei width = static_cast<GLsizei>(c.width); + GLsizei height = static_cast<GLsizei>(c.height); + parse_error::ParseError result = + ValidateViewport(this, arg_count, x, y, width, height); + if (result != parse_error::kParseNoError) { + return result; + } + glViewport(x, y, width, height); + return parse_error::kParseNoError; +} + +parse_error::ParseError GLES2DecoderImpl::HandleSwapBuffers( + unsigned int arg_count, const gles2::SwapBuffers& c) { + parse_error::ParseError result = + ValidateSwapBuffers(this, arg_count); + if (result != parse_error::kParseNoError) { + return result; + } + DoSwapBuffers(); + return parse_error::kParseNoError; +} + diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_validate.h b/gpu/command_buffer/service/gles2_cmd_decoder_validate.h new file mode 100644 index 0000000..616d3fc --- /dev/null +++ b/gpu/command_buffer/service/gles2_cmd_decoder_validate.h @@ -0,0 +1,1255 @@ + +// Copyright (c) 2006-2008 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. + + +namespace command_buffer { +namespace gles2 { + +namespace { + +parse_error::ParseError ValidateActiveTexture( + GLES2Decoder* decoder, unsigned int arg_count, GLenum texture) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateAttachShader( + GLES2Decoder* decoder, unsigned int arg_count, GLuint program, + GLuint shader) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateBindAttribLocation( + GLES2Decoder* decoder, unsigned int arg_count, GLuint program, GLuint index, + const char* name) { + if (name == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateBindAttribLocationImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLuint program, GLuint index, + const char* name) { + if (name == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateBindBuffer( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, + GLuint buffer) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateBindFramebuffer( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, + GLuint framebuffer) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateBindRenderbuffer( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, + GLuint renderbuffer) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateBindTexture( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, + GLuint texture) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateBlendColor( + GLES2Decoder* decoder, unsigned int arg_count, GLclampf red, GLclampf green, + GLclampf blue, GLclampf alpha) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateBlendEquation( + GLES2Decoder* decoder, unsigned int arg_count, GLenum mode) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateBlendEquationSeparate( + GLES2Decoder* decoder, unsigned int arg_count, GLenum modeRGB, + GLenum modeAlpha) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateBlendFunc( + GLES2Decoder* decoder, unsigned int arg_count, GLenum sfactor, + GLenum dfactor) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateBlendFuncSeparate( + GLES2Decoder* decoder, unsigned int arg_count, GLenum srcRGB, GLenum dstRGB, + GLenum srcAlpha, GLenum dstAlpha) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateBufferData( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, + GLsizeiptr size, const void* data, GLenum usage) { + if (data == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateBufferDataImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, + GLsizeiptr size, const void* data, GLenum usage) { + if (data == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateBufferSubData( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, + GLintptr offset, GLsizeiptr size, const void* data) { + if (data == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateBufferSubDataImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, + GLintptr offset, GLsizeiptr size, const void* data) { + if (data == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateCheckFramebufferStatus( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateClear( + GLES2Decoder* decoder, unsigned int arg_count, GLbitfield mask) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateClearColor( + GLES2Decoder* decoder, unsigned int arg_count, GLclampf red, GLclampf green, + GLclampf blue, GLclampf alpha) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateClearDepthf( + GLES2Decoder* decoder, unsigned int arg_count, GLclampf depth) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateClearStencil( + GLES2Decoder* decoder, unsigned int arg_count, GLint s) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateColorMask( + GLES2Decoder* decoder, unsigned int arg_count, GLboolean red, + GLboolean green, GLboolean blue, GLboolean alpha) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateCompileShader( + GLES2Decoder* decoder, unsigned int arg_count, GLuint shader) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateCompressedTexImage2D( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, GLint level, + GLenum internalformat, GLsizei width, GLsizei height, GLint border, + GLsizei imageSize, const void* data) { + if (data == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateCompressedTexImage2DImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, GLint level, + GLenum internalformat, GLsizei width, GLsizei height, GLint border, + GLsizei imageSize, const void* data) { + if (data == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateCompressedTexSubImage2D( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, + GLsizei imageSize, const void* data) { + if (data == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateCompressedTexSubImage2DImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, + GLsizei imageSize, const void* data) { + if (data == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateCopyTexImage2D( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, GLint level, + GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, + GLint border) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateCopyTexSubImage2D( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, + GLsizei height) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateCreateProgram( + GLES2Decoder* decoder, unsigned int arg_count) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateCreateShader( + GLES2Decoder* decoder, unsigned int arg_count, GLenum type) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateCullFace( + GLES2Decoder* decoder, unsigned int arg_count, GLenum mode) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateDeleteBuffers( + GLES2Decoder* decoder, unsigned int arg_count, GLsizei n, + const GLuint* buffers) { + if (buffers == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateDeleteBuffersImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLsizei n, + const GLuint* buffers) { + if (buffers == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateDeleteFramebuffers( + GLES2Decoder* decoder, unsigned int arg_count, GLsizei n, + const GLuint* framebuffers) { + if (framebuffers == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateDeleteFramebuffersImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLsizei n, + const GLuint* framebuffers) { + if (framebuffers == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateDeleteProgram( + GLES2Decoder* decoder, unsigned int arg_count, GLuint program) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateDeleteRenderbuffers( + GLES2Decoder* decoder, unsigned int arg_count, GLsizei n, + const GLuint* renderbuffers) { + if (renderbuffers == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateDeleteRenderbuffersImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLsizei n, + const GLuint* renderbuffers) { + if (renderbuffers == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateDeleteShader( + GLES2Decoder* decoder, unsigned int arg_count, GLuint shader) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateDeleteTextures( + GLES2Decoder* decoder, unsigned int arg_count, GLsizei n, + const GLuint* textures) { + if (textures == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateDeleteTexturesImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLsizei n, + const GLuint* textures) { + if (textures == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateDepthFunc( + GLES2Decoder* decoder, unsigned int arg_count, GLenum func) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateDepthMask( + GLES2Decoder* decoder, unsigned int arg_count, GLboolean flag) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateDepthRangef( + GLES2Decoder* decoder, unsigned int arg_count, GLclampf zNear, + GLclampf zFar) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateDetachShader( + GLES2Decoder* decoder, unsigned int arg_count, GLuint program, + GLuint shader) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateDisable( + GLES2Decoder* decoder, unsigned int arg_count, GLenum cap) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateDisableVertexAttribArray( + GLES2Decoder* decoder, unsigned int arg_count, GLuint index) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateDrawArrays( + GLES2Decoder* decoder, unsigned int arg_count, GLenum mode, GLint first, + GLsizei count) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateDrawElements( + GLES2Decoder* decoder, unsigned int arg_count, GLenum mode, GLsizei count, + GLenum type, const void* indices) { + if (indices == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateEnable( + GLES2Decoder* decoder, unsigned int arg_count, GLenum cap) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateEnableVertexAttribArray( + GLES2Decoder* decoder, unsigned int arg_count, GLuint index) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateFinish( + GLES2Decoder* decoder, unsigned int arg_count) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateFlush( + GLES2Decoder* decoder, unsigned int arg_count) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateFramebufferRenderbuffer( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, + GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateFramebufferTexture2D( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, + GLenum attachment, GLenum textarget, GLuint texture, GLint level) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateFrontFace( + GLES2Decoder* decoder, unsigned int arg_count, GLenum mode) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGenBuffers( + GLES2Decoder* decoder, unsigned int arg_count, GLsizei n, + GLuint* buffers) { + if (buffers == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGenBuffersImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLsizei n, + GLuint* buffers) { + if (buffers == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGenerateMipmap( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGenFramebuffers( + GLES2Decoder* decoder, unsigned int arg_count, GLsizei n, + GLuint* framebuffers) { + if (framebuffers == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGenFramebuffersImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLsizei n, + GLuint* framebuffers) { + if (framebuffers == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGenRenderbuffers( + GLES2Decoder* decoder, unsigned int arg_count, GLsizei n, + GLuint* renderbuffers) { + if (renderbuffers == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGenRenderbuffersImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLsizei n, + GLuint* renderbuffers) { + if (renderbuffers == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGenTextures( + GLES2Decoder* decoder, unsigned int arg_count, GLsizei n, + GLuint* textures) { + if (textures == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGenTexturesImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLsizei n, + GLuint* textures) { + if (textures == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGetActiveAttrib( + GLES2Decoder* decoder, unsigned int arg_count, GLuint program, GLuint index, + GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) { + if (length == NULL) { + return parse_error::kParseOutOfBounds; + } + if (size == NULL) { + return parse_error::kParseOutOfBounds; + } + if (type == NULL) { + return parse_error::kParseOutOfBounds; + } + if (name == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGetActiveUniform( + GLES2Decoder* decoder, unsigned int arg_count, GLuint program, GLuint index, + GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) { + if (length == NULL) { + return parse_error::kParseOutOfBounds; + } + if (size == NULL) { + return parse_error::kParseOutOfBounds; + } + if (type == NULL) { + return parse_error::kParseOutOfBounds; + } + if (name == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGetAttachedShaders( + GLES2Decoder* decoder, unsigned int arg_count, GLuint program, + GLsizei maxcount, GLsizei* count, GLuint* shaders) { + if (count == NULL) { + return parse_error::kParseOutOfBounds; + } + if (shaders == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGetAttribLocation( + GLES2Decoder* decoder, unsigned int arg_count, GLuint program, + const char* name) { + if (name == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGetAttribLocationImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLuint program, + const char* name) { + if (name == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGetBooleanv( + GLES2Decoder* decoder, unsigned int arg_count, GLenum pname, + GLboolean* params) { + if (params == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGetBufferParameteriv( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, GLenum pname, + GLint* params) { + if (params == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGetError( + GLES2Decoder* decoder, unsigned int arg_count) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGetFloatv( + GLES2Decoder* decoder, unsigned int arg_count, GLenum pname, + GLfloat* params) { + if (params == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGetFramebufferAttachmentParameteriv( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, + GLenum attachment, GLenum pname, GLint* params) { + if (params == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGetIntegerv( + GLES2Decoder* decoder, unsigned int arg_count, GLenum pname, + GLint* params) { + if (params == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGetProgramiv( + GLES2Decoder* decoder, unsigned int arg_count, GLuint program, GLenum pname, + GLint* params) { + if (params == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGetProgramInfoLog( + GLES2Decoder* decoder, unsigned int arg_count, GLuint program, + GLsizei bufsize, GLsizei* length, char* infolog) { + if (length == NULL) { + return parse_error::kParseOutOfBounds; + } + if (infolog == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGetRenderbufferParameteriv( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, GLenum pname, + GLint* params) { + if (params == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGetShaderiv( + GLES2Decoder* decoder, unsigned int arg_count, GLuint shader, GLenum pname, + GLint* params) { + if (params == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGetShaderInfoLog( + GLES2Decoder* decoder, unsigned int arg_count, GLuint shader, + GLsizei bufsize, GLsizei* length, char* infolog) { + if (length == NULL) { + return parse_error::kParseOutOfBounds; + } + if (infolog == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGetShaderPrecisionFormat( + GLES2Decoder* decoder, unsigned int arg_count, GLenum shadertype, + GLenum precisiontype, GLint* range, GLint* precision) { + if (range == NULL) { + return parse_error::kParseOutOfBounds; + } + if (precision == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGetShaderSource( + GLES2Decoder* decoder, unsigned int arg_count, GLuint shader, + GLsizei bufsize, GLsizei* length, char* source) { + if (length == NULL) { + return parse_error::kParseOutOfBounds; + } + if (source == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGetString( + GLES2Decoder* decoder, unsigned int arg_count, GLenum name) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGetTexParameterfv( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, GLenum pname, + GLfloat* params) { + if (params == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGetTexParameteriv( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, GLenum pname, + GLint* params) { + if (params == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGetUniformfv( + GLES2Decoder* decoder, unsigned int arg_count, GLuint program, + GLint location, GLfloat* params) { + if (params == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGetUniformiv( + GLES2Decoder* decoder, unsigned int arg_count, GLuint program, + GLint location, GLint* params) { + if (params == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGetUniformLocation( + GLES2Decoder* decoder, unsigned int arg_count, GLuint program, + const char* name) { + if (name == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGetUniformLocationImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLuint program, + const char* name) { + if (name == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGetVertexAttribfv( + GLES2Decoder* decoder, unsigned int arg_count, GLuint index, GLenum pname, + GLfloat* params) { + if (params == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGetVertexAttribiv( + GLES2Decoder* decoder, unsigned int arg_count, GLuint index, GLenum pname, + GLint* params) { + if (params == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateGetVertexAttribPointerv( + GLES2Decoder* decoder, unsigned int arg_count, GLuint index, GLenum pname, + void** pointer) { + if (pointer == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateHint( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, + GLenum mode) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateIsBuffer( + GLES2Decoder* decoder, unsigned int arg_count, GLuint buffer) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateIsEnabled( + GLES2Decoder* decoder, unsigned int arg_count, GLenum cap) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateIsFramebuffer( + GLES2Decoder* decoder, unsigned int arg_count, GLuint framebuffer) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateIsProgram( + GLES2Decoder* decoder, unsigned int arg_count, GLuint program) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateIsRenderbuffer( + GLES2Decoder* decoder, unsigned int arg_count, GLuint renderbuffer) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateIsShader( + GLES2Decoder* decoder, unsigned int arg_count, GLuint shader) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateIsTexture( + GLES2Decoder* decoder, unsigned int arg_count, GLuint texture) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateLineWidth( + GLES2Decoder* decoder, unsigned int arg_count, GLfloat width) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateLinkProgram( + GLES2Decoder* decoder, unsigned int arg_count, GLuint program) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidatePixelStorei( + GLES2Decoder* decoder, unsigned int arg_count, GLenum pname, GLint param) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidatePolygonOffset( + GLES2Decoder* decoder, unsigned int arg_count, GLfloat factor, + GLfloat units) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateReadPixels( + GLES2Decoder* decoder, unsigned int arg_count, GLint x, GLint y, + GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) { + if (pixels == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateRenderbufferStorage( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, + GLenum internalformat, GLsizei width, GLsizei height) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateSampleCoverage( + GLES2Decoder* decoder, unsigned int arg_count, GLclampf value, + GLboolean invert) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateScissor( + GLES2Decoder* decoder, unsigned int arg_count, GLint x, GLint y, + GLsizei width, GLsizei height) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateShaderSource( + GLES2Decoder* decoder, unsigned int arg_count, GLuint shader, GLsizei count, + const char** string, const GLint* length) { + if (string == NULL) { + return parse_error::kParseOutOfBounds; + } + if (length == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateShaderSourceImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLuint shader, GLsizei count, + const char** string, const GLint* length) { + if (string == NULL) { + return parse_error::kParseOutOfBounds; + } + if (length == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateStencilFunc( + GLES2Decoder* decoder, unsigned int arg_count, GLenum func, GLint ref, + GLuint mask) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateStencilFuncSeparate( + GLES2Decoder* decoder, unsigned int arg_count, GLenum face, GLenum func, + GLint ref, GLuint mask) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateStencilMask( + GLES2Decoder* decoder, unsigned int arg_count, GLuint mask) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateStencilMaskSeparate( + GLES2Decoder* decoder, unsigned int arg_count, GLenum face, GLuint mask) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateStencilOp( + GLES2Decoder* decoder, unsigned int arg_count, GLenum fail, GLenum zfail, + GLenum zpass) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateStencilOpSeparate( + GLES2Decoder* decoder, unsigned int arg_count, GLenum face, GLenum fail, + GLenum zfail, GLenum zpass) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateTexImage2D( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, GLint level, + GLint internalformat, GLsizei width, GLsizei height, GLint border, + GLenum format, GLenum type, const void* pixels) { + if (pixels == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateTexImage2DImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, GLint level, + GLint internalformat, GLsizei width, GLsizei height, GLint border, + GLenum format, GLenum type, const void* pixels) { + if (pixels == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateTexParameterf( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, GLenum pname, + GLfloat param) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateTexParameterfv( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, GLenum pname, + const GLfloat* params) { + if (params == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateTexParameterfvImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, GLenum pname, + const GLfloat* params) { + if (params == NULL) { + return parse_error::kParseOutOfBounds; + } + if (!CheckImmediateDataSize<TexParameterfvImmediate>( + arg_count, 1, sizeof(GLfloat), 1)) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateTexParameteri( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, GLenum pname, + GLint param) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateTexParameteriv( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, GLenum pname, + const GLint* params) { + if (params == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateTexParameterivImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, GLenum pname, + const GLint* params) { + if (params == NULL) { + return parse_error::kParseOutOfBounds; + } + if (!CheckImmediateDataSize<TexParameterivImmediate>( + arg_count, 1, sizeof(GLint), 1)) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateTexSubImage2D( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, + GLenum type, const void* pixels) { + if (pixels == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateTexSubImage2DImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, + GLenum type, const void* pixels) { + if (pixels == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateUniform1f( + GLES2Decoder* decoder, unsigned int arg_count, GLint location, GLfloat x) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateUniform1fv( + GLES2Decoder* decoder, unsigned int arg_count, GLint location, + GLsizei count, const GLfloat* v) { + if (v == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateUniform1fvImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLint location, + GLsizei count, const GLfloat* v) { + if (v == NULL) { + return parse_error::kParseOutOfBounds; + } + if (!CheckImmediateDataSize<Uniform1fvImmediate>( + arg_count, count, sizeof(GLfloat), 1)) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateUniform1i( + GLES2Decoder* decoder, unsigned int arg_count, GLint location, GLint x) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateUniform1iv( + GLES2Decoder* decoder, unsigned int arg_count, GLint location, + GLsizei count, const GLint* v) { + if (v == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateUniform1ivImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLint location, + GLsizei count, const GLint* v) { + if (v == NULL) { + return parse_error::kParseOutOfBounds; + } + if (!CheckImmediateDataSize<Uniform1ivImmediate>( + arg_count, count, sizeof(GLint), 1)) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateUniform2f( + GLES2Decoder* decoder, unsigned int arg_count, GLint location, GLfloat x, + GLfloat y) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateUniform2fv( + GLES2Decoder* decoder, unsigned int arg_count, GLint location, + GLsizei count, const GLfloat* v) { + if (v == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateUniform2fvImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLint location, + GLsizei count, const GLfloat* v) { + if (v == NULL) { + return parse_error::kParseOutOfBounds; + } + if (!CheckImmediateDataSize<Uniform2fvImmediate>( + arg_count, count, sizeof(GLfloat), 2)) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateUniform2i( + GLES2Decoder* decoder, unsigned int arg_count, GLint location, GLint x, + GLint y) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateUniform2iv( + GLES2Decoder* decoder, unsigned int arg_count, GLint location, + GLsizei count, const GLint* v) { + if (v == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateUniform2ivImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLint location, + GLsizei count, const GLint* v) { + if (v == NULL) { + return parse_error::kParseOutOfBounds; + } + if (!CheckImmediateDataSize<Uniform2ivImmediate>( + arg_count, count, sizeof(GLint), 2)) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateUniform3f( + GLES2Decoder* decoder, unsigned int arg_count, GLint location, GLfloat x, + GLfloat y, GLfloat z) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateUniform3fv( + GLES2Decoder* decoder, unsigned int arg_count, GLint location, + GLsizei count, const GLfloat* v) { + if (v == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateUniform3fvImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLint location, + GLsizei count, const GLfloat* v) { + if (v == NULL) { + return parse_error::kParseOutOfBounds; + } + if (!CheckImmediateDataSize<Uniform3fvImmediate>( + arg_count, count, sizeof(GLfloat), 3)) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateUniform3i( + GLES2Decoder* decoder, unsigned int arg_count, GLint location, GLint x, + GLint y, GLint z) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateUniform3iv( + GLES2Decoder* decoder, unsigned int arg_count, GLint location, + GLsizei count, const GLint* v) { + if (v == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateUniform3ivImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLint location, + GLsizei count, const GLint* v) { + if (v == NULL) { + return parse_error::kParseOutOfBounds; + } + if (!CheckImmediateDataSize<Uniform3ivImmediate>( + arg_count, count, sizeof(GLint), 3)) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateUniform4f( + GLES2Decoder* decoder, unsigned int arg_count, GLint location, GLfloat x, + GLfloat y, GLfloat z, GLfloat w) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateUniform4fv( + GLES2Decoder* decoder, unsigned int arg_count, GLint location, + GLsizei count, const GLfloat* v) { + if (v == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateUniform4fvImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLint location, + GLsizei count, const GLfloat* v) { + if (v == NULL) { + return parse_error::kParseOutOfBounds; + } + if (!CheckImmediateDataSize<Uniform4fvImmediate>( + arg_count, count, sizeof(GLfloat), 4)) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateUniform4i( + GLES2Decoder* decoder, unsigned int arg_count, GLint location, GLint x, + GLint y, GLint z, GLint w) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateUniform4iv( + GLES2Decoder* decoder, unsigned int arg_count, GLint location, + GLsizei count, const GLint* v) { + if (v == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateUniform4ivImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLint location, + GLsizei count, const GLint* v) { + if (v == NULL) { + return parse_error::kParseOutOfBounds; + } + if (!CheckImmediateDataSize<Uniform4ivImmediate>( + arg_count, count, sizeof(GLint), 4)) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateUniformMatrix2fv( + GLES2Decoder* decoder, unsigned int arg_count, GLint location, + GLsizei count, GLboolean transpose, const GLfloat* value) { + if (value == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateUniformMatrix2fvImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLint location, + GLsizei count, GLboolean transpose, const GLfloat* value) { + if (value == NULL) { + return parse_error::kParseOutOfBounds; + } + if (!CheckImmediateDataSize<UniformMatrix2fvImmediate>( + arg_count, count, sizeof(GLfloat), 4)) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateUniformMatrix3fv( + GLES2Decoder* decoder, unsigned int arg_count, GLint location, + GLsizei count, GLboolean transpose, const GLfloat* value) { + if (value == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateUniformMatrix3fvImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLint location, + GLsizei count, GLboolean transpose, const GLfloat* value) { + if (value == NULL) { + return parse_error::kParseOutOfBounds; + } + if (!CheckImmediateDataSize<UniformMatrix3fvImmediate>( + arg_count, count, sizeof(GLfloat), 9)) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateUniformMatrix4fv( + GLES2Decoder* decoder, unsigned int arg_count, GLint location, + GLsizei count, GLboolean transpose, const GLfloat* value) { + if (value == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateUniformMatrix4fvImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLint location, + GLsizei count, GLboolean transpose, const GLfloat* value) { + if (value == NULL) { + return parse_error::kParseOutOfBounds; + } + if (!CheckImmediateDataSize<UniformMatrix4fvImmediate>( + arg_count, count, sizeof(GLfloat), 16)) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateUseProgram( + GLES2Decoder* decoder, unsigned int arg_count, GLuint program) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateValidateProgram( + GLES2Decoder* decoder, unsigned int arg_count, GLuint program) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateVertexAttrib1f( + GLES2Decoder* decoder, unsigned int arg_count, GLuint indx, GLfloat x) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateVertexAttrib1fv( + GLES2Decoder* decoder, unsigned int arg_count, GLuint indx, + const GLfloat* values) { + if (values == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateVertexAttrib1fvImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLuint indx, + const GLfloat* values) { + if (values == NULL) { + return parse_error::kParseOutOfBounds; + } + if (!CheckImmediateDataSize<VertexAttrib1fvImmediate>( + arg_count, 1, sizeof(GLfloat), 1)) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateVertexAttrib2f( + GLES2Decoder* decoder, unsigned int arg_count, GLuint indx, GLfloat x, + GLfloat y) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateVertexAttrib2fv( + GLES2Decoder* decoder, unsigned int arg_count, GLuint indx, + const GLfloat* values) { + if (values == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateVertexAttrib2fvImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLuint indx, + const GLfloat* values) { + if (values == NULL) { + return parse_error::kParseOutOfBounds; + } + if (!CheckImmediateDataSize<VertexAttrib2fvImmediate>( + arg_count, 1, sizeof(GLfloat), 2)) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateVertexAttrib3f( + GLES2Decoder* decoder, unsigned int arg_count, GLuint indx, GLfloat x, + GLfloat y, GLfloat z) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateVertexAttrib3fv( + GLES2Decoder* decoder, unsigned int arg_count, GLuint indx, + const GLfloat* values) { + if (values == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateVertexAttrib3fvImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLuint indx, + const GLfloat* values) { + if (values == NULL) { + return parse_error::kParseOutOfBounds; + } + if (!CheckImmediateDataSize<VertexAttrib3fvImmediate>( + arg_count, 1, sizeof(GLfloat), 3)) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateVertexAttrib4f( + GLES2Decoder* decoder, unsigned int arg_count, GLuint indx, GLfloat x, + GLfloat y, GLfloat z, GLfloat w) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateVertexAttrib4fv( + GLES2Decoder* decoder, unsigned int arg_count, GLuint indx, + const GLfloat* values) { + if (values == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateVertexAttrib4fvImmediate( + GLES2Decoder* decoder, unsigned int arg_count, GLuint indx, + const GLfloat* values) { + if (values == NULL) { + return parse_error::kParseOutOfBounds; + } + if (!CheckImmediateDataSize<VertexAttrib4fvImmediate>( + arg_count, 1, sizeof(GLfloat), 4)) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateVertexAttribPointer( + GLES2Decoder* decoder, unsigned int arg_count, GLuint indx, GLint size, + GLenum type, GLboolean normalized, GLsizei stride, const void* ptr) { + if (ptr == NULL) { + return parse_error::kParseOutOfBounds; + } + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateViewport( + GLES2Decoder* decoder, unsigned int arg_count, GLint x, GLint y, + GLsizei width, GLsizei height) { + return parse_error::kParseNoError; +} +parse_error::ParseError ValidateSwapBuffers( + GLES2Decoder* decoder, unsigned int arg_count) { + return parse_error::kParseNoError; +} +} // anonymous namespace +} // namespace gles2 +} // namespace command_buffer + diff --git a/gpu/command_buffer/service/gpu_processor.cc b/gpu/command_buffer/service/gpu_processor.cc new file mode 100644 index 0000000..845d5b6 --- /dev/null +++ b/gpu/command_buffer/service/gpu_processor.cc @@ -0,0 +1,84 @@ +// Copyright (c) 2006-2008 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/gpu_processor.h" +#include "gpu/np_utils/np_browser.h" + +using ::base::SharedMemory; +using np_utils::NPBrowser; + +namespace command_buffer { + +GPUProcessor::~GPUProcessor() { +} + +namespace { +void InvokeProcessCommands(void* data) { + static_cast<GPUProcessor*>(data)->ProcessCommands(); +} +} // namespace anonymous + +void GPUProcessor::ProcessCommands() { + if (command_buffer_->GetErrorStatus()) + return; + + parser_->set_put(command_buffer_->GetPutOffset()); + + int commands_processed = 0; + while (commands_processed < commands_per_update_ && !parser_->IsEmpty()) { + command_buffer::parse_error::ParseError parse_error = + parser_->ProcessCommand(); + switch (parse_error) { + case command_buffer::parse_error::kParseUnknownCommand: + case command_buffer::parse_error::kParseInvalidArguments: + command_buffer_->SetParseError(parse_error); + break; + + case command_buffer::parse_error::kParseInvalidSize: + case command_buffer::parse_error::kParseOutOfBounds: + command_buffer_->SetParseError(parse_error); + command_buffer_->RaiseErrorStatus(); + return; + } + + ++commands_processed; + } + + command_buffer_->SetGetOffset(static_cast<int32>(parser_->get())); + + if (!parser_->IsEmpty()) { + NPBrowser::get()->PluginThreadAsyncCall(npp_, InvokeProcessCommands, this); + } +} + +void *GPUProcessor::GetSharedMemoryAddress(int32 shm_id) { + ::base::SharedMemory* shared_memory = + command_buffer_->GetTransferBuffer(shm_id); + if (!shared_memory) + return NULL; + + if (!shared_memory->memory()) { + if (!shared_memory->Map(shared_memory->max_size())) + return NULL; + } + + return shared_memory->memory(); +} + +// TODO(apatrick): Consolidate this with the above and return both the address +// and size. +size_t GPUProcessor::GetSharedMemorySize(int32 shm_id) { + ::base::SharedMemory* shared_memory = + command_buffer_->GetTransferBuffer(shm_id); + if (!shared_memory) + return 0; + + return shared_memory->max_size(); +} + +void GPUProcessor::set_token(int32 token) { + command_buffer_->SetToken(token); +} + +} // namespace command_buffer diff --git a/gpu/command_buffer/service/gpu_processor.h b/gpu/command_buffer/service/gpu_processor.h new file mode 100644 index 0000000..786e504 --- /dev/null +++ b/gpu/command_buffer/service/gpu_processor.h @@ -0,0 +1,99 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_GPU_PROCESSOR_H_ +#define GPU_COMMAND_BUFFER_SERVICE_GPU_PROCESSOR_H_ + +#include "base/ref_counted.h" +#include "base/scoped_ptr.h" +#include "base/shared_memory.h" +#include "gpu/command_buffer/common/command_buffer.h" +#include "gpu/command_buffer/service/cmd_buffer_engine.h" +#include "gpu/command_buffer/service/cmd_parser.h" +#include "gpu/command_buffer/service/gles2_cmd_decoder.h" +#include "gpu/np_utils/np_object_pointer.h" + +namespace command_buffer { + +// This class processes commands in a command buffer. It is event driven and +// posts tasks to the current message loop to do additional work. +class GPUProcessor : public ::base::RefCounted<GPUProcessor>, + public command_buffer::CommandBufferEngine { + public: + GPUProcessor(NPP npp, CommandBuffer* command_buffer); + + // This constructor is for unit tests. + GPUProcessor(CommandBuffer* command_buffer, + gles2::GLES2Decoder* decoder, + CommandParser* parser, + int commands_per_update); + + virtual bool Initialize(HWND hwnd); + + virtual ~GPUProcessor(); + + virtual void Destroy(); + + virtual void ProcessCommands(); + +#if defined(OS_WIN) + virtual bool SetWindow(HWND handle, int width, int height); +#endif + + // Implementation of CommandBufferEngine. + + // Gets the base address of a registered shared memory buffer. + // Parameters: + // shm_id: the identifier for the shared memory buffer. + virtual void *GetSharedMemoryAddress(int32 shm_id); + + // Gets the size of a registered shared memory buffer. + // Parameters: + // shm_id: the identifier for the shared memory buffer. + virtual size_t GetSharedMemorySize(int32 shm_id); + + // Sets the token value. + virtual void set_token(int32 token); + + private: + NPP npp_; + + // The GPUProcessor holds a weak reference to the CommandBuffer. The + // CommandBuffer owns the GPUProcessor and holds a strong reference to it + // through the ProcessCommands callback. + CommandBuffer* command_buffer_; + + scoped_ptr< ::base::SharedMemory> mapped_ring_buffer_; + int commands_per_update_; + + scoped_ptr<gles2::GLES2Decoder> decoder_; + scoped_ptr<CommandParser> parser_; +}; + +} // namespace command_buffer + +// Callbacks to the GPUProcessor hold a reference count. +template <typename Method> +class CallbackStorage<command_buffer::GPUProcessor, Method> { + public: + CallbackStorage(command_buffer::GPUProcessor* obj, Method method) + : obj_(obj), + meth_(method) { + DCHECK(obj_); + obj_->AddRef(); + } + + ~CallbackStorage() { + obj_->Release(); + } + + protected: + command_buffer::GPUProcessor* obj_; + Method meth_; + + private: + DISALLOW_COPY_AND_ASSIGN(CallbackStorage); +}; + +#endif // GPU_COMMAND_BUFFER_SERVICE_GPU_PROCESSOR_H_ diff --git a/gpu/command_buffer/service/gpu_processor_mock.h b/gpu/command_buffer/service/gpu_processor_mock.h new file mode 100644 index 0000000..d65965f --- /dev/null +++ b/gpu/command_buffer/service/gpu_processor_mock.h @@ -0,0 +1,40 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_GPU_PROCESSOR_MOCK_H_ +#define GPU_COMMAND_BUFFER_SERVICE_GPU_PROCESSOR_MOCK_H_ + +#include "gpu/command_buffer/service/gpu_processor.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace command_buffer { + +class MockGPUProcessor : public GPUProcessor { + public: + explicit MockGPUProcessor(CommandBuffer* command_buffer) + : GPUProcessor(NULL, command_buffer) { + } + +#if defined(OS_WIN) + MOCK_METHOD1(Initialize, bool(HWND handle)); +#endif + + MOCK_METHOD0(Destroy, void()); + MOCK_METHOD0(ProcessCommands, void()); + +#if defined(OS_WIN) + MOCK_METHOD3(SetWindow, bool(HWND handle, int width, int height)); +#endif + + MOCK_METHOD1(GetSharedMemoryAddress, void*(int32 shm_id)); + MOCK_METHOD1(GetSharedMemorySize, size_t(int32 shm_id)); + MOCK_METHOD1(set_token, void(int32 token)); + + private: + DISALLOW_COPY_AND_ASSIGN(MockGPUProcessor); +}; + +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_SERVICE_GPU_PROCESSOR_MOCK_H_ diff --git a/gpu/command_buffer/service/gpu_processor_unittest.cc b/gpu/command_buffer/service/gpu_processor_unittest.cc new file mode 100644 index 0000000..89a9392 --- /dev/null +++ b/gpu/command_buffer/service/gpu_processor_unittest.cc @@ -0,0 +1,285 @@ +// Copyright (c) 2006-2008 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 "base/at_exit.h" +#include "base/message_loop.h" +#include "gpu/command_buffer/common/command_buffer_mock.h" +#include "gpu/command_buffer/service/mocks.h" +#include "gpu/command_buffer/service/gpu_processor.h" +#include "gpu/command_buffer/service/gles2_cmd_decoder.h" +#include "gpu/np_utils/np_browser_mock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/gmock/include/gmock/gmock.h" + +using testing::_; +using testing::DoAll; +using testing::Invoke; +using testing::NiceMock; +using testing::Return; +using testing::SetArgumentPointee; +using testing::StrictMock; + +namespace command_buffer { + +const size_t kRingBufferSize = 1024; +const size_t kRingBufferEntries = kRingBufferSize / sizeof(int32); + +class GPUProcessorTest : public testing::Test { + protected: + virtual void SetUp() { + shared_memory_.reset(new ::base::SharedMemory); + shared_memory_->Create(std::wstring(), false, false, kRingBufferSize); + shared_memory_->Map(kRingBufferSize); + buffer_ = static_cast<int32*>(shared_memory_->memory()); + + memset(buffer_, 0, kRingBufferSize); + + // Don't mock PluginThreadAsyncCall. Have it schedule the task. + ON_CALL(mock_browser_, PluginThreadAsyncCall(_, _, _)) + .WillByDefault( + Invoke(&mock_browser_, + &np_utils::MockNPBrowser::ConcretePluginThreadAsyncCall)); + + command_buffer_.reset(new MockCommandBuffer); + ON_CALL(*command_buffer_.get(), GetRingBuffer()) + .WillByDefault(Return(shared_memory_.get())); + ON_CALL(*command_buffer_.get(), GetSize()) + .WillByDefault(Return(kRingBufferEntries)); + + async_api_.reset(new StrictMock<command_buffer::AsyncAPIMock>); + + decoder_ = gles2::GLES2Decoder::Create(); + + parser_ = new command_buffer::CommandParser(buffer_, + kRingBufferEntries, + 0, + kRingBufferEntries, + 0, + async_api_.get()); + + processor_ = new GPUProcessor(command_buffer_.get(), + decoder_, + parser_, + 2); + } + + virtual void TearDown() { + // Ensure that any unexpected tasks posted by the GPU processor are executed + // in order to fail the test. + MessageLoop::current()->RunAllPending(); + } + + base::AtExitManager at_exit_manager; + MessageLoop message_loop; + np_utils::MockNPBrowser mock_browser_; + scoped_ptr<MockCommandBuffer> command_buffer_; + scoped_ptr<::base::SharedMemory> shared_memory_; + int32* buffer_; + command_buffer::gles2::GLES2Decoder* decoder_; + command_buffer::CommandParser* parser_; + scoped_ptr<command_buffer::AsyncAPIMock> async_api_; + scoped_refptr<GPUProcessor> processor_; +}; + +TEST_F(GPUProcessorTest, ProcessorDoesNothingIfRingBufferIsEmpty) { + EXPECT_CALL(*command_buffer_, GetPutOffset()) + .WillOnce(Return(0)); + EXPECT_CALL(*command_buffer_, SetGetOffset(0)); + + processor_->ProcessCommands(); + + EXPECT_EQ(command_buffer::parse_error::kParseNoError, + command_buffer_->ResetParseError()); + EXPECT_FALSE(command_buffer_->GetErrorStatus()); +} + +TEST_F(GPUProcessorTest, ProcessesOneCommand) { + command_buffer::CommandHeader* header = + reinterpret_cast<command_buffer::CommandHeader*>(&buffer_[0]); + header[0].command = 7; + header[0].size = 2; + buffer_[1] = 123; + + EXPECT_CALL(*command_buffer_, GetPutOffset()) + .WillOnce(Return(2)); + EXPECT_CALL(*command_buffer_, SetGetOffset(2)); + + EXPECT_CALL(*async_api_, DoCommand(7, 1, &buffer_[0])) + .WillOnce(Return(command_buffer::parse_error::kParseNoError)); + + processor_->ProcessCommands(); + + EXPECT_EQ(command_buffer::parse_error::kParseNoError, + command_buffer_->ResetParseError()); + EXPECT_FALSE(command_buffer_->GetErrorStatus()); +} + +TEST_F(GPUProcessorTest, ProcessesTwoCommands) { + command_buffer::CommandHeader* header = + reinterpret_cast<command_buffer::CommandHeader*>(&buffer_[0]); + header[0].command = 7; + header[0].size = 2; + buffer_[1] = 123; + header[2].command = 8; + header[2].size = 1; + + EXPECT_CALL(*command_buffer_, GetPutOffset()) + .WillOnce(Return(3)); + EXPECT_CALL(*command_buffer_, SetGetOffset(3)); + + EXPECT_CALL(*async_api_, DoCommand(7, 1, &buffer_[0])) + .WillOnce(Return(command_buffer::parse_error::kParseNoError)); + + EXPECT_CALL(*async_api_, DoCommand(8, 0, &buffer_[2])) + .WillOnce(Return(command_buffer::parse_error::kParseNoError)); + + processor_->ProcessCommands(); +} + +TEST_F(GPUProcessorTest, PostsTaskToFinishRemainingCommands) { + command_buffer::CommandHeader* header = + reinterpret_cast<command_buffer::CommandHeader*>(&buffer_[0]); + header[0].command = 7; + header[0].size = 2; + buffer_[1] = 123; + header[2].command = 8; + header[2].size = 1; + header[3].command = 9; + header[3].size = 1; + + EXPECT_CALL(*command_buffer_, GetPutOffset()) + .WillOnce(Return(4)); + + EXPECT_CALL(*async_api_, DoCommand(7, 1, &buffer_[0])) + .WillOnce(Return(command_buffer::parse_error::kParseNoError)); + + EXPECT_CALL(*async_api_, DoCommand(8, 0, &buffer_[2])) + .WillOnce(Return(command_buffer::parse_error::kParseNoError)); + + EXPECT_CALL(*command_buffer_, SetGetOffset(3)); + + processor_->ProcessCommands(); + + // ProcessCommands is called a second time when the pending task is run. + + EXPECT_CALL(*command_buffer_, GetPutOffset()) + .WillOnce(Return(4)); + + EXPECT_CALL(*async_api_, DoCommand(9, 0, &buffer_[3])) + .WillOnce(Return(command_buffer::parse_error::kParseNoError)); + + EXPECT_CALL(*command_buffer_, SetGetOffset(4)); + + MessageLoop::current()->RunAllPending(); +} + +TEST_F(GPUProcessorTest, SetsErrorCodeOnCommandBuffer) { + command_buffer::CommandHeader* header = + reinterpret_cast<command_buffer::CommandHeader*>(&buffer_[0]); + header[0].command = 7; + header[0].size = 1; + + EXPECT_CALL(*command_buffer_, GetPutOffset()) + .WillOnce(Return(1)); + EXPECT_CALL(*command_buffer_, SetGetOffset(1)); + + EXPECT_CALL(*async_api_, DoCommand(7, 0, &buffer_[0])) + .WillOnce(Return( + command_buffer::parse_error::kParseUnknownCommand)); + + EXPECT_CALL(*command_buffer_, + SetParseError(command_buffer::parse_error::kParseUnknownCommand)); + + processor_->ProcessCommands(); +} + +TEST_F(GPUProcessorTest, + RecoverableParseErrorsAreNotClearedByFollowingSuccessfulCommands) { + command_buffer::CommandHeader* header = + reinterpret_cast<command_buffer::CommandHeader*>(&buffer_[0]); + header[0].command = 7; + header[0].size = 1; + header[1].command = 8; + header[1].size = 1; + + EXPECT_CALL(*command_buffer_, GetPutOffset()) + .WillOnce(Return(2)); + EXPECT_CALL(*command_buffer_, SetGetOffset(2)); + + EXPECT_CALL(*async_api_, DoCommand(7, 0, &buffer_[0])) + .WillOnce(Return( + command_buffer::parse_error::kParseUnknownCommand)); + + EXPECT_CALL(*async_api_, DoCommand(8, 0, &buffer_[1])) + .WillOnce(Return(command_buffer::parse_error::kParseNoError)); + + EXPECT_CALL(*command_buffer_, + SetParseError(command_buffer::parse_error::kParseUnknownCommand)); + + processor_->ProcessCommands(); +} + +TEST_F(GPUProcessorTest, UnrecoverableParseErrorsRaiseTheErrorStatus) { + command_buffer::CommandHeader* header = + reinterpret_cast<command_buffer::CommandHeader*>(&buffer_[0]); + header[0].command = 7; + header[0].size = 1; + header[1].command = 8; + header[1].size = 1; + + EXPECT_CALL(*command_buffer_, GetPutOffset()) + .WillOnce(Return(2)); + + EXPECT_CALL(*async_api_, DoCommand(7, 0, &buffer_[0])) + .WillOnce(Return(command_buffer::parse_error::kParseInvalidSize)); + + EXPECT_CALL(*command_buffer_, + SetParseError(command_buffer::parse_error::kParseInvalidSize)); + + EXPECT_CALL(*command_buffer_, RaiseErrorStatus()); + + processor_->ProcessCommands(); +} + +TEST_F(GPUProcessorTest, ProcessCommandsDoesNothingAfterUnrecoverableError) { + EXPECT_CALL(*command_buffer_, GetErrorStatus()) + .WillOnce(Return(true)); + + EXPECT_CALL(*command_buffer_, GetPutOffset()) + .Times(0); + + processor_->ProcessCommands(); +} + +TEST_F(GPUProcessorTest, CanGetAddressOfSharedMemory) { + EXPECT_CALL(*command_buffer_.get(), GetTransferBuffer(7)) + .WillOnce(Return(shared_memory_.get())); + + EXPECT_EQ(&buffer_[0], processor_->GetSharedMemoryAddress(7)); +} + +ACTION_P2(SetPointee, address, value) { + *address = value; +} + +TEST_F(GPUProcessorTest, GetAddressOfSharedMemoryMapsMemoryIfUnmapped) { + EXPECT_CALL(*command_buffer_.get(), GetTransferBuffer(7)) + .WillOnce(Return(shared_memory_.get())); + + EXPECT_EQ(&buffer_[0], processor_->GetSharedMemoryAddress(7)); +} + +TEST_F(GPUProcessorTest, CanGetSizeOfSharedMemory) { + EXPECT_CALL(*command_buffer_.get(), GetTransferBuffer(7)) + .WillOnce(Return(shared_memory_.get())); + + EXPECT_EQ(kRingBufferSize, processor_->GetSharedMemorySize(7)); +} + +TEST_F(GPUProcessorTest, SetTokenForwardsToCommandBuffer) { + EXPECT_CALL(*command_buffer_, SetToken(7)); + processor_->set_token(7); +} + +} // namespace command_buffer diff --git a/gpu/command_buffer/service/gpu_processor_win.cc b/gpu/command_buffer/service/gpu_processor_win.cc new file mode 100644 index 0000000..d672c12 --- /dev/null +++ b/gpu/command_buffer/service/gpu_processor_win.cc @@ -0,0 +1,80 @@ +// Copyright (c) 2006-2008 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 <windows.h> + +#include "gpu/command_buffer/service/gpu_processor.h" + +using ::base::SharedMemory; + +namespace command_buffer { + +GPUProcessor::GPUProcessor(NPP npp, CommandBuffer* command_buffer) + : npp_(npp), + command_buffer_(command_buffer), + commands_per_update_(100) { + DCHECK(command_buffer); + decoder_.reset(gles2::GLES2Decoder::Create()); + decoder_->set_engine(this); +} + +GPUProcessor::GPUProcessor(CommandBuffer* command_buffer, + gles2::GLES2Decoder* decoder, + CommandParser* parser, + int commands_per_update) + : npp_(NULL), + command_buffer_(command_buffer), + commands_per_update_(commands_per_update) { + DCHECK(command_buffer); + decoder_.reset(decoder); + parser_.reset(parser); +} + +bool GPUProcessor::Initialize(HWND handle) { + DCHECK(handle); + + // Cannot reinitialize. + if (decoder_->hwnd() != NULL) + return false; + + // Map the ring buffer and create the parser. + ::base::SharedMemory* ring_buffer = command_buffer_->GetRingBuffer(); + if (ring_buffer) { + size_t size = ring_buffer->max_size(); + if (!ring_buffer->Map(size)) { + return false; + } + + void* ptr = ring_buffer->memory(); + parser_.reset(new command_buffer::CommandParser(ptr, size, 0, size, 0, + decoder_.get())); + } else { + parser_.reset(new command_buffer::CommandParser(NULL, 0, 0, 0, 0, + decoder_.get())); + } + + // Initialize GAPI immediately if the window handle is valid. + decoder_->set_hwnd(handle); + return decoder_->Initialize(); +} + +void GPUProcessor::Destroy() { + // Destroy GAPI if window handle has not already become invalid. + if (decoder_->hwnd()) { + decoder_->Destroy(); + decoder_->set_hwnd(NULL); + } +} + +bool GPUProcessor::SetWindow(HWND handle, int width, int height) { + if (handle == NULL) { + // Destroy GAPI when the window handle becomes invalid. + Destroy(); + return true; + } else { + return Initialize(handle); + } +} + +} // namespace command_buffer diff --git a/gpu/command_buffer/service/mocks.h b/gpu/command_buffer/service/mocks.h new file mode 100644 index 0000000..3d85e32 --- /dev/null +++ b/gpu/command_buffer/service/mocks.h @@ -0,0 +1,108 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains definitions for mock objects, used for testing. + +// TODO: This file "manually" defines some mock objects. Using gMock +// would be definitely preferable, unfortunately it doesn't work on Windows +// yet. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_CROSS_MOCKS_H_ +#define GPU_COMMAND_BUFFER_SERVICE_CROSS_MOCKS_H_ + +#include <vector> +#include "testing/gmock/include/gmock/gmock.h" +#include "gpu/command_buffer/service/cmd_parser.h" +#include "gpu/command_buffer/service/cmd_buffer_engine.h" + +namespace command_buffer { + +// Mocks an AsyncAPIInterface, using GMock. +class AsyncAPIMock : public AsyncAPIInterface { + public: + AsyncAPIMock() { + testing::DefaultValue<parse_error::ParseError>::Set( + parse_error::kParseNoError); + } + + // Predicate that matches args passed to DoCommand, by looking at the values. + class IsArgs { + public: + IsArgs(unsigned int arg_count, const void* args) + : arg_count_(arg_count), + args_(static_cast<CommandBufferEntry*>(const_cast<void*>(args))) { + } + + bool operator() (const void* _args) const { + const CommandBufferEntry* args = + static_cast<const CommandBufferEntry*>(_args) + 1; + for (unsigned int i = 0; i < arg_count_; ++i) { + if (args[i].value_uint32 != args_[i].value_uint32) return false; + } + return true; + } + + private: + unsigned int arg_count_; + CommandBufferEntry *args_; + }; + + MOCK_METHOD3(DoCommand, parse_error::ParseError( + unsigned int command, + unsigned int arg_count, + const void* cmd_data)); + + const char* GetCommandName(unsigned int command_id) const { + return ""; + }; + + // Sets the engine, to forward SetToken commands to it. + void set_engine(CommandBufferEngine *engine) { engine_ = engine; } + + // Forwards the SetToken commands to the engine. + void SetToken(unsigned int command, + unsigned int arg_count, + const void* _args) { + DCHECK(engine_); + DCHECK_EQ(1u, command); + DCHECK_EQ(1u, arg_count); + const CommandBufferEntry* args = + static_cast<const CommandBufferEntry*>(_args); + engine_->set_token(args[0].value_uint32); + } + private: + CommandBufferEngine *engine_; +}; + +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_SERVICE_CROSS_MOCKS_H_ diff --git a/gpu/command_buffer/service/precompile.cc b/gpu/command_buffer/service/precompile.cc new file mode 100644 index 0000000..3e219b0 --- /dev/null +++ b/gpu/command_buffer/service/precompile.cc @@ -0,0 +1,33 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "gpu/command_buffer/service/precompile.h" diff --git a/gpu/command_buffer/service/precompile.h b/gpu/command_buffer/service/precompile.h new file mode 100644 index 0000000..55d2b21 --- /dev/null +++ b/gpu/command_buffer/service/precompile.h @@ -0,0 +1,50 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains includes for common headers used by command buffer server +// files. It is used for pre-compiled header support. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_CROSS_PRECOMPILE_H_ +#define GPU_COMMAND_BUFFER_SERVICE_CROSS_PRECOMPILE_H_ + +#include <build/build_config.h> + +#if defined(OS_WIN) +#include <windows.h> +#endif + +#include <assert.h> +#include <algorithm> +#include <map> +#include <vector> + +#endif // O3D_CORE_CROSS_PRECOMPILE_H_ diff --git a/gpu/command_buffer/service/resource.cc b/gpu/command_buffer/service/resource.cc new file mode 100644 index 0000000..1208d30 --- /dev/null +++ b/gpu/command_buffer/service/resource.cc @@ -0,0 +1,101 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the implementation of ResourceMapBase. + +#include "gpu/command_buffer/service/precompile.h" +#include "gpu/command_buffer/service/resource.h" + +namespace command_buffer { + +// Assigns a resource to a resource ID, by setting it at the right location +// into the list, resizing the list if necessary, and destroying an existing +// resource if one existed already. +void ResourceMapBase::Assign(ResourceId id, Resource *resource) { + if (id >= resources_.size()) { + resources_.resize(id + 1, NULL); + } else { + Resource *&entry = resources_[id]; + if (entry) { + delete entry; + entry = NULL; + } + } + DCHECK(resources_[id] == NULL); + resources_[id] = resource; +} + +// Destroys a resource contained in the map, setting its entry to NULL. If +// necessary, this will trim the list. +bool ResourceMapBase::Destroy(ResourceId id) { + if (id >= resources_.size()) { + return false; + } + Resource *&entry = resources_[id]; + if (entry) { + delete entry; + entry = NULL; + + // Removing the last element, we can trim the list. + // TODO: this may not be optimal to do every time. Investigate if it + // becomes an issue, and add a threshold before we resize. + if (id == resources_.size() - 1) { + size_t last_valid = resources_.max_size(); + for (unsigned int i = id; i < resources_.size(); --i) { + if (resources_[i]) { + last_valid = i; + break; + } + } + if (last_valid == resources_.max_size()) { + resources_.clear(); + } else { + resources_.resize(last_valid + 1); + } + } + return true; + } + return false; +} + +// Goes over all non-NULL entries in the list, destroying them, then clears the +// list. +void ResourceMapBase::DestroyAllResources() { + for (Container::iterator i = resources_.begin(); i != resources_.end(); ++i) { + if (*i) { + delete *i; + } + } + resources_.clear(); +} + +} // namespace command_buffer diff --git a/gpu/command_buffer/service/resource.h b/gpu/command_buffer/service/resource.h new file mode 100644 index 0000000..20e3038 --- /dev/null +++ b/gpu/command_buffer/service/resource.h @@ -0,0 +1,268 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file contains the definition for resource classes and the resource map. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_CROSS_RESOURCE_H_ +#define GPU_COMMAND_BUFFER_SERVICE_CROSS_RESOURCE_H_ + +#include <vector> +#include "base/scoped_ptr.h" +#include "gpu/command_buffer/common/resource.h" + +namespace command_buffer { + +// Base class for resources, just providing a common Destroy function. +class Resource { + public: + Resource() {} + virtual ~Resource() {} + private: + DISALLOW_COPY_AND_ASSIGN(Resource); +}; + +// VertexBuffer class, representing a vertex buffer resource. +class VertexBuffer: public Resource { + public: + VertexBuffer(unsigned int size, unsigned int flags) + : size_(size), + flags_(flags) {} + virtual ~VertexBuffer() {} + + // Returns the vertex buffer flags. + unsigned int flags() const { return flags_; } + // Sets the vertex buffer flags. + void set_flags(unsigned int flags) { flags_ = flags; } + // Returns the vertex buffer size. + unsigned int size() const { return size_; } + // Sets the vertex buffer size. + void set_size(unsigned int size) { size_ = size; } + protected: + unsigned int size_; + unsigned int flags_; + private: + DISALLOW_COPY_AND_ASSIGN(VertexBuffer); +}; + +// IndexBuffer class, representing an index buffer resource. +class IndexBuffer: public Resource { + public: + IndexBuffer(unsigned int size, unsigned int flags) + : size_(size), + flags_(flags) {} + virtual ~IndexBuffer() {} + + // Returns the index buffer flags. + unsigned int flags() const { return flags_; } + // Sets the index buffer flags. + void set_flags(unsigned int flags) { flags_ = flags; } + // Returns the index buffer size. + unsigned int size() const { return size_; } + // Sets the index buffer size. + void set_size(unsigned int size) { size_ = size; } + protected: + unsigned int size_; + unsigned int flags_; + private: + DISALLOW_COPY_AND_ASSIGN(IndexBuffer); +}; + +// VertexStruct class, representing a vertex struct resource. +class VertexStruct: public Resource { + public: + // The representation of an input data stream. + struct Element { + ResourceId vertex_buffer; + unsigned int offset; + unsigned int stride; + vertex_struct::Type type; + vertex_struct::Semantic semantic; + unsigned int semantic_index; + }; + + explicit VertexStruct(unsigned int count) + : count_(count), + elements_(new Element[count]) { + memset(elements_.get(), 0, count * sizeof(Element)); // NOLINT + } + + // Returns the number of inputs in this struct. + unsigned int count() const { return count_; } + // Returns an element by index. + Element &GetElement(unsigned int i) { + DCHECK_GT(count_, i); + return elements_[i]; + } + protected: + unsigned int count_; + scoped_array<Element> elements_; + private: + DISALLOW_COPY_AND_ASSIGN(VertexStruct); +}; + +// Effect class, representing an effect. +class Effect: public Resource { + public: + Effect() {} + private: + DISALLOW_COPY_AND_ASSIGN(Effect); +}; + +// EffectParam class, representing an effect parameter. +class EffectParam: public Resource { + public: + explicit EffectParam(effect_param::DataType data_type) + : data_type_(data_type) { + } + + // Gets the data type of this parameter. + effect_param::DataType data_type() const { return data_type_; } + private: + effect_param::DataType data_type_; + DISALLOW_COPY_AND_ASSIGN(EffectParam); +}; + +// Texture class, representing a texture resource. +class Texture: public Resource { + public: + Texture(texture::Type type, + unsigned int levels, + texture::Format format, + bool enable_render_surfaces, + unsigned int flags) + : type_(type), + levels_(levels), + format_(format), + render_surfaces_enabled_(enable_render_surfaces), + flags_(flags) {} + virtual ~Texture() {} + + // Returns the type of the texture. + texture::Type type() const { return type_; } + // Returns the texture flags. + unsigned int flags() const { return flags_; } + // Returns the texture format. + texture::Format format() const { return format_; } + // Returns whether the texture supports render surfaces + bool render_surfaces_enabled() const { return render_surfaces_enabled_; } + // Returns the number of mipmap levels in the texture. + unsigned int levels() const { return levels_; } + private: + texture::Type type_; + unsigned int levels_; + texture::Format format_; + bool render_surfaces_enabled_; + unsigned int flags_; + DISALLOW_COPY_AND_ASSIGN(Texture); +}; + +// RenderSurface class, representing a render surface/target +class RenderSurface: public Resource { + public: + RenderSurface() {} + private: + DISALLOW_COPY_AND_ASSIGN(RenderSurface); +}; + +// RenderSurface class, representing a render surface/target +class RenderDepthStencilSurface: public Resource { + public: + RenderDepthStencilSurface() {} + private: + DISALLOW_COPY_AND_ASSIGN(RenderDepthStencilSurface); +}; + + +// Texture class, representing a sampler resource. +class Sampler: public Resource { + public: + Sampler() {} + private: + DISALLOW_COPY_AND_ASSIGN(Sampler); +}; + +// Base of ResourceMap. Contains most of the implementation of ResourceMap, to +// avoid template bloat. +class ResourceMapBase { + public: + ResourceMapBase() : resources_() {} + ~ResourceMapBase() {} + + // Assigns a resource to a resource ID. Assigning a resource to an ID that + // already has an existing resource will destroy that existing resource. The + // map takes ownership of the resource. + void Assign(ResourceId id, Resource* resource); + // Destroys a resource. + bool Destroy(ResourceId id); + // Destroy all resources. + void DestroyAllResources(); + // Gets a resource by ID. + Resource *Get(ResourceId id) { + return (id < resources_.size()) ? resources_[id] : NULL; + } + private: + typedef std::vector<Resource *> Container; + Container resources_; +}; + +// Resource Map class, allowing resource ID <-> Resource association. This is a +// dense map, optimized for retrieval (O(1)). +template<class T> class ResourceMap { + public: + ResourceMap() : container_() {} + ~ResourceMap() {} + + // Assigns a resource to a resource ID. Assigning a resource to an ID that + // already has an existing resource will destroy that existing resource. The + // map takes ownership of the resource. + void Assign(ResourceId id, T* resource) { + container_.Assign(id, resource); + } + // Destroys a resource. + bool Destroy(ResourceId id) { + return container_.Destroy(id); + } + // Destroy all resources. + void DestroyAllResources() { + return container_.DestroyAllResources(); + } + // Gets a resource by ID. + T *Get(ResourceId id) { + return static_cast<T*>(container_.Get(id)); + } + private: + ResourceMapBase container_; +}; + +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_SERVICE_CROSS_RESOURCE_H_ diff --git a/gpu/command_buffer/service/resource_test.cc b/gpu/command_buffer/service/resource_test.cc new file mode 100644 index 0000000..7a9438b --- /dev/null +++ b/gpu/command_buffer/service/resource_test.cc @@ -0,0 +1,127 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// Tests for the ResourceMap. + +#include "gpu/command_buffer/service/precompile.h" +#include "gpu/command_buffer/service/resource.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace command_buffer { + +// Mock resource implementation that checks for leaks. +class ResourceMock : public Resource { + public: + ResourceMock() : Resource() { + ++instance_count_; + } + virtual ~ResourceMock() { + --instance_count_; + } + + // Returns the instance count. The instance count is increased in the + // constructor and decreased in the destructor, to track leaks. The reason is + // that we can't mock the destructor, though we want to make sure the mock is + // destroyed. + static int instance_count() { return instance_count_; } + private: + static int instance_count_; + DISALLOW_COPY_AND_ASSIGN(ResourceMock); +}; +int ResourceMock::instance_count_ = 0; + +// Test fixture for ResourceMap test. Creates a ResourceMap using a mock +// Resource, and checks for ResourceMock leaks. +class ResourceMapTest : public testing::Test { + protected: + typedef ResourceMap<ResourceMock> Map; + virtual void SetUp() { + instance_count_ = ResourceMock::instance_count(); + map_.reset(new Map()); + } + virtual void TearDown() { + CheckLeaks(); + } + + // Makes sure we didn't leak any ResourceMock object. + void CheckLeaks() { + EXPECT_EQ(instance_count_, ResourceMock::instance_count()); + } + + Map *map() const { return map_.get(); } + private: + int instance_count_; + scoped_ptr<Map> map_; +}; + +TEST_F(ResourceMapTest, TestMap) { + // check that initial mapping is empty. + EXPECT_EQ(NULL, map()->Get(0)); + EXPECT_EQ(NULL, map()->Get(1)); + EXPECT_EQ(NULL, map()->Get(392)); + + // create a new resource, assign it to an ID. + ResourceMock *resource = new ResourceMock(); + map()->Assign(123, resource); + EXPECT_EQ(resource, map()->Get(123)); + + // Destroy the resource, making sure the object is deleted. + EXPECT_EQ(true, map()->Destroy(123)); + EXPECT_EQ(false, map()->Destroy(123)); // destroying again should fail. + resource = NULL; + CheckLeaks(); + + // create a new resource, add it to the map, and make sure it gets deleted + // when we assign a new resource to that ID. + resource = new ResourceMock(); + map()->Assign(1, resource); + resource = new ResourceMock(); + map()->Assign(1, resource); + EXPECT_EQ(resource, map()->Get(1)); // check that we have the new resource. + EXPECT_EQ(true, map()->Destroy(1)); + CheckLeaks(); + + // Adds 3 resources, then call DestroyAllResources(). + resource = new ResourceMock(); + map()->Assign(1, resource); + resource = new ResourceMock(); + map()->Assign(2, resource); + resource = new ResourceMock(); + map()->Assign(3, resource); + map()->DestroyAllResources(); + EXPECT_EQ(NULL, map()->Get(1)); + EXPECT_EQ(NULL, map()->Get(2)); + EXPECT_EQ(NULL, map()->Get(3)); + CheckLeaks(); +} + +} // namespace command_buffer diff --git a/gpu/command_buffer/service/x_utils.cc b/gpu/command_buffer/service/x_utils.cc new file mode 100644 index 0000000..b9eb9d9 --- /dev/null +++ b/gpu/command_buffer/service/x_utils.cc @@ -0,0 +1,92 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This class implements the XWindowWrapper class. + +#include "gpu/command_buffer/service/precompile.h" +#include "gpu/command_buffer/common/cross/logging.h" +#include "gpu/command_buffer/service/linux/x_utils.h" + +namespace command_buffer { + +bool XWindowWrapper::Initialize() { + XWindowAttributes attributes; + XGetWindowAttributes(display_, window_, &attributes); + XVisualInfo visual_info_template; + visual_info_template.visualid = XVisualIDFromVisual(attributes.visual); + int visual_info_count = 0; + XVisualInfo *visual_info_list = XGetVisualInfo(display_, VisualIDMask, + &visual_info_template, + &visual_info_count); + DCHECK(visual_info_list); + DCHECK_GT(visual_info_count, 0); + context_ = 0; + for (int i = 0; i < visual_info_count; ++i) { + context_ = glXCreateContext(display_, visual_info_list + i, 0, + True); + if (context_) break; + } + XFree(visual_info_list); + if (!context_) { + DLOG(ERROR) << "Couldn't create GL context."; + return false; + } + return true; +} + +bool XWindowWrapper::MakeCurrent() { + if (glXMakeCurrent(display_, window_, context_) != True) { + glXDestroyContext(display_, context_); + context_ = 0; + DLOG(ERROR) << "Couldn't make context current."; + return false; + } + return true; +} + +void XWindowWrapper::Destroy() { + Bool result = glXMakeCurrent(display_, 0, 0); + // glXMakeCurrent isn't supposed to fail when unsetting the context, unless + // we have pending draws on an invalid window - which shouldn't be the case + // here. + DCHECK(result); + if (context_) { + glXDestroyContext(display_, context_); + context_ = 0; + } +} + +void XWindowWrapper::SwapBuffers() { + glXSwapBuffers(display_, window_); +} + +} // namespace command_buffer diff --git a/gpu/command_buffer/service/x_utils.h b/gpu/command_buffer/service/x_utils.h new file mode 100644 index 0000000..0d8c26a --- /dev/null +++ b/gpu/command_buffer/service/x_utils.h @@ -0,0 +1,76 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +// This file declares the XWindowWrapper class. + +#ifndef GPU_COMMAND_BUFFER_SERVICE_X_UTILS_H_ +#define GPU_COMMAND_BUFFER_SERVICE_X_UTILS_H_ + +#include <GL/glx.h> +#include "base/basictypes.h" +#include "gpu/command_buffer/common/cross/logging.h" + +namespace command_buffer { + +// This class is a wrapper around an X Window and associated GL context. It is +// useful to isolate intrusive X headers, since it can be forward declared +// (Window and GLXContext can't). +class XWindowWrapper { + public: + XWindowWrapper(Display *display, Window window) + : display_(display), + window_(window) { + DCHECK(display_); + DCHECK(window_); + } + // Initializes the GL context. + bool Initialize(); + + // Destroys the GL context. + void Destroy(); + + // Makes the GL context current on the current thread. + bool MakeCurrent(); + + // Swaps front and back buffers. + void SwapBuffers(); + + private: + Display *display_; + Window window_; + GLXContext context_; + DISALLOW_COPY_AND_ASSIGN(XWindowWrapper); +}; + +} // namespace command_buffer + +#endif // GPU_COMMAND_BUFFER_SERVICE_X_UTILS_H_ diff --git a/gpu/gpu.gyp b/gpu/gpu.gyp new file mode 100644 index 0000000..aa89b51 --- /dev/null +++ b/gpu/gpu.gyp @@ -0,0 +1,412 @@ +# 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. + +{ + 'variables': { + 'chromium_code': 1, + }, + 'includes': [ + '../build/common.gypi', + ], + 'targets': [ + { + 'target_name': 'gl_libs', + 'type': 'static_library', + 'include_dirs': [ + '../third_party/glew/include', + ], + 'defines': [ + 'GLEW_STATIC', + ], + 'all_dependent_settings': { + 'include_dirs': [ + '../third_party/glew/include', + ], + 'defines': [ + 'GLEW_STATIC', + ], + }, + 'sources': [ + '../third_party/glew/src/glew.c', + ], + 'conditions': [ + [ 'OS=="linux"', + { + 'all_dependent_settings': { + 'defines': [ + 'GL_GLEXT_PROTOTYPES', + ], + 'ldflags': [ + '-L<(PRODUCT_DIR)', + ], + 'libraries': [ + '-lGL', + '-lX11', + ], + }, + }, + ], + [ 'OS=="mac"', + { + 'direct_dependent_settings': { + 'libraries': [ + '$(SDKROOT)/System/Library/Frameworks/OpenGL.framework', + ], + }, + }, + ], + [ 'OS=="win"', + { + 'all_dependent_settings': { + 'libraries': [ + '-lOpenGL32.lib', + ], + }, + }, + ], + ], + }, + { + 'target_name': 'command_buffer_common', + 'type': 'static_library', + 'include_dirs': [ + 'command_buffer/common', + '..', + ], + 'all_dependent_settings': { + 'include_dirs': [ + 'command_buffer/common', + '..', + ], + }, + 'sources': [ + 'command_buffer/common/bitfield_helpers.h', + 'command_buffer/common/cmd_buffer_common.h', + 'command_buffer/common/cmd_buffer_common.cc', + 'command_buffer/common/command_buffer.h', + 'command_buffer/common/command_buffer_mock.h', + 'command_buffer/common/gles2_cmd_ids_autogen.h', + 'command_buffer/common/gles2_cmd_ids.h', + 'command_buffer/common/gles2_cmd_format_autogen.h', + 'command_buffer/common/gles2_cmd_format.cc', + 'command_buffer/common/gles2_cmd_format.h', + 'command_buffer/common/gles2_cmd_utils.cc', + 'command_buffer/common/gles2_cmd_utils.h', + 'command_buffer/common/logging.h', + 'command_buffer/common/mocks.h', + 'command_buffer/common/resource.cc', + 'command_buffer/common/resource.h', + 'command_buffer/common/types.h', + ], + }, + { + # Library helps make GLES2 command buffers. + 'target_name': 'gles2_cmd_helper', + 'type': 'static_library', + 'dependencies': [ + 'command_buffer_common', + 'np_utils', + ], + 'sources': [ + 'command_buffer/client/gles2_cmd_helper.cc', + 'command_buffer/client/gles2_cmd_helper.h', + 'command_buffer/client/gles2_cmd_helper_autogen.h', + ], + }, + { + # Library emulates GLES2 using command_buffers. + 'target_name': 'gles2_implementation', + 'type': 'static_library', + 'dependencies': [ + 'gles2_cmd_helper', + ], + 'sources': [ + 'command_buffer/client/gles2_implementation_autogen.h', + 'command_buffer/client/gles2_implementation.cc', + 'command_buffer/client/gles2_implementation_gen.h', + 'command_buffer/client/gles2_implementation.h', + ], + }, + { + # Stub to expose gles2_implementation as a namespace rather than a class + # so GLES2 C++ programs can work with no changes. + 'target_name': 'gles2_lib', + 'type': 'static_library', + 'dependencies': [ + 'gles2_implementation', + ], + 'sources': [ + 'command_buffer/client/gles2_lib.cc', + 'command_buffer/client/gles2_lib.h', + ], + }, + { + # Stub to expose gles2_implemenation in C instead of C++. + # so GLES2 C programs can work with no changes. + 'target_name': 'gles2_c_lib', + 'type': 'static_library', + 'dependencies': [ + 'gles2_lib', + ], + 'sources': [ + 'command_buffer/client/gles2_c_lib.h', + 'command_buffer/client/gles2_c_lib.cc', + 'command_buffer/client/gles2_c_lib_autogen.h', + ], + }, + { + 'target_name': 'command_buffer_common_unittests', + 'type': 'none', + 'include_dirs': [ + 'command_buffer/common', + ], + 'dependencies': [ + 'gles2_lib', + 'gles2_implementation', + 'gles2_cmd_helper', + ], + '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', + ], + }, + }, + { + 'target_name': 'command_buffer_client', + 'type': 'static_library', + 'dependencies': [ + 'command_buffer_common', + ], + 'sources': [ + 'command_buffer/client/cmd_buffer_helper.cc', + 'command_buffer/client/cmd_buffer_helper.h', + 'command_buffer/client/fenced_allocator.cc', + 'command_buffer/client/fenced_allocator.h', + 'command_buffer/client/id_allocator.cc', + 'command_buffer/client/id_allocator.h', + ], + }, + { + 'target_name': 'command_buffer_client_unittests', + 'type': 'none', + 'direct_dependent_settings': { + 'sources': [ + 'command_buffer/client/cmd_buffer_helper_test.cc', + 'command_buffer/client/fenced_allocator_test.cc', + 'command_buffer/client/id_allocator_test.cc', + ], + }, + }, + { + 'target_name': 'command_buffer_service', + 'type': 'static_library', + 'include_dirs': [ + '..', + ], + 'all_dependent_settings': { + 'include_dirs': [ + '..', + ], + }, + 'dependencies': [ + 'command_buffer_common', + 'gl_libs', + ], + 'sources': [ + 'command_buffer/service/common_decoder.cc', + 'command_buffer/service/common_decoder.h', + 'command_buffer/service/cmd_buffer_engine.h', + 'command_buffer/service/command_buffer_service.cc', + '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_validate.h', + 'command_buffer/service/gles2_cmd_decoder_autogen.h', + 'command_buffer/service/gles2_cmd_decoder.cc', + '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', + 'command_buffer/service/mocks.h', + 'command_buffer/service/precompile.cc', + 'command_buffer/service/precompile.h', + 'command_buffer/service/resource.cc', + 'command_buffer/service/resource.h', + ], + 'conditions': [ + ['OS == "linux"', + { + 'sources': [ + 'command_buffer/service/linux/x_utils.cc', + 'command_buffer/service/linux/x_utils.h', + ], + }, + ], + ['OS == "win"', + { + 'sources': [ + 'command_buffer/service/gpu_processor_win.cc', + ], + }, + ], + ], + }, + { + 'target_name': 'command_buffer_service_unittests', + 'type': 'none', + 'direct_dependent_settings': { + 'sources': [ + 'command_buffer/service/cmd_parser_test.cc', + 'command_buffer/service/command_buffer_service_unittest.cc', + 'command_buffer/service/gpu_processor_unittest.cc', + 'command_buffer/service/resource_test.cc', + ], + }, + }, + { + 'target_name': 'np_utils', + 'type': '<(library)', + 'dependencies': [ + '../base/base.gyp:base', + ], + 'include_dirs': [ + '..', + ], + 'all_dependent_settings': { + 'include_dirs': [ + '..', + ], + }, + 'sources': [ + 'np_utils/default_np_object.h', + 'np_utils/dynamic_np_object.cc', + 'np_utils/dynamic_np_object.h', + 'np_utils/np_browser.cc', + 'np_utils/np_browser.h', + 'np_utils/np_browser_mock.h', + 'np_utils/np_browser_stub.cc', + 'np_utils/np_browser_stub.h', + 'np_utils/np_class.h', + 'np_utils/np_dispatcher.cc', + 'np_utils/np_dispatcher.h', + 'np_utils/np_dispatcher_specializations.h', + 'np_utils/np_headers.h', + 'np_utils/np_object_mock.h', + 'np_utils/np_object_pointer.h', + 'np_utils/np_plugin_object.h', + 'np_utils/np_plugin_object_mock.h', + 'np_utils/np_plugin_object_factory.cc', + 'np_utils/np_plugin_object_factory.h', + 'np_utils/np_plugin_object_factory_mock.h', + 'np_utils/np_utils.cc', + 'np_utils/np_utils.h', + 'np_utils/webkit_browser.h', + ], + }, + { + 'target_name': 'np_utils_unittests', + 'type': 'none', + 'direct_dependent_settings': { + 'include_dirs': [ + '..', + ], + 'sources': [ + 'np_utils/dispatched_np_object_unittest.cc', + 'np_utils/dynamic_np_object_unittest.cc', + 'np_utils/np_class_unittest.cc', + 'np_utils/np_object_pointer_unittest.cc', + 'np_utils/np_utils_unittest.cc', + ], + }, + }, + { + 'target_name': 'gpu_plugin', + 'type': '<(library)', + 'dependencies': [ + '../base/base.gyp:base', + 'command_buffer_service', + 'np_utils', + ], + 'include_dirs': [ + '..', + ], + 'all_dependent_settings': { + 'include_dirs': [ + '..', + ], + }, + 'sources': [ + 'gpu_plugin/gpu_plugin.cc', + 'gpu_plugin/gpu_plugin.h', + 'gpu_plugin/gpu_plugin_object.cc', + 'gpu_plugin/gpu_plugin_object.h', + 'gpu_plugin/gpu_plugin_object_win.cc', + 'gpu_plugin/gpu_plugin_object_factory.cc', + 'gpu_plugin/gpu_plugin_object_factory.h', + ], + }, + { + 'target_name': 'gpu_plugin_unittests', + 'type': 'none', + 'direct_dependent_settings': { + 'include_dirs': [ + '..', + ], + 'sources': [ + 'gpu_plugin/gpu_plugin_unittest.cc', + 'gpu_plugin/gpu_plugin_object_unittest.cc', + 'gpu_plugin/gpu_plugin_object_factory_unittest.cc', + ], + }, + }, + { + 'target_name': 'gpu_all_unittests', + 'type': 'executable', + 'dependencies': [ + '../testing/gmock.gyp:gmock', + '../testing/gmock.gyp:gmockmain', + '../testing/gtest.gyp:gtest', + 'command_buffer_client', + 'command_buffer_client_unittests', + 'command_buffer_common', + 'command_buffer_common_unittests', + 'command_buffer_service', + 'command_buffer_service_unittests', + 'gpu_plugin', + 'gpu_plugin_unittests', + 'np_utils', + 'np_utils_unittests', + ], + }, + { + 'target_name': 'gles2_demo', + 'type': 'executable', + 'dependencies': [ + 'command_buffer_client', + 'command_buffer_service', + 'gles2_lib', + 'gles2_c_lib', + 'gpu_plugin', + 'np_utils', + ], + 'sources': [ + 'command_buffer/client/gles2_demo.cc', + 'command_buffer/client/gles2_demo_c.h', + 'command_buffer/client/gles2_demo_c.c', + 'command_buffer/client/gles2_demo_cc.h', + 'command_buffer/client/gles2_demo_cc.cc', + ], + }, + ] +} + +# Local Variables: +# tab-width:2 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=2 shiftwidth=2: diff --git a/gpu/gpu_plugin/gpu_plugin.cc b/gpu/gpu_plugin/gpu_plugin.cc new file mode 100644 index 0000000..35771fd --- /dev/null +++ b/gpu/gpu_plugin/gpu_plugin.cc @@ -0,0 +1,135 @@ +// Copyright (c) 2006-2008 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/gpu_plugin/gpu_plugin.h" +#include "gpu/gpu_plugin/gpu_plugin_object_factory.h" +#include "gpu/np_utils/np_browser.h" +#include "gpu/np_utils/np_plugin_object.h" +#include "gpu/np_utils/np_plugin_object_factory.h" +#include "webkit/glue/plugins/nphostapi.h" + +using np_utils::NPBrowser; +using np_utils::NPPluginObjectFactory; +using np_utils::PluginObject; + +namespace gpu_plugin { + +// Definitions of NPAPI plugin entry points. + +namespace { +NPBrowser* g_browser; +GPUPluginObjectFactory g_plugin_object_factory; + +NPError NPP_New(NPMIMEType plugin_type, NPP instance, + uint16 mode, int16 argc, char* argn[], + char* argv[], NPSavedData* saved) { + if (!instance) + return NPERR_INVALID_INSTANCE_ERROR; + + PluginObject* plugin_object = + NPPluginObjectFactory::get()->CreatePluginObject(instance, plugin_type); + if (!plugin_object) + return NPERR_GENERIC_ERROR; + + instance->pdata = plugin_object; + + NPError error = plugin_object->New(plugin_type, argc, argn, argv, saved); + if (error != NPERR_NO_ERROR) { + plugin_object->Release(); + } + + return error; +} + +NPError NPP_Destroy(NPP instance, NPSavedData** saved) { + if (!instance) + return NPERR_INVALID_INSTANCE_ERROR; + + PluginObject* plugin_object = static_cast<PluginObject*>(instance->pdata); + NPError error = plugin_object->Destroy(saved); + + if (error == NPERR_NO_ERROR) { + plugin_object->Release(); + } + + return error; +} + +NPError NPP_SetWindow(NPP instance, NPWindow* window) { + if (!instance) + return NPERR_INVALID_INSTANCE_ERROR; + + PluginObject* plugin_object = static_cast<PluginObject*>(instance->pdata); + return plugin_object->SetWindow(window); +} + +int16 NPP_HandleEvent(NPP instance, void* event) { + if (!instance) + return 0; + + PluginObject* plugin_object = static_cast<PluginObject*>(instance->pdata); + return plugin_object->HandleEvent(static_cast<NPEvent*>(event)); +} + +NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value) { + if (!instance) + return NPERR_INVALID_INSTANCE_ERROR; + + PluginObject* plugin_object = static_cast<PluginObject*>(instance->pdata); + switch (variable) { + case NPPVpluginScriptableNPObject: + *reinterpret_cast<NPObject**>(value) = + plugin_object->GetScriptableNPObject(); + return NPERR_NO_ERROR; + default: + return NPERR_GENERIC_ERROR; + } +} + +NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value) { + return NPERR_NO_ERROR; +} +} + +NPError NP_GetEntryPoints(NPPluginFuncs* funcs) { + funcs->newp = NPP_New; + funcs->destroy = NPP_Destroy; + funcs->setwindow = NPP_SetWindow; + funcs->event = NPP_HandleEvent; + funcs->getvalue = NPP_GetValue; + funcs->setvalue = NPP_SetValue; + return NPERR_NO_ERROR; +} + +#if defined(OS_LINUX) +NPError API_CALL NP_Initialize(NPNetscapeFuncs *browser_funcs, + NPPluginFuncs* plugin_funcs) { +#else +NPError NP_Initialize(NPNetscapeFuncs *browser_funcs) { +#endif + if (!browser_funcs) + return NPERR_INVALID_FUNCTABLE_ERROR; + + if (g_browser) + return NPERR_GENERIC_ERROR; + +#if defined(OS_LINUX) + NP_GetEntryPoints(plugin_funcs); +#endif + + g_browser = new NPBrowser(browser_funcs); + + return NPERR_NO_ERROR; +} + +NPError NP_Shutdown() { + if (!g_browser) + return NPERR_GENERIC_ERROR; + + delete g_browser; + g_browser = NULL; + + return NPERR_NO_ERROR; +} +} // namespace gpu_plugin diff --git a/gpu/gpu_plugin/gpu_plugin.h b/gpu/gpu_plugin/gpu_plugin.h new file mode 100644 index 0000000..0f90f77 --- /dev/null +++ b/gpu/gpu_plugin/gpu_plugin.h @@ -0,0 +1,30 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_GPU_PLUGIN_GPU_PLUGIN_H_ +#define GPU_GPU_PLUGIN_GPU_PLUGIN_H_ + +#include "gpu/np_utils/np_headers.h" + +typedef struct _NPPluginFuncs NPPluginFuncs; +typedef struct _NPNetscapeFuncs NPNetscapeFuncs; + +namespace gpu_plugin { + +// Declarations of NPAPI plugin entry points. + +NPError NP_GetEntryPoints(NPPluginFuncs* funcs); + +#if defined(OS_LINUX) +NPError NP_Initialize(NPNetscapeFuncs *browser_funcs, + NPPluginFuncs* plugin_funcs); +#else +NPError NP_Initialize(NPNetscapeFuncs* browser_funcs); +#endif + +NPError NP_Shutdown(); + +} // namespace gpu_plugin + +#endif // GPU_GPU_PLUGIN_GPU_PLUGIN_H_ diff --git a/gpu/gpu_plugin/gpu_plugin_object.cc b/gpu/gpu_plugin/gpu_plugin_object.cc new file mode 100644 index 0000000..d4ea9150 --- /dev/null +++ b/gpu/gpu_plugin/gpu_plugin_object.cc @@ -0,0 +1,123 @@ +// Copyright (c) 2006-2008 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 <stdlib.h> + +#include "base/logging.h" +#include "gpu/command_buffer/service/command_buffer_service.h" +#include "gpu/command_buffer/service/gpu_processor.h" +#include "gpu/np_utils/np_utils.h" +#include "gpu/gpu_plugin/gpu_plugin_object.h" + +using ::base::SharedMemory; +using command_buffer::CommandBuffer; +using command_buffer::CommandBufferService; +using command_buffer::GPUProcessor; +using np_utils::NPBrowser; +using np_utils::NPObjectPointer; + +namespace gpu_plugin { + +const NPUTF8 GPUPluginObject::kPluginType[] = + "application/vnd.google.chrome.gpu-plugin"; + +GPUPluginObject::GPUPluginObject(NPP npp) + : npp_(npp), + status_(kWaitingForNew), + command_buffer_(new CommandBufferService), + processor_(new GPUProcessor(npp, command_buffer_.get())) { + memset(&window_, 0, sizeof(window_)); +} + +NPError GPUPluginObject::New(NPMIMEType plugin_type, + int16 argc, + char* argn[], + char* argv[], + NPSavedData* saved) { + if (status_ != kWaitingForNew) + return NPERR_GENERIC_ERROR; + + status_ = kWaitingForSetWindow; + + return NPERR_NO_ERROR; +} + +NPError GPUPluginObject::SetWindow(NPWindow* new_window) { + if (status_ == kWaitingForNew || status_ == kDestroyed) + return NPERR_GENERIC_ERROR; + + // PlatformSpecificSetWindow advances the status depending on what happens. + NPError error = PlatformSpecificSetWindow(new_window); + if (error == NPERR_NO_ERROR) { + window_ = *new_window; + + if (event_sync_.Get()) { + NPInvokeVoid(npp_, + event_sync_, + "resize", + static_cast<int32>(window_.width), + static_cast<int32>(window_.height)); + } + } else { + memset(&window_, 0, sizeof(window_)); + } + + return error; +} + +int16 GPUPluginObject::HandleEvent(NPEvent* event) { + return 0; +} + +NPError GPUPluginObject::Destroy(NPSavedData** saved) { + if (status_ == kWaitingForNew || status_ == kDestroyed) + return NPERR_GENERIC_ERROR; + + if (command_buffer_.get()) { + command_buffer_->SetPutOffsetChangeCallback(NULL); + } + + status_ = kDestroyed; + + return NPERR_NO_ERROR; +} + +void GPUPluginObject::Release() { + DCHECK(status_ == kWaitingForNew || status_ == kDestroyed); + NPBrowser::get()->ReleaseObject(this); +} + +NPObject*GPUPluginObject::GetScriptableNPObject() { + NPBrowser::get()->RetainObject(this); + return this; +} + +CommandBuffer* GPUPluginObject::OpenCommandBuffer() { + if (status_ == kInitializationSuccessful) + return command_buffer_.get(); + + // SetWindow must have been called before OpenCommandBuffer. + // PlatformSpecificSetWindow advances the status to + // kWaitingForOpenCommandBuffer. + if (status_ != kWaitingForOpenCommandBuffer) + return NULL; + + scoped_ptr<SharedMemory> ring_buffer(new SharedMemory); + if (!ring_buffer->Create(std::wstring(), false, false, kCommandBufferSize)) + return NULL; + + if (command_buffer_->Initialize(ring_buffer.release())) { + if (processor_->Initialize(static_cast<HWND>(window_.window))) { + command_buffer_->SetPutOffsetChangeCallback( + NewCallback(processor_.get(), + &GPUProcessor::ProcessCommands)); + status_ = kInitializationSuccessful; + return command_buffer_.get(); + } + } + + return NULL; +} + +} // namespace gpu_plugin diff --git a/gpu/gpu_plugin/gpu_plugin_object.h b/gpu/gpu_plugin/gpu_plugin_object.h new file mode 100644 index 0000000..0602aa9 --- /dev/null +++ b/gpu/gpu_plugin/gpu_plugin_object.h @@ -0,0 +1,133 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_GPU_PLUGIN_GPU_PLUGIN_OBJECT_H_ +#define GPU_GPU_PLUGIN_GPU_PLUGIN_OBJECT_H_ + +#include <string> + +#include "base/ref_counted.h" +#include "base/thread.h" +#include "gpu/command_buffer/common/command_buffer.h" +#include "gpu/command_buffer/service/gpu_processor.h" +#include "gpu/np_utils/default_np_object.h" +#include "gpu/np_utils/np_dispatcher.h" +#include "gpu/np_utils/np_headers.h" +#include "gpu/np_utils/np_plugin_object.h" +#include "gpu/np_utils/np_utils.h" + +namespace gpu_plugin { + +// The scriptable object for the GPU plugin. +class GPUPluginObject : public np_utils::DefaultNPObject<NPObject>, + public np_utils::PluginObject { + public: + static const int32 kCommandBufferSize = 1024 * 1024; + + enum Status { + // In the state of waiting for the named function to be called to continue + // the initialization sequence. + kWaitingForNew, + kWaitingForSetWindow, + kWaitingForOpenCommandBuffer, + + // Initialization either succeeded or failed. + kInitializationSuccessful, + kInitializationFailed, + + // Destroy has now been called and the plugin object cannot be used. + kDestroyed, + }; + + static const NPUTF8 kPluginType[]; + + explicit GPUPluginObject(NPP npp); + + virtual NPError New(NPMIMEType plugin_type, + int16 argc, + char* argn[], + char* argv[], + NPSavedData* saved); + + virtual NPError SetWindow(NPWindow* new_window); + const NPWindow& GetWindow() { return window_; } + + virtual int16 HandleEvent(NPEvent* event); + + virtual NPError Destroy(NPSavedData** saved); + + virtual void Release(); + + virtual NPObject* GetScriptableNPObject(); + + // Returns the current initialization status. See Status enum. + int32 GetStatus() { + return status_; + } + + // Get the width of the plugin window. + int32 GetWidth() { + return window_.width; + } + + // Get the height of the plugin window. + int32 GetHeight() { + return window_.height; + } + + // Set the object that receives notifications of GPU plugin object events + // such as resize and keyboard and mouse input. + void SetEventSync(np_utils::NPObjectPointer<NPObject> event_sync) { + event_sync_ = event_sync; + } + + np_utils::NPObjectPointer<NPObject> GetEventSync() { + return event_sync_; + } + + // Initializes and returns the command buffer object. Returns NULL if the + // command buffer cannot be initialized, for example if the plugin does not + // yet have a window handle. + command_buffer::CommandBuffer* OpenCommandBuffer(); + + // Set the status for testing. + void set_status(Status status) { + status_ = status; + } + + // Replace the default command buffer for testing. Takes ownership. + void set_command_buffer(command_buffer::CommandBuffer* + command_buffer) { + command_buffer_.reset(command_buffer); + } + + // Replace the default GPU processor for testing. + void set_gpu_processor( + const scoped_refptr<command_buffer::GPUProcessor>& processor) { + processor_ = processor; + } + + NP_UTILS_BEGIN_DISPATCHER_CHAIN(GPUPluginObject, DefaultNPObject<NPObject>) + NP_UTILS_DISPATCHER(GetStatus, int32()) + NP_UTILS_DISPATCHER(GetWidth, int32()) + NP_UTILS_DISPATCHER(GetHeight, int32()) + NP_UTILS_DISPATCHER(SetEventSync, + void(np_utils::NPObjectPointer<NPObject> sync)) + NP_UTILS_DISPATCHER(GetEventSync, np_utils::NPObjectPointer<NPObject>()) + NP_UTILS_END_DISPATCHER_CHAIN + + private: + NPError PlatformSpecificSetWindow(NPWindow* new_window); + + NPP npp_; + Status status_; + NPWindow window_; + scoped_ptr<command_buffer::CommandBuffer> command_buffer_; + scoped_refptr<command_buffer::GPUProcessor> processor_; + np_utils::NPObjectPointer<NPObject> event_sync_; +}; + +} // namespace gpu_plugin + +#endif // GPU_GPU_PLUGIN_GPU_PLUGIN_OBJECT_H_ diff --git a/gpu/gpu_plugin/gpu_plugin_object_factory.cc b/gpu/gpu_plugin/gpu_plugin_object_factory.cc new file mode 100644 index 0000000..da9e17a --- /dev/null +++ b/gpu/gpu_plugin/gpu_plugin_object_factory.cc @@ -0,0 +1,27 @@ +// Copyright (c) 2006-2008 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/gpu_plugin/gpu_plugin_object.h" +#include "gpu/gpu_plugin/gpu_plugin_object_factory.h" +#include "gpu/np_utils/np_utils.h" + +namespace gpu_plugin { + +GPUPluginObjectFactory::GPUPluginObjectFactory() { +} + +GPUPluginObjectFactory::~GPUPluginObjectFactory() { +} + +np_utils::PluginObject* GPUPluginObjectFactory::CreatePluginObject( + NPP npp, + NPMIMEType plugin_type) { + if (strcmp(plugin_type, GPUPluginObject::kPluginType) == 0) { + return np_utils::NPCreateObject<GPUPluginObject>(npp).ToReturned(); + } + + return NULL; +} + +} // namespace gpu_plugin diff --git a/gpu/gpu_plugin/gpu_plugin_object_factory.h b/gpu/gpu_plugin/gpu_plugin_object_factory.h new file mode 100644 index 0000000..0d1d80e --- /dev/null +++ b/gpu/gpu_plugin/gpu_plugin_object_factory.h @@ -0,0 +1,27 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_GPU_PLUGIN_GPU_PLUGIN_OBJECT_FACTORY_H_ +#define GPU_GPU_PLUGIN_GPU_PLUGIN_OBJECT_FACTORY_H_ + +#include "gpu/np_utils/np_plugin_object_factory.h" + +namespace gpu_plugin { + +// Plugin object factory for creating the GPUPluginObject. +class GPUPluginObjectFactory : public np_utils::NPPluginObjectFactory { + public: + GPUPluginObjectFactory(); + virtual ~GPUPluginObjectFactory(); + + virtual np_utils::PluginObject* CreatePluginObject(NPP npp, + NPMIMEType plugin_type); + + private: + DISALLOW_COPY_AND_ASSIGN(GPUPluginObjectFactory); +}; + +} // namespace gpu_plugin + +#endif // GPU_GPU_PLUGIN_GPU_PLUGIN_OBJECT_FACTORY_H_ diff --git a/gpu/gpu_plugin/gpu_plugin_object_factory_unittest.cc b/gpu/gpu_plugin/gpu_plugin_object_factory_unittest.cc new file mode 100644 index 0000000..298a8c5 --- /dev/null +++ b/gpu/gpu_plugin/gpu_plugin_object_factory_unittest.cc @@ -0,0 +1,41 @@ +// Copyright (c) 2006-2008 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/gpu_plugin/gpu_plugin_object.h" +#include "gpu/gpu_plugin/gpu_plugin_object_factory.h" +#include "gpu/np_utils/np_browser_stub.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using np_utils::PluginObject; + +namespace gpu_plugin { + +class PluginObjectFactoryTest : public testing::Test { + protected: + virtual void SetUp() { + factory_ = new GPUPluginObjectFactory; + } + + virtual void TearDown() { + delete factory_; + } + + np_utils::StubNPBrowser stub_browser_; + GPUPluginObjectFactory* factory_; +}; + +TEST_F(PluginObjectFactoryTest, ReturnsNullForUnknownMimeType) { + PluginObject* plugin_object = factory_->CreatePluginObject( + NULL, "application/unknown"); + EXPECT_TRUE(NULL == plugin_object); +} + +TEST_F(PluginObjectFactoryTest, CreatesGPUPlugin) { + PluginObject* plugin_object = factory_->CreatePluginObject( + NULL, const_cast<NPMIMEType>(GPUPluginObject::kPluginType)); + EXPECT_TRUE(NULL != plugin_object); +} + +} // namespace gpu_plugin diff --git a/gpu/gpu_plugin/gpu_plugin_object_unittest.cc b/gpu/gpu_plugin/gpu_plugin_object_unittest.cc new file mode 100644 index 0000000..b032aa0 --- /dev/null +++ b/gpu/gpu_plugin/gpu_plugin_object_unittest.cc @@ -0,0 +1,319 @@ +// Copyright (c) 2006-2008 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/common/command_buffer_mock.h" +#include "gpu/gpu_plugin/gpu_plugin_object.h" +#include "gpu/command_buffer/service/gpu_processor_mock.h" +#include "gpu/np_utils/np_browser_mock.h" +#include "gpu/np_utils/dynamic_np_object.h" +#include "gpu/np_utils/np_object_mock.h" +#include "gpu/np_utils/np_object_pointer.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "webkit/glue/plugins/nphostapi.h" + +using ::base::SharedMemory; +using command_buffer::GPUProcessor; +using command_buffer::MockCommandBuffer; +using command_buffer::MockGPUProcessor; +using np_utils::MockNPBrowser; +using np_utils::NPBrowser; +using np_utils::NPObjectPointer; +using testing::_; +using testing::DoAll; +using testing::Invoke; +using testing::NotNull; +using testing::Return; +using testing::SetArgumentPointee; +using testing::StrictMock; + +namespace gpu_plugin { + +class GPUPluginObjectTest : public testing::Test { + protected: + virtual void SetUp() { + plugin_object_ = np_utils::NPCreateObject<GPUPluginObject>(NULL); + + command_buffer_ = new MockCommandBuffer; + + // Takes ownership. + plugin_object_->set_command_buffer(command_buffer_); + + processor_ = new MockGPUProcessor(command_buffer_); + plugin_object_->set_gpu_processor(processor_.get()); + } + + MockNPBrowser mock_browser_; + NPObjectPointer<GPUPluginObject> plugin_object_; + MockCommandBuffer* command_buffer_; + scoped_refptr<MockGPUProcessor> processor_; +}; + +namespace { +template <typename T> +void DeleteObject(T* object) { + delete object; +} +} // namespace anonymous + + +TEST_F(GPUPluginObjectTest, CanInstantiateAndDestroyPluginObject) { + EXPECT_EQ(GPUPluginObject::kWaitingForNew, plugin_object_->GetStatus()); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo", + 0, + NULL, + NULL, + NULL)); + + EXPECT_EQ(GPUPluginObject::kWaitingForSetWindow, plugin_object_->GetStatus()); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL)); + + EXPECT_EQ(GPUPluginObject::kDestroyed, plugin_object_->GetStatus()); +} + +TEST_F(GPUPluginObjectTest, DestroyFailsIfNotInitialized) { + EXPECT_EQ(NPERR_GENERIC_ERROR, plugin_object_->Destroy(NULL)); +} + +TEST_F(GPUPluginObjectTest, NewFailsIfAlreadyInitialized) { + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo", + 0, + NULL, + NULL, + NULL)); + + EXPECT_EQ(NPERR_GENERIC_ERROR, plugin_object_->New("application/foo", + 0, + NULL, + NULL, + NULL)); + + EXPECT_EQ(GPUPluginObject::kWaitingForSetWindow, plugin_object_->GetStatus()); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL)); + + EXPECT_EQ(GPUPluginObject::kDestroyed, plugin_object_->GetStatus()); +} + +TEST_F(GPUPluginObjectTest, NewFailsIfObjectHasPreviouslyBeenDestroyed) { + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo", + 0, + NULL, + NULL, + NULL)); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL)); + + EXPECT_EQ(NPERR_GENERIC_ERROR, plugin_object_->New("application/foo", + 0, + NULL, + NULL, + NULL)); + + EXPECT_EQ(GPUPluginObject::kDestroyed, plugin_object_->GetStatus()); +} + +TEST_F(GPUPluginObjectTest, WindowIsNullBeforeSetWindowCalled) { + NPWindow window = plugin_object_->GetWindow(); + EXPECT_EQ(NULL, window.window); +} + +TEST_F(GPUPluginObjectTest, CanSetWindow) { + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo", + 0, + NULL, + NULL, + NULL)); + + NPWindow window = {0}; + window.window = &window; + window.x = 7; + + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->SetWindow(&window)); + EXPECT_EQ(0, memcmp(&window, &plugin_object_->GetWindow(), sizeof(window))); + EXPECT_EQ(GPUPluginObject::kWaitingForOpenCommandBuffer, + plugin_object_->GetStatus()); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL)); +} + +TEST_F(GPUPluginObjectTest, CanGetWindowSize) { + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo", + 0, + NULL, + NULL, + NULL)); + + NPWindow window = {0}; + window.window = &window; + window.x = 10; + window.y = 10; + window.width = 100; + window.height = 200; + + EXPECT_EQ(0, plugin_object_->GetWidth()); + EXPECT_EQ(0, plugin_object_->GetHeight()); + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->SetWindow(&window)); + EXPECT_EQ(100, plugin_object_->GetWidth()); + EXPECT_EQ(200, plugin_object_->GetHeight()); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL)); +} + +TEST_F(GPUPluginObjectTest, SetWindowFailsIfNotInitialized) { + NPWindow window = {0}; + EXPECT_EQ(NPERR_GENERIC_ERROR, plugin_object_->SetWindow(&window)); + EXPECT_EQ(GPUPluginObject::kWaitingForNew, plugin_object_->GetStatus()); +} + +TEST_F(GPUPluginObjectTest, CanGetScriptableNPObject) { + NPObject* scriptable_object = plugin_object_->GetScriptableNPObject(); + EXPECT_EQ(plugin_object_.Get(), scriptable_object); + NPBrowser::get()->ReleaseObject(scriptable_object); +} + +TEST_F(GPUPluginObjectTest, OpenCommandBufferReturnsInitializedCommandBuffer) { + EXPECT_CALL(*command_buffer_, Initialize(NotNull())) + .WillOnce(DoAll(Invoke(DeleteObject<SharedMemory>), + Return(true))); + + EXPECT_CALL(*processor_.get(), Initialize(NULL)) + .WillOnce(Return(true)); + + EXPECT_CALL(*command_buffer_, SetPutOffsetChangeCallback(NotNull())) + .WillOnce(Invoke(DeleteObject<Callback0::Type>)); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo", + 0, + NULL, + NULL, + NULL)); + + // Set status as though SetWindow has been called. Avoids having to create a + // valid window handle to pass to SetWindow in tests. + plugin_object_->set_status(GPUPluginObject::kWaitingForOpenCommandBuffer); + + EXPECT_EQ(command_buffer_, plugin_object_->OpenCommandBuffer()); + + // Calling OpenCommandBuffer again just returns the existing command buffer. + EXPECT_EQ(command_buffer_, plugin_object_->OpenCommandBuffer()); + + EXPECT_EQ(GPUPluginObject::kInitializationSuccessful, + plugin_object_->GetStatus()); + + EXPECT_CALL(*command_buffer_, SetPutOffsetChangeCallback(NULL)); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL)); +} + +TEST_F(GPUPluginObjectTest, OpenCommandBufferReturnsNullIfWindowNotReady) { + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo", + 0, + NULL, + NULL, + NULL)); + + // Set status as though SetWindow has not been called. + plugin_object_->set_status(GPUPluginObject::kWaitingForSetWindow); + + EXPECT_TRUE(NULL == plugin_object_->OpenCommandBuffer()); + + EXPECT_EQ(GPUPluginObject::kWaitingForSetWindow, plugin_object_->GetStatus()); +} + + +TEST_F(GPUPluginObjectTest, + OpenCommandBufferReturnsNullIfCommandBufferCannotInitialize) { + EXPECT_CALL(*command_buffer_, Initialize(NotNull())) + .WillOnce(DoAll(Invoke(DeleteObject<SharedMemory>), + Return(false))); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo", + 0, + NULL, + NULL, + NULL)); + + // Set status as though SetWindow has been called. Avoids having to create a + // valid window handle to pass to SetWindow in tests. + plugin_object_->set_status(GPUPluginObject::kWaitingForOpenCommandBuffer); + + EXPECT_TRUE(NULL == plugin_object_->OpenCommandBuffer()); + + EXPECT_EQ(GPUPluginObject::kWaitingForOpenCommandBuffer, + plugin_object_->GetStatus()); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL)); +} + +TEST_F(GPUPluginObjectTest, + OpenCommandBufferReturnsNullIGPUProcessorCannotInitialize) { + EXPECT_CALL(*command_buffer_, Initialize(NotNull())) + .WillOnce(DoAll(Invoke(DeleteObject<SharedMemory>), + Return(true))); + + EXPECT_CALL(*processor_.get(), Initialize(NULL)) + .WillOnce(Return(false)); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo", + 0, + NULL, + NULL, + NULL)); + + // Set status as though SetWindow has been called. Avoids having to create a + // valid window handle to pass to SetWindow in tests. + plugin_object_->set_status(GPUPluginObject::kWaitingForOpenCommandBuffer); + + EXPECT_TRUE(NULL == plugin_object_->OpenCommandBuffer()); + + EXPECT_EQ(GPUPluginObject::kWaitingForOpenCommandBuffer, + plugin_object_->GetStatus()); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL)); +} + +class MockEventSync : public np_utils::DefaultNPObject<NPObject> { + public: + explicit MockEventSync(NPP npp) { + } + + MOCK_METHOD2(Resize, void(int32 width, int32 height)); + + NP_UTILS_BEGIN_DISPATCHER_CHAIN(MockEventSync, DefaultNPObject<NPObject>) + NP_UTILS_DISPATCHER(Resize, void(int32 width, int32 height)) + NP_UTILS_END_DISPATCHER_CHAIN + + private: + DISALLOW_COPY_AND_ASSIGN(MockEventSync); +}; + +TEST_F(GPUPluginObjectTest, SendsResizeEventOnSetWindow) { + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->New("application/foo", + 0, + NULL, + NULL, + NULL)); + + NPObjectPointer<MockEventSync> event_sync = + np_utils::NPCreateObject<MockEventSync>(NULL); + plugin_object_->SetEventSync(event_sync); + + EXPECT_CALL(*event_sync.Get(), Resize(100, 200)); + + NPWindow window = {0}; + window.window = &window; + window.x = 10; + window.y = 10; + window.width = 100; + window.height = 200; + + plugin_object_->SetWindow(&window); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_object_->Destroy(NULL)); +} + +} // namespace gpu_plugin diff --git a/gpu/gpu_plugin/gpu_plugin_object_win.cc b/gpu/gpu_plugin/gpu_plugin_object_win.cc new file mode 100644 index 0000000..31c6393 --- /dev/null +++ b/gpu/gpu_plugin/gpu_plugin_object_win.cc @@ -0,0 +1,62 @@ +// Copyright (c) 2006-2008 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 <windows.h> + +#include "gpu/command_buffer/service/gpu_processor.h" +#include "gpu/gpu_plugin/gpu_plugin_object.h" + +namespace gpu_plugin { + +namespace { +const LPCTSTR kPluginObjectProperty = TEXT("GPUPluginObject"); +const LPCTSTR kOriginalWindowProc = TEXT("GPUPluginObjectOriginalWindowProc"); + +LRESULT CALLBACK WindowProc(HWND handle, + UINT message, + WPARAM w_param, + LPARAM l_param) { + return ::DefWindowProc(handle, message, w_param, l_param); +} +} // namespace anonymous + +NPError GPUPluginObject::PlatformSpecificSetWindow(NPWindow* new_window) { + // Detach properties from old window and restore the original window proc. + if (window_.window) { + HWND handle = reinterpret_cast<HWND>(window_.window); + ::RemoveProp(handle, kPluginObjectProperty); + + LONG original_window_proc = reinterpret_cast<LONG>( + ::GetProp(handle, kOriginalWindowProc)); + ::SetWindowLong(handle, GWL_WNDPROC, + original_window_proc); + ::RemoveProp(handle, kOriginalWindowProc); + } + + // Attach properties to new window and set a new window proc. + if (new_window->window) { + HWND handle = reinterpret_cast<HWND>(new_window->window); + ::SetProp(handle, + kPluginObjectProperty, + reinterpret_cast<HANDLE>(this)); + + LONG original_window_proc = ::GetWindowLong(handle, GWL_WNDPROC); + ::SetProp(handle, + kOriginalWindowProc, + reinterpret_cast<HANDLE>(original_window_proc)); + ::SetWindowLong(handle, GWL_WNDPROC, + reinterpret_cast<LONG>(WindowProc)); + + status_ = kWaitingForOpenCommandBuffer; + } else { + status_ = kWaitingForSetWindow; + if (processor_) { + processor_->Destroy(); + } + } + + return NPERR_NO_ERROR; +} + +} // namespace gpu_plugin diff --git a/gpu/gpu_plugin/gpu_plugin_unittest.cc b/gpu/gpu_plugin/gpu_plugin_unittest.cc new file mode 100644 index 0000000..ea1bb5f --- /dev/null +++ b/gpu/gpu_plugin/gpu_plugin_unittest.cc @@ -0,0 +1,302 @@ +// Copyright (c) 2006-2008 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/gpu_plugin/gpu_plugin.h" +#include "gpu/gpu_plugin/gpu_plugin_object.h" +#include "gpu/np_utils/np_object_mock.h" +#include "gpu/np_utils/np_plugin_object_factory_mock.h" +#include "gpu/np_utils/np_plugin_object_mock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "webkit/glue/plugins/nphostapi.h" + +#if defined(OS_LINUX) +#define INITIALIZE_PLUGIN_FUNCS , &plugin_funcs_ +#else +#define INITIALIZE_PLUGIN_FUNCS +#endif + +using np_utils::MockPluginObject; +using np_utils::PluginObject; +using testing::_; +using testing::DoAll; +using testing::NiceMock; +using testing::Return; +using testing::SetArgumentPointee; +using testing::StrictMock; + +namespace gpu_plugin { + +class GPUPluginTest : public testing::Test { + protected: + virtual void SetUp() { + memset(&npp_, 0, sizeof(npp_)); + memset(&browser_funcs_, 0, sizeof(browser_funcs_)); + memset(&plugin_funcs_, 0, sizeof(plugin_funcs_)); + + plugin_object_factory_ = new StrictMock<np_utils::MockPluginObjectFactory>; + + np_class_ = np_utils::NPGetClass<StrictMock<np_utils::MockNPObject> >(); + } + + virtual void TearDown() { + delete plugin_object_factory_; + } + + NPP_t npp_; + NPNetscapeFuncs browser_funcs_; + NPPluginFuncs plugin_funcs_; + np_utils::MockPluginObjectFactory* plugin_object_factory_; + const NPClass* np_class_; +}; + +TEST_F(GPUPluginTest, GetEntryPointsSetsNeededFunctionPointers) { +#if defined(OS_LINUX) + NPError error = gpu_plugin::NP_Initialize(&browser_funcs_, + &plugin_funcs_); + gpu_plugin::NP_Shutdown(); +#else + NPError error = gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); +#endif + + EXPECT_EQ(NPERR_NO_ERROR, error); + EXPECT_TRUE(NULL != plugin_funcs_.newp); + EXPECT_TRUE(NULL != plugin_funcs_.destroy); + EXPECT_TRUE(NULL != plugin_funcs_.setwindow); + EXPECT_TRUE(NULL != plugin_funcs_.event); + EXPECT_TRUE(NULL != plugin_funcs_.getvalue); + EXPECT_TRUE(NULL != plugin_funcs_.setvalue); +} + +TEST_F(GPUPluginTest, CanInitializeAndShutdownPlugin) { + EXPECT_EQ(NPERR_NO_ERROR, + gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS)); + EXPECT_EQ(NPERR_NO_ERROR, gpu_plugin::NP_Shutdown()); +} + +TEST_F(GPUPluginTest, InitializeFailsIfBrowserFuncsIsNull) { + EXPECT_EQ(NPERR_INVALID_FUNCTABLE_ERROR, + gpu_plugin::NP_Initialize(NULL INITIALIZE_PLUGIN_FUNCS)); +} + +TEST_F(GPUPluginTest, InitializeFailsIfAlreadyInitialized) { + EXPECT_EQ(NPERR_NO_ERROR, + gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS)); + EXPECT_EQ(NPERR_GENERIC_ERROR, + gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS)); + EXPECT_EQ(NPERR_NO_ERROR, gpu_plugin::NP_Shutdown()); +} + +TEST_F(GPUPluginTest, ShutdownFailsIfNotInitialized) { + EXPECT_EQ(NPERR_GENERIC_ERROR, gpu_plugin::NP_Shutdown()); +} + +TEST_F(GPUPluginTest, NewReturnsErrorForInvalidInstance) { + gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); + gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS); + + EXPECT_EQ(NPERR_INVALID_INSTANCE_ERROR, plugin_funcs_.newp( + const_cast<NPMIMEType>(GPUPluginObject::kPluginType), + NULL, 0, 0, NULL, NULL, NULL)); + + gpu_plugin::NP_Shutdown(); +} + +TEST_F(GPUPluginTest, GetValueReturnsErrorForInvalidInstance) { + gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); + gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS); + + int* result = NULL; + EXPECT_EQ(NPERR_INVALID_INSTANCE_ERROR, plugin_funcs_.getvalue( + NULL, NPPVjavaClass, &result)); + + gpu_plugin::NP_Shutdown(); +} + +TEST_F(GPUPluginTest, DestroyReturnsErrorForInvalidInstance) { + gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); + gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS); + + EXPECT_EQ(NPERR_INVALID_INSTANCE_ERROR, plugin_funcs_.destroy(NULL, NULL)); + + gpu_plugin::NP_Shutdown(); +} + +TEST_F(GPUPluginTest, SetWindowReturnsErrorForInvalidInstance) { + gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); + gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS); + + EXPECT_EQ(NPERR_INVALID_INSTANCE_ERROR, plugin_funcs_.setwindow(NULL, NULL)); + + gpu_plugin::NP_Shutdown(); +} + +TEST_F(GPUPluginTest, HandleEventReturnsFalseForInvalidInstance) { + gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); + gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS); + + EXPECT_EQ(0, plugin_funcs_.event(NULL, NULL)); + + gpu_plugin::NP_Shutdown(); +} + +TEST_F(GPUPluginTest, NewCreatesAPluginObjectAndInitializesIt) { + StrictMock<np_utils::MockPluginObject> plugin_object; + + EXPECT_CALL(*plugin_object_factory_, CreatePluginObject( + &npp_, const_cast<NPMIMEType>(GPUPluginObject::kPluginType))) + .WillOnce(Return(&plugin_object)); + + NPObject scriptable_object; + + EXPECT_CALL(plugin_object, New( + const_cast<NPMIMEType>(GPUPluginObject::kPluginType), + 0, NULL, NULL, NULL)) + .WillOnce(Return(NPERR_NO_ERROR)); + + EXPECT_CALL(plugin_object, GetScriptableNPObject()) + .WillOnce(Return(&scriptable_object)); + + EXPECT_CALL(plugin_object, Destroy(static_cast<NPSavedData**>(NULL))) + .WillOnce(Return(NPERR_NO_ERROR)); + + EXPECT_CALL(plugin_object, Release()); + + gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); + gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.newp( + const_cast<NPMIMEType>(GPUPluginObject::kPluginType), + &npp_, 0, 0, NULL, NULL, NULL)); + + NPObject* result; + EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.getvalue( + &npp_, NPPVpluginScriptableNPObject, &result)); + EXPECT_EQ(&scriptable_object, result); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.destroy(&npp_, NULL)); + + gpu_plugin::NP_Shutdown(); +} + +TEST_F(GPUPluginTest, NewFailsIfPluginObjectFactoryFails) { + EXPECT_CALL(*plugin_object_factory_, CreatePluginObject( + &npp_, const_cast<NPMIMEType>(GPUPluginObject::kPluginType))) + .WillOnce(Return(static_cast<PluginObject*>(NULL))); + + gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); + gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS); + + EXPECT_EQ(NPERR_GENERIC_ERROR, plugin_funcs_.newp( + const_cast<NPMIMEType>(GPUPluginObject::kPluginType), + &npp_, 0, 0, NULL, NULL, NULL)); + + gpu_plugin::NP_Shutdown(); +} + +TEST_F(GPUPluginTest, SetWindowForwardsToPluginObject) { + StrictMock<MockPluginObject> plugin_object; + + EXPECT_CALL(*plugin_object_factory_, CreatePluginObject( + &npp_, const_cast<NPMIMEType>(GPUPluginObject::kPluginType))) + .WillOnce(Return(&plugin_object)); + + EXPECT_CALL(plugin_object, New( + const_cast<NPMIMEType>(GPUPluginObject::kPluginType), + 0, NULL, NULL, NULL)) + .WillOnce(Return(NPERR_NO_ERROR)); + + NPWindow window = {0}; + + EXPECT_CALL(plugin_object, SetWindow(&window)) + .WillOnce(Return(NPERR_NO_ERROR)); + + EXPECT_CALL(plugin_object, Destroy(static_cast<NPSavedData**>(NULL))) + .WillOnce(Return(NPERR_NO_ERROR)); + + EXPECT_CALL(plugin_object, Release()); + + gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); + gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.newp( + const_cast<NPMIMEType>(GPUPluginObject::kPluginType), + &npp_, 0, 0, NULL, NULL, NULL)); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.setwindow(&npp_, &window)); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.destroy(&npp_, NULL)); + + gpu_plugin::NP_Shutdown(); +} + +TEST_F(GPUPluginTest, HandleEventForwardsToPluginObject) { + StrictMock<MockPluginObject> plugin_object; + + EXPECT_CALL(*plugin_object_factory_, CreatePluginObject( + &npp_, const_cast<NPMIMEType>(GPUPluginObject::kPluginType))) + .WillOnce(Return(&plugin_object)); + + EXPECT_CALL(plugin_object, New( + const_cast<NPMIMEType>(GPUPluginObject::kPluginType), + 0, NULL, NULL, NULL)) + .WillOnce(Return(NPERR_NO_ERROR)); + + NPEvent event = {0}; + + EXPECT_CALL(plugin_object, HandleEvent(&event)) + .WillOnce(Return(7)); + + EXPECT_CALL(plugin_object, Destroy(static_cast<NPSavedData**>(NULL))) + .WillOnce(Return(NPERR_NO_ERROR)); + + EXPECT_CALL(plugin_object, Release()); + + gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); + gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.newp( + const_cast<NPMIMEType>(GPUPluginObject::kPluginType), + &npp_, 0, 0, NULL, NULL, NULL)); + + EXPECT_EQ(7, plugin_funcs_.event(&npp_, &event)); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.destroy(&npp_, NULL)); + + gpu_plugin::NP_Shutdown(); +} + +TEST_F(GPUPluginTest, GetValueReturnsErrorForUnknownVariable) { + StrictMock<MockPluginObject> plugin_object; + + EXPECT_CALL(*plugin_object_factory_, CreatePluginObject( + &npp_, const_cast<NPMIMEType>(GPUPluginObject::kPluginType))) + .WillOnce(Return(&plugin_object)); + + EXPECT_CALL(plugin_object, New( + const_cast<NPMIMEType>(GPUPluginObject::kPluginType), + 0, NULL, NULL, NULL)) + .WillOnce(Return(NPERR_NO_ERROR)); + + EXPECT_CALL(plugin_object, Destroy(static_cast<NPSavedData**>(NULL))) + .WillOnce(Return(NPERR_NO_ERROR)); + + EXPECT_CALL(plugin_object, Release()); + + gpu_plugin::NP_GetEntryPoints(&plugin_funcs_); + gpu_plugin::NP_Initialize(&browser_funcs_ INITIALIZE_PLUGIN_FUNCS); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.newp( + const_cast<NPMIMEType>(GPUPluginObject::kPluginType), + &npp_, 0, 0, NULL, NULL, NULL)); + + int* result = NULL; + EXPECT_EQ(NPERR_GENERIC_ERROR, plugin_funcs_.getvalue( + &npp_, NPPVjavaClass, &result)); + + EXPECT_EQ(NPERR_NO_ERROR, plugin_funcs_.destroy(&npp_, NULL)); + + gpu_plugin::NP_Shutdown(); +} + +} // namespace gpu_plugin diff --git a/gpu/np_utils/default_np_object.h b/gpu/np_utils/default_np_object.h new file mode 100644 index 0000000..b3b5fc0 --- /dev/null +++ b/gpu/np_utils/default_np_object.h @@ -0,0 +1,84 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_NP_UTILS_DEFAULT_NP_OBJECT_H_ +#define GPU_NP_UTILS_DEFAULT_NP_OBJECT_H_ + +#include "base/basictypes.h" +#include "gpu/np_utils/np_headers.h" + +namespace np_utils { + +class BaseNPDispatcher; + +// This class implements each of the functions in the NPClass interface. They +// all return error by default. Note that these are not virtual functions and +// this is not an interface. This class can be used as a mixin so that an +// NPObject class does not need to implement every NPClass function but rather +// inherits a default from DefaultNPObject. +template <typename RootClass> +class DefaultNPObject : public RootClass { + public: + void Invalidate() {} + + bool HasMethod(NPIdentifier name) { + return false; + } + + bool Invoke(NPIdentifier name, + const NPVariant* args, + uint32_t num_args, + NPVariant* result) { + return false; + } + + bool InvokeDefault(const NPVariant* args, + uint32_t num_args, + NPVariant* result) { + return false; + } + + bool HasProperty(NPIdentifier name) { + return false; + } + + bool GetProperty(NPIdentifier name, NPVariant* result) { + return false; + } + + bool SetProperty(NPIdentifier name, const NPVariant* value) { + return false; + } + + bool RemoveProperty(NPIdentifier name) { + return false; + } + + bool Enumerate(NPIdentifier** names, + uint32_t* count) { + *names = NULL; + *count = 0; + return true; + } + + bool Construct(const NPVariant* args, + uint32_t num_args, + NPVariant* result) { + return false; + } + + static BaseNPDispatcher* GetDispatcherChain() { + return NULL; + } + + protected: + DefaultNPObject() {} + virtual ~DefaultNPObject() {} + + private: + DISALLOW_COPY_AND_ASSIGN(DefaultNPObject); +}; +} // namespace np_utils + +#endif // GPU_NP_UTILS_DEFAULT_NP_OBJECT_H_ diff --git a/gpu/np_utils/dispatched_np_object_unittest.cc b/gpu/np_utils/dispatched_np_object_unittest.cc new file mode 100644 index 0000000..19d5a2b --- /dev/null +++ b/gpu/np_utils/dispatched_np_object_unittest.cc @@ -0,0 +1,403 @@ +// Copyright (c) 2006-2008 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 <string> + +#include "gpu/np_utils/default_np_object.h" +#include "gpu/np_utils/np_browser_stub.h" +#include "gpu/np_utils/np_dispatcher.h" +#include "gpu/np_utils/np_object_mock.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::Return; +using testing::StrictMock; + +namespace np_utils { + +// This mock class has a dispatcher chain with an entry for each mocked +// function. The tests that follow that invoking an NPAPI method calls the +// corresponding mocked member function. +class MockDispatchedNPObject : public DefaultNPObject<NPObject> { + public: + explicit MockDispatchedNPObject(NPP npp) { + } + + MOCK_METHOD0(VoidReturnNoParams, void()); + MOCK_METHOD1(VoidReturnBoolParam, void(bool)); + MOCK_METHOD1(VoidReturnIntParam, void(int)); + MOCK_METHOD1(VoidReturnFloatParam, void(float)); + MOCK_METHOD1(VoidReturnDoubleParam, void(double)); + MOCK_METHOD1(VoidReturnStringParam, void(std::string)); + MOCK_METHOD1(VoidReturnObjectParam, void(NPObjectPointer<NPObject>)); + MOCK_METHOD2(VoidReturnTwoParams, void(bool, int)); + MOCK_METHOD0(Overloaded, void()); + MOCK_METHOD1(Overloaded, void(bool)); + MOCK_METHOD1(Overloaded, void(std::string)); + MOCK_METHOD0(BoolReturn, bool()); + MOCK_METHOD0(IntReturn, int()); + MOCK_METHOD0(FloatReturn, float()); + MOCK_METHOD0(DoubleReturn, double()); + MOCK_METHOD0(StringReturn, std::string()); + MOCK_METHOD0(ObjectReturn, NPObjectPointer<NPObject>()); + + NP_UTILS_BEGIN_DISPATCHER_CHAIN(MockDispatchedNPObject, DefaultNPObject<NPObject>) + NP_UTILS_DISPATCHER(VoidReturnNoParams, void()) + NP_UTILS_DISPATCHER(VoidReturnBoolParam, void(bool)) + NP_UTILS_DISPATCHER(VoidReturnIntParam, void(int)) + NP_UTILS_DISPATCHER(VoidReturnFloatParam, void(float)) + NP_UTILS_DISPATCHER(VoidReturnDoubleParam, void(double)) + NP_UTILS_DISPATCHER(VoidReturnStringParam, void(std::string)) + NP_UTILS_DISPATCHER(VoidReturnObjectParam, void(NPObjectPointer<NPObject>)) + NP_UTILS_DISPATCHER(VoidReturnTwoParams, void(bool, int)) + NP_UTILS_DISPATCHER(Overloaded, void()) + NP_UTILS_DISPATCHER(Overloaded, void(bool)) + NP_UTILS_DISPATCHER(Overloaded, void(std::string)) + NP_UTILS_DISPATCHER(BoolReturn, bool()) + NP_UTILS_DISPATCHER(IntReturn, int()) + NP_UTILS_DISPATCHER(FloatReturn, float()) + NP_UTILS_DISPATCHER(DoubleReturn, double()) + NP_UTILS_DISPATCHER(StringReturn, std::string()) + NP_UTILS_DISPATCHER(ObjectReturn, NPObjectPointer<NPObject>()); + NP_UTILS_END_DISPATCHER_CHAIN +}; + +class DispatchedNPObjectTest : public testing::Test { + protected: + virtual void SetUp() { + object_ = NPCreateObject<StrictMock<MockDispatchedNPObject> >(NULL); + passed_object_ = NPCreateObject<MockNPObject>(NULL); + + for (int i = 0; i != arraysize(args_); ++i) { + NULL_TO_NPVARIANT(args_[i]); + } + NULL_TO_NPVARIANT(result_); + } + + StubNPBrowser stub_browser_; + NPVariant args_[3]; + NPVariant result_; + NPObjectPointer<MockDispatchedNPObject> object_; + NPObjectPointer<NPObject> passed_object_; +}; + +TEST_F(DispatchedNPObjectTest, CannotInvokeMissingFunction) { + EXPECT_FALSE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("missing"), + NULL, + 0, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnNoParams) { + EXPECT_CALL(*object_, VoidReturnNoParams()); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("voidReturnNoParams"), + NULL, + 0, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); +} + +TEST_F(DispatchedNPObjectTest, + CannotInvokeVoidReturnNoParamsWithTooManyParams) { + EXPECT_FALSE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("voidReturnNoParams"), + args_, + 1, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnIntParam) { + EXPECT_CALL(*object_, VoidReturnIntParam(7)); + + INT32_TO_NPVARIANT(7, args_[0]); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("voidReturnIntParam"), + args_, + 1, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnBoolParam) { + EXPECT_CALL(*object_, VoidReturnBoolParam(true)); + + BOOLEAN_TO_NPVARIANT(true, args_[0]); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("voidReturnBoolParam"), + args_, + 1, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnFloatParamWithDoubleParam) { + EXPECT_CALL(*object_, VoidReturnFloatParam(7.0f)); + + DOUBLE_TO_NPVARIANT(7.0, args_[0]); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("voidReturnFloatParam"), + args_, + 1, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnFloatParamWithIntParam) { + EXPECT_CALL(*object_, VoidReturnFloatParam(7.0f)); + + INT32_TO_NPVARIANT(7, args_[0]); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("voidReturnFloatParam"), + args_, + 1, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnDoubleParamWithDoubleParam) { + EXPECT_CALL(*object_, VoidReturnDoubleParam(7.0)); + + DOUBLE_TO_NPVARIANT(7.0, args_[0]); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("voidReturnDoubleParam"), + args_, + 1, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnDoubleParamWithIntParam) { + EXPECT_CALL(*object_, VoidReturnDoubleParam(7.0f)); + + INT32_TO_NPVARIANT(7, args_[0]); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("voidReturnDoubleParam"), + args_, + 1, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnStringParam) { + EXPECT_CALL(*object_, VoidReturnStringParam(std::string("hello"))); + + STRINGZ_TO_NPVARIANT("hello", args_[0]); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("voidReturnStringParam"), + args_, + 1, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnObjectParamWithObject) { + EXPECT_CALL(*object_, VoidReturnObjectParam(passed_object_)); + + OBJECT_TO_NPVARIANT(passed_object_.Get(), args_[0]); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("voidReturnObjectParam"), + args_, + 1, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnObjectParamWithNull) { + EXPECT_CALL( + *object_, + VoidReturnObjectParam(NPObjectPointer<NPObject>())); + + NULL_TO_NPVARIANT(args_[0]); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("voidReturnObjectParam"), + args_, + 1, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeVoidReturnTwoParams) { + EXPECT_CALL(*object_, VoidReturnTwoParams(false, 7)); + + BOOLEAN_TO_NPVARIANT(false, args_[0]); + INT32_TO_NPVARIANT(7, args_[1]); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("voidReturnTwoParams"), + args_, + 2, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeOverloadedWithNoParams) { + EXPECT_CALL(*object_, Overloaded()); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("overloaded"), + NULL, + 0, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeOverloadedWithOneStringParam) { + EXPECT_CALL(*object_, Overloaded(std::string("hello"))); + + STRINGZ_TO_NPVARIANT("hello", args_[0]); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("overloaded"), + args_, + 1, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeOverloadedWithOneBoolParam) { + EXPECT_CALL(*object_, Overloaded(true)); + + BOOLEAN_TO_NPVARIANT(true, args_[0]); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("overloaded"), + args_, + 1, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_VOID(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeBoolReturn) { + EXPECT_CALL(*object_, BoolReturn()).WillOnce(Return(true)); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("boolReturn"), + NULL, + 0, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_BOOLEAN(result_)); + EXPECT_TRUE(NPVARIANT_TO_BOOLEAN(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeIntReturn) { + EXPECT_CALL(*object_, IntReturn()).WillOnce(Return(7)); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("intReturn"), + NULL, + 0, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_INT32(result_)); + EXPECT_EQ(7, NPVARIANT_TO_INT32(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeFloatReturn) { + EXPECT_CALL(*object_, FloatReturn()).WillOnce(Return(7.0f)); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("floatReturn"), + NULL, + 0, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_DOUBLE(result_)); + EXPECT_EQ(7.0, NPVARIANT_TO_DOUBLE(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeDoubleReturn) { + EXPECT_CALL(*object_, DoubleReturn()).WillOnce(Return(7.0)); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("doubleReturn"), + NULL, + 0, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_DOUBLE(result_)); + EXPECT_EQ(7.0, NPVARIANT_TO_DOUBLE(result_)); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeStringReturn) { + EXPECT_CALL(*object_, StringReturn()).WillOnce(Return(std::string("hello"))); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("stringReturn"), + NULL, + 0, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_STRING(result_)); + + NPString& str = NPVARIANT_TO_STRING(result_); + EXPECT_EQ(std::string("hello"), + std::string(str.UTF8Characters, str.UTF8Length)); + + // Callee is responsible for releasing string. + NPBrowser::get()->ReleaseVariantValue(&result_); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeObjectReturnWithObject) { + EXPECT_CALL(*object_, ObjectReturn()).WillOnce(Return(passed_object_)); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("objectReturn"), + NULL, + 0, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_OBJECT(result_)); + EXPECT_EQ(passed_object_.Get(), NPVARIANT_TO_OBJECT(result_)); + + NPBrowser::get()->ReleaseVariantValue(&result_); +} + +TEST_F(DispatchedNPObjectTest, CanInvokeObjectReturnWithNull) { + EXPECT_CALL(*object_, ObjectReturn()) + .WillOnce(Return(NPObjectPointer<NPObject>())); + + EXPECT_TRUE(object_->Invoke( + NPBrowser::get()->GetStringIdentifier("objectReturn"), + NULL, + 0, + &result_)); + EXPECT_TRUE(NPVARIANT_IS_NULL(result_)); +} + +TEST_F(DispatchedNPObjectTest, HasMethodReturnsTrueIfMatchingMemberVariable) { + EXPECT_TRUE(object_->HasMethod( + NPBrowser::get()->GetStringIdentifier("objectReturn"))); +} + +TEST_F(DispatchedNPObjectTest, HasMethodReturnsTrueIfNoMatchingMemberVariable) { + EXPECT_FALSE(object_->HasMethod( + NPBrowser::get()->GetStringIdentifier("missing"))); +} + +TEST_F(DispatchedNPObjectTest, EnumeratesAllAvailableMethods) { + NPIdentifier* names; + uint32_t num_names; + ASSERT_TRUE(object_->Enumerate(&names, &num_names)); + + // Don't compare all of them; this test would need to change every time new + // dispatchers were added to the test NPObject class. Just compare the first + // registered (last in the dispatcher chain) and that more than one is + // returned. + EXPECT_GT(num_names, 1u); + EXPECT_EQ(NPBrowser::get()->GetStringIdentifier("voidReturnNoParams"), + names[num_names - 1]); + + NPBrowser::get()->MemFree(names); +} + +} // namespace np_utils diff --git a/gpu/np_utils/dynamic_np_object.cc b/gpu/np_utils/dynamic_np_object.cc new file mode 100644 index 0000000..e037fdc --- /dev/null +++ b/gpu/np_utils/dynamic_np_object.cc @@ -0,0 +1,59 @@ +// Copyright (c) 2006-2008 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/np_utils/dynamic_np_object.h" + +namespace np_utils { + +DynamicNPObject::DynamicNPObject(NPP npp) { +} + +void DynamicNPObject::Invalidate() { + for (PropertyMap::iterator it = properties_.begin(); + it != properties_.end(); + ++it) { + it->second.Invalidate(); + } +} + +bool DynamicNPObject::HasProperty(NPIdentifier name) { + PropertyMap::iterator it = properties_.find(name); + return it != properties_.end(); +} + +bool DynamicNPObject::GetProperty(NPIdentifier name, NPVariant* result) { + PropertyMap::iterator it = properties_.find(name); + if (it == properties_.end()) + return false; + + it->second.CopyTo(result); + return true; +} + +bool DynamicNPObject::SetProperty(NPIdentifier name, const NPVariant* value) { + properties_[name] = *value; + return true; +} + +bool DynamicNPObject::RemoveProperty(NPIdentifier name) { + properties_.erase(name); + return false; +} + +bool DynamicNPObject::Enumerate(NPIdentifier** names, uint32_t* count) { + *names = static_cast<NPIdentifier*>( + NPBrowser::get()->MemAlloc(properties_.size() * sizeof(*names))); + *count = properties_.size(); + + int i = 0; + for (PropertyMap::iterator it = properties_.begin(); + it != properties_.end(); + ++it) { + (*names)[i] = it->first; + ++i; + } + + return true; +} +} // namespace np_utils diff --git a/gpu/np_utils/dynamic_np_object.h b/gpu/np_utils/dynamic_np_object.h new file mode 100644 index 0000000..2b63e78 --- /dev/null +++ b/gpu/np_utils/dynamic_np_object.h @@ -0,0 +1,35 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_NP_UTILS_DYNAMIC_NP_OBJECT_H_ +#define GPU_NP_UTILS_DYNAMIC_NP_OBJECT_H_ + +#include <map> + +#include "gpu/np_utils/default_np_object.h" +#include "gpu/np_utils/np_utils.h" + +namespace np_utils { + +// NPObjects of this type have a dictionary of property name / variant pairs +// that can be changed at runtime through NPAPI. +class DynamicNPObject : public DefaultNPObject<NPObject> { + public: + explicit DynamicNPObject(NPP npp); + + void Invalidate(); + bool HasProperty(NPIdentifier name); + bool GetProperty(NPIdentifier name, NPVariant* result); + bool SetProperty(NPIdentifier name, const NPVariant* value); + bool RemoveProperty(NPIdentifier name); + bool Enumerate(NPIdentifier** names, uint32_t* count); + + private: + typedef std::map<NPIdentifier, SmartNPVariant> PropertyMap; + PropertyMap properties_; + DISALLOW_COPY_AND_ASSIGN(DynamicNPObject); +}; +} // namespace np_utils + +#endif // GPU_NP_UTILS_DYNAMIC_NP_OBJECT_H_ diff --git a/gpu/np_utils/dynamic_np_object_unittest.cc b/gpu/np_utils/dynamic_np_object_unittest.cc new file mode 100644 index 0000000..d58e963 --- /dev/null +++ b/gpu/np_utils/dynamic_np_object_unittest.cc @@ -0,0 +1,83 @@ +// Copyright (c) 2006-2008 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 <string> + +#include "gpu/np_utils/dynamic_np_object.h" +#include "gpu/np_utils/np_browser_stub.h" +#include "gpu/np_utils/np_utils.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::Return; +using testing::StrictMock; + +namespace np_utils { + +class NPDynamicNPObjectTest : public testing::Test { + protected: + virtual void SetUp() { + object_ = NPCreateObject<DynamicNPObject>(NULL); + } + + StubNPBrowser stub_browser_; + NPObjectPointer<DynamicNPObject> object_; +}; + +TEST_F(NPDynamicNPObjectTest, HasPropertyReturnsFalseForMissingProperty) { + EXPECT_FALSE(NPHasProperty(NULL, object_, "missing")); +} + +TEST_F(NPDynamicNPObjectTest, GetPropertyReturnsFalseForMissingProperty) { + int32 r; + EXPECT_FALSE(NPGetProperty(NULL, object_, "missing", &r)); +} + +TEST_F(NPDynamicNPObjectTest, CanSetProperty) { + EXPECT_TRUE(NPSetProperty(NULL, object_, "foo", 7)); + int32 r; + EXPECT_TRUE(NPHasProperty(NULL, object_, "foo")); + EXPECT_TRUE(NPGetProperty(NULL, object_, "foo", &r)); + EXPECT_EQ(7, r); +} + +TEST_F(NPDynamicNPObjectTest, CanRemoveProperty) { + EXPECT_TRUE(NPSetProperty(NULL, object_, "foo", 7)); + EXPECT_TRUE(NPHasProperty(NULL, object_, "foo")); + EXPECT_FALSE(NPRemoveProperty(NULL, object_, "foo")); + EXPECT_FALSE(NPHasProperty(NULL, object_, "foo")); + int32 r; + EXPECT_FALSE(NPGetProperty(NULL, object_, "foo", &r)); +} + +TEST_F(NPDynamicNPObjectTest, CanEnumerateProperties) { + EXPECT_TRUE(NPSetProperty(NULL, object_, "foo", 7)); + + NPIdentifier* names; + uint32 num_names; + EXPECT_TRUE(object_->_class->enumerate(object_.Get(), &names, &num_names)); + + EXPECT_EQ(1, num_names); + EXPECT_EQ(NPBrowser::get()->GetStringIdentifier("foo"), names[0]); + + NPBrowser::get()->MemFree(names); +} + +// Properties should not be +TEST_F(NPDynamicNPObjectTest, InvalidateNullsObjectProperties) { + EXPECT_EQ(1, object_->referenceCount); + { + EXPECT_TRUE(NPSetProperty(NULL, object_, "foo", object_)); + EXPECT_TRUE(NPHasProperty(NULL, object_, "foo")); + object_->_class->invalidate(object_.Get()); + EXPECT_TRUE(NPHasProperty(NULL, object_, "foo")); + NPObjectPointer<DynamicNPObject> r; + EXPECT_TRUE(NPGetProperty(NULL, object_, "foo", &r)); + EXPECT_TRUE(NULL == r.Get()); + } + // Invalidate did not release object + EXPECT_EQ(2, object_->referenceCount); + NPBrowser::get()->ReleaseObject(object_.Get()); +} +} // namespace np_utils diff --git a/gpu/np_utils/np_browser.cc b/gpu/np_utils/np_browser.cc new file mode 100644 index 0000000..d0d703c --- /dev/null +++ b/gpu/np_utils/np_browser.cc @@ -0,0 +1,123 @@ +// Copyright (c) 2006-2008 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/np_utils/np_browser.h" +#include "base/logging.h" +#include "webkit/glue/plugins/nphostapi.h" + +namespace np_utils { + +NPBrowser* NPBrowser::browser_; + +NPBrowser::NPBrowser(NPNetscapeFuncs* funcs) + : netscape_funcs_(funcs) { + // Make this the first browser in the linked list. + previous_browser_ = browser_; + browser_ = this; +} + +NPBrowser::~NPBrowser() { + // Remove this browser from the linked list. + DCHECK(browser_ == this); + browser_ = previous_browser_; +} + +NPIdentifier NPBrowser::GetStringIdentifier(const NPUTF8* name) { + return netscape_funcs_->getstringidentifier(name); +} + +void* NPBrowser::MemAlloc(size_t size) { + return netscape_funcs_->memalloc(size); +} + +void NPBrowser::MemFree(void* p) { + netscape_funcs_->memfree(p); +} + +NPObject* NPBrowser::CreateObject(NPP npp, const NPClass* cl) { + return netscape_funcs_->createobject(npp, const_cast<NPClass*>(cl)); +} + +NPObject* NPBrowser::RetainObject(NPObject* object) { + return netscape_funcs_->retainobject(object); +} + +void NPBrowser::ReleaseObject(NPObject* object) { + netscape_funcs_->releaseobject(object); +} + +void NPBrowser::ReleaseVariantValue(NPVariant* variant) { + netscape_funcs_->releasevariantvalue(variant); +} + +bool NPBrowser::HasProperty(NPP npp, + NPObject* object, + NPIdentifier name) { + return netscape_funcs_->hasproperty(npp, object, name); +} + +bool NPBrowser::GetProperty(NPP npp, + NPObject* object, + NPIdentifier name, + NPVariant* result) { + return netscape_funcs_->getproperty(npp, object, name, result); +} + +bool NPBrowser::SetProperty(NPP npp, + NPObject* object, + NPIdentifier name, + const NPVariant* result) { + return netscape_funcs_->setproperty(npp, object, name, result); +} + +bool NPBrowser::RemoveProperty(NPP npp, + NPObject* object, + NPIdentifier name) { + return netscape_funcs_->removeproperty(npp, object, name); +} + +bool NPBrowser::HasMethod(NPP npp, + NPObject* object, + NPIdentifier name) { + return netscape_funcs_->hasmethod(npp, object, name); +} + +bool NPBrowser::Invoke(NPP npp, + NPObject* object, + NPIdentifier name, + const NPVariant* args, + uint32_t num_args, + NPVariant* result) { + return netscape_funcs_->invoke(npp, object, name, args, num_args, result); +} + +NPObject* NPBrowser::GetWindowNPObject(NPP npp) { + NPObject* window; + if (NPERR_NO_ERROR == netscape_funcs_->getvalue(npp, + NPNVWindowNPObject, + &window)) { + return window; + } else { + return NULL; + } +} + +void NPBrowser::PluginThreadAsyncCall(NPP npp, + PluginThreadAsyncCallProc callback, + void* data) { + netscape_funcs_->pluginthreadasynccall(npp, callback, data); +} + +uint32 NPBrowser::ScheduleTimer(NPP npp, + uint32 interval, + bool repeat, + TimerProc callback) { + return netscape_funcs_->scheduletimer(npp, interval, repeat, callback); +} + +void NPBrowser::UnscheduleTimer(NPP npp, uint32 timer_id) { + netscape_funcs_->unscheduletimer(npp, timer_id); +} + +} // namespace np_utils diff --git a/gpu/np_utils/np_browser.h b/gpu/np_utils/np_browser.h new file mode 100644 index 0000000..e46bf38 --- /dev/null +++ b/gpu/np_utils/np_browser.h @@ -0,0 +1,95 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_NP_UTILS_NP_BROWSER_H_ +#define GPU_NP_UTILS_NP_BROWSER_H_ + +#include "base/basictypes.h" +#include "gpu/np_utils/np_headers.h" + +typedef struct _NPNetscapeFuncs NPNetscapeFuncs; + +namespace np_utils { + +// This class exposes the functions provided by the browser to a plugin (the +// ones prefixed NPN_). +class NPBrowser { + public: + explicit NPBrowser(NPNetscapeFuncs* funcs); + virtual ~NPBrowser(); + + static NPBrowser* get() { + return browser_; + } + + // Standard functions from NPNetscapeFuncs. + + virtual NPIdentifier GetStringIdentifier(const NPUTF8* name); + + virtual void* MemAlloc(size_t size); + + virtual void MemFree(void* p); + + virtual NPObject* CreateObject(NPP npp, const NPClass* cl); + + virtual NPObject* RetainObject(NPObject* object); + + virtual void ReleaseObject(NPObject* object); + + virtual void ReleaseVariantValue(NPVariant* variant); + + virtual bool HasProperty(NPP npp, + NPObject* object, + NPIdentifier name); + + virtual bool GetProperty(NPP npp, + NPObject* object, + NPIdentifier name, + NPVariant* result); + + virtual bool SetProperty(NPP npp, + NPObject* object, + NPIdentifier name, + const NPVariant* result); + + virtual bool RemoveProperty(NPP npp, + NPObject* object, + NPIdentifier name); + + virtual bool HasMethod(NPP npp, + NPObject* object, + NPIdentifier name); + + virtual bool Invoke(NPP npp, + NPObject* object, + NPIdentifier name, + const NPVariant* args, + uint32_t num_args, + NPVariant* result); + + virtual NPObject* GetWindowNPObject(NPP npp); + + typedef void (*PluginThreadAsyncCallProc)(void* data); + virtual void PluginThreadAsyncCall(NPP npp, + PluginThreadAsyncCallProc callback, + void* data); + + typedef void (*TimerProc)(NPP npp, uint32 timer_id); + virtual uint32 ScheduleTimer(NPP npp, + uint32 interval, + bool repeat, + TimerProc callback); + + virtual void UnscheduleTimer(NPP npp, uint32 timer_id); + + private: + static NPBrowser* browser_; + NPBrowser* previous_browser_; + NPNetscapeFuncs* netscape_funcs_; + DISALLOW_COPY_AND_ASSIGN(NPBrowser); +}; + +} // namespace np_utils + +#endif // GPU_NP_UTILS_NP_BROWSER_H_ diff --git a/gpu/np_utils/np_browser_mock.h b/gpu/np_utils/np_browser_mock.h new file mode 100644 index 0000000..c5361c7 --- /dev/null +++ b/gpu/np_utils/np_browser_mock.h @@ -0,0 +1,50 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_NP_UTILS_NP_BROWSER_MOCK_H_ +#define GPU_NP_UTILS_NP_BROWSER_MOCK_H_ + +#include "gpu/np_utils/np_browser_stub.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace np_utils { + +// This mocks certain member functions of the stub browser. Those relating +// to identifiers, memory management, reference counting and forwarding to +// NPObjects are deliberately not mocked so the mock browser can be used as +// normal for these calls. +class MockNPBrowser : public StubNPBrowser { + public: + NPObject* ConcreteCreateObject(NPP npp, const NPClass* cl) { + return StubNPBrowser::CreateObject(npp, cl); + } + + MockNPBrowser() { + // Do not mock CreateObject by default but allow it to be mocked so object + // creation can be intercepted. + ON_CALL(*this, CreateObject(testing::_, testing::_)) + .WillByDefault(testing::Invoke(this, + &MockNPBrowser::ConcreteCreateObject)); + } + + void ConcretePluginThreadAsyncCall(NPP npp, + PluginThreadAsyncCallProc callback, + void* data) { + return StubNPBrowser::PluginThreadAsyncCall(npp, callback, data); + } + + MOCK_METHOD2(CreateObject, NPObject*(NPP npp, const NPClass* cl)); + MOCK_METHOD1(GetWindowNPObject, NPObject*(NPP cpp)); + MOCK_METHOD3(PluginThreadAsyncCall, + void(NPP npp, PluginThreadAsyncCallProc callback, void* data)); + MOCK_METHOD4(ScheduleTimer, uint32(NPP npp, + uint32 interval, + bool repeat, + TimerProc callback)); + MOCK_METHOD2(UnscheduleTimer, void(NPP npp, uint32 timer_id)); +}; + +} // namespace np_utils + +#endif // GPU_NP_UTILS_NP_BROWSER_MOCK_H_ diff --git a/gpu/np_utils/np_browser_stub.cc b/gpu/np_utils/np_browser_stub.cc new file mode 100644 index 0000000..2e1c757 --- /dev/null +++ b/gpu/np_utils/np_browser_stub.cc @@ -0,0 +1,125 @@ +// Copyright (c) 2006-2008 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/np_utils/np_browser_stub.h" +#include "base/logging.h" +#include "base/message_loop.h" + +namespace np_utils { + +StubNPBrowser::StubNPBrowser() : NPBrowser(NULL) { +} + +StubNPBrowser::~StubNPBrowser() { +} + +NPIdentifier StubNPBrowser::GetStringIdentifier(const NPUTF8* name) { + static std::set<std::string> names; + std::set<std::string>::iterator it = names.find(name); + if (it == names.end()) { + it = names.insert(name).first; + } + return const_cast<NPUTF8*>((*it).c_str()); +} + +void* StubNPBrowser::MemAlloc(size_t size) { + return malloc(size); +} + +void StubNPBrowser::MemFree(void* p) { + free(p); +} + +NPObject* StubNPBrowser::CreateObject(NPP npp, const NPClass* cl) { + NPObject* object = cl->allocate(npp, const_cast<NPClass*>(cl)); + object->referenceCount = 1; + object->_class = const_cast<NPClass*>(cl); + return object; +} + +NPObject* StubNPBrowser::RetainObject(NPObject* object) { + ++object->referenceCount; + return object; +} + +void StubNPBrowser::ReleaseObject(NPObject* object) { + DCHECK_GE(object->referenceCount, 0u); + --object->referenceCount; + if (object->referenceCount == 0) { + object->_class->deallocate(object); + } +} + +void StubNPBrowser::ReleaseVariantValue(NPVariant* variant) { + if (NPVARIANT_IS_STRING(*variant)) { + MemFree(const_cast<NPUTF8*>(variant->value.stringValue.UTF8Characters)); + } else if (NPVARIANT_IS_OBJECT(*variant)) { + ReleaseObject(NPVARIANT_TO_OBJECT(*variant)); + } +} + +bool StubNPBrowser::HasProperty(NPP npp, + NPObject* object, + NPIdentifier name) { + return object->_class->hasProperty(object, name); +} + +bool StubNPBrowser::GetProperty(NPP npp, + NPObject* object, + NPIdentifier name, + NPVariant* result) { + return object->_class->getProperty(object, name, result); +} + +bool StubNPBrowser::SetProperty(NPP npp, + NPObject* object, + NPIdentifier name, + const NPVariant* result) { + return object->_class->setProperty(object, name, result); +} + +bool StubNPBrowser::RemoveProperty(NPP npp, + NPObject* object, + NPIdentifier name) { + return object->_class->removeProperty(object, name); +} + +bool StubNPBrowser::HasMethod(NPP npp, + NPObject* object, + NPIdentifier name) { + return object->_class->hasMethod(object, name); +} + +bool StubNPBrowser::Invoke(NPP npp, + NPObject* object, + NPIdentifier name, + const NPVariant* args, + uint32_t num_args, + NPVariant* result) { + return object->_class->invoke(object, name, args, num_args, result); +} + +NPObject* StubNPBrowser::GetWindowNPObject(NPP npp) { + return NULL; +} + +void StubNPBrowser::PluginThreadAsyncCall( + NPP npp, + PluginThreadAsyncCallProc callback, + void* data) { + MessageLoop::current()->PostTask(FROM_HERE, + NewRunnableFunction(callback, data)); +} + +uint32 StubNPBrowser::ScheduleTimer(NPP npp, + uint32 interval, + bool repeat, + TimerProc callback) { + return 0; +} + +void StubNPBrowser::UnscheduleTimer(NPP npp, uint32 timer_id) { +} + +} // namespace np_utils diff --git a/gpu/np_utils/np_browser_stub.h b/gpu/np_utils/np_browser_stub.h new file mode 100644 index 0000000..f208b7b --- /dev/null +++ b/gpu/np_utils/np_browser_stub.h @@ -0,0 +1,84 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_NP_UTILS_NP_BROWSER_STUB_H_ +#define GPU_NP_UTILS_NP_BROWSER_STUB_H_ + +#include <set> +#include <string> + +#include "gpu/np_utils/np_browser.h" + +namespace np_utils { + +// Simple implementation of subset of the NPN functions for testing. +class StubNPBrowser : public NPBrowser { + public: + StubNPBrowser(); + virtual ~StubNPBrowser(); + + // Standard functions from NPNetscapeFuncs. + + virtual NPIdentifier GetStringIdentifier(const NPUTF8* name); + + virtual void* MemAlloc(size_t size); + + virtual void MemFree(void* p); + + virtual NPObject* CreateObject(NPP npp, const NPClass* cl); + + virtual NPObject* RetainObject(NPObject* object); + + virtual void ReleaseObject(NPObject* object); + + virtual void ReleaseVariantValue(NPVariant* variant); + + virtual bool HasProperty(NPP npp, + NPObject* object, + NPIdentifier name); + + virtual bool GetProperty(NPP npp, + NPObject* object, + NPIdentifier name, + NPVariant* result); + + virtual bool SetProperty(NPP npp, + NPObject* object, + NPIdentifier name, + const NPVariant* result); + + virtual bool RemoveProperty(NPP npp, + NPObject* object, + NPIdentifier name); + + virtual bool HasMethod(NPP npp, + NPObject* object, + NPIdentifier name); + virtual bool Invoke(NPP npp, + NPObject* object, + NPIdentifier name, + const NPVariant* args, + uint32_t num_args, + NPVariant* result); + + virtual NPObject* GetWindowNPObject(NPP npp); + + virtual void PluginThreadAsyncCall(NPP npp, + PluginThreadAsyncCallProc callback, + void* data); + + virtual uint32 ScheduleTimer(NPP npp, + uint32 interval, + bool repeat, + TimerProc callback); + + virtual void UnscheduleTimer(NPP npp, uint32 timer_id); + + private: + DISALLOW_COPY_AND_ASSIGN(StubNPBrowser); +}; + +} // namespace np_utils + +#endif // GPU_NP_UTILS_NP_BROWSER_STUB_H_ diff --git a/gpu/np_utils/np_class.h b/gpu/np_utils/np_class.h new file mode 100644 index 0000000..21d1d4b --- /dev/null +++ b/gpu/np_utils/np_class.h @@ -0,0 +1,125 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_NP_UTILS_NP_CLASS_H_ +#define GPU_NP_UTILS_NP_CLASS_H_ + +#include "gpu/np_utils/np_object_pointer.h" +#include "gpu/np_utils/np_headers.h" + +// This file implements NPGetClass<T>. This function returns an NPClass +// that can be used to instantiate an NPObject subclass T. The NPClass +// function pointers will invoke the most derived corresponding member +// functions in T. + +namespace np_utils { + +namespace np_class_impl { + // This template version of the NPClass allocate function creates a subclass + // of BaseNPObject. + template <typename NPObjectType> + static NPObject* Allocate(NPP npp, NPClass*) { + return new NPObjectType(npp); + } + + // These implementations of the NPClass functions forward to the virtual + // functions in DefaultNPObject. + template <typename NPObjectType> + static void Deallocate(NPObject* object) { + delete static_cast<NPObjectType*>(object); + } + + template <typename NPObjectType> + static void Invalidate(NPObject* object) { + return static_cast<NPObjectType*>(object)->Invalidate(); + } + + template <typename NPObjectType> + static bool HasMethod(NPObject* object, NPIdentifier name) { + return static_cast<NPObjectType*>(object)->HasMethod(name); + } + + template <typename NPObjectType> + static bool Invoke(NPObject* object, + NPIdentifier name, + const NPVariant* args, + uint32_t num_args, + NPVariant* result) { + return static_cast<NPObjectType*>(object)->Invoke( + name, args, num_args, result); + } + + template <typename NPObjectType> + static bool InvokeDefault(NPObject* object, + const NPVariant* args, + uint32_t num_args, + NPVariant* result) { + return static_cast<NPObjectType*>(object)->InvokeDefault( + args, num_args, result); + } + + template <typename NPObjectType> + static bool HasProperty(NPObject* object, NPIdentifier name) { + return static_cast<NPObjectType*>(object)->HasProperty(name); + } + + template <typename NPObjectType> + static bool GetProperty(NPObject* object, + NPIdentifier name, + NPVariant* result) { + return static_cast<NPObjectType*>(object)->GetProperty(name, result); + } + + template <typename NPObjectType> + static bool SetProperty(NPObject* object, + NPIdentifier name, + const NPVariant* value) { + return static_cast<NPObjectType*>(object)->SetProperty(name, value); + } + + template <typename NPObjectType> + static bool RemoveProperty(NPObject* object, NPIdentifier name) { + return static_cast<NPObjectType*>(object)->RemoveProperty(name); + } + + template <typename NPObjectType> + static bool Enumerate(NPObject* object, + NPIdentifier** names, + uint32_t* count) { + return static_cast<NPObjectType*>(object)->Enumerate(names, count); + }; + + template <typename NPObjectType> + static bool Construct(NPObject* object, + const NPVariant* args, + uint32_t num_args, + NPVariant* result) { + return static_cast<NPObjectType*>(object)->Construct( + args, num_args, result); + } +} // namespace np_class_impl; + +template <typename NPObjectType> +const NPClass* NPGetClass() { + static const NPClass np_class = { + NP_CLASS_STRUCT_VERSION, + np_class_impl::Allocate<NPObjectType>, + np_class_impl::Deallocate<NPObjectType>, + np_class_impl::Invalidate<NPObjectType>, + np_class_impl::HasMethod<NPObjectType>, + np_class_impl::Invoke<NPObjectType>, + np_class_impl::InvokeDefault<NPObjectType>, + np_class_impl::HasProperty<NPObjectType>, + np_class_impl::GetProperty<NPObjectType>, + np_class_impl::SetProperty<NPObjectType>, + np_class_impl::RemoveProperty<NPObjectType>, + np_class_impl::Enumerate<NPObjectType>, + np_class_impl::Construct<NPObjectType>, + }; + return &np_class; +}; + +} // namespace np_utils + +#endif // GPU_NP_UTILS_NP_CLASS_H_ diff --git a/gpu/np_utils/np_class_unittest.cc b/gpu/np_utils/np_class_unittest.cc new file mode 100644 index 0000000..0e7807f --- /dev/null +++ b/gpu/np_utils/np_class_unittest.cc @@ -0,0 +1,143 @@ +// Copyright (c) 2006-2008 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/np_utils/np_class.h" +#include "gpu/np_utils/np_object_mock.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::StrictMock; + +namespace np_utils { + +class NPClassTest : public testing::Test { + protected: + virtual void SetUp() { + np_class = NPGetClass<StrictMock<MockNPObject> >(); + + // Dummy identifier is never used with real NPAPI so it can point to + // anything. + identifier = this; + } + + virtual void TearDown() { + } + + NPP_t npp_; + const NPClass* np_class; + NPIdentifier identifier; + NPVariant args[3]; + NPVariant result; +}; + +TEST_F(NPClassTest, AllocateAndDeallocateObject) { + MockNPObject* object = static_cast<MockNPObject*>( + np_class->allocate(&npp_, const_cast<NPClass*>(np_class))); + EXPECT_TRUE(NULL != object); + + np_class->deallocate(object); +} + +TEST_F(NPClassTest, InvalidateForwards) { + MockNPObject* object = static_cast<MockNPObject*>( + np_class->allocate(&npp_, const_cast<NPClass*>(np_class))); + + EXPECT_CALL(*object, Invalidate()); + np_class->invalidate(object); + + np_class->deallocate(object); +} + +TEST_F(NPClassTest, HasMethodForwards) { + MockNPObject* object = static_cast<MockNPObject*>( + np_class->allocate(&npp_, const_cast<NPClass*>(np_class))); + + EXPECT_CALL(*object, HasMethod(identifier)); + np_class->hasMethod(object, identifier); + + np_class->deallocate(object); +} + +TEST_F(NPClassTest, InvokeForwards) { + MockNPObject* object = static_cast<MockNPObject*>( + np_class->allocate(&npp_, const_cast<NPClass*>(np_class))); + + EXPECT_CALL(*object, Invoke(identifier, args, 3, &result)); + np_class->invoke(object, identifier, args, 3, &result); + + np_class->deallocate(object); +} + +TEST_F(NPClassTest, InvokeDefaultForwards) { + MockNPObject* object = static_cast<MockNPObject*>( + np_class->allocate(&npp_, const_cast<NPClass*>(np_class))); + + EXPECT_CALL(*object, InvokeDefault(args, 3, &result)); + np_class->invokeDefault(object, args, 3, &result); + + np_class->deallocate(object); +} + +TEST_F(NPClassTest, HasPropertyForwards) { + MockNPObject* object = static_cast<MockNPObject*>( + np_class->allocate(&npp_, const_cast<NPClass*>(np_class))); + + EXPECT_CALL(*object, HasProperty(identifier)); + np_class->hasProperty(object, identifier); + + np_class->deallocate(object); +} + +TEST_F(NPClassTest, GetPropertyForwards) { + MockNPObject* object = static_cast<MockNPObject*>( + np_class->allocate(&npp_, const_cast<NPClass*>(np_class))); + + EXPECT_CALL(*object, GetProperty(identifier, &result)); + np_class->getProperty(object, identifier, &result); + + np_class->deallocate(object); +} + +TEST_F(NPClassTest, SetPropertyForwards) { + MockNPObject* object = static_cast<MockNPObject*>( + np_class->allocate(&npp_, const_cast<NPClass*>(np_class))); + + EXPECT_CALL(*object, SetProperty(identifier, &result)); + np_class->setProperty(object, identifier, &result); + + np_class->deallocate(object); +} + +TEST_F(NPClassTest, RemovePropertyForwards) { + MockNPObject* object = static_cast<MockNPObject*>( + np_class->allocate(&npp_, const_cast<NPClass*>(np_class))); + + EXPECT_CALL(*object, RemoveProperty(identifier)); + np_class->removeProperty(object, identifier); + + np_class->deallocate(object); +} + +TEST_F(NPClassTest, EnumerateForwards) { + MockNPObject* object = static_cast<MockNPObject*>( + np_class->allocate(&npp_, const_cast<NPClass*>(np_class))); + + NPIdentifier* identifier = NULL; + uint32_t count; + EXPECT_CALL(*object, Enumerate(&identifier, &count)); + np_class->enumerate(object, &identifier, &count); + + np_class->deallocate(object); +} + +TEST_F(NPClassTest, ConstructForwards) { + MockNPObject* object = static_cast<MockNPObject*>( + np_class->allocate(&npp_, const_cast<NPClass*>(np_class))); + + EXPECT_CALL(*object, Construct(args, 3, &result)); + np_class->construct(object, args, 3, &result); + + np_class->deallocate(object); +} +} // namespace np_utils diff --git a/gpu/np_utils/np_dispatcher.cc b/gpu/np_utils/np_dispatcher.cc new file mode 100644 index 0000000..63293c0 --- /dev/null +++ b/gpu/np_utils/np_dispatcher.cc @@ -0,0 +1,86 @@ +// Copyright (c) 2006-2008 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/np_utils/np_dispatcher.h" + +namespace np_utils { + +bool DispatcherHasMethodHelper(BaseNPDispatcher* chain, + NPObject* object, + NPIdentifier name) { + for (BaseNPDispatcher* dispatcher = chain; + dispatcher; + dispatcher = dispatcher->next()) { + if (dispatcher->name() == name) { + return true; + } + } + + return false; +} + +bool DispatcherInvokeHelper(BaseNPDispatcher* chain, + NPObject* object, + NPIdentifier name, + const NPVariant* args, + uint32_t num_args, + NPVariant* result) { + VOID_TO_NPVARIANT(*result); + + for (BaseNPDispatcher* dispatcher = chain; + dispatcher; + dispatcher = dispatcher->next()) { + if (dispatcher->name() == name && + dispatcher->num_args() == static_cast<int>(num_args)) { + if (dispatcher->Invoke(object, args, num_args, result)) + return true; + } + } + + return false; +} + +bool DispatcherEnumerateHelper(BaseNPDispatcher* chain, + NPObject* object, + NPIdentifier** names, + uint32_t* num_names) { + // Count the number of names. + *num_names = 0; + for (BaseNPDispatcher* dispatcher = chain; + dispatcher; + dispatcher = dispatcher->next()) { + ++(*num_names); + } + + // Copy names into the array. + *names = static_cast<NPIdentifier*>( + NPBrowser::get()->MemAlloc((*num_names) * sizeof(**names))); + int i = 0; + for (BaseNPDispatcher* dispatcher = chain; + dispatcher; + dispatcher = dispatcher->next()) { + (*names)[i] = dispatcher->name(); + ++i; + } + + return true; +} + +BaseNPDispatcher::BaseNPDispatcher(BaseNPDispatcher* next, const NPUTF8* name) + : next_(next) { + // Convert first character to lower case if it is the ASCII range. + // TODO(apatrick): do this correctly for non-ASCII characters. + std::string java_script_style_name(name); + if (isupper(java_script_style_name[0])) { + java_script_style_name[0] = tolower(java_script_style_name[0]); + } + + name_ = NPBrowser::get()->GetStringIdentifier( + java_script_style_name.c_str()); +} + +BaseNPDispatcher::~BaseNPDispatcher() { +} + +} // namespace np_utils diff --git a/gpu/np_utils/np_dispatcher.h b/gpu/np_utils/np_dispatcher.h new file mode 100644 index 0000000..ff6bed5 --- /dev/null +++ b/gpu/np_utils/np_dispatcher.h @@ -0,0 +1,224 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_NP_UTILS_NP_DISPATCHER_H_ +#define GPU_NP_UTILS_NP_DISPATCHER_H_ + +#include <string> + +#include "gpu/np_utils/np_utils.h" +#include "gpu/np_utils/np_headers.h" + +// Dispatchers make regular member functions available as NPObject methods. +// Usage: +// +// class MyNPObject : public DefaultNPObject<NPObject> { +// public: +// int MyMethod(bool a, float b); +// NP_UTILS_BEGIN_DISPATCHER_CHAIN(MyNPObject, DispatchedNPObject) +// NP_UTILS_DISPATCHER(MyMethod, int(bool, float)) +// NP_UTILS_END_DISPATCHER_CHAIN +// }; +// +// Multiple member functions may be listed in the dispatcher chain. Inheritance +// is supported. The following types are supported as return types and parameter +// types: +// * bool +// * int +// * float +// * double +// * std::string +// * NPObject* +// + +// These macros are used to make dispatcher chains. +#define NP_UTILS_NP_UTILS_DISPATCHER_JOIN2(a, b) a ## b +#define NP_UTILS_DISPATCHER_JOIN(a, b) NP_UTILS_NP_UTILS_DISPATCHER_JOIN2(a, b) +#define NP_UTILS_DISPATCHER_UNIQUE \ + NP_UTILS_DISPATCHER_JOIN(dispatcher, __LINE__) + +#define NP_UTILS_BEGIN_DISPATCHER_CHAIN(Class, BaseClass) \ + static ::np_utils::BaseNPDispatcher* GetDispatcherChain() { \ + typedef Class ThisClass; \ + ::np_utils::BaseNPDispatcher* top_dispatcher = \ + BaseClass::GetDispatcherChain(); \ + +#define NP_UTILS_DISPATCHER(name, Signature) \ + static ::np_utils::NPDispatcher<ThisClass, Signature> \ + NP_UTILS_DISPATCHER_UNIQUE( \ + top_dispatcher, \ + #name, \ + &ThisClass::name); \ + top_dispatcher = &NP_UTILS_DISPATCHER_UNIQUE; \ + +#define NP_UTILS_END_DISPATCHER_CHAIN \ + return top_dispatcher; \ + } \ + bool HasMethod(NPIdentifier name) { \ + return ::np_utils::DispatcherHasMethodHelper( \ + GetDispatcherChain(), this, name); \ + } \ + bool Invoke(NPIdentifier name, \ + const NPVariant* args, \ + uint32_t num_args, \ + NPVariant* result) { \ + return ::np_utils::DispatcherInvokeHelper(GetDispatcherChain(), \ + this, \ + name, \ + args, \ + num_args, \ + result); \ + } \ + bool Enumerate(NPIdentifier** names, uint32_t* num_names) { \ + return ::np_utils::DispatcherEnumerateHelper(GetDispatcherChain(), \ + this, \ + names, \ + num_names); \ + } \ + +namespace np_utils { + +class BaseNPDispatcher { + public: + BaseNPDispatcher(BaseNPDispatcher* next, const NPUTF8* name); + + virtual ~BaseNPDispatcher(); + + BaseNPDispatcher* next() const { + return next_; + } + + NPIdentifier name() const { + return name_; + } + + virtual int num_args() const = 0; + + virtual bool Invoke(NPObject* object, + const NPVariant* args, + uint32_t num_args, + NPVariant* result) = 0; + + private: + BaseNPDispatcher* next_; + NPIdentifier name_; + DISALLOW_COPY_AND_ASSIGN(BaseNPDispatcher); +}; + +bool DispatcherHasMethodHelper(BaseNPDispatcher* chain, + NPObject* object, + NPIdentifier name); + +bool DispatcherInvokeHelper(BaseNPDispatcher* chain, + NPObject* object, + NPIdentifier name, + const NPVariant* args, + uint32_t num_args, + NPVariant* result); + +bool DispatcherEnumerateHelper(BaseNPDispatcher* chain, + NPObject* object, + NPIdentifier** names, + uint32_t* num_names); + +// This class should never be instantiated. It is always specialized. Attempting +// to instantiate it results in a compilation error. This might mean an +// attempt to instantiate a dispatcher with more parameters than have been +// specialized for. See the specialization code below. +template <typename NPObjectType, typename FunctionType> +struct NPDispatcher { +}; + +#define TO_NPVARIANT(index) \ + T##index n##index; \ + if (!NPVariantToValue(&n##index, args[index])) \ + return false; \ + +#define NUM_PARAMS 0 +#define PARAM_TYPENAMES +#define PARAM_TYPES +#define PARAM_NAMES +#define PARAM_DECLS // NOLINT + +#define PARAM_TO_NVPARIANT_CONVERSIONS \ + +#include "gpu/np_utils/np_dispatcher_specializations.h" // NOLINT + + +#define NUM_PARAMS 1 +#define PARAM_TYPENAMES , typename T0 +#define PARAM_TYPES T0 +#define PARAM_NAMES n0 +#define PARAM_DECLS T0 n0; // NOLINT + +#define PARAM_TO_NVPARIANT_CONVERSIONS \ + TO_NPVARIANT(0); \ + +#include "gpu/np_utils/np_dispatcher_specializations.h" // NOLINT + + +#define NUM_PARAMS 2 +#define PARAM_TYPENAMES , typename T0, typename T1 +#define PARAM_TYPES T0, T1 +#define PARAM_NAMES n0, n1 +#define PARAM_DECLS T0 n0; T1 n1; // NOLINT + +#define PARAM_TO_NVPARIANT_CONVERSIONS \ + TO_NPVARIANT(0); \ + TO_NPVARIANT(1); \ + +#include "gpu/np_utils/np_dispatcher_specializations.h" // NOLINT + + +#define NUM_PARAMS 3 +#define PARAM_TYPENAMES , typename T0, typename T1, typename T2 +#define PARAM_TYPES T0, T1, T2 +#define PARAM_NAMES n0, n1, n2 +#define PARAM_DECLS T0 n0; T1 n1; T2 n2; // NOLINT + +#define PARAM_TO_NVPARIANT_CONVERSIONS \ + TO_NPVARIANT(0); \ + TO_NPVARIANT(1); \ + TO_NPVARIANT(2); \ + +#include "gpu/np_utils/np_dispatcher_specializations.h" // NOLINT + + +#define NUM_PARAMS 4 +#define PARAM_TYPENAMES , typename T0, typename T1, typename T2, typename T3 +#define PARAM_TYPES T0, T1, T2, T3 +#define PARAM_NAMES n0, n1, n2, n3 +#define PARAM_DECLS T0 n0; T1 n1; T2 n2; T3 n3; // NOLINT + +#define PARAM_TO_NVPARIANT_CONVERSIONS \ + TO_NPVARIANT(0); \ + TO_NPVARIANT(1); \ + TO_NPVARIANT(2); \ + TO_NPVARIANT(3); \ + +#include "gpu/np_utils/np_dispatcher_specializations.h" // NOLINT + + +#define NUM_PARAMS 5 +#define PARAM_TYPENAMES , typename T0, typename T1, typename T2, typename T3, \ + typename T4 +#define PARAM_TYPES T0, T1, T2, T3, T4 +#define PARAM_NAMES n0, n1, n2, n3, n4 +#define PARAM_DECLS T0 n0; T1 n1; T2 n2; T3 n3; T4 n4; // NOLINT + +#define PARAM_TO_NVPARIANT_CONVERSIONS \ + TO_NPVARIANT(0); \ + TO_NPVARIANT(1); \ + TO_NPVARIANT(2); \ + TO_NPVARIANT(3); \ + TO_NPVARIANT(4); \ + +#include "gpu/np_utils/np_dispatcher_specializations.h" // NOLINT + + +#undef TO_NPVARIANT + +} // namespace np_utils + +#endif // GPU_NP_UTILS_NP_DISPATCHER_H_ diff --git a/gpu/np_utils/np_dispatcher_specializations.h b/gpu/np_utils/np_dispatcher_specializations.h new file mode 100644 index 0000000..62fb8c4 --- /dev/null +++ b/gpu/np_utils/np_dispatcher_specializations.h @@ -0,0 +1,85 @@ +// Copyright (c) 2006-2008 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. + +// There is deliberately no header guard here. This file is included multiple +// times, once for each dispatcher specialiation arity. Do not include this +// file directly. Include np_dispatcher.h instead. + +template <typename NPObjectType PARAM_TYPENAMES> +class NPDispatcher<NPObjectType, void(PARAM_TYPES)> + : public BaseNPDispatcher { + typedef void (NPObjectType::*FunctionType)(PARAM_TYPES); + public: + NPDispatcher(BaseNPDispatcher* next, + const NPUTF8* name, + FunctionType function) + : BaseNPDispatcher(next, name), + function_(function) { + } + + virtual bool Invoke(NPObject* object, + const NPVariant* args, + uint32_t num_args, + NPVariant* result) { + VOID_TO_NPVARIANT(*result); + + if (num_args != NUM_PARAMS) + return false; + + PARAM_TO_NVPARIANT_CONVERSIONS + + (static_cast<NPObjectType*>(object)->*function_)(PARAM_NAMES); + return true; + } + + virtual int num_args() const { + return NUM_PARAMS; + } + + private: + FunctionType function_; +}; + +template <typename NPObjectType, typename R PARAM_TYPENAMES> +class NPDispatcher<NPObjectType, R(PARAM_TYPES)> + : public BaseNPDispatcher { + typedef R (NPObjectType::*FunctionType)(PARAM_TYPES); + public: + NPDispatcher(BaseNPDispatcher* next, + const NPUTF8* name, + FunctionType function) + : BaseNPDispatcher(next, name), + function_(function) { + } + + virtual bool Invoke(NPObject* object, + const NPVariant* args, + uint32_t num_args, + NPVariant* result) { + VOID_TO_NPVARIANT(*result); + + if (num_args != NUM_PARAMS) + return false; + + PARAM_TO_NVPARIANT_CONVERSIONS + + ValueToNPVariant( + (static_cast<NPObjectType*>(object)->*function_)(PARAM_NAMES), result); + return true; + } + + virtual int num_args() const { + return NUM_PARAMS; + } + + private: + FunctionType function_; +}; + +#undef NUM_PARAMS +#undef PARAM_TYPENAMES +#undef PARAM_TYPES +#undef PARAM_NAMES +#undef PARAM_DECLS +#undef PARAM_TO_NVPARIANT_CONVERSIONS diff --git a/gpu/np_utils/np_headers.h b/gpu/np_utils/np_headers.h new file mode 100644 index 0000000..cd4d8f9 --- /dev/null +++ b/gpu/np_utils/np_headers.h @@ -0,0 +1,11 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_NP_UTILS_NP_HEADERS_H_ +#define GPU_NP_UTILS_NP_HEADERS_H_ + +#include "third_party/npapi/bindings/npapi.h" +#include "third_party/npapi/bindings/npruntime.h" + +#endif // GPU_NP_UTILS_NP_HEADERS_H_ diff --git a/gpu/np_utils/np_object_mock.h b/gpu/np_utils/np_object_mock.h new file mode 100644 index 0000000..99d1ff6 --- /dev/null +++ b/gpu/np_utils/np_object_mock.h @@ -0,0 +1,36 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_NP_UTILS_NP_OBJECT_MOCK_H_ +#define GPU_NP_UTILS_NP_OBJECT_MOCK_H_ + +#include "gpu/np_utils/np_browser.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace np_utils { + +class MockNPObject : public NPObject { + public: + explicit MockNPObject(NPP npp) { + } + + MOCK_METHOD0(Invalidate, void()); + MOCK_METHOD1(HasMethod, bool(NPIdentifier)); + MOCK_METHOD4(Invoke, + bool(NPIdentifier, const NPVariant*, uint32_t, NPVariant*)); + MOCK_METHOD3(InvokeDefault, bool(const NPVariant*, uint32_t, NPVariant*)); + MOCK_METHOD1(HasProperty, bool(NPIdentifier)); + MOCK_METHOD2(GetProperty, bool(NPIdentifier, NPVariant*)); + MOCK_METHOD2(SetProperty, bool(NPIdentifier, const NPVariant*)); + MOCK_METHOD1(RemoveProperty, bool(NPIdentifier)); + MOCK_METHOD2(Enumerate, bool(NPIdentifier**, uint32_t*)); + MOCK_METHOD3(Construct, bool(const NPVariant*, uint32_t, NPVariant*)); + + private: + DISALLOW_COPY_AND_ASSIGN(MockNPObject); +}; + +} // namespace np_utils + +#endif // GPU_NP_UTILS_NP_OBJECT_MOCK_H_ diff --git a/gpu/np_utils/np_object_pointer.h b/gpu/np_utils/np_object_pointer.h new file mode 100644 index 0000000..44286a7 --- /dev/null +++ b/gpu/np_utils/np_object_pointer.h @@ -0,0 +1,119 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_NP_UTILS_NP_OBJECT_POINTER_H_ +#define GPU_NP_UTILS_NP_OBJECT_POINTER_H_ + +#include "base/logging.h" +#include "gpu/np_utils/np_browser.h" +#include "gpu/np_utils/np_headers.h" + +namespace np_utils { + +// Smart pointer for NPObjects that automatically handles reference counting. +template <typename NPObjectType> +class NPObjectPointer { + public: + NPObjectPointer() : object_(NULL) {} + + NPObjectPointer(const NPObjectPointer& rhs) : object_(rhs.object_) { + Retain(); + } + + explicit NPObjectPointer(NPObjectType* p) : object_(p) { + Retain(); + } + + template <typename RHS> + NPObjectPointer(const NPObjectPointer<RHS>& rhs) : object_(rhs.Get()) { + Retain(); + } + + ~NPObjectPointer() { + Release(); + } + + NPObjectPointer& operator=(const NPObjectPointer& rhs) { + if (object_ == rhs.Get()) + return *this; + + Release(); + object_ = rhs.object_; + Retain(); + return *this; + } + + template <typename RHS> + NPObjectPointer& operator=(const NPObjectPointer<RHS>& rhs) { + if (object_ == rhs.Get()) + return *this; + + Release(); + object_ = rhs.Get(); + Retain(); + return *this; + } + + template <class RHS> + bool operator==(const NPObjectPointer<RHS>& rhs) const { + return object_ == rhs.Get(); + } + + template <class RHS> + bool operator!=(const NPObjectPointer<RHS>& rhs) const { + return object_ != rhs.Get(); + } + + // The NPObject convention for returning an NPObject pointer from a function + // is that the caller is responsible for releasing the reference count. + static NPObjectPointer FromReturned(NPObjectType* p) { + NPObjectPointer pointer(p); + pointer.Release(); + return pointer; + } + + // The NPObject convention for returning an NPObject pointer from a function + // is that the caller is responsible for releasing the reference count. + NPObjectType* ToReturned() const { + Retain(); + return object_; + } + + NPObjectType* Get() const { + return object_; + } + + NPObjectType* operator->() const { + return object_; + } + + NPObjectType& operator*() const { + return *object_; + } + + private: + void Retain() const { + if (object_) { + NPBrowser::get()->RetainObject(object_); + } + } + + void Release() const { + if (object_) { + NPBrowser::get()->ReleaseObject(object_); + } + } + + NPObjectType* object_; +}; + +// For test diagnostics. +template <typename NPObjectType> +std::ostream& operator<<(std::ostream& stream, + const NPObjectPointer<NPObjectType>& pointer) { + return stream << pointer.Get(); +} +} // namespace np_utils + +#endif // GPU_NP_UTILS_NP_OBJECT_POINTER_H_ diff --git a/gpu/np_utils/np_object_pointer_unittest.cc b/gpu/np_utils/np_object_pointer_unittest.cc new file mode 100644 index 0000000..1e48453 --- /dev/null +++ b/gpu/np_utils/np_object_pointer_unittest.cc @@ -0,0 +1,220 @@ +// Copyright (c) 2006-2008 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/np_utils/np_class.h" +#include "gpu/np_utils/np_object_mock.h" +#include "gpu/np_utils/np_browser_stub.h" +#include "gpu/np_utils/np_object_pointer.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::Return; +using testing::StrictMock; + +namespace np_utils { + +class DerivedNPObject : public MockNPObject { + public: + explicit DerivedNPObject(NPP npp) : MockNPObject(npp) { + } +}; + +class NPObjectPointerTest : public testing::Test { + protected: + virtual void SetUp() { + np_class_ = NPGetClass<StrictMock<MockNPObject> >(); + + raw_pointer_ = static_cast<MockNPObject*>( + NPBrowser::get()->CreateObject(NULL, np_class_)); + + raw_derived_pointer_ = static_cast<DerivedNPObject*>( + NPBrowser::get()->CreateObject(NULL, np_class_)); + } + + virtual void TearDown() { + NPBrowser::get()->ReleaseObject(raw_pointer_); + NPBrowser::get()->ReleaseObject(raw_derived_pointer_); + } + + StubNPBrowser stub_browser_; + const NPClass* np_class_; + MockNPObject* raw_pointer_; + DerivedNPObject* raw_derived_pointer_; +}; + +TEST_F(NPObjectPointerTest, PointerIsNullByDefault) { + NPObjectPointer<MockNPObject> p; + ASSERT_TRUE(NULL == p.Get()); +} + +TEST_F(NPObjectPointerTest, PointerCanBeExplicitlyConstructedFromRawPointer) { + EXPECT_EQ(1, raw_pointer_->referenceCount); + { + NPObjectPointer<MockNPObject> p(raw_pointer_); + ASSERT_TRUE(raw_pointer_ == p.Get()); + EXPECT_EQ(2, raw_pointer_->referenceCount); + } + EXPECT_EQ(1, raw_pointer_->referenceCount); +} + +TEST_F(NPObjectPointerTest, + PointerCanBeExplicitlyConstructedFromNullRawPointer) { + NPObjectPointer<MockNPObject> p(NULL); + ASSERT_TRUE(NULL == p.Get()); +} + +TEST_F(NPObjectPointerTest, PointerCanBeCopyConstructed) { + NPObjectPointer<MockNPObject> p1(raw_pointer_); + EXPECT_EQ(2, raw_pointer_->referenceCount); + { + NPObjectPointer<MockNPObject> p2(p1); + ASSERT_TRUE(raw_pointer_ == p2.Get()); + EXPECT_EQ(3, raw_pointer_->referenceCount); + } + EXPECT_EQ(2, raw_pointer_->referenceCount); +} + +TEST_F(NPObjectPointerTest, PointerCanBeConstructedFromDerived) { + NPObjectPointer<DerivedNPObject> p1(raw_derived_pointer_); + EXPECT_EQ(2, raw_derived_pointer_->referenceCount); + { + NPObjectPointer<MockNPObject> p2(p1); + ASSERT_TRUE(raw_derived_pointer_ == p2.Get()); + EXPECT_EQ(3, raw_derived_pointer_->referenceCount); + } + EXPECT_EQ(2, raw_derived_pointer_->referenceCount); +} + +TEST_F(NPObjectPointerTest, + PointerCanBeCopyConstructedFromNull) { + NPObjectPointer<MockNPObject> p(NULL); + ASSERT_TRUE(NULL == p.Get()); +} + +TEST_F(NPObjectPointerTest, PointerCanBeAssigned) { + NPObjectPointer<MockNPObject> p1(raw_pointer_); + EXPECT_EQ(2, raw_pointer_->referenceCount); + { + NPObjectPointer<MockNPObject> p2; + p2 = p1; + ASSERT_TRUE(raw_pointer_ == p2.Get()); + EXPECT_EQ(3, raw_pointer_->referenceCount); + + p2 = NPObjectPointer<MockNPObject>(); + ASSERT_TRUE(NULL == p2.Get()); + EXPECT_EQ(2, raw_pointer_->referenceCount); + + p2 = p1; + ASSERT_TRUE(raw_pointer_ == p2.Get()); + EXPECT_EQ(3, raw_pointer_->referenceCount); + } + EXPECT_EQ(2, raw_pointer_->referenceCount); +} + +TEST_F(NPObjectPointerTest, PointerCanBeAssignedToSelf) { + NPObjectPointer<MockNPObject> p(raw_pointer_); + NPBrowser::get()->ReleaseObject(raw_pointer_); + EXPECT_EQ(1, raw_pointer_->referenceCount); + p = p; + EXPECT_EQ(1, raw_pointer_->referenceCount); + NPBrowser::get()->RetainObject(raw_pointer_); +} + +TEST_F(NPObjectPointerTest, PointerCanBeAssignedDerived) { + NPObjectPointer<DerivedNPObject> p1(raw_derived_pointer_); + EXPECT_EQ(2, raw_derived_pointer_->referenceCount); + { + NPObjectPointer<MockNPObject> p2; + p2 = p1; + ASSERT_TRUE(raw_derived_pointer_ == p2.Get()); + EXPECT_EQ(3, raw_derived_pointer_->referenceCount); + + p2 = NPObjectPointer<MockNPObject>(); + ASSERT_TRUE(NULL == p2.Get()); + EXPECT_EQ(2, raw_derived_pointer_->referenceCount); + + p2 = p1; + ASSERT_TRUE(raw_derived_pointer_ == p2.Get()); + EXPECT_EQ(3, raw_derived_pointer_->referenceCount); + } + EXPECT_EQ(2, raw_derived_pointer_->referenceCount); +} + +TEST_F(NPObjectPointerTest, DerivedPointerCanBeAssignedToSelf) { + NPObjectPointer<MockNPObject> p1(raw_derived_pointer_); + NPObjectPointer<DerivedNPObject> p2(raw_derived_pointer_); + NPBrowser::get()->ReleaseObject(raw_derived_pointer_); + NPBrowser::get()->ReleaseObject(raw_derived_pointer_); + EXPECT_EQ(1, raw_derived_pointer_->referenceCount); + p1 = p2; + EXPECT_EQ(1, raw_derived_pointer_->referenceCount); + NPBrowser::get()->RetainObject(raw_derived_pointer_); + NPBrowser::get()->RetainObject(raw_derived_pointer_); +} + +TEST_F(NPObjectPointerTest, CanComparePointersForEqual) { + NPObjectPointer<MockNPObject> p1(raw_pointer_); + NPObjectPointer<DerivedNPObject> p2(raw_derived_pointer_); + EXPECT_TRUE(p1 == p1); + EXPECT_FALSE(p1 == p2); + EXPECT_FALSE(p2 == p1); + EXPECT_FALSE(p1 == NPObjectPointer<MockNPObject>()); +} + +TEST_F(NPObjectPointerTest, CanComparePointersForNotEqual) { + NPObjectPointer<MockNPObject> p1(raw_pointer_); + NPObjectPointer<DerivedNPObject> p2(raw_derived_pointer_); + EXPECT_FALSE(p1 != p1); + EXPECT_TRUE(p1 != p2); + EXPECT_TRUE(p2 != p1); + EXPECT_TRUE(p1 != NPObjectPointer<MockNPObject>()); +} + +TEST_F(NPObjectPointerTest, ArrowOperatorCanBeUsedToAccessNPObjectMembers) { + NPIdentifier name = NPBrowser::get()->GetStringIdentifier("hello"); + + EXPECT_CALL(*raw_pointer_, HasProperty(name)).WillOnce(Return(true)); + + NPObjectPointer<MockNPObject> p(raw_pointer_); + EXPECT_TRUE(p->HasProperty(name)); +} + +TEST_F(NPObjectPointerTest, StarOperatorReturnsNPObjectReference) { + NPObjectPointer<MockNPObject> p(raw_pointer_); + EXPECT_EQ(raw_pointer_, &*p); +} + +TEST_F(NPObjectPointerTest, PointerCanBeConstructedFromReturnedNPObject) { + NPBrowser::get()->RetainObject(raw_pointer_); + EXPECT_EQ(2, raw_pointer_->referenceCount); + { + NPObjectPointer<MockNPObject> p( + NPObjectPointer<MockNPObject>::FromReturned(raw_pointer_)); + EXPECT_EQ(2, raw_pointer_->referenceCount); + } + EXPECT_EQ(1, raw_pointer_->referenceCount); +} + +TEST_F(NPObjectPointerTest, PointerCanBeConstructedFromReturnedNullNPObject) { + NPObjectPointer<MockNPObject> p( + NPObjectPointer<MockNPObject>::FromReturned(NULL)); + EXPECT_TRUE(NULL == p.Get()); +} + +TEST_F(NPObjectPointerTest, PointerCanBeReturnedAsARawNPObject) { + NPObjectPointer<MockNPObject> p(raw_pointer_); + EXPECT_EQ(raw_pointer_, p.ToReturned()); + + // Check reference count is incremented before return for caller. + EXPECT_EQ(3, raw_pointer_->referenceCount); + + NPBrowser::get()->ReleaseObject(raw_pointer_); +} + +TEST_F(NPObjectPointerTest, NULLPointerCanBeReturnedAsARawNPObject) { + NPObjectPointer<MockNPObject> p; + EXPECT_TRUE(NULL == p.ToReturned()); +} + +} // namespace np_utils diff --git a/gpu/np_utils/np_plugin_object.h b/gpu/np_utils/np_plugin_object.h new file mode 100644 index 0000000..ad578e4 --- /dev/null +++ b/gpu/np_utils/np_plugin_object.h @@ -0,0 +1,50 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_NP_UTILS_NP_PLUGIN_OBJECT_H_ +#define GPU_NP_UTILS_NP_PLUGIN_OBJECT_H_ + +#include "gpu/np_utils/np_object_pointer.h" +#include "gpu/np_utils/np_headers.h" + +namespace np_utils { + +// Interface for a plugin instance. The NPP plugin calls forwards to an instance +// of this interface. +class PluginObject { + public: + // Initialize this object. + virtual NPError New(NPMIMEType plugin_type, + int16 argc, + char* argn[], + char* argv[], + NPSavedData* saved) = 0; + + virtual NPError SetWindow(NPWindow* new_window) = 0; + + virtual int16 HandleEvent(NPEvent* event) = 0; + + // Uninitialize but do not deallocate the object. Release will be called to + // deallocate if Destroy succeeds. + virtual NPError Destroy(NPSavedData** saved) = 0; + + // Deallocate this object. This object is invalid after this returns. + virtual void Release() = 0; + + virtual NPObject* GetScriptableNPObject() = 0; + + protected: + PluginObject() { + } + + virtual ~PluginObject() { + } + + private: + DISALLOW_COPY_AND_ASSIGN(PluginObject); +}; + +} // namespace np_utils + +#endif // GPU_NP_UTILS_NP_PLUGIN_OBJECT_H_ diff --git a/gpu/np_utils/np_plugin_object_factory.cc b/gpu/np_utils/np_plugin_object_factory.cc new file mode 100644 index 0000000..7eedcc8 --- /dev/null +++ b/gpu/np_utils/np_plugin_object_factory.cc @@ -0,0 +1,30 @@ +// Copyright (c) 2006-2008 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/gpu_plugin/gpu_plugin_object_factory.h" +#include "base/logging.h" + +namespace np_utils { + +NPPluginObjectFactory* NPPluginObjectFactory::factory_; + +PluginObject* NPPluginObjectFactory::CreatePluginObject( + NPP npp, + NPMIMEType plugin_type) { + return NULL; +} + +NPPluginObjectFactory::NPPluginObjectFactory() { + // Make this the first factory in the linked list. + previous_factory_ = factory_; + factory_ = this; +} + +NPPluginObjectFactory::~NPPluginObjectFactory() { + // Remove this factory from the linked list. + DCHECK(factory_ == this); + factory_ = previous_factory_; +} + +} // namespace np_utils diff --git a/gpu/np_utils/np_plugin_object_factory.h b/gpu/np_utils/np_plugin_object_factory.h new file mode 100644 index 0000000..969f5a3 --- /dev/null +++ b/gpu/np_utils/np_plugin_object_factory.h @@ -0,0 +1,37 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_NP_UTILS_NP_PLUGIN_OBJECT_FACTORY_H_ +#define GPU_NP_UTILS_NP_PLUGIN_OBJECT_FACTORY_H_ + +#include "base/basictypes.h" +#include "gpu/np_utils/np_headers.h" + +namespace np_utils { + +class PluginObject; + +// Mockable factory base class used to create instances of PluginObject based on +// plugin mime type. +class NPPluginObjectFactory { + public: + virtual PluginObject* CreatePluginObject(NPP npp, NPMIMEType plugin_type); + + static NPPluginObjectFactory* get() { + return factory_; + } + + protected: + NPPluginObjectFactory(); + virtual ~NPPluginObjectFactory(); + + private: + static NPPluginObjectFactory* factory_; + NPPluginObjectFactory* previous_factory_; + DISALLOW_COPY_AND_ASSIGN(NPPluginObjectFactory); +}; + +} // namespace np_utils + +#endif // GPU_NP_UTILS_NP_PLUGIN_OBJECT_FACTORY_H_ diff --git a/gpu/np_utils/np_plugin_object_factory_mock.h b/gpu/np_utils/np_plugin_object_factory_mock.h new file mode 100644 index 0000000..a09205c --- /dev/null +++ b/gpu/np_utils/np_plugin_object_factory_mock.h @@ -0,0 +1,23 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_NP_UTILS_NP_PLUGIN_OBJECT_FACTORY_MOCK_H_ +#define GPU_NP_UTILS_NP_PLUGIN_OBJECT_FACTORY_MOCK_H_ + +#include "gpu/np_utils/np_plugin_object_factory.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace np_utils { + +// Mockable factory used to create instances of PluginObject based on plugin +// mime type. +class MockPluginObjectFactory : public NPPluginObjectFactory { + public: + MOCK_METHOD2(CreatePluginObject, PluginObject*(NPP, NPMIMEType)); +}; + +} // namespace np_utils + +#endif // GPU_NP_UTILS_NP_PLUGIN_OBJECT_FACTORY_MOCK_H_ diff --git a/gpu/np_utils/np_plugin_object_mock.h b/gpu/np_utils/np_plugin_object_mock.h new file mode 100644 index 0000000..342b22c --- /dev/null +++ b/gpu/np_utils/np_plugin_object_mock.h @@ -0,0 +1,26 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_NP_UTILS_NP_PLUGIN_OBJECT_MOCK_H_ +#define GPU_NP_UTILS_NP_PLUGIN_OBJECT_MOCK_H_ + +#include "gpu/np_utils/np_plugin_object.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace np_utils { + +class MockPluginObject : public PluginObject { + public: + MOCK_METHOD5(New, NPError(NPMIMEType, int16, char*[], char*[], NPSavedData*)); + MOCK_METHOD1(SetWindow, NPError(NPWindow*)); + MOCK_METHOD1(HandleEvent, int16(NPEvent*)); + MOCK_METHOD1(Destroy, NPError(NPSavedData**)); + MOCK_METHOD0(Release, void()); + MOCK_METHOD0(GetScriptableNPObject, NPObject*()); +}; + +} // namespace np_utils + +#endif // GPU_NP_UTILS_NP_PLUGIN_OBJECT_MOCK_H_ diff --git a/gpu/np_utils/np_utils.cc b/gpu/np_utils/np_utils.cc new file mode 100644 index 0000000..d6a15a4 --- /dev/null +++ b/gpu/np_utils/np_utils.cc @@ -0,0 +1,170 @@ +// Copyright (c) 2006-2008 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/np_utils/np_utils.h" + +namespace np_utils { + +bool NPVariantToValue(bool* value, const NPVariant& variant) { + if (NPVARIANT_IS_BOOLEAN(variant)) { + *value = NPVARIANT_TO_BOOLEAN(variant); + return true; + } + + return false; +} + +bool NPVariantToValue(int32* value, const NPVariant& variant) { + if (NPVARIANT_IS_INT32(variant)) { + *value = NPVARIANT_TO_INT32(variant); + return true; + } + + return false; +} + +bool NPVariantToValue(float* value, const NPVariant& variant) { + if (NPVARIANT_IS_DOUBLE(variant)) { + *value = static_cast<float>(NPVARIANT_TO_DOUBLE(variant)); + return true; + } else if (NPVARIANT_IS_INT32(variant)) { + *value = static_cast<float>(NPVARIANT_TO_INT32(variant)); + return true; + } + + return false; +} + +bool NPVariantToValue(double* value, const NPVariant& variant) { + if (NPVARIANT_IS_DOUBLE(variant)) { + *value = NPVARIANT_TO_DOUBLE(variant); + return true; + } else if (NPVARIANT_IS_INT32(variant)) { + *value = NPVARIANT_TO_INT32(variant); + return true; + } + + return false; +} + +bool NPVariantToValue(std::string* value, const NPVariant& variant) { + if (NPVARIANT_IS_STRING(variant)) { + const NPString& str = NPVARIANT_TO_STRING(variant); + *value = std::string(str.UTF8Characters, str.UTF8Length); + return true; + } + + return false; +} + +void ValueToNPVariant(bool value, NPVariant* variant) { + BOOLEAN_TO_NPVARIANT(value, *variant); +} + +void ValueToNPVariant(int32 value, NPVariant* variant) { + INT32_TO_NPVARIANT(value, *variant); +} + +void ValueToNPVariant(float value, NPVariant* variant) { + DOUBLE_TO_NPVARIANT(value, *variant); +} + +void ValueToNPVariant(double value, NPVariant* variant) { + DOUBLE_TO_NPVARIANT(value, *variant); +} + +void ValueToNPVariant(const std::string& value, NPVariant* variant) { + NPUTF8* p = static_cast<NPUTF8*>(NPBrowser::get()->MemAlloc(value.length())); + memcpy(p, value.c_str(), value.length()); + STRINGN_TO_NPVARIANT(p, value.length(), *variant); +} + +SmartNPVariant::SmartNPVariant() { + VOID_TO_NPVARIANT(*this); +} + +SmartNPVariant::SmartNPVariant(const SmartNPVariant& rhs) { + rhs.CopyTo(this); +} + +SmartNPVariant::SmartNPVariant(const NPVariant& rhs) { + static_cast<const SmartNPVariant&>(rhs).CopyTo(this); +} + +SmartNPVariant::~SmartNPVariant() { + Release(); +} + +SmartNPVariant& SmartNPVariant::operator=(const SmartNPVariant& rhs) { + Release(); + rhs.CopyTo(this); + return *this; +} + +SmartNPVariant& SmartNPVariant::operator=(const NPVariant& rhs) { + Release(); + static_cast<const SmartNPVariant&>(rhs).CopyTo(this); + return *this; +} + +bool SmartNPVariant::IsVoid() const { + return NPVARIANT_IS_VOID(*this); +} + +void SmartNPVariant::Release() { + NPBrowser::get()->ReleaseVariantValue(this); + VOID_TO_NPVARIANT(*this); +} + +void SmartNPVariant::Invalidate() { + if (NPVARIANT_IS_OBJECT(*this)) { + NULL_TO_NPVARIANT(*this); + } +} + +void SmartNPVariant::CopyTo(NPVariant* rhs) const { + if (NPVARIANT_IS_OBJECT(*this)) { + NPObject* object = NPVARIANT_TO_OBJECT(*this); + OBJECT_TO_NPVARIANT(object, *rhs); + NPBrowser::get()->RetainObject(object); + } else if (NPVARIANT_IS_STRING(*this)) { + NPUTF8* copy = static_cast<NPUTF8*>(NPBrowser::get()->MemAlloc( + value.stringValue.UTF8Length)); + memcpy(copy, + value.stringValue.UTF8Characters, + value.stringValue.UTF8Length); + STRINGN_TO_NPVARIANT(copy, value.stringValue.UTF8Length, *rhs); + } else { + memcpy(rhs, this, sizeof(*rhs)); + } +} + +bool NPHasMethod(NPP npp, + const NPObjectPointer<NPObject>& object, + const NPUTF8* name) { + return NPBrowser::get()->HasMethod( + npp, + object.Get(), + NPBrowser::get()->GetStringIdentifier(name)); +} + +bool NPHasProperty(NPP npp, + const NPObjectPointer<NPObject>& object, + const NPUTF8* name) { + return NPBrowser::get()->HasProperty( + npp, + object.Get(), + NPBrowser::get()->GetStringIdentifier(name)); +} + +bool NPRemoveProperty(NPP npp, + const NPObjectPointer<NPObject>& object, + const NPUTF8* name) { + return NPBrowser::get()->RemoveProperty( + npp, + object.Get(), + NPBrowser::get()->GetStringIdentifier(name)); +} + +} // namespace np_utils diff --git a/gpu/np_utils/np_utils.h b/gpu/np_utils/np_utils.h new file mode 100644 index 0000000..5c7e3b7 --- /dev/null +++ b/gpu/np_utils/np_utils.h @@ -0,0 +1,271 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_NP_UTILS_NP_UTILS_H_ +#define GPU_NP_UTILS_NP_UTILS_H_ + +#include <string> + +#include "gpu/np_utils/np_browser.h" +#include "gpu/np_utils/np_class.h" +#include "gpu/np_utils/np_object_pointer.h" +#include "gpu/np_utils/np_headers.h" + +namespace np_utils { + +// Convert NPVariant to C++ type. Returns whether the conversion was successful. +bool NPVariantToValue(bool* value, const NPVariant& variant); +bool NPVariantToValue(int32* value, const NPVariant& variant); +bool NPVariantToValue(float* value, const NPVariant& variant); +bool NPVariantToValue(double* value, const NPVariant& variant); +bool NPVariantToValue(std::string* value, const NPVariant& variant); + +template <typename T> +bool NPVariantToValue(NPObjectPointer<T>* value, + const NPVariant& variant) { + if (NPVARIANT_IS_NULL(variant)) { + *value = NPObjectPointer<T>(); + return true; + } else if (NPVARIANT_IS_OBJECT(variant)) { + NPObject* object = NPVARIANT_TO_OBJECT(variant); + if (object->_class == NPGetClass<T>()) { + *value = NPObjectPointer<T>(static_cast<T*>( + NPVARIANT_TO_OBJECT(variant))); + return true; + } + } + + return false; +} + +// Specialization for NPObject does not check for mismatched NPClass. +template <> +inline bool NPVariantToValue(NPObjectPointer<NPObject>* value, + const NPVariant& variant) { + if (NPVARIANT_IS_NULL(variant)) { + *value = NPObjectPointer<NPObject>(); + return true; + } else if (NPVARIANT_IS_OBJECT(variant)) { + *value = NPObjectPointer<NPObject>(NPVARIANT_TO_OBJECT(variant)); + return true; + } + + return false; +} + +// Convert C++ type to NPVariant. +void ValueToNPVariant(bool value, NPVariant* variant); +void ValueToNPVariant(int32 value, NPVariant* variant); +void ValueToNPVariant(float value, NPVariant* variant); +void ValueToNPVariant(double value, NPVariant* variant); +void ValueToNPVariant(const std::string& value, NPVariant* variant); + +template <typename T> +void ValueToNPVariant(const NPObjectPointer<T>& value, + NPVariant* variant) { + if (value.Get()) { + NPBrowser::get()->RetainObject(value.Get()); + OBJECT_TO_NPVARIANT(value.Get(), *variant); + } else { + NULL_TO_NPVARIANT(*variant); + } +} + +// NPVariant that automatically manages lifetime of string and object variants. +class SmartNPVariant : public NPVariant { + public: + SmartNPVariant(); + SmartNPVariant(const SmartNPVariant& rhs); + explicit SmartNPVariant(const NPVariant& rhs); + + template <typename T> + explicit SmartNPVariant(const T& v) { + ValueToNPVariant(v, this); + } + + ~SmartNPVariant(); + + SmartNPVariant& operator=(const SmartNPVariant& rhs); + SmartNPVariant& operator=(const NPVariant& rhs); + + template <typename T> + bool GetValue(T* v) const { + return NPVariantToValue(v, *this); + } + + bool IsVoid() const; + + template <typename T> + void SetValue(const T& v) { + Release(); + ValueToNPVariant(v, this); + } + + void CopyTo(NPVariant* target) const; + + // Sets the variant to void. + void Release(); + + // Called when an NPObject is invalidated to clear any references to other + // NPObjects. Does not release the object as it might no longer be valid. + void Invalidate(); +}; + +// These allow a method to be invoked with automatic conversion of C++ +// types to variants for arguments and return values. + +bool NPHasMethod(NPP npp, + const NPObjectPointer<NPObject>& object, + const NPUTF8* name); + +inline bool NPInvokeVoid(NPP npp, + const NPObjectPointer<NPObject>& object, + const NPUTF8* name) { + SmartNPVariant result; + return NPBrowser::get()->Invoke( + npp, + object.Get(), + NPBrowser::get()->GetStringIdentifier(name), + NULL, 0, + &result); +} + +template<typename R> +bool NPInvoke(NPP npp, + const NPObjectPointer<NPObject>& object, + const NPUTF8* name, + R* r) { + SmartNPVariant result; + if (NPBrowser::get()->Invoke( + npp, + object.Get(), + NPBrowser::get()->GetStringIdentifier(name), + NULL, 0, + &result)) { + return result.GetValue(r); + } + return false; +} + +template<typename P0> +bool NPInvokeVoid(NPP npp, + const NPObjectPointer<NPObject>& object, + const NPUTF8* name, + P0 p0) { + SmartNPVariant args[1]; + args[0].SetValue(p0); + SmartNPVariant result; + return NPBrowser::get()->Invoke( + npp, + object.Get(), + NPBrowser::get()->GetStringIdentifier(name), + &args[0], 1, + &result); +} + +template<typename R, typename P0> +bool NPInvoke(NPP npp, + const NPObjectPointer<NPObject>& object, + const NPUTF8* name, + P0 p0, + R* r) { + SmartNPVariant args[1]; + args[0].SetValue(p0); + SmartNPVariant result; + if (NPBrowser::get()->Invoke( + npp, + object.Get(), + NPBrowser::get()->GetStringIdentifier(name), + &args[0], 1, + &result)) { + return result.GetValue(r); + } + return false; +} + +template<typename P0, typename P1> +bool NPInvokeVoid(NPP npp, + const NPObjectPointer<NPObject>& object, + const NPUTF8* name, + P0 p0, P1 p1) { + SmartNPVariant args[2]; + args[0].SetValue(p0); + args[1].SetValue(p1); + SmartNPVariant result; + return NPBrowser::get()->Invoke( + npp, + object.Get(), + NPBrowser::get()->GetStringIdentifier(name), + &args[0], 2, + &result); +} + +template<typename R, typename P0, typename P1> +bool NPInvoke(NPP npp, + const NPObjectPointer<NPObject>& object, + const NPUTF8* name, + P0 p0, P1 p1, + R* r) { + SmartNPVariant args[2]; + args[0].SetValue(p0); + args[1].SetValue(p1); + SmartNPVariant result; + if (NPBrowser::get()->Invoke( + npp, + object.Get(), + NPBrowser::get()->GetStringIdentifier(name), + &args[0], 2, + &result)) { + return result.GetValue(r); + } + return false; +} + +bool NPHasProperty(NPP npp, + const NPObjectPointer<NPObject>& object, + const NPUTF8* name); + +template <typename T> +bool NPGetProperty(NPP npp, + const NPObjectPointer<NPObject>& object, + const NPUTF8* name, + T* value) { + SmartNPVariant result; + if (NPBrowser::get()->GetProperty(npp, + object.Get(), + NPBrowser::get()->GetStringIdentifier(name), + &result)) { + return result.GetValue(value); + } + return false; +} + +template <typename T> +bool NPSetProperty(NPP npp, + const NPObjectPointer<NPObject>& object, + const NPUTF8* name, + const T& value) { + SmartNPVariant variant(value); + return NPBrowser::get()->SetProperty( + npp, + object.Get(), + NPBrowser::get()->GetStringIdentifier(name), + &variant); +} + +bool NPRemoveProperty(NPP npp, + const NPObjectPointer<NPObject>& object, + const NPUTF8* name); + +template <typename NPObjectType> +NPObjectPointer<NPObjectType> NPCreateObject(NPP npp) { + const NPClass* np_class = NPGetClass<NPObjectType>(); + NPObjectType* object = static_cast<NPObjectType*>( + NPBrowser::get()->CreateObject(npp, np_class)); + return NPObjectPointer<NPObjectType>::FromReturned(object); +} + +} // namespace np_utils + +#endif // GPU_NP_UTILS_NP_UTILS_H_ diff --git a/gpu/np_utils/np_utils_unittest.cc b/gpu/np_utils/np_utils_unittest.cc new file mode 100644 index 0000000..ceb87ad --- /dev/null +++ b/gpu/np_utils/np_utils_unittest.cc @@ -0,0 +1,424 @@ +// Copyright (c) 2006-2008 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/np_utils/np_object_mock.h" +#include "gpu/np_utils/np_browser_stub.h" +#include "gpu/np_utils/np_utils.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::_; +using testing::DoAll; +using testing::MakeMatcher; +using testing::Matcher; +using testing::Pointee; +using testing::Return; +using testing::SetArgumentPointee; +using testing::StrictMock; + +namespace np_utils { + +class NPUtilsTest : public testing::Test { + protected: + StubNPBrowser stub_browser_; + NPP_t npp_; + NPVariant variant_; +}; + +TEST_F(NPUtilsTest, TestBoolNPVariantToValue) { + bool v; + + BOOLEAN_TO_NPVARIANT(false, variant_); + EXPECT_TRUE(NPVariantToValue(&v, variant_)); + EXPECT_FALSE(v); + + BOOLEAN_TO_NPVARIANT(true, variant_); + EXPECT_TRUE(NPVariantToValue(&v, variant_)); + EXPECT_TRUE(v); + + INT32_TO_NPVARIANT(7, variant_); + EXPECT_FALSE(NPVariantToValue(&v, variant_)); +} + +TEST_F(NPUtilsTest, TestIntNPVariantToValue) { + INT32_TO_NPVARIANT(7, variant_); + + int v1; + EXPECT_TRUE(NPVariantToValue(&v1, variant_)); + EXPECT_EQ(7, v1); + + float v2; + EXPECT_TRUE(NPVariantToValue(&v2, variant_)); + EXPECT_EQ(7.0f, v2); + + double v3; + EXPECT_TRUE(NPVariantToValue(&v3, variant_)); + EXPECT_EQ(7.0, v3); + + BOOLEAN_TO_NPVARIANT(false, variant_); + EXPECT_FALSE(NPVariantToValue(&v1, variant_)); +} + +TEST_F(NPUtilsTest, TestFloatNPVariantToValue) { + float v; + + DOUBLE_TO_NPVARIANT(7.0, variant_); + EXPECT_TRUE(NPVariantToValue(&v, variant_)); + EXPECT_EQ(7.0f, v); + + BOOLEAN_TO_NPVARIANT(false, variant_); + EXPECT_FALSE(NPVariantToValue(&v, variant_)); +} + +TEST_F(NPUtilsTest, TestDoubleNPVariantToValue) { + double v; + + DOUBLE_TO_NPVARIANT(7.0, variant_); + EXPECT_TRUE(NPVariantToValue(&v, variant_)); + EXPECT_EQ(7.0, v); + + BOOLEAN_TO_NPVARIANT(false, variant_); + EXPECT_FALSE(NPVariantToValue(&v, variant_)); +} + +TEST_F(NPUtilsTest, TestStringNPVariantToValue) { + std::string v; + + STRINGZ_TO_NPVARIANT("hello", variant_); + EXPECT_TRUE(NPVariantToValue(&v, variant_)); + EXPECT_EQ(std::string("hello"), v); + + BOOLEAN_TO_NPVARIANT(false, variant_); + EXPECT_FALSE(NPVariantToValue(&v, variant_)); +} + +TEST_F(NPUtilsTest, TestObjectNPVariantToValue) { + NPObjectPointer<NPObject> object = + NPCreateObject<StrictMock<MockNPObject> >(NULL); + NPObjectPointer<NPObject> v; + + OBJECT_TO_NPVARIANT(object.Get(), variant_); + EXPECT_TRUE(NPVariantToValue(&v, variant_)); + EXPECT_EQ(object, v); + + BOOLEAN_TO_NPVARIANT(false, variant_); + EXPECT_FALSE(NPVariantToValue(&v, variant_)); +} + +TEST_F(NPUtilsTest, TestNullNPVariantToValue) { + NPObjectPointer<NPObject> v; + + NULL_TO_NPVARIANT(variant_); + EXPECT_TRUE(NPVariantToValue(&v, variant_)); + EXPECT_TRUE(NPObjectPointer<NPObject>() == v); + + BOOLEAN_TO_NPVARIANT(false, variant_); + EXPECT_FALSE(NPVariantToValue(&v, variant_)); +} + +TEST_F(NPUtilsTest, TestDerivedObjectNPVariantToValue) { + NPObjectPointer<NPObject> object = + NPCreateObject<StrictMock<MockNPObject> >(NULL); + NPObjectPointer<StrictMock<MockNPObject> > v; + + OBJECT_TO_NPVARIANT(object.Get(), variant_); + EXPECT_TRUE(NPVariantToValue(&v, variant_)); + EXPECT_EQ(object, v); +} + +TEST_F(NPUtilsTest, + TestDerivedObjectNPVariantToValueFailsIfValueHasDifferentType) { + NPObjectPointer<NPObject> object = + NPCreateObject<StrictMock<MockNPObject> >(NULL); + NPObjectPointer<MockNPObject> v; + + OBJECT_TO_NPVARIANT(object.Get(), variant_); + EXPECT_FALSE(NPVariantToValue(&v, variant_)); +} + +TEST_F(NPUtilsTest, TestBoolValueToNPVariant) { + ValueToNPVariant(true, &variant_); + EXPECT_TRUE(NPVARIANT_IS_BOOLEAN(variant_)); + EXPECT_TRUE(NPVARIANT_TO_BOOLEAN(variant_)); + + ValueToNPVariant(false, &variant_); + EXPECT_TRUE(NPVARIANT_IS_BOOLEAN(variant_)); + EXPECT_FALSE(NPVARIANT_TO_BOOLEAN(variant_)); +} + +TEST_F(NPUtilsTest, TestIntValueToNPVariant) { + ValueToNPVariant(7, &variant_); + EXPECT_TRUE(NPVARIANT_IS_INT32(variant_)); + EXPECT_EQ(7, NPVARIANT_TO_INT32(variant_)); +} + +TEST_F(NPUtilsTest, TestFloatValueToNPVariant) { + ValueToNPVariant(7.0f, &variant_); + EXPECT_TRUE(NPVARIANT_IS_DOUBLE(variant_)); + EXPECT_EQ(7.0, NPVARIANT_TO_DOUBLE(variant_)); +} + +TEST_F(NPUtilsTest, TestDoubleValueToNPVariant) { + ValueToNPVariant(7.0, &variant_); + EXPECT_TRUE(NPVARIANT_IS_DOUBLE(variant_)); + EXPECT_EQ(7.0, NPVARIANT_TO_DOUBLE(variant_)); +} + +TEST_F(NPUtilsTest, TestStringValueToNPVariant) { + ValueToNPVariant(std::string("hello"), &variant_); + EXPECT_TRUE(NPVARIANT_IS_STRING(variant_)); + EXPECT_EQ(std::string("hello"), + std::string(variant_.value.stringValue.UTF8Characters, + variant_.value.stringValue.UTF8Length)); +} + +TEST_F(NPUtilsTest, TestObjectValueToNPVariant) { + NPObjectPointer<NPObject> object = + NPCreateObject<StrictMock<MockNPObject> >(NULL); + + ValueToNPVariant(object, &variant_); + EXPECT_TRUE(NPVARIANT_IS_OBJECT(variant_)); + EXPECT_EQ(object.Get(), NPVARIANT_TO_OBJECT(variant_)); + + NPBrowser::get()->ReleaseVariantValue(&variant_); +} + +TEST_F(NPUtilsTest, TestNullValueToNPVariant) { + ValueToNPVariant(NPObjectPointer<NPObject>(), &variant_); + EXPECT_TRUE(NPVARIANT_IS_NULL(variant_)); +} + +TEST_F(NPUtilsTest, CanCopyObjectSmartVariant) { + NPObjectPointer<NPObject> object = + NPCreateObject<StrictMock<MockNPObject> >(NULL); + EXPECT_EQ(1, object->referenceCount); + { + SmartNPVariant v1(object); + EXPECT_EQ(2, object->referenceCount); + { + SmartNPVariant v2(v1); + EXPECT_EQ(3, object->referenceCount); + } + EXPECT_EQ(2, object->referenceCount); + } + EXPECT_EQ(1, object->referenceCount); +} + +TEST_F(NPUtilsTest, CanCopyStringSmartVariant) { + SmartNPVariant v1(std::string("hello")); + SmartNPVariant v2(v1); + std::string r; + EXPECT_TRUE(NPVariantToValue(&r, v2)); + EXPECT_EQ(std::string("hello"), r); + EXPECT_NE(v1.value.stringValue.UTF8Characters, + v2.value.stringValue.UTF8Characters); +} + +TEST_F(NPUtilsTest, CanReleaseSmartVariant) { + SmartNPVariant variant(std::string("hello")); + EXPECT_FALSE(variant.IsVoid()); + variant.Release(); + EXPECT_TRUE(variant.IsVoid()); +} + +template <typename T> +class VariantMatcher : public testing::MatcherInterface<const NPVariant&> { + public: + explicit VariantMatcher(const T& value) : value_(value) { + } + + virtual bool Matches(const NPVariant& variant) const { + T other_value; + return NPVariantToValue(&other_value, variant) && other_value == value_; + } + + virtual void DescribeTo(::std::ostream* os) const { + *os << "equals " << value_; + } + + virtual void DescribeNegationTo(::std::ostream* os) const { + *os << "does not equal " << value_; + } + + private: + T value_; +}; + +template <typename T> +Matcher<const NPVariant&> VariantMatches(const T& value) { + return MakeMatcher(new VariantMatcher<T>(value)); +} + +TEST_F(NPUtilsTest, CanDetermineIfObjectHasMethod) { + NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); + NPObjectPointer<MockNPObject> object = + NPCreateObject<StrictMock<MockNPObject> >(NULL); + + EXPECT_CALL(*object, HasMethod(name)) + .WillOnce(Return(true)); + + EXPECT_TRUE(NPHasMethod(NULL, object, "foo")); +} + +TEST_F(NPUtilsTest, CanInvokeVoidMethodWithNativeTypes) { + NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); + NPObjectPointer<MockNPObject> object = + NPCreateObject<StrictMock<MockNPObject> >(NULL); + + VOID_TO_NPVARIANT(variant_); + + EXPECT_CALL(*object, Invoke(name, Pointee(VariantMatches<int32>(7)), 1, _)) + .WillOnce(DoAll(SetArgumentPointee<3>(variant_), + Return(true))); + + EXPECT_TRUE(NPInvokeVoid(NULL, object, "foo", 7)); +} + +TEST_F(NPUtilsTest, InvokeVoidMethodCanFail) { + NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); + NPObjectPointer<MockNPObject> object = + NPCreateObject<StrictMock<MockNPObject> >(NULL); + + VOID_TO_NPVARIANT(variant_); + + EXPECT_CALL(*object, Invoke(name, Pointee(VariantMatches<int32>(7)), 1, _)) + .WillOnce(DoAll(SetArgumentPointee<3>(variant_), + Return(false))); + + EXPECT_FALSE(NPInvokeVoid(NULL, object, "foo", 7)); +} + +TEST_F(NPUtilsTest, CanInvokeNonVoidMethodWithNativeTypes) { + NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); + NPObjectPointer<MockNPObject> object = + NPCreateObject<StrictMock<MockNPObject> >(NULL); + + DOUBLE_TO_NPVARIANT(1.5, variant_); + + EXPECT_CALL(*object, Invoke(name, Pointee(VariantMatches<int32>(7)), 1, _)) + .WillOnce(DoAll(SetArgumentPointee<3>(variant_), + Return(true))); + + double r; + EXPECT_TRUE(NPInvoke(NULL, object, "foo", 7, &r)); + EXPECT_EQ(1.5, r); +} + +TEST_F(NPUtilsTest, InvokeNonVoidMethodCanFail) { + NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); + NPObjectPointer<MockNPObject> object = + NPCreateObject<StrictMock<MockNPObject> >(NULL); + + DOUBLE_TO_NPVARIANT(1.5, variant_); + + EXPECT_CALL(*object, Invoke(name, Pointee(VariantMatches<int32>(7)), 1, _)) + .WillOnce(DoAll(SetArgumentPointee<3>(variant_), + Return(false))); + + double r; + EXPECT_FALSE(NPInvoke(NULL, object, "foo", 7, &r)); +} + +TEST_F(NPUtilsTest, InvokeNonVoidMethodFailsIfResultIsIncompatible) { + NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); + NPObjectPointer<MockNPObject> object = + NPCreateObject<StrictMock<MockNPObject> >(NULL); + + DOUBLE_TO_NPVARIANT(1.5, variant_); + + EXPECT_CALL(*object, Invoke(name, Pointee(VariantMatches<int32>(7)), 1, _)) + .WillOnce(DoAll(SetArgumentPointee<3>(variant_), + Return(true))); + + int r; + EXPECT_FALSE(NPInvoke(NULL, object, "foo", 7, &r)); +} + +TEST_F(NPUtilsTest, CanDetermineIfObjectHasProperty) { + NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); + NPObjectPointer<MockNPObject> object = + NPCreateObject<StrictMock<MockNPObject> >(NULL); + + EXPECT_CALL(*object, HasProperty(name)) + .WillOnce(Return(true)); + + EXPECT_TRUE(NPHasProperty(NULL, object, "foo")); +} + +TEST_F(NPUtilsTest, CanGetPropertyValue) { + NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); + NPObjectPointer<MockNPObject> object = + NPCreateObject<StrictMock<MockNPObject> >(NULL); + + DOUBLE_TO_NPVARIANT(1.5, variant_); + + EXPECT_CALL(*object, GetProperty(name, _)) + .WillOnce(DoAll(SetArgumentPointee<1>(variant_), + Return(true))); + + double r; + EXPECT_TRUE(NPGetProperty(NULL, object, "foo", &r)); +} + +TEST_F(NPUtilsTest, NPGetPropertyReportsFailureIfResultTypeIsDifferent) { + NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); + NPObjectPointer<MockNPObject> object = + NPCreateObject<StrictMock<MockNPObject> >(NULL); + + DOUBLE_TO_NPVARIANT(1.5, variant_); + + EXPECT_CALL(*object, GetProperty(name, _)) + .WillOnce(DoAll(SetArgumentPointee<1>(variant_), + Return(true))); + + bool r; + EXPECT_FALSE(NPGetProperty(NULL, object, "foo", &r)); +} + +TEST_F(NPUtilsTest, NPGetPropertyReportsFailureFromGetProperty) { + NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); + NPObjectPointer<MockNPObject> object = + NPCreateObject<StrictMock<MockNPObject> >(NULL); + + EXPECT_CALL(*object, GetProperty(name, _)) + .WillOnce(Return(false)); + + double r; + EXPECT_FALSE(NPGetProperty(NULL, object, "foo", &r)); +} + +TEST_F(NPUtilsTest, CanSetPropertyValue) { + NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); + NPObjectPointer<MockNPObject> object = + NPCreateObject<StrictMock<MockNPObject> >(NULL); + + EXPECT_CALL(*object, SetProperty(name, Pointee(VariantMatches(1.5)))) + .WillOnce(Return(true)); + + EXPECT_TRUE(NPSetProperty(NULL, object, "foo", 1.5)); +} + +TEST_F(NPUtilsTest, NPSetPropertyReportsFailureFromSetProperty) { + NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); + NPObjectPointer<MockNPObject> object = + NPCreateObject<StrictMock<MockNPObject> >(NULL); + + EXPECT_CALL(*object, SetProperty(name, Pointee(VariantMatches(1.5)))) + .WillOnce(Return(false)); + + EXPECT_FALSE(NPSetProperty(NULL, object, "foo", 1.5)); +} + +TEST_F(NPUtilsTest, CanRemovePropertyValue) { + NPIdentifier name = NPBrowser::get()->GetStringIdentifier("foo"); + NPObjectPointer<MockNPObject> object = + NPCreateObject<StrictMock<MockNPObject> >(NULL); + + EXPECT_CALL(*object, RemoveProperty(name)) + .WillOnce(Return(true)); + + EXPECT_TRUE(NPRemoveProperty(NULL, object, "foo")); +} + +} // namespace np_utils diff --git a/gpu/np_utils/webkit_browser.h b/gpu/np_utils/webkit_browser.h new file mode 100644 index 0000000..6b57d05 --- /dev/null +++ b/gpu/np_utils/webkit_browser.h @@ -0,0 +1,117 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_NP_UTILS_WEBKIT_BROWSER_H_ +#define GPU_NP_UTILS_WEBKIT_BROWSER_H_ + +// TODO(apatrick): This does not belong in np_utils. np_utils should not be +// dependent on WebKit (and it isn't - that's why the member functions are +// inline). + +#include <stdlib.h> + +#include "gpu/np_utils/np_browser.h" +#include "WebKit/api/public/WebBindings.h" + +typedef struct _NPNetscapeFuncs NPNetscapeFuncs; +typedef struct _NPChromiumFuncs NPChromiumFuncs; + +namespace np_utils { + +// This class implements NPBrowser for the WebKit WebBindings. +class WebKitBrowser : public NPBrowser { + public: + WebKitBrowser(): NPBrowser(NULL) { + } + + // Standard functions from NPNetscapeFuncs. + + virtual NPIdentifier GetStringIdentifier(const NPUTF8* name) { + return WebKit::WebBindings::getStringIdentifier(name); + } + + virtual void* MemAlloc(size_t size) { + return malloc(size); + } + + virtual void MemFree(void* p) { + free(p); + } + + virtual NPObject* CreateObject(NPP npp, const NPClass* cl) { + return WebKit::WebBindings::createObject(npp, const_cast<NPClass*>(cl)); + } + + virtual NPObject* RetainObject(NPObject* object) { + return WebKit::WebBindings::retainObject(object); + } + + virtual void ReleaseObject(NPObject* object) { + WebKit::WebBindings::releaseObject(object); + } + + virtual void ReleaseVariantValue(NPVariant* variant) { + WebKit::WebBindings::releaseVariantValue(variant); + } + + virtual bool HasProperty(NPP npp, + NPObject* object, + NPIdentifier name) { + return WebKit::WebBindings::hasProperty(npp, object, name); + } + + virtual bool GetProperty(NPP npp, + NPObject* object, + NPIdentifier name, + NPVariant* result) { + return WebKit::WebBindings::getProperty(npp, object, name, result); + } + + virtual bool SetProperty(NPP npp, + NPObject* object, + NPIdentifier name, + const NPVariant* result) { + return WebKit::WebBindings::setProperty(npp, object, name, result); + } + + virtual bool RemoveProperty(NPP npp, + NPObject* object, + NPIdentifier name) { + return WebKit::WebBindings::removeProperty(npp, object, name); + } + + virtual bool HasMethod(NPP npp, + NPObject* object, + NPIdentifier name) { + return WebKit::WebBindings::hasMethod(npp, object, name); + } + + virtual bool Invoke(NPP npp, + NPObject* object, + NPIdentifier name, + const NPVariant* args, + uint32_t num_args, + NPVariant* result) { + return WebKit::WebBindings::invoke(npp, object, name, args, num_args, + result); + } + + virtual NPObject* GetWindowNPObject(NPP npp) { + NPObject* window; + if (NPERR_NO_ERROR == NPN_GetValue(npp, + NPNVWindowNPObject, + &window)) { + return window; + } else { + return NULL; + } + } + + private: + DISALLOW_COPY_AND_ASSIGN(WebKitBrowser); +}; + +} // namespace np_utils + +#endif // GPU_NP_UTILS_WEBKIT_BROWSER_H_ |