summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xgpu/command_buffer/build_gles2_cmd_buffer.py179
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc648
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_autogen.h610
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;
}