diff options
-rwxr-xr-x | gpu/command_buffer/build_gles2_cmd_buffer.py | 179 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.cc | 648 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder_autogen.h | 610 |
3 files changed, 895 insertions, 542 deletions
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index b5bed72..d7878de 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -663,10 +663,13 @@ _FUNCTION_INFO = { 'DeleteShader': {'type': 'Custom', 'DecoderFunc': 'DoDeleteShader'}, 'DeleteTextures': {'type': 'DELn'}, 'DepthRangef': {'DecoderFunc': 'glDepthRange'}, + 'DisableVertexAttribArray': {'DecoderFunc': 'DoDisableVertexAttribArray'}, + 'DrawArrays': { 'DecoderFunc': 'DoDrawArrays'}, 'DrawElements': { 'type': 'Manual', 'cmd_args': 'GLenum mode, GLsizei count, GLenum type, GLuint index_offset', }, + 'EnableVertexAttribArray': {'DecoderFunc': 'DoEnableVertexAttribArray'}, 'FramebufferRenderbuffer': {'DecoderFunc': 'glFramebufferRenderbufferEXT'}, 'FramebufferTexture2D': {'DecoderFunc': 'glFramebufferTexture2DEXT'}, 'GenerateMipmap': {'DecoderFunc': 'glGenerateMipmapEXT'}, @@ -724,6 +727,7 @@ _FUNCTION_INFO = { 'IsRenderbuffer': {'type': 'Is', 'DecoderFunc': 'glIsRenderbufferEXT'}, 'IsShader': {'type': 'Is'}, 'IsTexture': {'type': 'Is'}, + 'LinkProgram': {'DecoderFunc': 'DoLinkProgram'}, 'PixelStorei': {'type': 'Manual'}, 'RenderbufferStorage': {'DecoderFunc': 'glRenderbufferStorageEXT'}, 'ReadPixels': {'type': 'Custom', 'immediate': False}, @@ -751,6 +755,7 @@ _FUNCTION_INFO = { 'UniformMatrix2fv': {'type': 'PUTn', 'data_type': 'GLfloat', 'count': 4}, 'UniformMatrix3fv': {'type': 'PUTn', 'data_type': 'GLfloat', 'count': 9}, 'UniformMatrix4fv': {'type': 'PUTn', 'data_type': 'GLfloat', 'count': 16}, + 'UseProgram': {'DecoderFunc': 'DoUseProgram'}, 'VertexAttrib1fv': {'type': 'PUT', 'data_type': 'GLfloat', 'count': 1}, 'VertexAttrib2fv': {'type': 'PUT', 'data_type': 'GLfloat', 'count': 2}, 'VertexAttrib3fv': {'type': 'PUT', 'data_type': 'GLfloat', 'count': 3}, @@ -941,6 +946,10 @@ class TypeHandler(object): file.Write("}\n") file.Write("\n") + def WriteGetDataSizeCode(self, func, file): + """Writes the code to set data_size used in validation""" + pass + def WriteImmediateCmdSizeTest(self, func, file): """Writes a size test for an immediate version of a command.""" file.Write(" // TODO(gman): Compute correct size.\n") @@ -948,8 +957,6 @@ class TypeHandler(object): def WriteImmediateHandlerImplementation (self, func, file): """Writes the handler impl for the immediate version of a command.""" - file.Write(" // Immediate version.\n") - func.WriteHandlerValidation(file) file.Write(" %s(%s);\n" % (func.GetGLFunctionName(), func.MakeOriginalArgString(""))) @@ -959,8 +966,13 @@ class TypeHandler(object): "parse_error::ParseError GLES2DecoderImpl::Handle%s(\n" % func.name) file.Write( " uint32 immediate_data_size, const gles2::%s& c) {\n" % func.name) - for arg in func.GetOriginalArgs(): - arg.WriteGetCode(file) + if len(func.GetOriginalArgs()) > 0: + last_arg = func.GetLastOriginalArg() + all_but_last_arg = func.GetOriginalArgs()[:-1] + for arg in all_but_last_arg: + arg.WriteGetCode(file) + self.WriteGetDataSizeCode(func, file) + last_arg.WriteGetCode(file) func.WriteHandlerValidation(file) func.WriteHandlerImplementation(file) file.Write(" return parse_error::kParseNoError;\n") @@ -973,8 +985,12 @@ class TypeHandler(object): "parse_error::ParseError GLES2DecoderImpl::Handle%s(\n" % func.name) file.Write( " uint32 immediate_data_size, const gles2::%s& c) {\n" % func.name) - for arg in func.GetOriginalArgs(): + last_arg = func.GetLastOriginalArg() + all_but_last_arg = func.GetOriginalArgs()[:-1] + for arg in all_but_last_arg: arg.WriteGetCode(file) + self.WriteGetDataSizeCode(func, file) + last_arg.WriteGetCode(file) func.WriteHandlerValidation(file) func.WriteHandlerImplementation(file) file.Write(" return parse_error::kParseNoError;\n") @@ -1199,46 +1215,34 @@ class ManualHandler(CustomHandler): CustomHandler.WriteImmediateCmdGetTotalSize(self, func, file) -class DataHandler(CustomHandler): +class DataHandler(TypeHandler): """Handler for glBufferData, glBufferSubData, glTexImage2D, glTexSubImage2D, glCompressedTexImage2D, glCompressedTexImageSub2D.""" def __init__(self): - CustomHandler.__init__(self) + TypeHandler.__init__(self) - def WriteServiceImplementation(self, func, file): + def WriteGetDataSizeCode(self, func, file): """Overrriden from TypeHandler.""" - file.Write( - "parse_error::ParseError GLES2DecoderImpl::Handle%s(\n" % func.name) - file.Write( - " uint32 immediate_data_size, 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': + name = func.name + if name.endswith("Immediate"): + name = name[0:-9] + if name == 'BufferData': file.Write(" uint32 data_size = size;\n") - elif func.name == 'BufferSubData': + elif name == 'BufferSubData': file.Write(" uint32 data_size = size;\n") - elif func.name == 'CompressedTexImage2D': + elif name == 'CompressedTexImage2D': file.Write(" uint32 data_size = imageSize;\n") - elif func.name == 'CompressedTexSubImage2D': + elif name == 'CompressedTexSubImage2D': file.Write(" uint32 data_size = imageSize;\n") - elif func.name == 'TexImage2D': - file.Write(" uint32 pixels_size = GLES2Util::ComputeImageDataSize(\n") + elif name == 'TexImage2D': + file.Write(" uint32 data_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") + elif name == 'TexSubImage2D': + file.Write(" uint32 data_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.WriteHandlerValidation(file) - func.WriteHandlerImplementation(file) - file.Write(" return parse_error::kParseNoError;\n") - file.Write("}\n") - file.Write("\n") + file.Write("// uint32 data_size = 0; // TODO(gman): get correct size!\n") def WriteImmediateCmdGetTotalSize(self, func, file): """Overrriden from TypeHandler.""" @@ -1277,6 +1281,29 @@ class DataHandler(CustomHandler): " uint32 total_size = 0; // TODO(gman): get correct size\n") file.Write(" EXPECT_EQ(sizeof(cmd), total_size);\n") + 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") + def WriteImmediateFormatTest(self, func, file): """Overrriden from TypeHandler.""" # TODO(gman): Remove this exception. @@ -1298,15 +1325,17 @@ class GENnHandler(TypeHandler): """Overrriden from TypeHandler.""" pass + def WriteGetDataSizeCode(self, func, file): + """Overrriden from TypeHandler.""" + file.Write(" uint32 data_size = n * sizeof(GLuint);\n") + def WriteHandlerImplementation (self, func, file): """Overrriden from TypeHandler.""" - func.WriteHandlerValidation(file) file.Write(" GenGLObjects<GL%sHelper>(n, %s);\n" % (func.name, func.GetLastOriginalArg().name)) def WriteImmediateHandlerImplementation(self, func, file): """Overrriden from TypeHandler.""" - func.WriteHandlerValidation(file) file.Write(" GenGLObjects<GL%sHelper>(n, %s);\n" % (func.original_name, func.GetLastOriginalArg().name)) @@ -1435,7 +1464,6 @@ class CreateHandler(TypeHandler): def WriteHandlerImplementation (self, func, file): """Overrriden from TypeHandler.""" file.Write(" uint32 client_id = c.client_id;\n") - func.WriteHandlerValidation(file) file.Write(" %sHelper(%s);\n" % (func.name, func.MakeCmdArgString(""))) @@ -1463,15 +1491,17 @@ class DELnHandler(TypeHandler): def __init__(self): TypeHandler.__init__(self) + def WriteGetDataSizeCode(self, func, file): + """Overrriden from TypeHandler.""" + file.Write(" uint32 data_size = n * sizeof(GLuint);\n") + def WriteHandlerImplementation (self, func, file): """Overrriden from TypeHandler.""" - func.WriteHandlerValidation(file) file.Write(" DeleteGLObjects<GL%sHelper>(n, %s);\n" % (func.name, func.GetLastOriginalArg().name)) def WriteImmediateHandlerImplementation (self, func, file): """Overrriden from TypeHandler.""" - func.WriteHandlerValidation(file) file.Write(" DeleteGLObjects<GL%sHelper>(n, %s);\n" % (func.original_name, func.GetLastOriginalArg().name)) @@ -1650,13 +1680,11 @@ class PUTHandler(TypeHandler): def __init__(self): TypeHandler.__init__(self) - def WriteImmediateValidationCode(self, func, file): + def WriteGetDataSizeCode(self, func, file): """Overrriden from TypeHandler.""" - file.Write(" if (!CheckImmediateDataSize<%s>(" - "immediate_data_size, 1, sizeof(%s), %d)) {\n" % - (func.name, func.info.data_type, func.info.count)) - file.Write(" return parse_error::kParseOutOfBounds;\n") - file.Write(" }\n") + file.Write(" uint32 data_size = ComputeImmediateDataSize(" + "immediate_data_size, 1, sizeof(%s), %d);\n" % + (func.info.data_type, func.info.count)) def WriteGLES2ImplementationHeader(self, func, file): """Overrriden from TypeHandler.""" @@ -1783,13 +1811,11 @@ class PUTnHandler(TypeHandler): def __init__(self): TypeHandler.__init__(self) - def WriteImmediateValidationCode(self, func, file): + def WriteGetDataSizeCode(self, func, file): """Overrriden from TypeHandler.""" - file.Write(" if (!CheckImmediateDataSize<%s>(" - "immediate_data_size, count, sizeof(%s), %d)) {\n" % - (func.name, func.info.data_type, func.info.count)) - file.Write(" return parse_error::kParseOutOfBounds;\n") - file.Write(" }\n") + file.Write(" uint32 data_size = ComputeImmediateDataSize(" + "immediate_data_size, 1, sizeof(%s), %d);\n" % + (func.info.data_type, func.info.count)) def WriteGLES2ImplementationHeader(self, func, file): """Overrriden from TypeHandler.""" @@ -1960,9 +1986,8 @@ class GLcharHandler(TypeHandler): 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\n") - file.Write(" // immediate_data_size covers data_size.\n") + " const char* name = GetImmediateDataAs<const char*>(\n") + file.Write(" c, name_size, immediate_data_size);\n") func.WriteHandlerValidation(file) arg_string = ", ".join(["%s" % arg.name for arg in all_but_last_arg]) file.Write(" String name_str(name, name_size);\n") @@ -2129,9 +2154,8 @@ class GetGLcharHandler(GLcharHandler): 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\n") - file.Write(" // immediate_data_size covers data_size.\n") + " const char* name = GetImmediateDataAs<const char*>(\n") + file.Write(" c, name_size, immediate_data_size);\n") file.Write(" GLint* location = GetSharedMemoryAs<GLint*>(\n") file.Write( " c.location_shm_id, c.location_shm_offset, sizeof(*location));\n") @@ -2316,6 +2340,44 @@ class STRnHandler(TypeHandler): file.Write("// TODO(gman): Implement this\n") TypeHandler.WriteGLES2ImplementationHeader(self, func, file) + def WriteServiceImplementation(self, func, file): + """Overrriden from TypeHandler.""" + file.Write( + "parse_error::ParseError GLES2DecoderImpl::Handle%s(\n" % func.name) + file.Write( + " uint32 immediate_data_size, const gles2::%s& c) {\n" % func.name) + args = func.GetOriginalArgs() + all_but_last_2_args = args[:-2] + for arg in all_but_last_2_args: + arg.WriteGetCode(file) + self.WriteGetDataSizeCode(func, file) + size_arg = args[-2] + file.Write(" uint32 size_shm_id = c.%s_shm_id;\n" % size_arg.name) + file.Write(" uint32 size_shm_offset = c.%s_shm_offset;\n" % size_arg.name) + file.Write(" GLsizei* length = NULL;\n") + file.Write(" if (size_shm_id != 0 || size_shm_offset != 0) {\n" + " length = GetSharedMemoryAs<GLsizei*>(\n" + " size_shm_id, size_shm_offset, sizeof(*length));\n" + " if (!length) {\n" + " return parse_error::kParseOutOfBounds;\n" + " }\n" + " }\n") + dest_arg = args[-1] + bufsize_arg = args[-3] + file.Write( + " %s %s = GetSharedMemoryAs<%s>(\n" % + (dest_arg.type, dest_arg.name, dest_arg.type)) + file.Write( + " c.%s_shm_id, c.%s_shm_offset, %s);\n" % + (dest_arg.name, dest_arg.name, bufsize_arg.name)) + for arg in all_but_last_2_args + [dest_arg]: + arg.WriteValidationCode(file) + func.WriteValidationCode(file) + func.WriteHandlerImplementation(file) + file.Write(" return parse_error::kParseNoError;\n") + file.Write("}\n") + file.Write("\n") + class FunctionInfo(object): """Holds info about a function.""" @@ -2427,8 +2489,9 @@ class ImmediatePointerArgument(Argument): def WriteGetCode(self, file): """Overridden from Argument.""" file.Write( - " %s %s = GetImmediateDataAs<%s>(c);\n" % - (self.type, self.name, self.type)) + " %s %s = GetImmediateDataAs<%s>(\n" % + (self.type, self.name, self.type)) + file.Write(" c, data_size, immediate_data_size);\n") def WriteValidationCode(self, file): """Overridden from Argument.""" @@ -2462,7 +2525,7 @@ class PointerArgument(Argument): " %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" % + " c.%s_shm_id, c.%s_shm_offset, data_size);\n" % (self.name, self.name)) def WriteGetAddress(self, file): diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 63e6799..f13944f 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -18,28 +18,60 @@ namespace gpu { namespace gles2 { +// Check that certain assumptions the code makes are true. There are places in +// the code where shared memory is passed direclty to GL. Example, glUniformiv, +// glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe +// a few others) are 32bits. If they are not 32bits the code will have to change +// to call those GL functions with service side memory and then copy the results +// to shared memory, converting the sizes. +COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT + GLint_not_same_size_as_uint32); +COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT + GLint_not_same_size_as_uint32); + namespace { +size_t GetGLTypeSize(GLenum type) { + switch (type) { + case GL_BYTE: + return sizeof(GLbyte); // NOLINT + case GL_UNSIGNED_BYTE: + return sizeof(GLubyte); // NOLINT + case GL_SHORT: + return sizeof(GLshort); // NOLINT + case GL_UNSIGNED_SHORT: + return sizeof(GLushort); // NOLINT + case GL_FLOAT: + return sizeof(GLfloat); // NOLINT + default: + return 0; + } +} + // 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. +// Returns the address of the frst byte after the struct or NULL if size > +// immediate_data_size. template <typename RETURN_TYPE, typename COMMAND_TYPE> -RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod) { - return static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))); +RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod, + uint32 size, + uint32 immediate_data_size) { + return (size <= immediate_data_size) ? + static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) : + NULL; } -// Checks if there is enough immediate data. -template<typename T> -bool CheckImmediateDataSize( +// Computes the data size for certain gl commands like glUniform. +uint32 ComputeImmediateDataSize( uint32 immediate_data_size, GLuint count, size_t size, unsigned int elements_per_unit) { - return immediate_data_size == count * size * elements_per_unit; + return count * size * elements_per_unit; } // A struct to hold info about each command. @@ -59,39 +91,6 @@ const CommandInfo g_command_info[] = { #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, @@ -221,6 +220,131 @@ bool IdMap::GetClientId(GLuint service_id, GLuint* client_id) { // cmd stuff to outside this class. class GLES2DecoderImpl : public GLES2Decoder { public: + // Info about Vertex Attributes. This is used to track what the user currently + // has bound on each Vertex Attribute so that checking can be done at + // glDrawXXX time. + class VertexAttribInfo { + public: + VertexAttribInfo() + : enabled_(false), + size_(0), + type_(0), + offset_(0), + real_stride_(0), + buffer_(0), + buffer_size_(0), + num_elements_(0) { + } + // Returns true if this VertexAttrib can access index. + bool CanAccess(GLuint index); + + void set_enabled(bool enabled) { + enabled_ = enabled; + } + + GLuint buffer() const { + return buffer_; + } + + void Clear() { + buffer_ = 0; + SetBufferSize(0); + } + + void SetBufferSize(GLsizeiptr buffer_size) { + buffer_size_ = buffer_size; + if (offset_ > buffer_size || real_stride_ == 0) { + num_elements_ = 0; + } else { + uint32 size = buffer_size - offset_; + num_elements_ = size / real_stride_ + + (size % real_stride_ >= GetGLTypeSize(type_) ? 1 : 0); + } + } + + void SetInfo( + GLuint buffer, + GLsizeiptr buffer_size, + GLint size, + GLenum type, + GLsizei real_stride, + GLsizei offset) { + DCHECK(real_stride > 0); + buffer_ = buffer; + size_ = size; + type_ = type; + real_stride_ = real_stride; + offset_ = offset; + SetBufferSize(buffer_size); + } + + private: + // Whether or not this attribute is enabled. + bool enabled_; + + // number of components (1, 2, 3, 4) + GLint size_; + + // GL_BYTE, GL_FLOAT, etc. See glVertexAttribPointer. + GLenum type_; + + // The offset into the buffer. + GLsizei offset_; + + // The stride that will be used to access the buffer. This is the actual + // stide, NOT the GL bogus stride. In other words there is never a stride + // of 0. + GLsizei real_stride_; + + // The service side name of the buffer bound to this attribute. 0 = invalid + GLuint buffer_; + + // The size of the buffer. + GLsizeiptr buffer_size_; + + // The number of elements that can be accessed. + GLuint num_elements_; + }; + + // Info about Buffers currently in the system. + struct BufferInfo { + BufferInfo() + : size(0) { + } + + explicit BufferInfo(GLsizeiptr _size) + : size(_size) { + } + + GLsizeiptr size; + }; + + // This is used to track which attributes a particular program needs + // so we can verify at glDrawXXX time that every attribute is either disabled + // or if enabled that it points to a valid source. + class ProgramInfo { + public: + typedef std::vector<GLuint> AttribLocationVector; + + ProgramInfo() { + } + + void SetNumAttributes(int num_attribs) { + attrib_locations_.resize(num_attribs); + } + + void SetAttributeLocation(GLuint index, int location) { + DCHECK(index < attrib_locations_.size()); + attrib_locations_[index] = location; + } + + const AttribLocationVector& GetAttribLocations() const { + return attrib_locations_; + } + private: + AttribLocationVector attrib_locations_; + }; + GLES2DecoderImpl(); // Overridden from AsyncAPIInterface. @@ -237,41 +361,59 @@ class GLES2DecoderImpl : public GLES2Decoder { // Overridden from GLES2Decoder. virtual void Destroy(); + // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used + // on glDeleteBuffers so we can make sure the user does not try to render + // with deleted buffers. + void RemoveBufferInfo(GLuint buffer_id); + private: bool InitPlatformSpecific(); bool InitGlew(); // Template to help call glGenXXX functions. - template <void gl_gen_function(GLsizei, GLuint*)> + template <void gl_gen_function(GLES2DecoderImpl*, 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()); + gl_gen_function(this, 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; + return RegisterObjects(n, client_ids, temp.get()); } // Template to help call glDeleteXXX functions. - template <void gl_delete_function(GLsizei, GLuint*)> + template <void gl_delete_function(GLES2DecoderImpl*, 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()); + UnregisterObjects(n, client_ids, temp.get()); + gl_delete_function(this, n, temp.get()); return true; } + // Register client ids with generated service ids. + bool RegisterObjects( + GLsizei n, const GLuint* client_ids, const GLuint* service_ids); + + // Unregisters client ids with service ids. + void UnregisterObjects( + GLsizei n, const GLuint* client_ids, GLuint* service_ids); + + // Gets the program info for the given program. Returns NULL if none exists. + // Programs that have no had glLinkProgram succesfully called on them will + // not exist. + ProgramInfo* GetProgramInfo(GLuint program); + + // Updates the program info for the given program. + void UpdateProgramInfo(GLuint program); + + // Deletes the program info for the given program. + void RemoveProgramInfo(GLuint program); + + // Gets the buffer info for the given buffer. + const BufferInfo* GetBufferInfo(GLuint buffer); + + // Sets the info for a buffer. + void SetBufferInfo(GLuint buffer, GLsizeiptr size); + // Wrapper for glCreateProgram void CreateProgramHelper(GLuint client_id); @@ -281,15 +423,46 @@ class GLES2DecoderImpl : public GLES2Decoder { // Wrapper for glBindBuffer since we need to track the current targets. void DoBindBuffer(GLenum target, GLuint buffer); + // Wrapper for glDrawArrays. + void DoDrawArrays(GLenum mode, GLint first, GLsizei count); + + // Wrapper for glDisableVertexAttribArray. + void DoDisableVertexAttribArray(GLuint index); + + // Wrapper for glEnableVertexAttribArray. + void DoEnableVertexAttribArray(GLuint index); + + // Wrapper for glLinkProgram + void DoLinkProgram(GLuint program); + // Swaps the buffers (copies/renders to the current window). void DoSwapBuffers(); + // Wrapper for glUseProgram + void DoUseProgram(GLuint program); + // Gets the GLError through our wrapper. GLenum GetGLError(); // Sets our wrapper for the GLError. void SetGLError(GLenum error); + // Copies the real GL errors to the wrapper. This is so we can + // make sure there are no native GL errors before calling some GL function + // so that on return we know any error generated was for that specific + // command. + void CopyRealGLErrorsToWrapper(); + + // Checks if the current program and vertex attributes are valid for drawing. + bool IsDrawValid(GLuint max_vertex_accessed); + + // Gets the buffer id for a given target. + GLuint GetBufferForTarget(GLenum target) { + DCHECK(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER); + return target == GL_ARRAY_BUFFER ? bound_array_buffer_ : + bound_element_array_buffer_; + } + // Generate a member function prototype for each command in an automated and // typesafe way. #define GLES2_CMD_OP(name) \ @@ -324,6 +497,26 @@ class GLES2DecoderImpl : public GLES2Decoder { // to call glDrawElements. GLuint bound_element_array_buffer_; + // The maximum vertex attributes. + GLuint max_vertex_attribs_; + + // Info for each vertex attribute saved so we can check at glDrawXXX time + // if it is safe to draw. + scoped_array<VertexAttribInfo> vertex_attrib_infos_; + + // Info for each buffer in the system. + // TODO(gman): Choose a faster container. + typedef std::map<GLuint, BufferInfo> BufferInfoMap; + BufferInfoMap buffer_infos_; + + // Info for each "successfully linked" program by service side program Id. + // TODO(gman): Choose a faster container. + typedef std::map<GLuint, ProgramInfo> ProgramInfoMap; + ProgramInfoMap program_infos_; + + // The program in current use through glUseProgram. + ProgramInfo* current_program_info_; + #if defined(OS_WIN) HDC device_context_; HGLRC gl_context_; @@ -346,6 +539,8 @@ GLES2DecoderImpl::GLES2DecoderImpl() unpack_alignment_(4), bound_array_buffer_(0), bound_element_array_buffer_(0), + max_vertex_attribs_(0), + current_program_info_(NULL), #ifdef OS_WIN device_context_(NULL), gl_context_(NULL), @@ -360,6 +555,17 @@ bool GLES2DecoderImpl::Initialize() { return false; CHECK_GL_ERROR(); + // Lookup GL things we need to know. + GLint value; + glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &value); + max_vertex_attribs_ = value; + + DCHECK_GE(max_vertex_attribs_, 8u); + + vertex_attrib_infos_.reset(new VertexAttribInfo[max_vertex_attribs_]); + memset(vertex_attrib_infos_.get(), 0, + sizeof(vertex_attrib_infos_[0]) * max_vertex_attribs_); + //glBindFramebuffer(0, 0); return true; } @@ -533,9 +739,84 @@ bool GetWindowsPixelFormat(HWND window, return true; } +// These commands convert from c calls to local os calls. +void GLGenBuffersHelper( + GLES2DecoderImpl*, GLsizei n, GLuint* ids) { + glGenBuffersARB(n, ids); +} + +void GLGenFramebuffersHelper( + GLES2DecoderImpl*, GLsizei n, GLuint* ids) { + glGenFramebuffersEXT(n, ids); +} + +void GLGenRenderbuffersHelper( + GLES2DecoderImpl*, GLsizei n, GLuint* ids) { + glGenRenderbuffersEXT(n, ids); +} + +void GLGenTexturesHelper( + GLES2DecoderImpl*, GLsizei n, GLuint* ids) { + glGenTextures(n, ids); +} + +void GLDeleteBuffersHelper( + GLES2DecoderImpl* decoder, GLsizei n, GLuint* ids) { + glDeleteBuffersARB(n, ids); + for (GLsizei ii = 0; ii < n; ++ii) { + decoder->RemoveBufferInfo(ids[ii]); + } +} + +void GLDeleteFramebuffersHelper( + GLES2DecoderImpl*, GLsizei n, GLuint* ids) { + glDeleteFramebuffersEXT(n, ids); +} + +void GLDeleteRenderbuffersHelper( + GLES2DecoderImpl*, GLsizei n, GLuint* ids) { + glDeleteRenderbuffersEXT(n, ids); +} + +void GLDeleteTexturesHelper( + GLES2DecoderImpl*, GLsizei n, GLuint* ids) { + glDeleteTextures(n, ids); +} + } // anonymous namespace #endif +bool GLES2DecoderImpl::RegisterObjects( + GLsizei n, const GLuint* client_ids, const GLuint* service_ids) { + for (GLsizei ii = 0; ii < n; ++ii) { + if (!id_map_.AddMapping(client_ids[ii], service_ids[ii])) { + // TODO(gman): fail. + } + } + return true; +} + +void GLES2DecoderImpl::UnregisterObjects( + GLsizei n, const GLuint* client_ids, GLuint* service_ids) { + // TODO(gman): check for success before copying results. + for (GLsizei ii = 0; ii < n; ++ii) { + if (id_map_.GetServiceId(client_ids[ii], &service_ids[ii])) { + id_map_.RemoveMapping(client_ids[ii], service_ids[ii]); + } else { + service_ids[ii] = 0; + } + } +} + +void GLES2DecoderImpl::RemoveBufferInfo(GLuint buffer_id) { + for (GLuint ii = 0; ii < max_vertex_attribs_; ++ii) { + if (vertex_attrib_infos_[ii].buffer() == buffer_id) { + vertex_attrib_infos_[ii].Clear(); + } + } + buffer_infos_.erase(buffer_id); +} + bool GLES2DecoderImpl::InitPlatformSpecific() { #if defined(OS_WIN) device_context_ = ::GetDC(hwnd()); @@ -678,8 +959,10 @@ parse_error::ParseError GLES2DecoderImpl::DoCommand( #undef GLES2_CMD_OP } if (debug()) { - if (glGetError() != 0) { + GLenum error; + while ((error = glGetError()) != GL_NO_ERROR) { // TODO(gman): Change output to something useful for NaCl. + SetGLError(error); printf("GL ERROR b4: %s\n", GetCommandName(command)); } } @@ -723,6 +1006,24 @@ void GLES2DecoderImpl::DoBindBuffer(GLenum target, GLuint buffer) { glBindBuffer(target, buffer); } +void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) { + if (index < max_vertex_attribs_) { + vertex_attrib_infos_[index].set_enabled(false); + glEnableVertexAttribArray(index); + } else { + SetGLError(GL_INVALID_VALUE); + } +} + +void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) { + if (index < max_vertex_attribs_) { + vertex_attrib_infos_[index].set_enabled(true); + glEnableVertexAttribArray(index); + } else { + SetGLError(GL_INVALID_VALUE); + } +} + parse_error::ParseError GLES2DecoderImpl::HandleDeleteShader( uint32 immediate_data_size, const gles2::DeleteShader& c) { GLuint shader = c.shader; @@ -731,7 +1032,7 @@ parse_error::ParseError GLES2DecoderImpl::HandleDeleteShader( SetGLError(GL_INVALID_VALUE); return parse_error::kParseNoError; } - glDeleteProgram(service_id); + glDeleteShader(service_id); id_map_.RemoveMapping(shader, service_id); return parse_error::kParseNoError; } @@ -744,11 +1045,31 @@ parse_error::ParseError GLES2DecoderImpl::HandleDeleteProgram( SetGLError(GL_INVALID_VALUE); return parse_error::kParseNoError; } + RemoveProgramInfo(program); glDeleteProgram(service_id); id_map_.RemoveMapping(program, service_id); return parse_error::kParseNoError; } +void GLES2DecoderImpl::DoDrawArrays( + GLenum mode, GLint first, GLsizei count) { + if (IsDrawValid(first + count - 1)) { + glDrawArrays(mode, first, count); + } +} + +void GLES2DecoderImpl::DoLinkProgram(GLuint program) { + CopyRealGLErrorsToWrapper(); + glLinkProgram(program); + GLenum error = glGetError(); + if (error != GL_NO_ERROR) { + RemoveProgramInfo(program); + SetGLError(error); + } else { + UpdateProgramInfo(program); + } +}; + // 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() { @@ -762,6 +1083,17 @@ void GLES2DecoderImpl::DoSwapBuffers() { #endif } +void GLES2DecoderImpl::DoUseProgram(GLuint program) { + ProgramInfo* info = GetProgramInfo(program); + if (!info) { + // Program was not linked successfully. (ie, glLinkProgram) + SetGLError(GL_INVALID_OPERATION); + } else { + current_program_info_ = info; + glUseProgram(program); + } +} + GLenum GLES2DecoderImpl::GetGLError() { // Check the GL error first, then our wrapped error. GLenum error = glGetError(); @@ -786,6 +1118,97 @@ void GLES2DecoderImpl::SetGLError(GLenum error) { error_bits_ |= GLErrorToErrorBit(error); } +void GLES2DecoderImpl::CopyRealGLErrorsToWrapper() { + GLenum error; + while ((error = glGetError()) != GL_NO_ERROR) { + SetGLError(error); + } +} + +const GLES2DecoderImpl::BufferInfo* GLES2DecoderImpl::GetBufferInfo( + GLuint buffer) { + BufferInfoMap::iterator it = buffer_infos_.find(buffer); + return it != buffer_infos_.end() ? &it->second : NULL; +} + +void GLES2DecoderImpl::SetBufferInfo(GLuint buffer, GLsizeiptr size) { + buffer_infos_[buffer] = BufferInfo(size); + + // Also go through VertexAttribInfo and update any info that references + // the same buffer. + for (GLuint ii = 0; ii < max_vertex_attribs_; ++ii) { + if (vertex_attrib_infos_[ii].buffer() == buffer) { + vertex_attrib_infos_[ii].SetBufferSize(size); + } + } +} + +GLES2DecoderImpl::ProgramInfo* GLES2DecoderImpl::GetProgramInfo( + GLuint program) { + ProgramInfoMap::iterator it = program_infos_.find(program); + return it != program_infos_.end() ? &it->second : NULL; +} + +void GLES2DecoderImpl::UpdateProgramInfo(GLuint program) { + ProgramInfo* info = GetProgramInfo(program); + if (!info) { + std::pair<ProgramInfoMap::iterator, bool> result = + program_infos_.insert(std::make_pair(program, ProgramInfo())); + DCHECK(result.second); + info = &result.first->second; + } + GLint num_attribs = 0; + GLint max_len = 0; + glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &num_attribs); + info->SetNumAttributes(num_attribs); + glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_len); + // TODO(gman): Should we check for error? + scoped_array<char> name_buffer(new char[max_len + 1]); + for (GLint ii = 0; ii < num_attribs; ++ii) { + GLsizei length; + GLsizei size; + GLenum type; + glGetActiveAttrib( + program, ii, max_len + 1, &length, &size, &type, name_buffer.get()); + // TODO(gman): Should we check for error? + GLint location = glGetAttribLocation(program, name_buffer.get()); + info->SetAttributeLocation(ii, num_attribs); + } +} + +void GLES2DecoderImpl::RemoveProgramInfo(GLuint program) { + ProgramInfoMap::iterator it = program_infos_.find(program); + if (it != program_infos_.end()) { + if (current_program_info_ == &it->second) { + current_program_info_ = NULL; + } + program_infos_.erase(it); + } +} + +bool GLES2DecoderImpl::VertexAttribInfo::CanAccess(GLuint index) { + return !enabled_ || (buffer_ != 0 && index < num_elements_); +} + +bool GLES2DecoderImpl::IsDrawValid(GLuint max_vertex_accessed) { + if (current_program_info_) { + // Validate that all attribs current program needs are setup correctly. + const ProgramInfo::AttribLocationVector& locations = + current_program_info_->GetAttribLocations(); + for (size_t ii = 0; ii < locations.size(); ++ii) { + GLuint location = locations[ii]; + DCHECK_LT(location, max_vertex_attribs_); + if (!vertex_attrib_infos_[location].CanAccess(max_vertex_accessed)) { + SetGLError(GL_INVALID_OPERATION); + } + } + return true; + } + // We do not set a GL error here because the GL spec says no error if the + // program is invalid. + return false; +}; + parse_error::ParseError GLES2DecoderImpl::HandleDrawElements( uint32 immediate_data_size, const gles2::DrawElements& c) { if (bound_element_array_buffer_ != 0) { @@ -797,9 +1220,15 @@ parse_error::ParseError GLES2DecoderImpl::HandleDrawElements( SetGLError(GL_INVALID_VALUE); } else { const GLvoid* indices = reinterpret_cast<const GLvoid*>(c.index_offset); - // TODO(gman): Validate indices - // TOOD(gman): Validate all attribs current program needs are setup. - glDrawElements(mode, count, type, indices); + // TODO(gman): Validate indices. Get maximum index. + // + // This value should be computed by walking the index buffer from 0 to + // count and finding the maximum vertex accessed. + // For now we'll special case 0 to not check. + GLuint max_vertex_accessed = 0; + if (IsDrawValid(max_vertex_accessed)) { + glDrawElements(mode, count, type, indices); + } } } else { SetGLError(GL_INVALID_VALUE); @@ -865,8 +1294,8 @@ parse_error::ParseError GLES2DecoderImpl::HandleShaderSourceImmediate( } 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); + const char** data = GetImmediateDataAs<const char**>( + c, data_size, immediate_data_size); if (!data) { return parse_error::kParseOutOfBounds; } @@ -876,21 +1305,35 @@ parse_error::ParseError GLES2DecoderImpl::HandleShaderSourceImmediate( parse_error::ParseError GLES2DecoderImpl::HandleVertexAttribPointer( uint32 immediate_data_size, const gles2::VertexAttribPointer& c) { - // TODO(gman): Is this a valid check or does this check have to come - // at glDrawElements time. 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); + GLsizei offset = c.offset; + const void* ptr = reinterpret_cast<const void*>(offset); if (!ValidateGLenumVertexAttribType(type) || - !ValidateGLenumVertexAttribSize(size)) { + !ValidateGLenumVertexAttribSize(size) || + indx >= max_vertex_attribs_ || + stride < 0) { SetGLError(GL_INVALID_VALUE); return parse_error::kParseNoError; } + const BufferInfo* buffer_info = GetBufferInfo(bound_array_buffer_); + GLsizei component_size = GetGLTypeSize(type); + GLsizei real_stride = stride != 0 ? stride : component_size * size; + if (offset % component_size > 0) { + SetGLError(GL_INVALID_VALUE); + return parse_error::kParseNoError; + } + vertex_attrib_infos_[indx].SetInfo( + bound_array_buffer_, + buffer_info ? buffer_info->size : 0, + size, + type, + real_stride, + offset); glVertexAttribPointer(indx, size, type, normalized, stride, ptr); } else { SetGLError(GL_INVALID_VALUE); @@ -975,9 +1418,8 @@ parse_error::ParseError GLES2DecoderImpl::HandleGetAttribLocationImmediate( 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. + const char* name = GetImmediateDataAs<const char*>( + c, name_size, immediate_data_size); GLint* location = GetSharedMemoryAs<GLint*>( c.location_shm_id, c.location_shm_offset, sizeof(GLint)); if (!location || !name) { @@ -1016,9 +1458,8 @@ parse_error::ParseError GLES2DecoderImpl::HandleGetUniformLocationImmediate( 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. + const char* name = GetImmediateDataAs<const char*>( + c, name_size, immediate_data_size); GLint* location = GetSharedMemoryAs<GLint*>( c.location_shm_id, c.location_shm_offset, sizeof(GLint)); if (!location || !name) { @@ -1043,13 +1484,26 @@ parse_error::ParseError GLES2DecoderImpl::HandleBufferData( return parse_error::kParseOutOfBounds; } } - // TODO(gman): Validate case where data is NULL. if (!ValidateGLenumBufferTarget(target) || !ValidateGLenumBufferUsage(usage)) { SetGLError(GL_INVALID_VALUE); return parse_error::kParseNoError; } + // Clear the buffer to 0 if no initial data was passed in. + scoped_array<int8> zero; + if (!data) { + zero.reset(new int8[size]); + memset(zero.get(), 0, size); + data = zero.get(); + } + CopyRealGLErrorsToWrapper(); glBufferData(target, size, data, usage); + GLenum error = glGetError(); + if (error != GL_NO_ERROR) { + SetGLError(error); + } else { + SetBufferInfo(GetBufferForTarget(target), size); + } return parse_error::kParseNoError; } @@ -1057,15 +1511,25 @@ parse_error::ParseError GLES2DecoderImpl::HandleBufferDataImmediate( uint32 immediate_data_size, 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); + const void* data = GetImmediateDataAs<const void*>( + c, size, immediate_data_size); + if (!data) { + return parse_error::kParseOutOfBounds; + } GLenum usage = static_cast<GLenum>(c.usage); if (!ValidateGLenumBufferTarget(target) || !ValidateGLenumBufferUsage(usage)) { SetGLError(GL_INVALID_VALUE); return parse_error::kParseNoError; } - // TODO(gman): Handle case where data is NULL. + CopyRealGLErrorsToWrapper(); glBufferData(target, size, data, usage); + GLenum error = glGetError(); + if (error != GL_NO_ERROR) { + SetGLError(error); + } else { + SetBufferInfo(GetBufferForTarget(target), size); + } return parse_error::kParseNoError; } @@ -1093,7 +1557,12 @@ parse_error::ParseError GLES2DecoderImpl::HandleCompressedTexImage2D( SetGLError(GL_INVALID_VALUE); return parse_error::kParseNoError; } - // TODO(gman): Validate case where data is NULL. + scoped_array<int8> zero; + if (!data) { + zero.reset(new int8[image_size]); + memset(zero.get(), 0, image_size); + data = zero.get(); + } glCompressedTexImage2D( target, level, internal_format, width, height, border, image_size, data); return parse_error::kParseNoError; @@ -1108,9 +1577,8 @@ parse_error::ParseError GLES2DecoderImpl::HandleCompressedTexImage2DImmediate( GLsizei height = static_cast<GLsizei>(c.height); GLint border = static_cast<GLint>(c.border); GLsizei image_size = static_cast<GLsizei>(c.imageSize); - const void* data = GetImmediateDataAs<const void*>(c); - // Immediate version. - // TODO(gman): Handle case where data is NULL. + const void* data = GetImmediateDataAs<const void*>( + c, image_size, immediate_data_size); if (!data) { return parse_error::kParseOutOfBounds; } @@ -1153,7 +1621,12 @@ parse_error::ParseError GLES2DecoderImpl::HandleTexImage2D( SetGLError(GL_INVALID_VALUE); return parse_error::kParseNoError; } - // TODO(gman): Validate case where data is NULL. + scoped_array<int8> zero; + if (!pixels) { + zero.reset(new int8[pixels_size]); + memset(zero.get(), 0, pixels_size); + pixels = zero.get(); + } glTexImage2D( target, level, internal_format, width, height, border, format, type, pixels); @@ -1170,9 +1643,10 @@ parse_error::ParseError GLES2DecoderImpl::HandleTexImage2DImmediate( 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. - // TODO(gman): Handle case where data is NULL. + uint32 size = GLES2Util::ComputeImageDataSize( + width, height, format, type, unpack_alignment_); + const void* pixels = GetImmediateDataAs<const void*>( + c, size, immediate_data_size); if (!pixels) { return parse_error::kParseOutOfBounds; } diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h index 957ccad..24e7340 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h @@ -53,9 +53,8 @@ parse_error::ParseError GLES2DecoderImpl::HandleBindAttribLocationImmediate( } 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 - // immediate_data_size covers data_size. + const char* name = GetImmediateDataAs<const char*>( + c, name_size, immediate_data_size); if (name == NULL) { return parse_error::kParseOutOfBounds; } @@ -212,11 +211,9 @@ parse_error::ParseError GLES2DecoderImpl::HandleBufferSubData( 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); + c.data_shm_id, c.data_shm_offset, data_size); if (!ValidateGLenumBufferTarget(target)) { SetGLError(GL_INVALID_VALUE); return parse_error::kParseNoError; @@ -233,15 +230,9 @@ parse_error::ParseError GLES2DecoderImpl::HandleBufferSubDataImmediate( 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); - if (!ValidateGLenumBufferTarget(target)) { - SetGLError(GL_INVALID_VALUE); - return parse_error::kParseNoError; - } - if (data == NULL) { - return parse_error::kParseOutOfBounds; - } - // Immediate version. + uint32 data_size = size; + const void* data = GetImmediateDataAs<const void*>( + c, data_size, immediate_data_size); if (!ValidateGLenumBufferTarget(target)) { SetGLError(GL_INVALID_VALUE); return parse_error::kParseNoError; @@ -326,11 +317,9 @@ parse_error::ParseError GLES2DecoderImpl::HandleCompressedTexSubImage2D( 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); + c.data_shm_id, c.data_shm_offset, data_size); if (!ValidateGLenumTextureTarget(target)) { SetGLError(GL_INVALID_VALUE); return parse_error::kParseNoError; @@ -355,15 +344,9 @@ parse_error::ParseError GLES2DecoderImpl::HandleCompressedTexSubImage2DImmediate 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); - if (!ValidateGLenumTextureTarget(target)) { - SetGLError(GL_INVALID_VALUE); - return parse_error::kParseNoError; - } - if (data == NULL) { - return parse_error::kParseOutOfBounds; - } - // Immediate version. + uint32 data_size = imageSize; + const void* data = GetImmediateDataAs<const void*>( + c, data_size, immediate_data_size); if (!ValidateGLenumTextureTarget(target)) { SetGLError(GL_INVALID_VALUE); return parse_error::kParseNoError; @@ -427,10 +410,6 @@ parse_error::ParseError GLES2DecoderImpl::HandleCreateShader( return parse_error::kParseNoError; } uint32 client_id = c.client_id; - if (!ValidateGLenumShaderType(type)) { - SetGLError(GL_INVALID_VALUE); - return parse_error::kParseNoError; - } CreateShaderHelper(type, client_id); return parse_error::kParseNoError; } @@ -449,11 +428,9 @@ parse_error::ParseError GLES2DecoderImpl::HandleCullFace( parse_error::ParseError GLES2DecoderImpl::HandleDeleteBuffers( uint32 immediate_data_size, const gles2::DeleteBuffers& c) { GLsizei n = static_cast<GLsizei>(c.n); + uint32 data_size = n * sizeof(GLuint); const GLuint* buffers = GetSharedMemoryAs<const GLuint*>( - c.buffers_shm_id, c.buffers_shm_offset, 0 /* TODO(gman): size */); - if (buffers == NULL) { - return parse_error::kParseOutOfBounds; - } + c.buffers_shm_id, c.buffers_shm_offset, data_size); if (buffers == NULL) { return parse_error::kParseOutOfBounds; } @@ -464,10 +441,9 @@ parse_error::ParseError GLES2DecoderImpl::HandleDeleteBuffers( parse_error::ParseError GLES2DecoderImpl::HandleDeleteBuffersImmediate( uint32 immediate_data_size, const gles2::DeleteBuffersImmediate& c) { GLsizei n = static_cast<GLsizei>(c.n); - const GLuint* buffers = GetImmediateDataAs<const GLuint*>(c); - if (buffers == NULL) { - return parse_error::kParseOutOfBounds; - } + uint32 data_size = n * sizeof(GLuint); + const GLuint* buffers = GetImmediateDataAs<const GLuint*>( + c, data_size, immediate_data_size); if (buffers == NULL) { return parse_error::kParseOutOfBounds; } @@ -478,12 +454,9 @@ parse_error::ParseError GLES2DecoderImpl::HandleDeleteBuffersImmediate( parse_error::ParseError GLES2DecoderImpl::HandleDeleteFramebuffers( uint32 immediate_data_size, const gles2::DeleteFramebuffers& c) { GLsizei n = static_cast<GLsizei>(c.n); + uint32 data_size = n * sizeof(GLuint); const GLuint* framebuffers = GetSharedMemoryAs<const GLuint*>( - c.framebuffers_shm_id, c.framebuffers_shm_offset, 0 /* TODO( - gman): size */); - if (framebuffers == NULL) { - return parse_error::kParseOutOfBounds; - } + c.framebuffers_shm_id, c.framebuffers_shm_offset, data_size); if (framebuffers == NULL) { return parse_error::kParseOutOfBounds; } @@ -494,10 +467,9 @@ parse_error::ParseError GLES2DecoderImpl::HandleDeleteFramebuffers( parse_error::ParseError GLES2DecoderImpl::HandleDeleteFramebuffersImmediate( uint32 immediate_data_size, const gles2::DeleteFramebuffersImmediate& c) { GLsizei n = static_cast<GLsizei>(c.n); - const GLuint* framebuffers = GetImmediateDataAs<const GLuint*>(c); - if (framebuffers == NULL) { - return parse_error::kParseOutOfBounds; - } + uint32 data_size = n * sizeof(GLuint); + const GLuint* framebuffers = GetImmediateDataAs<const GLuint*>( + c, data_size, immediate_data_size); if (framebuffers == NULL) { return parse_error::kParseOutOfBounds; } @@ -508,12 +480,9 @@ parse_error::ParseError GLES2DecoderImpl::HandleDeleteFramebuffersImmediate( parse_error::ParseError GLES2DecoderImpl::HandleDeleteRenderbuffers( uint32 immediate_data_size, const gles2::DeleteRenderbuffers& c) { GLsizei n = static_cast<GLsizei>(c.n); + uint32 data_size = n * sizeof(GLuint); const GLuint* renderbuffers = GetSharedMemoryAs<const GLuint*>( - c.renderbuffers_shm_id, c.renderbuffers_shm_offset, 0 /* TODO( - gman): size */); - if (renderbuffers == NULL) { - return parse_error::kParseOutOfBounds; - } + c.renderbuffers_shm_id, c.renderbuffers_shm_offset, data_size); if (renderbuffers == NULL) { return parse_error::kParseOutOfBounds; } @@ -524,10 +493,9 @@ parse_error::ParseError GLES2DecoderImpl::HandleDeleteRenderbuffers( parse_error::ParseError GLES2DecoderImpl::HandleDeleteRenderbuffersImmediate( uint32 immediate_data_size, const gles2::DeleteRenderbuffersImmediate& c) { GLsizei n = static_cast<GLsizei>(c.n); - const GLuint* renderbuffers = GetImmediateDataAs<const GLuint*>(c); - if (renderbuffers == NULL) { - return parse_error::kParseOutOfBounds; - } + uint32 data_size = n * sizeof(GLuint); + const GLuint* renderbuffers = GetImmediateDataAs<const GLuint*>( + c, data_size, immediate_data_size); if (renderbuffers == NULL) { return parse_error::kParseOutOfBounds; } @@ -538,11 +506,9 @@ parse_error::ParseError GLES2DecoderImpl::HandleDeleteRenderbuffersImmediate( parse_error::ParseError GLES2DecoderImpl::HandleDeleteTextures( uint32 immediate_data_size, const gles2::DeleteTextures& c) { GLsizei n = static_cast<GLsizei>(c.n); + uint32 data_size = n * sizeof(GLuint); const GLuint* textures = GetSharedMemoryAs<const GLuint*>( - c.textures_shm_id, c.textures_shm_offset, 0 /* TODO(gman): size */); - if (textures == NULL) { - return parse_error::kParseOutOfBounds; - } + c.textures_shm_id, c.textures_shm_offset, data_size); if (textures == NULL) { return parse_error::kParseOutOfBounds; } @@ -553,10 +519,9 @@ parse_error::ParseError GLES2DecoderImpl::HandleDeleteTextures( parse_error::ParseError GLES2DecoderImpl::HandleDeleteTexturesImmediate( uint32 immediate_data_size, const gles2::DeleteTexturesImmediate& c) { GLsizei n = static_cast<GLsizei>(c.n); - const GLuint* textures = GetImmediateDataAs<const GLuint*>(c); - if (textures == NULL) { - return parse_error::kParseOutOfBounds; - } + uint32 data_size = n * sizeof(GLuint); + const GLuint* textures = GetImmediateDataAs<const GLuint*>( + c, data_size, immediate_data_size); if (textures == NULL) { return parse_error::kParseOutOfBounds; } @@ -620,7 +585,7 @@ parse_error::ParseError GLES2DecoderImpl::HandleDisable( parse_error::ParseError GLES2DecoderImpl::HandleDisableVertexAttribArray( uint32 immediate_data_size, const gles2::DisableVertexAttribArray& c) { GLuint index = static_cast<GLuint>(c.index); - glDisableVertexAttribArray(index); + DoDisableVertexAttribArray(index); return parse_error::kParseNoError; } @@ -633,7 +598,7 @@ parse_error::ParseError GLES2DecoderImpl::HandleDrawArrays( SetGLError(GL_INVALID_VALUE); return parse_error::kParseNoError; } - glDrawArrays(mode, first, count); + DoDrawArrays(mode, first, count); return parse_error::kParseNoError; } @@ -651,7 +616,7 @@ parse_error::ParseError GLES2DecoderImpl::HandleEnable( parse_error::ParseError GLES2DecoderImpl::HandleEnableVertexAttribArray( uint32 immediate_data_size, const gles2::EnableVertexAttribArray& c) { GLuint index = static_cast<GLuint>(c.index); - glEnableVertexAttribArray(index); + DoEnableVertexAttribArray(index); return parse_error::kParseNoError; } @@ -735,11 +700,9 @@ parse_error::ParseError GLES2DecoderImpl::HandleFrontFace( parse_error::ParseError GLES2DecoderImpl::HandleGenBuffers( uint32 immediate_data_size, const gles2::GenBuffers& c) { GLsizei n = static_cast<GLsizei>(c.n); + uint32 data_size = n * sizeof(GLuint); GLuint* buffers = GetSharedMemoryAs<GLuint*>( - c.buffers_shm_id, c.buffers_shm_offset, 0 /* TODO(gman): size */); - if (buffers == NULL) { - return parse_error::kParseOutOfBounds; - } + c.buffers_shm_id, c.buffers_shm_offset, data_size); if (buffers == NULL) { return parse_error::kParseOutOfBounds; } @@ -750,10 +713,9 @@ parse_error::ParseError GLES2DecoderImpl::HandleGenBuffers( parse_error::ParseError GLES2DecoderImpl::HandleGenBuffersImmediate( uint32 immediate_data_size, const gles2::GenBuffersImmediate& c) { GLsizei n = static_cast<GLsizei>(c.n); - GLuint* buffers = GetImmediateDataAs<GLuint*>(c); - if (buffers == NULL) { - return parse_error::kParseOutOfBounds; - } + uint32 data_size = n * sizeof(GLuint); + GLuint* buffers = GetImmediateDataAs<GLuint*>( + c, data_size, immediate_data_size); if (buffers == NULL) { return parse_error::kParseOutOfBounds; } @@ -775,12 +737,9 @@ parse_error::ParseError GLES2DecoderImpl::HandleGenerateMipmap( parse_error::ParseError GLES2DecoderImpl::HandleGenFramebuffers( uint32 immediate_data_size, const gles2::GenFramebuffers& c) { GLsizei n = static_cast<GLsizei>(c.n); + uint32 data_size = n * sizeof(GLuint); GLuint* framebuffers = GetSharedMemoryAs<GLuint*>( - c.framebuffers_shm_id, c.framebuffers_shm_offset, 0 /* TODO( - gman): size */); - if (framebuffers == NULL) { - return parse_error::kParseOutOfBounds; - } + c.framebuffers_shm_id, c.framebuffers_shm_offset, data_size); if (framebuffers == NULL) { return parse_error::kParseOutOfBounds; } @@ -791,10 +750,9 @@ parse_error::ParseError GLES2DecoderImpl::HandleGenFramebuffers( parse_error::ParseError GLES2DecoderImpl::HandleGenFramebuffersImmediate( uint32 immediate_data_size, const gles2::GenFramebuffersImmediate& c) { GLsizei n = static_cast<GLsizei>(c.n); - GLuint* framebuffers = GetImmediateDataAs<GLuint*>(c); - if (framebuffers == NULL) { - return parse_error::kParseOutOfBounds; - } + uint32 data_size = n * sizeof(GLuint); + GLuint* framebuffers = GetImmediateDataAs<GLuint*>( + c, data_size, immediate_data_size); if (framebuffers == NULL) { return parse_error::kParseOutOfBounds; } @@ -805,12 +763,9 @@ parse_error::ParseError GLES2DecoderImpl::HandleGenFramebuffersImmediate( parse_error::ParseError GLES2DecoderImpl::HandleGenRenderbuffers( uint32 immediate_data_size, const gles2::GenRenderbuffers& c) { GLsizei n = static_cast<GLsizei>(c.n); + uint32 data_size = n * sizeof(GLuint); GLuint* renderbuffers = GetSharedMemoryAs<GLuint*>( - c.renderbuffers_shm_id, c.renderbuffers_shm_offset, 0 /* TODO( - gman): size */); - if (renderbuffers == NULL) { - return parse_error::kParseOutOfBounds; - } + c.renderbuffers_shm_id, c.renderbuffers_shm_offset, data_size); if (renderbuffers == NULL) { return parse_error::kParseOutOfBounds; } @@ -821,10 +776,9 @@ parse_error::ParseError GLES2DecoderImpl::HandleGenRenderbuffers( parse_error::ParseError GLES2DecoderImpl::HandleGenRenderbuffersImmediate( uint32 immediate_data_size, const gles2::GenRenderbuffersImmediate& c) { GLsizei n = static_cast<GLsizei>(c.n); - GLuint* renderbuffers = GetImmediateDataAs<GLuint*>(c); - if (renderbuffers == NULL) { - return parse_error::kParseOutOfBounds; - } + uint32 data_size = n * sizeof(GLuint); + GLuint* renderbuffers = GetImmediateDataAs<GLuint*>( + c, data_size, immediate_data_size); if (renderbuffers == NULL) { return parse_error::kParseOutOfBounds; } @@ -835,11 +789,9 @@ parse_error::ParseError GLES2DecoderImpl::HandleGenRenderbuffersImmediate( parse_error::ParseError GLES2DecoderImpl::HandleGenTextures( uint32 immediate_data_size, const gles2::GenTextures& c) { GLsizei n = static_cast<GLsizei>(c.n); + uint32 data_size = n * sizeof(GLuint); GLuint* textures = GetSharedMemoryAs<GLuint*>( - c.textures_shm_id, c.textures_shm_offset, 0 /* TODO(gman): size */); - if (textures == NULL) { - return parse_error::kParseOutOfBounds; - } + c.textures_shm_id, c.textures_shm_offset, data_size); if (textures == NULL) { return parse_error::kParseOutOfBounds; } @@ -850,10 +802,9 @@ parse_error::ParseError GLES2DecoderImpl::HandleGenTextures( parse_error::ParseError GLES2DecoderImpl::HandleGenTexturesImmediate( uint32 immediate_data_size, const gles2::GenTexturesImmediate& c) { GLsizei n = static_cast<GLsizei>(c.n); - GLuint* textures = GetImmediateDataAs<GLuint*>(c); - if (textures == NULL) { - return parse_error::kParseOutOfBounds; - } + uint32 data_size = n * sizeof(GLuint); + GLuint* textures = GetImmediateDataAs<GLuint*>( + c, data_size, immediate_data_size); if (textures == NULL) { return parse_error::kParseOutOfBounds; } @@ -1001,13 +952,18 @@ parse_error::ParseError GLES2DecoderImpl::HandleGetProgramInfoLog( 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 */); - if (length == NULL) { - return parse_error::kParseOutOfBounds; + uint32 size_shm_id = c.length_shm_id; + uint32 size_shm_offset = c.length_shm_offset; + GLsizei* length = NULL; + if (size_shm_id != 0 || size_shm_offset != 0) { + length = GetSharedMemoryAs<GLsizei*>( + size_shm_id, size_shm_offset, sizeof(*length)); + if (!length) { + return parse_error::kParseOutOfBounds; + } } + char* infolog = GetSharedMemoryAs<char*>( + c.infolog_shm_id, c.infolog_shm_offset, bufsize); if (infolog == NULL) { return parse_error::kParseOutOfBounds; } @@ -1071,13 +1027,18 @@ parse_error::ParseError GLES2DecoderImpl::HandleGetShaderInfoLog( 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 */); - if (length == NULL) { - return parse_error::kParseOutOfBounds; + uint32 size_shm_id = c.length_shm_id; + uint32 size_shm_offset = c.length_shm_offset; + GLsizei* length = NULL; + if (size_shm_id != 0 || size_shm_offset != 0) { + length = GetSharedMemoryAs<GLsizei*>( + size_shm_id, size_shm_offset, sizeof(*length)); + if (!length) { + return parse_error::kParseOutOfBounds; + } } + char* infolog = GetSharedMemoryAs<char*>( + c.infolog_shm_id, c.infolog_shm_offset, bufsize); if (infolog == NULL) { return parse_error::kParseOutOfBounds; } @@ -1093,13 +1054,18 @@ parse_error::ParseError GLES2DecoderImpl::HandleGetShaderSource( 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 */); - if (length == NULL) { - return parse_error::kParseOutOfBounds; + uint32 size_shm_id = c.length_shm_id; + uint32 size_shm_offset = c.length_shm_offset; + GLsizei* length = NULL; + if (size_shm_id != 0 || size_shm_offset != 0) { + length = GetSharedMemoryAs<GLsizei*>( + size_shm_id, size_shm_offset, sizeof(*length)); + if (!length) { + return parse_error::kParseOutOfBounds; + } } + char* source = GetSharedMemoryAs<char*>( + c.source_shm_id, c.source_shm_offset, bufsize); if (source == NULL) { return parse_error::kParseOutOfBounds; } @@ -1327,7 +1293,7 @@ parse_error::ParseError GLES2DecoderImpl::HandleLinkProgram( SetGLError(GL_INVALID_VALUE); return parse_error::kParseNoError; } - glLinkProgram(program); + DoLinkProgram(program); return parse_error::kParseNoError; } @@ -1493,8 +1459,10 @@ parse_error::ParseError GLES2DecoderImpl::HandleTexParameterfv( uint32 immediate_data_size, const gles2::TexParameterfv& c) { GLenum target = static_cast<GLenum>(c.target); GLenum pname = static_cast<GLenum>(c.pname); + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 1); const GLfloat* params = GetSharedMemoryAs<const GLfloat*>( - c.params_shm_id, c.params_shm_offset, 0 /* TODO(gman): size */); + c.params_shm_id, c.params_shm_offset, data_size); if (!ValidateGLenumTextureBindTarget(target)) { SetGLError(GL_INVALID_VALUE); return parse_error::kParseNoError; @@ -1514,7 +1482,10 @@ parse_error::ParseError GLES2DecoderImpl::HandleTexParameterfvImmediate( uint32 immediate_data_size, 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); + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 1); + const GLfloat* params = GetImmediateDataAs<const GLfloat*>( + c, data_size, immediate_data_size); if (!ValidateGLenumTextureBindTarget(target)) { SetGLError(GL_INVALID_VALUE); return parse_error::kParseNoError; @@ -1526,26 +1497,6 @@ parse_error::ParseError GLES2DecoderImpl::HandleTexParameterfvImmediate( if (params == NULL) { return parse_error::kParseOutOfBounds; } - if (!CheckImmediateDataSize<TexParameterfvImmediate>( - immediate_data_size, 1, sizeof(GLfloat), 1)) { - return parse_error::kParseOutOfBounds; - } - // Immediate version. - if (!ValidateGLenumTextureBindTarget(target)) { - SetGLError(GL_INVALID_VALUE); - return parse_error::kParseNoError; - } - if (!ValidateGLenumTextureParameter(pname)) { - SetGLError(GL_INVALID_VALUE); - return parse_error::kParseNoError; - } - if (params == NULL) { - return parse_error::kParseOutOfBounds; - } - if (!CheckImmediateDataSize<TexParameterfvImmediate>( - immediate_data_size, 1, sizeof(GLfloat), 1)) { - return parse_error::kParseOutOfBounds; - } glTexParameterfv(target, pname, params); return parse_error::kParseNoError; } @@ -1571,8 +1522,10 @@ parse_error::ParseError GLES2DecoderImpl::HandleTexParameteriv( uint32 immediate_data_size, const gles2::TexParameteriv& c) { GLenum target = static_cast<GLenum>(c.target); GLenum pname = static_cast<GLenum>(c.pname); + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLint), 1); const GLint* params = GetSharedMemoryAs<const GLint*>( - c.params_shm_id, c.params_shm_offset, 0 /* TODO(gman): size */); + c.params_shm_id, c.params_shm_offset, data_size); if (!ValidateGLenumTextureBindTarget(target)) { SetGLError(GL_INVALID_VALUE); return parse_error::kParseNoError; @@ -1592,23 +1545,10 @@ parse_error::ParseError GLES2DecoderImpl::HandleTexParameterivImmediate( uint32 immediate_data_size, 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); - if (!ValidateGLenumTextureBindTarget(target)) { - SetGLError(GL_INVALID_VALUE); - return parse_error::kParseNoError; - } - if (!ValidateGLenumTextureParameter(pname)) { - SetGLError(GL_INVALID_VALUE); - return parse_error::kParseNoError; - } - if (params == NULL) { - return parse_error::kParseOutOfBounds; - } - if (!CheckImmediateDataSize<TexParameterivImmediate>( - immediate_data_size, 1, sizeof(GLint), 1)) { - return parse_error::kParseOutOfBounds; - } - // Immediate version. + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLint), 1); + const GLint* params = GetImmediateDataAs<const GLint*>( + c, data_size, immediate_data_size); if (!ValidateGLenumTextureBindTarget(target)) { SetGLError(GL_INVALID_VALUE); return parse_error::kParseNoError; @@ -1620,10 +1560,6 @@ parse_error::ParseError GLES2DecoderImpl::HandleTexParameterivImmediate( if (params == NULL) { return parse_error::kParseOutOfBounds; } - if (!CheckImmediateDataSize<TexParameterivImmediate>( - immediate_data_size, 1, sizeof(GLint), 1)) { - return parse_error::kParseOutOfBounds; - } glTexParameteriv(target, pname, params); return parse_error::kParseNoError; } @@ -1638,12 +1574,10 @@ parse_error::ParseError GLES2DecoderImpl::HandleTexSubImage2D( 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( + uint32 data_size = GLES2Util::ComputeImageDataSize( width, height, format, type, unpack_alignment_); const void* pixels = GetSharedMemoryAs<const void*>( - pixels_shm_id, pixels_shm_offset, pixels_size); + c.pixels_shm_id, c.pixels_shm_offset, data_size); if (!ValidateGLenumTextureTarget(target)) { SetGLError(GL_INVALID_VALUE); return parse_error::kParseNoError; @@ -1674,23 +1608,10 @@ parse_error::ParseError GLES2DecoderImpl::HandleTexSubImage2DImmediate( 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); - if (!ValidateGLenumTextureTarget(target)) { - SetGLError(GL_INVALID_VALUE); - return parse_error::kParseNoError; - } - if (!ValidateGLenumTextureFormat(format)) { - SetGLError(GL_INVALID_VALUE); - return parse_error::kParseNoError; - } - if (!ValidateGLenumPixelType(type)) { - SetGLError(GL_INVALID_VALUE); - return parse_error::kParseNoError; - } - if (pixels == NULL) { - return parse_error::kParseOutOfBounds; - } - // Immediate version. + uint32 data_size = GLES2Util::ComputeImageDataSize( + width, height, format, type, unpack_alignment_); + const void* pixels = GetImmediateDataAs<const void*>( + c, data_size, immediate_data_size); if (!ValidateGLenumTextureTarget(target)) { SetGLError(GL_INVALID_VALUE); return parse_error::kParseNoError; @@ -1723,8 +1644,10 @@ parse_error::ParseError GLES2DecoderImpl::HandleUniform1fv( uint32 immediate_data_size, const gles2::Uniform1fv& c) { GLint location = static_cast<GLint>(c.location); GLsizei count = static_cast<GLsizei>(c.count); + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 1); const GLfloat* v = GetSharedMemoryAs<const GLfloat*>( - c.v_shm_id, c.v_shm_offset, 0 /* TODO(gman): size */); + c.v_shm_id, c.v_shm_offset, data_size); if (v == NULL) { return parse_error::kParseOutOfBounds; } @@ -1736,22 +1659,13 @@ parse_error::ParseError GLES2DecoderImpl::HandleUniform1fvImmediate( uint32 immediate_data_size, 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); + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 1); + const GLfloat* v = GetImmediateDataAs<const GLfloat*>( + c, data_size, immediate_data_size); if (v == NULL) { return parse_error::kParseOutOfBounds; } - if (!CheckImmediateDataSize<Uniform1fvImmediate>( - immediate_data_size, count, sizeof(GLfloat), 1)) { - return parse_error::kParseOutOfBounds; - } - // Immediate version. - if (v == NULL) { - return parse_error::kParseOutOfBounds; - } - if (!CheckImmediateDataSize<Uniform1fvImmediate>( - immediate_data_size, count, sizeof(GLfloat), 1)) { - return parse_error::kParseOutOfBounds; - } glUniform1fv(location, count, v); return parse_error::kParseNoError; } @@ -1768,8 +1682,10 @@ parse_error::ParseError GLES2DecoderImpl::HandleUniform1iv( uint32 immediate_data_size, const gles2::Uniform1iv& c) { GLint location = static_cast<GLint>(c.location); GLsizei count = static_cast<GLsizei>(c.count); + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLint), 1); const GLint* v = GetSharedMemoryAs<const GLint*>( - c.v_shm_id, c.v_shm_offset, 0 /* TODO(gman): size */); + c.v_shm_id, c.v_shm_offset, data_size); if (v == NULL) { return parse_error::kParseOutOfBounds; } @@ -1781,22 +1697,13 @@ parse_error::ParseError GLES2DecoderImpl::HandleUniform1ivImmediate( uint32 immediate_data_size, 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); + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLint), 1); + const GLint* v = GetImmediateDataAs<const GLint*>( + c, data_size, immediate_data_size); if (v == NULL) { return parse_error::kParseOutOfBounds; } - if (!CheckImmediateDataSize<Uniform1ivImmediate>( - immediate_data_size, count, sizeof(GLint), 1)) { - return parse_error::kParseOutOfBounds; - } - // Immediate version. - if (v == NULL) { - return parse_error::kParseOutOfBounds; - } - if (!CheckImmediateDataSize<Uniform1ivImmediate>( - immediate_data_size, count, sizeof(GLint), 1)) { - return parse_error::kParseOutOfBounds; - } glUniform1iv(location, count, v); return parse_error::kParseNoError; } @@ -1814,8 +1721,10 @@ parse_error::ParseError GLES2DecoderImpl::HandleUniform2fv( uint32 immediate_data_size, const gles2::Uniform2fv& c) { GLint location = static_cast<GLint>(c.location); GLsizei count = static_cast<GLsizei>(c.count); + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 2); const GLfloat* v = GetSharedMemoryAs<const GLfloat*>( - c.v_shm_id, c.v_shm_offset, 0 /* TODO(gman): size */); + c.v_shm_id, c.v_shm_offset, data_size); if (v == NULL) { return parse_error::kParseOutOfBounds; } @@ -1827,22 +1736,13 @@ parse_error::ParseError GLES2DecoderImpl::HandleUniform2fvImmediate( uint32 immediate_data_size, 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); + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 2); + const GLfloat* v = GetImmediateDataAs<const GLfloat*>( + c, data_size, immediate_data_size); if (v == NULL) { return parse_error::kParseOutOfBounds; } - if (!CheckImmediateDataSize<Uniform2fvImmediate>( - immediate_data_size, count, sizeof(GLfloat), 2)) { - return parse_error::kParseOutOfBounds; - } - // Immediate version. - if (v == NULL) { - return parse_error::kParseOutOfBounds; - } - if (!CheckImmediateDataSize<Uniform2fvImmediate>( - immediate_data_size, count, sizeof(GLfloat), 2)) { - return parse_error::kParseOutOfBounds; - } glUniform2fv(location, count, v); return parse_error::kParseNoError; } @@ -1860,8 +1760,10 @@ parse_error::ParseError GLES2DecoderImpl::HandleUniform2iv( uint32 immediate_data_size, const gles2::Uniform2iv& c) { GLint location = static_cast<GLint>(c.location); GLsizei count = static_cast<GLsizei>(c.count); + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLint), 2); const GLint* v = GetSharedMemoryAs<const GLint*>( - c.v_shm_id, c.v_shm_offset, 0 /* TODO(gman): size */); + c.v_shm_id, c.v_shm_offset, data_size); if (v == NULL) { return parse_error::kParseOutOfBounds; } @@ -1873,22 +1775,13 @@ parse_error::ParseError GLES2DecoderImpl::HandleUniform2ivImmediate( uint32 immediate_data_size, 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); + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLint), 2); + const GLint* v = GetImmediateDataAs<const GLint*>( + c, data_size, immediate_data_size); if (v == NULL) { return parse_error::kParseOutOfBounds; } - if (!CheckImmediateDataSize<Uniform2ivImmediate>( - immediate_data_size, count, sizeof(GLint), 2)) { - return parse_error::kParseOutOfBounds; - } - // Immediate version. - if (v == NULL) { - return parse_error::kParseOutOfBounds; - } - if (!CheckImmediateDataSize<Uniform2ivImmediate>( - immediate_data_size, count, sizeof(GLint), 2)) { - return parse_error::kParseOutOfBounds; - } glUniform2iv(location, count, v); return parse_error::kParseNoError; } @@ -1907,8 +1800,10 @@ parse_error::ParseError GLES2DecoderImpl::HandleUniform3fv( uint32 immediate_data_size, const gles2::Uniform3fv& c) { GLint location = static_cast<GLint>(c.location); GLsizei count = static_cast<GLsizei>(c.count); + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 3); const GLfloat* v = GetSharedMemoryAs<const GLfloat*>( - c.v_shm_id, c.v_shm_offset, 0 /* TODO(gman): size */); + c.v_shm_id, c.v_shm_offset, data_size); if (v == NULL) { return parse_error::kParseOutOfBounds; } @@ -1920,22 +1815,13 @@ parse_error::ParseError GLES2DecoderImpl::HandleUniform3fvImmediate( uint32 immediate_data_size, 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); + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 3); + const GLfloat* v = GetImmediateDataAs<const GLfloat*>( + c, data_size, immediate_data_size); if (v == NULL) { return parse_error::kParseOutOfBounds; } - if (!CheckImmediateDataSize<Uniform3fvImmediate>( - immediate_data_size, count, sizeof(GLfloat), 3)) { - return parse_error::kParseOutOfBounds; - } - // Immediate version. - if (v == NULL) { - return parse_error::kParseOutOfBounds; - } - if (!CheckImmediateDataSize<Uniform3fvImmediate>( - immediate_data_size, count, sizeof(GLfloat), 3)) { - return parse_error::kParseOutOfBounds; - } glUniform3fv(location, count, v); return parse_error::kParseNoError; } @@ -1954,8 +1840,10 @@ parse_error::ParseError GLES2DecoderImpl::HandleUniform3iv( uint32 immediate_data_size, const gles2::Uniform3iv& c) { GLint location = static_cast<GLint>(c.location); GLsizei count = static_cast<GLsizei>(c.count); + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLint), 3); const GLint* v = GetSharedMemoryAs<const GLint*>( - c.v_shm_id, c.v_shm_offset, 0 /* TODO(gman): size */); + c.v_shm_id, c.v_shm_offset, data_size); if (v == NULL) { return parse_error::kParseOutOfBounds; } @@ -1967,22 +1855,13 @@ parse_error::ParseError GLES2DecoderImpl::HandleUniform3ivImmediate( uint32 immediate_data_size, 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); + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLint), 3); + const GLint* v = GetImmediateDataAs<const GLint*>( + c, data_size, immediate_data_size); if (v == NULL) { return parse_error::kParseOutOfBounds; } - if (!CheckImmediateDataSize<Uniform3ivImmediate>( - immediate_data_size, count, sizeof(GLint), 3)) { - return parse_error::kParseOutOfBounds; - } - // Immediate version. - if (v == NULL) { - return parse_error::kParseOutOfBounds; - } - if (!CheckImmediateDataSize<Uniform3ivImmediate>( - immediate_data_size, count, sizeof(GLint), 3)) { - return parse_error::kParseOutOfBounds; - } glUniform3iv(location, count, v); return parse_error::kParseNoError; } @@ -2002,8 +1881,10 @@ parse_error::ParseError GLES2DecoderImpl::HandleUniform4fv( uint32 immediate_data_size, const gles2::Uniform4fv& c) { GLint location = static_cast<GLint>(c.location); GLsizei count = static_cast<GLsizei>(c.count); + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 4); const GLfloat* v = GetSharedMemoryAs<const GLfloat*>( - c.v_shm_id, c.v_shm_offset, 0 /* TODO(gman): size */); + c.v_shm_id, c.v_shm_offset, data_size); if (v == NULL) { return parse_error::kParseOutOfBounds; } @@ -2015,22 +1896,13 @@ parse_error::ParseError GLES2DecoderImpl::HandleUniform4fvImmediate( uint32 immediate_data_size, 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); + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 4); + const GLfloat* v = GetImmediateDataAs<const GLfloat*>( + c, data_size, immediate_data_size); if (v == NULL) { return parse_error::kParseOutOfBounds; } - if (!CheckImmediateDataSize<Uniform4fvImmediate>( - immediate_data_size, count, sizeof(GLfloat), 4)) { - return parse_error::kParseOutOfBounds; - } - // Immediate version. - if (v == NULL) { - return parse_error::kParseOutOfBounds; - } - if (!CheckImmediateDataSize<Uniform4fvImmediate>( - immediate_data_size, count, sizeof(GLfloat), 4)) { - return parse_error::kParseOutOfBounds; - } glUniform4fv(location, count, v); return parse_error::kParseNoError; } @@ -2050,8 +1922,10 @@ parse_error::ParseError GLES2DecoderImpl::HandleUniform4iv( uint32 immediate_data_size, const gles2::Uniform4iv& c) { GLint location = static_cast<GLint>(c.location); GLsizei count = static_cast<GLsizei>(c.count); + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLint), 4); const GLint* v = GetSharedMemoryAs<const GLint*>( - c.v_shm_id, c.v_shm_offset, 0 /* TODO(gman): size */); + c.v_shm_id, c.v_shm_offset, data_size); if (v == NULL) { return parse_error::kParseOutOfBounds; } @@ -2063,22 +1937,13 @@ parse_error::ParseError GLES2DecoderImpl::HandleUniform4ivImmediate( uint32 immediate_data_size, 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); - if (v == NULL) { - return parse_error::kParseOutOfBounds; - } - if (!CheckImmediateDataSize<Uniform4ivImmediate>( - immediate_data_size, count, sizeof(GLint), 4)) { - return parse_error::kParseOutOfBounds; - } - // Immediate version. + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLint), 4); + const GLint* v = GetImmediateDataAs<const GLint*>( + c, data_size, immediate_data_size); if (v == NULL) { return parse_error::kParseOutOfBounds; } - if (!CheckImmediateDataSize<Uniform4ivImmediate>( - immediate_data_size, count, sizeof(GLint), 4)) { - return parse_error::kParseOutOfBounds; - } glUniform4iv(location, count, v); return parse_error::kParseNoError; } @@ -2088,8 +1953,10 @@ parse_error::ParseError GLES2DecoderImpl::HandleUniformMatrix2fv( GLint location = static_cast<GLint>(c.location); GLsizei count = static_cast<GLsizei>(c.count); GLboolean transpose = static_cast<GLboolean>(c.transpose); + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 4); const GLfloat* value = GetSharedMemoryAs<const GLfloat*>( - c.value_shm_id, c.value_shm_offset, 0 /* TODO(gman): size */); + c.value_shm_id, c.value_shm_offset, data_size); if (value == NULL) { return parse_error::kParseOutOfBounds; } @@ -2102,22 +1969,13 @@ parse_error::ParseError GLES2DecoderImpl::HandleUniformMatrix2fvImmediate( 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); + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 4); + const GLfloat* value = GetImmediateDataAs<const GLfloat*>( + c, data_size, immediate_data_size); if (value == NULL) { return parse_error::kParseOutOfBounds; } - if (!CheckImmediateDataSize<UniformMatrix2fvImmediate>( - immediate_data_size, count, sizeof(GLfloat), 4)) { - return parse_error::kParseOutOfBounds; - } - // Immediate version. - if (value == NULL) { - return parse_error::kParseOutOfBounds; - } - if (!CheckImmediateDataSize<UniformMatrix2fvImmediate>( - immediate_data_size, count, sizeof(GLfloat), 4)) { - return parse_error::kParseOutOfBounds; - } glUniformMatrix2fv(location, count, transpose, value); return parse_error::kParseNoError; } @@ -2127,8 +1985,10 @@ parse_error::ParseError GLES2DecoderImpl::HandleUniformMatrix3fv( GLint location = static_cast<GLint>(c.location); GLsizei count = static_cast<GLsizei>(c.count); GLboolean transpose = static_cast<GLboolean>(c.transpose); + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 9); const GLfloat* value = GetSharedMemoryAs<const GLfloat*>( - c.value_shm_id, c.value_shm_offset, 0 /* TODO(gman): size */); + c.value_shm_id, c.value_shm_offset, data_size); if (value == NULL) { return parse_error::kParseOutOfBounds; } @@ -2141,22 +2001,13 @@ parse_error::ParseError GLES2DecoderImpl::HandleUniformMatrix3fvImmediate( 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); + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 9); + const GLfloat* value = GetImmediateDataAs<const GLfloat*>( + c, data_size, immediate_data_size); if (value == NULL) { return parse_error::kParseOutOfBounds; } - if (!CheckImmediateDataSize<UniformMatrix3fvImmediate>( - immediate_data_size, count, sizeof(GLfloat), 9)) { - return parse_error::kParseOutOfBounds; - } - // Immediate version. - if (value == NULL) { - return parse_error::kParseOutOfBounds; - } - if (!CheckImmediateDataSize<UniformMatrix3fvImmediate>( - immediate_data_size, count, sizeof(GLfloat), 9)) { - return parse_error::kParseOutOfBounds; - } glUniformMatrix3fv(location, count, transpose, value); return parse_error::kParseNoError; } @@ -2166,8 +2017,10 @@ parse_error::ParseError GLES2DecoderImpl::HandleUniformMatrix4fv( GLint location = static_cast<GLint>(c.location); GLsizei count = static_cast<GLsizei>(c.count); GLboolean transpose = static_cast<GLboolean>(c.transpose); + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 16); const GLfloat* value = GetSharedMemoryAs<const GLfloat*>( - c.value_shm_id, c.value_shm_offset, 0 /* TODO(gman): size */); + c.value_shm_id, c.value_shm_offset, data_size); if (value == NULL) { return parse_error::kParseOutOfBounds; } @@ -2180,22 +2033,13 @@ parse_error::ParseError GLES2DecoderImpl::HandleUniformMatrix4fvImmediate( 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); + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 16); + const GLfloat* value = GetImmediateDataAs<const GLfloat*>( + c, data_size, immediate_data_size); if (value == NULL) { return parse_error::kParseOutOfBounds; } - if (!CheckImmediateDataSize<UniformMatrix4fvImmediate>( - immediate_data_size, count, sizeof(GLfloat), 16)) { - return parse_error::kParseOutOfBounds; - } - // Immediate version. - if (value == NULL) { - return parse_error::kParseOutOfBounds; - } - if (!CheckImmediateDataSize<UniformMatrix4fvImmediate>( - immediate_data_size, count, sizeof(GLfloat), 16)) { - return parse_error::kParseOutOfBounds; - } glUniformMatrix4fv(location, count, transpose, value); return parse_error::kParseNoError; } @@ -2207,7 +2051,7 @@ parse_error::ParseError GLES2DecoderImpl::HandleUseProgram( SetGLError(GL_INVALID_VALUE); return parse_error::kParseNoError; } - glUseProgram(program); + DoUseProgram(program); return parse_error::kParseNoError; } @@ -2233,8 +2077,10 @@ parse_error::ParseError GLES2DecoderImpl::HandleVertexAttrib1f( parse_error::ParseError GLES2DecoderImpl::HandleVertexAttrib1fv( uint32 immediate_data_size, const gles2::VertexAttrib1fv& c) { GLuint indx = static_cast<GLuint>(c.indx); + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 1); const GLfloat* values = GetSharedMemoryAs<const GLfloat*>( - c.values_shm_id, c.values_shm_offset, 0 /* TODO(gman): size */); + c.values_shm_id, c.values_shm_offset, data_size); if (values == NULL) { return parse_error::kParseOutOfBounds; } @@ -2245,22 +2091,13 @@ parse_error::ParseError GLES2DecoderImpl::HandleVertexAttrib1fv( parse_error::ParseError GLES2DecoderImpl::HandleVertexAttrib1fvImmediate( uint32 immediate_data_size, const gles2::VertexAttrib1fvImmediate& c) { GLuint indx = static_cast<GLuint>(c.indx); - const GLfloat* values = GetImmediateDataAs<const GLfloat*>(c); + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 1); + const GLfloat* values = GetImmediateDataAs<const GLfloat*>( + c, data_size, immediate_data_size); if (values == NULL) { return parse_error::kParseOutOfBounds; } - if (!CheckImmediateDataSize<VertexAttrib1fvImmediate>( - immediate_data_size, 1, sizeof(GLfloat), 1)) { - return parse_error::kParseOutOfBounds; - } - // Immediate version. - if (values == NULL) { - return parse_error::kParseOutOfBounds; - } - if (!CheckImmediateDataSize<VertexAttrib1fvImmediate>( - immediate_data_size, 1, sizeof(GLfloat), 1)) { - return parse_error::kParseOutOfBounds; - } glVertexAttrib1fv(indx, values); return parse_error::kParseNoError; } @@ -2277,8 +2114,10 @@ parse_error::ParseError GLES2DecoderImpl::HandleVertexAttrib2f( parse_error::ParseError GLES2DecoderImpl::HandleVertexAttrib2fv( uint32 immediate_data_size, const gles2::VertexAttrib2fv& c) { GLuint indx = static_cast<GLuint>(c.indx); + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 2); const GLfloat* values = GetSharedMemoryAs<const GLfloat*>( - c.values_shm_id, c.values_shm_offset, 0 /* TODO(gman): size */); + c.values_shm_id, c.values_shm_offset, data_size); if (values == NULL) { return parse_error::kParseOutOfBounds; } @@ -2289,22 +2128,13 @@ parse_error::ParseError GLES2DecoderImpl::HandleVertexAttrib2fv( parse_error::ParseError GLES2DecoderImpl::HandleVertexAttrib2fvImmediate( uint32 immediate_data_size, const gles2::VertexAttrib2fvImmediate& c) { GLuint indx = static_cast<GLuint>(c.indx); - const GLfloat* values = GetImmediateDataAs<const GLfloat*>(c); + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 2); + const GLfloat* values = GetImmediateDataAs<const GLfloat*>( + c, data_size, immediate_data_size); if (values == NULL) { return parse_error::kParseOutOfBounds; } - if (!CheckImmediateDataSize<VertexAttrib2fvImmediate>( - immediate_data_size, 1, sizeof(GLfloat), 2)) { - return parse_error::kParseOutOfBounds; - } - // Immediate version. - if (values == NULL) { - return parse_error::kParseOutOfBounds; - } - if (!CheckImmediateDataSize<VertexAttrib2fvImmediate>( - immediate_data_size, 1, sizeof(GLfloat), 2)) { - return parse_error::kParseOutOfBounds; - } glVertexAttrib2fv(indx, values); return parse_error::kParseNoError; } @@ -2322,8 +2152,10 @@ parse_error::ParseError GLES2DecoderImpl::HandleVertexAttrib3f( parse_error::ParseError GLES2DecoderImpl::HandleVertexAttrib3fv( uint32 immediate_data_size, const gles2::VertexAttrib3fv& c) { GLuint indx = static_cast<GLuint>(c.indx); + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 3); const GLfloat* values = GetSharedMemoryAs<const GLfloat*>( - c.values_shm_id, c.values_shm_offset, 0 /* TODO(gman): size */); + c.values_shm_id, c.values_shm_offset, data_size); if (values == NULL) { return parse_error::kParseOutOfBounds; } @@ -2334,22 +2166,13 @@ parse_error::ParseError GLES2DecoderImpl::HandleVertexAttrib3fv( parse_error::ParseError GLES2DecoderImpl::HandleVertexAttrib3fvImmediate( uint32 immediate_data_size, const gles2::VertexAttrib3fvImmediate& c) { GLuint indx = static_cast<GLuint>(c.indx); - const GLfloat* values = GetImmediateDataAs<const GLfloat*>(c); + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 3); + const GLfloat* values = GetImmediateDataAs<const GLfloat*>( + c, data_size, immediate_data_size); if (values == NULL) { return parse_error::kParseOutOfBounds; } - if (!CheckImmediateDataSize<VertexAttrib3fvImmediate>( - immediate_data_size, 1, sizeof(GLfloat), 3)) { - return parse_error::kParseOutOfBounds; - } - // Immediate version. - if (values == NULL) { - return parse_error::kParseOutOfBounds; - } - if (!CheckImmediateDataSize<VertexAttrib3fvImmediate>( - immediate_data_size, 1, sizeof(GLfloat), 3)) { - return parse_error::kParseOutOfBounds; - } glVertexAttrib3fv(indx, values); return parse_error::kParseNoError; } @@ -2368,8 +2191,10 @@ parse_error::ParseError GLES2DecoderImpl::HandleVertexAttrib4f( parse_error::ParseError GLES2DecoderImpl::HandleVertexAttrib4fv( uint32 immediate_data_size, const gles2::VertexAttrib4fv& c) { GLuint indx = static_cast<GLuint>(c.indx); + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 4); const GLfloat* values = GetSharedMemoryAs<const GLfloat*>( - c.values_shm_id, c.values_shm_offset, 0 /* TODO(gman): size */); + c.values_shm_id, c.values_shm_offset, data_size); if (values == NULL) { return parse_error::kParseOutOfBounds; } @@ -2380,22 +2205,13 @@ parse_error::ParseError GLES2DecoderImpl::HandleVertexAttrib4fv( parse_error::ParseError GLES2DecoderImpl::HandleVertexAttrib4fvImmediate( uint32 immediate_data_size, const gles2::VertexAttrib4fvImmediate& c) { GLuint indx = static_cast<GLuint>(c.indx); - const GLfloat* values = GetImmediateDataAs<const GLfloat*>(c); + uint32 data_size = + ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 4); + const GLfloat* values = GetImmediateDataAs<const GLfloat*>( + c, data_size, immediate_data_size); if (values == NULL) { return parse_error::kParseOutOfBounds; } - if (!CheckImmediateDataSize<VertexAttrib4fvImmediate>( - immediate_data_size, 1, sizeof(GLfloat), 4)) { - return parse_error::kParseOutOfBounds; - } - // Immediate version. - if (values == NULL) { - return parse_error::kParseOutOfBounds; - } - if (!CheckImmediateDataSize<VertexAttrib4fvImmediate>( - immediate_data_size, 1, sizeof(GLfloat), 4)) { - return parse_error::kParseOutOfBounds; - } glVertexAttrib4fv(indx, values); return parse_error::kParseNoError; } |