Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2261)

Unified Diff: gpu/command_buffer/build_gles2_cmd_buffer.py

Issue 863253002: Update from https://crrev.com/312600 (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: gpu/command_buffer/build_gles2_cmd_buffer.py
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py
index 38cbb494e9f7316ae51ad0f02dce7a7c26bf5107..922c1f9488ae28991361e313a3fd3e92d75b142d 100755
--- a/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -1368,6 +1368,27 @@ _NAMED_TYPE_INFO = {
'GL_UNKNOWN_CONTEXT_RESET_ARB',
],
},
+ 'SyncCondition': {
+ 'type': 'GLenum',
+ 'is_complete': True,
+ 'valid': [
+ #TODO(zmo): avoid using the direct number.
+ '0x9117', # GL_SYNC_GPU_COMMANDS_COMPLETE
+ ],
+ 'invalid': [
+ '0',
+ ],
+ },
+ 'SyncFlags': {
+ 'type': 'GLbitfield',
+ 'is_complete': True,
+ 'valid': [
+ '0',
+ ],
+ 'invalid': [
+ '1',
+ ],
+ },
}
# This table specifies the different pepper interfaces that are supported for
@@ -1815,7 +1836,7 @@ _FUNCTION_INFO = {
'resource_type': 'Framebuffer',
'resource_types': 'Framebuffers',
},
- 'DeleteProgram': {'type': 'Delete', 'decoder_func': 'DoDeleteProgram'},
+ 'DeleteProgram': { 'type': 'Delete' },
'DeleteRenderbuffers': {
'type': 'DELn',
'gl_test_func': 'glDeleteRenderbuffersEXT',
@@ -1828,7 +1849,13 @@ _FUNCTION_INFO = {
'resource_types': 'Samplers',
'unsafe': True,
},
- 'DeleteShader': {'type': 'Delete', 'decoder_func': 'DoDeleteShader'},
+ 'DeleteShader': { 'type': 'Delete' },
+ 'DeleteSync': {
+ 'type': 'Delete',
+ 'cmd_args': 'GLuint sync',
+ 'resource_type': 'Sync',
+ 'unsafe': True,
+ },
'DeleteTextures': {
'type': 'DELn',
'resource_type': 'Texture',
@@ -1883,6 +1910,11 @@ _FUNCTION_INFO = {
'decoder_func': 'DoEnableVertexAttribArray',
'impl_decl': False,
},
+ 'FenceSync': {
+ 'type': 'Create',
+ 'client_test': False,
+ 'unsafe': True,
+ },
'Finish': {
'impl_func': False,
'client_test': False,
@@ -2209,6 +2241,7 @@ _FUNCTION_INFO = {
'IsEnabled': {
'type': 'Is',
'decoder_func': 'DoIsEnabled',
+ 'client_test': False,
'impl_func': False,
'expectation': False,
},
@@ -2238,6 +2271,13 @@ _FUNCTION_INFO = {
'expectation': False,
'unsafe': True,
},
+ 'IsSync': {
+ 'type': 'Is',
+ 'id_mapping': [ 'Sync' ],
+ 'cmd_args': 'GLuint sync',
+ 'expectation': False,
+ 'unsafe': True,
+ },
'IsTexture': {
'type': 'Is',
'decoder_func': 'DoIsTexture',
@@ -2398,12 +2438,12 @@ _FUNCTION_INFO = {
'client_test': False,
},
'ShaderSource': {
- 'type': 'Manual',
+ 'type': 'PUTSTR',
+ 'decoder_func': 'DoShaderSource',
'data_transfer_methods': ['bucket'],
- 'needs_size': True,
'client_test': False,
'cmd_args':
- 'GLuint shader, const char* data',
+ 'GLuint shader, const char** str',
'pepper_args':
'GLuint shader, GLsizei count, const char** str, const GLint* length',
},
@@ -3383,17 +3423,23 @@ static_assert(offsetof(%(cmd_name)s::Result, %(field_name)s) == %(offset)d,
file.Write(" // TODO(gman): Compute correct size.\n")
file.Write(" EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);\n")
+ def __WriteIdMapping(self, func, file):
+ """Writes client side / service side ID mapping."""
+ if not func.IsUnsafe() or not func.GetInfo('id_mapping'):
+ return
+ for id_type in func.GetInfo('id_mapping'):
+ file.Write(" group_->Get%sServiceId(%s, &%s);\n" %
+ (id_type, id_type.lower(), id_type.lower()))
+
def WriteImmediateHandlerImplementation (self, func, file):
"""Writes the handler impl for the immediate version of a command."""
- if func.IsUnsafe() and func.GetInfo('id_mapping'):
- for id_type in func.GetInfo('id_mapping'):
- file.Write(" group_->Get%sServiceId(%s, &%s);\n" %
- (id_type, id_type.lower(), id_type.lower()))
+ self.__WriteIdMapping(func, file)
file.Write(" %s(%s);\n" %
(func.GetGLFunctionName(), func.MakeOriginalArgString("")))
def WriteBucketHandlerImplementation (self, func, file):
"""Writes the handler impl for the bucket version of a command."""
+ self.__WriteIdMapping(func, file)
file.Write(" %s(%s);\n" %
(func.GetGLFunctionName(), func.MakeOriginalArgString("")))
@@ -3449,9 +3495,7 @@ static_assert(offsetof(%(cmd_name)s::Result, %(field_name)s) == %(offset)d,
self.WriteServiceHandlerFunctionHeader(func, file)
self.WriteHandlerExtensionCheck(func, file)
self.WriteHandlerDeferReadWrite(func, file);
- for arg in func.GetOriginalArgs():
- if arg.IsPointer():
- self.WriteGetDataSizeCode(func, file)
+ for arg in func.GetCmdArgs():
arg.WriteGetCode(file)
func.WriteHandlerValidation(file)
func.WriteHandlerImplementation(file)
@@ -4252,10 +4296,6 @@ class HandWrittenHandler(CustomHandler):
"""Overrriden from TypeHandler."""
pass
- def WriteBucketCmdHelper(self, func, file):
- """Overrriden from TypeHandler."""
- pass
-
def WriteCmdHelper(self, func, file):
"""Overrriden from TypeHandler."""
pass
@@ -4942,26 +4982,61 @@ class CreateHandler(TypeHandler):
"""Overrriden from TypeHandler."""
func.AddCmdArg(Argument("client_id", 'uint32_t'))
+ def __GetResourceType(self, func):
+ if func.return_type == "GLsync":
+ return "Sync"
+ else:
+ return func.name[6:] # Create*
+
def WriteServiceUnitTest(self, func, file, *extras):
"""Overrriden from TypeHandler."""
valid_test = """
TEST_P(%(test_name)s, %(name)sValidArgs) {
- EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s))
- .WillOnce(Return(kNewServiceId));
+ %(id_type_cast)sEXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s))
+ .WillOnce(Return(%(const_service_id)s));
SpecializedSetup<cmds::%(name)s, 0>(true);
cmds::%(name)s cmd;
- cmd.Init(%(args)s%(comma)skNewClientId);
+ cmd.Init(%(args)s%(comma)skNewClientId);"""
+ if func.IsUnsafe():
+ valid_test += """
+ decoder_->set_unsafe_es3_apis_enabled(true);"""
+ valid_test += """
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
- EXPECT_EQ(GL_NO_ERROR, GetGLError());
- EXPECT_TRUE(Get%(resource_type)s(kNewClientId) != NULL);
+ EXPECT_EQ(GL_NO_ERROR, GetGLError());"""
+ if func.IsUnsafe():
+ valid_test += """
+ %(return_type)s service_id = 0;
+ EXPECT_TRUE(Get%(resource_type)sServiceId(kNewClientId, &service_id));
+ EXPECT_EQ(%(const_service_id)s, service_id);
+ decoder_->set_unsafe_es3_apis_enabled(false);
+ EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
+}
+"""
+ else:
+ valid_test += """
+ EXPECT_TRUE(Get%(resource_type)s(kNewClientId));
}
"""
comma = ""
- if len(func.GetOriginalArgs()):
- comma =", "
+ cmd_arg_count = 0
+ for arg in func.GetOriginalArgs():
+ if not arg.IsConstant():
+ cmd_arg_count += 1
+ if cmd_arg_count:
+ comma = ", "
+ if func.return_type == 'GLsync':
+ id_type_cast = ("const GLsync kNewServiceIdGLuint = reinterpret_cast"
+ "<GLsync>(kNewServiceId);\n ")
+ const_service_id = "kNewServiceIdGLuint"
+ else:
+ id_type_cast = ""
+ const_service_id = "kNewServiceId"
self.WriteValidUnitTest(func, file, valid_test, {
'comma': comma,
- 'resource_type': func.name[6:],
+ 'resource_type': self.__GetResourceType(func),
+ 'return_type': func.return_type,
+ 'id_type_cast': id_type_cast,
+ 'const_service_id': const_service_id,
}, *extras)
invalid_test = """
TEST_P(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
@@ -4978,11 +5053,33 @@ TEST_P(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
def WriteHandlerImplementation (self, func, file):
"""Overrriden from TypeHandler."""
- file.Write(" uint32_t client_id = c.client_id;\n")
- file.Write(" if (!%sHelper(%s)) {\n" %
- (func.name, func.MakeCmdArgString("")))
- file.Write(" return error::kInvalidArguments;\n")
- file.Write(" }\n")
+ if func.IsUnsafe():
+ code = """ uint32_t client_id = c.client_id;
+ %(return_type)s service_id = 0;
+ if (group_->Get%(resource_name)sServiceId(client_id, &service_id)) {
+ return error::kInvalidArguments;
+ }
+ service_id = %(gl_func_name)s(%(gl_args)s);
+ if (service_id) {
+ group_->Add%(resource_name)sId(client_id, service_id);
+ }
+"""
+ else:
+ code = """ uint32_t client_id = c.client_id;
+ if (Get%(resource_name)s(client_id)) {
+ return error::kInvalidArguments;
+ }
+ %(return_type)s service_id = %(gl_func_name)s(%(gl_args)s);
+ if (service_id) {
+ Create%(resource_name)s(client_id, service_id%(gl_args_with_comma)s);
+ }
+"""
+ file.Write(code % {
+ 'resource_name': self.__GetResourceType(func),
+ 'return_type': func.return_type,
+ 'gl_func_name': func.GetGLFunctionName(),
+ 'gl_args': func.MakeOriginalArgString(""),
+ 'gl_args_with_comma': func.MakeOriginalArgString("", True) })
def WriteGLES2Implementation(self, func, file):
"""Overrriden from TypeHandler."""
@@ -4995,14 +5092,21 @@ TEST_P(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
for arg in func.GetOriginalArgs():
arg.WriteClientSideValidationCode(file, func)
file.Write(" GLuint client_id;\n")
- file.Write(
- " GetIdHandler(id_namespaces::kProgramsAndShaders)->\n")
+ if func.return_type == "GLsync":
+ file.Write(
+ " GetIdHandler(id_namespaces::kSyncs)->\n")
+ else:
+ file.Write(
+ " GetIdHandler(id_namespaces::kProgramsAndShaders)->\n")
file.Write(" MakeIds(this, 0, 1, &client_id);\n")
file.Write(" helper_->%s(%s);\n" %
(func.name, func.MakeCmdArgString("")))
file.Write(' GPU_CLIENT_LOG("returned " << client_id);\n')
file.Write(" CheckGLError();\n")
- file.Write(" return client_id;\n")
+ if func.return_type == "GLsync":
+ file.Write(" return reinterpret_cast<GLsync>(client_id);\n")
+ else:
+ file.Write(" return client_id;\n")
file.Write("}\n")
file.Write("\n")
@@ -5015,6 +5119,9 @@ class DeleteHandler(TypeHandler):
def WriteServiceImplementation(self, func, file):
"""Overrriden from TypeHandler."""
+ if func.IsUnsafe():
+ TypeHandler.WriteServiceImplementation(self, func, file)
+ # HandleDeleteShader and HandleDeleteProgram are manually written.
pass
def WriteGLES2Implementation(self, func, file):
@@ -5035,6 +5142,25 @@ class DeleteHandler(TypeHandler):
file.Write("}\n")
file.Write("\n")
+ def WriteHandlerImplementation (self, func, file):
+ """Overrriden from TypeHandler."""
+ assert len(func.GetOriginalArgs()) == 1
+ arg = func.GetOriginalArgs()[0]
+ if func.IsUnsafe():
+ file.Write(""" %(arg_type)s service_id = 0;
+ if (group_->Get%(resource_type)sServiceId(%(arg_name)s, &service_id)) {
+ glDelete%(resource_type)s(service_id);
+ group_->Remove%(resource_type)sId(%(arg_name)s);
+ } else {
+ LOCAL_SET_GL_ERROR(
+ GL_INVALID_VALUE, "gl%(func_name)s", "unknown %(arg_name)s");
+ }
+""" % { 'resource_type': func.GetInfo('resource_type'),
+ 'arg_name': arg.name,
+ 'arg_type': arg.type,
+ 'func_name': func.original_name })
+ else:
+ file.Write(" %sHelper(%s);\n" % (func.original_name, arg.name))
class DELnHandler(TypeHandler):
"""Handler for glDelete___ type functions."""
@@ -6227,6 +6353,160 @@ TEST_F(GLES2ImplementationTest, %(name)sInvalidConstantArg%(invalid_index)d) {
file.Write("}\n")
file.Write("\n")
+class PUTSTRHandler(ArrayArgTypeHandler):
+ """Handler for functions that pass a string array."""
+
+ def __init__(self):
+ ArrayArgTypeHandler.__init__(self)
+
+ def __GetDataArg(self, func):
+ """Return the argument that points to the 2D char arrays"""
+ for arg in func.GetOriginalArgs():
+ if arg.IsPointer2D():
+ return arg
+ return None
+
+ def __GetLengthArg(self, func):
+ """Return the argument that holds length for each char array"""
+ for arg in func.GetOriginalArgs():
+ if arg.IsPointer() and not arg.IsPointer2D():
+ return arg
+ return None
+
+ def WriteGLES2Implementation(self, func, file):
+ """Overrriden from TypeHandler."""
+ file.Write("%s GLES2Implementation::%s(%s) {\n" %
+ (func.return_type, func.original_name,
+ func.MakeTypedOriginalArgString("")))
+ file.Write(" GPU_CLIENT_SINGLE_THREAD_CHECK();\n")
+ func.WriteDestinationInitalizationValidation(file)
+ self.WriteClientGLCallLog(func, file)
+ data_arg = self.__GetDataArg(func)
+ length_arg = self.__GetLengthArg(func)
+ log_code_block = """ GPU_CLIENT_LOG_CODE_BLOCK({
+ for (GLsizei ii = 0; ii < count; ++ii) {
+ if (%(data)s[ii]) {"""
+ if length_arg == None:
+ log_code_block += """
+ GPU_CLIENT_LOG(" " << ii << ": ---\\n" << %(data)s[ii] << "\\n---");"""
+ else:
+ log_code_block += """
+ if (%(length)s && %(length)s[ii] >= 0) {
+ const std::string my_str(%(data)s[ii], %(length)s[ii]);
+ GPU_CLIENT_LOG(" " << ii << ": ---\\n" << my_str << "\\n---");
+ } else {
+ GPU_CLIENT_LOG(" " << ii << ": ---\\n" << %(data)s[ii] << "\\n---");
+ }"""
+ log_code_block += """
+ } else {
+ GPU_CLIENT_LOG(" " << ii << ": NULL");
+ }
+ }
+ });
+"""
+ file.Write(log_code_block % {
+ 'data': data_arg.name,
+ 'length': length_arg.name if not length_arg == None else ''
+ })
+ for arg in func.GetOriginalArgs():
+ arg.WriteClientSideValidationCode(file, func)
+ size_code_block = """ // Compute the total size.
+ base::CheckedNumeric<size_t> total_size = count;
+ total_size += 1;
+ total_size *= sizeof(GLint);
+ if (!total_size.IsValid()) {
+ SetGLError(GL_INVALID_VALUE, "glShaderSource", "overflow");
+ return;
+ }
+ size_t header_size = total_size.ValueOrDefault(0);
+ std::vector<GLint> header(count + 1);
+ header[0] = static_cast<GLint>(count);
+ for (GLsizei ii = 0; ii < count; ++ii) {
+ GLint len = 0;
+ if (%(data)s[ii]) {"""
+ if length_arg == None:
+ size_code_block += """
+ len = base::static_cast<GLint>(strlen(%(data)s[ii]));"""
+ else:
+ size_code_block += """
+ len = (%(length)s && %(length)s[ii] >= 0) ?
+ %(length)s[ii] : base::checked_cast<GLint>(strlen(%(data)s[ii]));"""
+ size_code_block += """
+ }
+ total_size += len;
+ total_size += 1; // NULL at the end of each char array.
+ if (!total_size.IsValid()) {
+ SetGLError(GL_INVALID_VALUE, "glShaderSource", "overflow");
+ return;
+ }
+ header[ii + 1] = len;
+}
+"""
+ file.Write(size_code_block % {
+ 'data': data_arg.name,
+ 'length': length_arg.name if not length_arg == None else ''
+ })
+ data_code_block = """ // Pack data into a bucket on the service.
+ helper_->SetBucketSize(kResultBucketId, total_size.ValueOrDefault(0));
+ size_t offset = 0;
+ for (GLsizei ii = 0; ii <= count; ++ii) {
+ const char* src = (ii == 0) ? reinterpret_cast<const char*>(&header[0]) :
+ %(data)s[ii - 1];
+ base::CheckedNumeric<size_t> checked_size = (ii == 0) ? header_size :
+ static_cast<size_t>(header[ii]);
+ if (ii > 0) {
+ checked_size += 1; // NULL in the end.
+ }
+ if (!checked_size.IsValid()) {
+ SetGLError(GL_INVALID_VALUE, "glShaderSource", "overflow");
+ return;
+ }
+ size_t size = checked_size.ValueOrDefault(0);
+ while (size) {
+ ScopedTransferBufferPtr buffer(size, helper_, transfer_buffer_);
+ if (!buffer.valid() || buffer.size() == 0) {
+ SetGLError(GL_OUT_OF_MEMORY, "glShaderSource", "too large");
+ return;
+ }
+ size_t copy_size = buffer.size();
+ if (ii > 0 && buffer.size() == size)
+ --copy_size;
+ if (copy_size)
+ memcpy(buffer.address(), src, copy_size);
+ if (copy_size < buffer.size()) {
+ // Append NULL in the end.
+ DCHECK(copy_size + 1 == buffer.size());
+ char* str = reinterpret_cast<char*>(buffer.address());
+ str[copy_size] = 0;
+ }
+ helper_->SetBucketData(kResultBucketId, offset, buffer.size(),
+ buffer.shm_id(), buffer.offset());
+ offset += buffer.size();
+ src += buffer.size();
+ size -= buffer.size();
+ }
+ }
+ DCHECK_EQ(total_size.ValueOrDefault(0), offset);
+"""
+ file.Write(data_code_block % {
+ 'data': data_arg.name,
+ 'length': length_arg.name if not length_arg == None else ''
+ })
+ bucket_cmd_arg_string = ""
+ for arg in func.GetCmdArgs()[0:-2]:
+ if bucket_cmd_arg_string:
+ bucket_cmd_arg_string += ", "
+ bucket_cmd_arg_string += arg.name
+ if bucket_cmd_arg_string:
+ bucket_cmd_arg_string += ", "
+ bucket_cmd_arg_string += 'kResultBucketId'
+ file.Write(" helper_->%sBucket(%s);\n" %
+ (func.name, bucket_cmd_arg_string))
+ file.Write(" helper_->SetBucketSize(kResultBucketId, 0);");
+ file.Write(" CheckGLError();\n")
+ file.Write("}\n")
+ file.Write("\n")
+
class PUTXnHandler(ArrayArgTypeHandler):
"""Handler for glUniform?f functions."""
@@ -6561,8 +6841,10 @@ TEST_P(%(test_name)s, %(name)sInvalidArgsBadSharedMemoryId) {
if func.IsUnsafe():
assert func.GetInfo('id_mapping')
assert len(func.GetInfo('id_mapping')) == 1
+ assert len(args) == 1
id_type = func.GetInfo('id_mapping')[0]
- file.Write(" *result_dst = group_->Get%sServiceId(%s, &%s);\n" %
+ file.Write(" %s service_%s = 0;\n" % (args[0].type, id_type.lower()))
+ file.Write(" *result_dst = group_->Get%sServiceId(%s, &service_%s);\n" %
(id_type, id_type.lower(), id_type.lower()))
else:
file.Write(" *result_dst = %s(%s);\n" %
@@ -6589,13 +6871,15 @@ TEST_P(%(test_name)s, %(name)sInvalidArgsBadSharedMemoryId) {
file.Write(" return %s;\n" % error_value)
file.Write(" }\n")
file.Write(" *result = 0;\n")
- arg_string = func.MakeOriginalArgString("")
- comma = ""
- if len(arg_string) > 0:
- comma = ", "
+ assert len(func.GetOriginalArgs()) == 1
+ id_arg = func.GetOriginalArgs()[0]
+ if id_arg.type == 'GLsync':
+ arg_string = "ToGLuint(%s)" % func.MakeOriginalArgString("")
+ else:
+ arg_string = func.MakeOriginalArgString("")
file.Write(
- " helper_->%s(%s%sGetResultShmId(), GetResultShmOffset());\n" %
- (func.name, arg_string, comma))
+ " helper_->%s(%s, GetResultShmId(), GetResultShmOffset());\n" %
+ (func.name, arg_string))
file.Write(" WaitForCmd();\n")
file.Write(" %s result_value = *result" % func.return_type)
if func.return_type == "GLboolean":
@@ -6619,20 +6903,23 @@ TEST_F(GLES2ImplementationTest, %(name)s) {
Cmds expected;
ExpectedMemoryInfo result1 =
GetExpectedResultMemory(sizeof(cmds::%(name)s::Result));
- expected.cmd.Init(1, result1.id, result1.offset);
+ expected.cmd.Init(%(cmd_id_value)s, result1.id, result1.offset);
EXPECT_CALL(*command_buffer(), OnFlush())
- .WillOnce(SetMemory(result1.ptr, uint32_t(1)))
+ .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE)))
.RetiresOnSaturation();
- GLboolean result = gl_->%(name)s(1);
+ GLboolean result = gl_->%(name)s(%(gl_id_value)s);
EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
EXPECT_TRUE(result);
}
"""
+ args = func.GetOriginalArgs()
+ assert len(args) == 1
file.Write(code % {
- 'name': func.name,
- })
+ 'name': func.name,
+ 'cmd_id_value': args[0].GetValidClientSideCmdArg(func),
+ 'gl_id_value': args[0].GetValidClientSideArg(func) })
class STRnHandler(TypeHandler):
@@ -6823,6 +7110,10 @@ class Argument(object):
"""Returns true if argument is a pointer."""
return False
+ def IsPointer2D(self):
+ """Returns true if argument is a 2D pointer."""
+ return False
+
def IsConstant(self):
"""Returns true if the argument has only one valid value."""
return False
@@ -6853,6 +7144,8 @@ class Argument(object):
return valid_arg
index = func.GetOriginalArgs().index(self)
+ if self.type == 'GLsync':
+ return ("reinterpret_cast<GLsync>(%d)" % (index + 1))
return str(index + 1)
def GetValidClientSideCmdArg(self, func):
@@ -6870,7 +7163,10 @@ class Argument(object):
def GetValidGLArg(self, func):
"""Gets a valid GL value for this argument."""
- return self.GetValidArg(func)
+ value = self.GetValidArg(func)
+ if self.type == 'GLsync':
+ return ("reinterpret_cast<GLsync>(%s)" % value)
+ return value
def GetValidNonCachedClientSideArg(self, func):
"""Returns a valid value for this argument in a GL call.
@@ -6903,8 +7199,12 @@ class Argument(object):
def WriteGetCode(self, file):
"""Writes the code to get an argument from a command structure."""
+ if self.type == 'GLsync':
+ my_type = 'GLuint'
+ else:
+ my_type = self.type
file.Write(" %s %s = static_cast<%s>(c.%s);\n" %
- (self.type, self.name, self.type, self.name))
+ (my_type, self.name, my_type, self.name))
def WriteValidationCode(self, file, func):
"""Writes the validation code for an argument."""
@@ -7038,7 +7338,8 @@ class SizeNotNegativeArgument(SizeArgument):
class EnumBaseArgument(Argument):
- """Base class for EnumArgument, IntArgument and ValidatedBoolArgument"""
+ """Base class for EnumArgument, IntArgument, BitfieldArgument, and
+ ValidatedBoolArgument."""
def __init__(self, name, gl_type, type, gl_error):
Argument.__init__(self, name, gl_type)
@@ -7154,7 +7455,7 @@ class EnumArgument(EnumBaseArgument):
class IntArgument(EnumBaseArgument):
- """A class for a GLint argument that can only except specific values.
+ """A class for a GLint argument that can only accept specific values.
For example glTexImage2D takes a GLint for its internalformat
argument instead of a GLenum.
@@ -7165,7 +7466,7 @@ class IntArgument(EnumBaseArgument):
class ValidatedBoolArgument(EnumBaseArgument):
- """A class for a GLboolean argument that can only except specific values.
+ """A class for a GLboolean argument that can only accept specific values.
For example glUniformMatrix takes a GLboolean for it's transpose but it
must be false.
@@ -7179,6 +7480,18 @@ class ValidatedBoolArgument(EnumBaseArgument):
return 'GLES2Util::GetStringBool(%s)' % self.name
+class BitFieldArgument(EnumBaseArgument):
+ """A class for a GLbitfield argument that can only accept specific values.
+
+ For example glFenceSync takes a GLbitfield for its flags argument bit it
+ must be 0.
+ """
+
+ def __init__(self, name, type):
+ EnumBaseArgument.__init__(self, name, "GLbitfield", type,
+ "GL_INVALID_VALUE")
+
+
class ImmediatePointerArgument(Argument):
"""A class that represents an immediate argument to a function.
@@ -7269,6 +7582,10 @@ class PointerArgument(Argument):
"""Returns true if argument is a pointer."""
return True
+ def IsPointer2D(self):
+ """Returns true if argument is a 2D pointer."""
+ return self.type.count('*') == 2
+
def GetPointedType(self):
match = re.match('(const\s+)?(?P<element_type>[\w]+)\s*\*', self.type)
assert match
@@ -7333,7 +7650,9 @@ class PointerArgument(Argument):
def GetBucketVersion(self):
"""Overridden from Argument."""
- if self.type == "const char*":
+ if self.type.find('char') >= 0:
+ if self.IsPointer2D():
+ return InputStringArrayBucketArgument(self.name, self.type)
return InputStringBucketArgument(self.name, self.type)
return BucketPointerArgument(self.name, self.type)
@@ -7343,26 +7662,68 @@ class PointerArgument(Argument):
class InputStringBucketArgument(Argument):
- """An string input argument where the string is passed in a bucket."""
+ """A string input argument where the string is passed in a bucket."""
+
+ def __init__(self, name, type):
+ Argument.__init__(self, name + "_bucket_id", "uint32_t")
+
+
+class InputStringArrayBucketArgument(Argument):
+ """A string array input argument where the strings are passed in a bucket."""
def __init__(self, name, type):
Argument.__init__(self, name + "_bucket_id", "uint32_t")
+ self._original_name = name
def WriteGetCode(self, file):
"""Overridden from Argument."""
code = """
- Bucket* %(name)s_bucket = GetBucket(c.%(name)s);
- if (!%(name)s_bucket) {
+ const size_t kMinBucketSize = sizeof(GLint);
+ // Each string has at least |length| in the header and a NUL character.
+ const size_t kMinStringSize = sizeof(GLint) + 1;
+ Bucket* bucket = GetBucket(c.%(name)s);
+ if (!bucket) {
+ return error::kInvalidArguments;
+ }
+ const size_t bucket_size = bucket->size();
+ if (bucket_size < kMinBucketSize) {
+ return error::kInvalidArguments;
+ }
+ const char* bucket_data = bucket->GetDataAs<const char*>(0, bucket_size);
+ const GLint* header = reinterpret_cast<const GLint*>(bucket_data);
+ GLsizei count = static_cast<GLsizei>(header[0]);
+ if (count < 0) {
return error::kInvalidArguments;
}
- std::string %(name)s_str;
- if (!%(name)s_bucket->GetAsString(&%(name)s_str)) {
+ const size_t max_count = (bucket_size - kMinBucketSize) / kMinStringSize;
+ if (max_count < static_cast<size_t>(count)) {
+ return error::kInvalidArguments;
+ }
+ const GLint* length = header + 1;
+ scoped_ptr<const char*[]> strs;
+ if (count > 0)
+ strs.reset(new const char*[count]);
+ const char** %(original_name)s = strs.get();
+ base::CheckedNumeric<size_t> total_size = sizeof(GLint);
+ total_size *= count + 1; // Header size.
+ if (!total_size.IsValid())
+ return error::kInvalidArguments;
+ for (GLsizei ii = 0; ii < count; ++ii) {
+ %(original_name)s[ii] = bucket_data + total_size.ValueOrDefault(0);
+ total_size += length[ii];
+ total_size += 1; // NUL char at the end of each char array.
+ if (!total_size.IsValid() || total_size.ValueOrDefault(0) > bucket_size ||
+ %(original_name)s[ii][length[ii]] != 0) {
+ return error::kInvalidArguments;
+ }
+ }
+ if (total_size.ValueOrDefault(0) != bucket_size) {
return error::kInvalidArguments;
}
- const char* %(name)s = %(name)s_str.c_str();
"""
file.Write(code % {
'name': self.name,
+ 'original_name': self._original_name,
})
def GetValidArg(self, func):
@@ -7378,17 +7739,26 @@ class ResourceIdArgument(Argument):
def __init__(self, name, type):
match = re.match("(GLid\w+)", type)
self.resource_type = match.group(1)[4:]
- type = type.replace(match.group(1), "GLuint")
+ if self.resource_type == "Sync":
+ type = type.replace(match.group(1), "GLsync")
+ else:
+ type = type.replace(match.group(1), "GLuint")
Argument.__init__(self, name, type)
def WriteGetCode(self, file):
"""Overridden from Argument."""
- file.Write(" %s %s = c.%s;\n" % (self.type, self.name, self.name))
+ if self.type == "GLsync":
+ my_type = "GLuint"
+ else:
+ my_type = self.type
+ file.Write(" %s %s = c.%s;\n" % (my_type, self.name, self.name))
def GetValidArg(self, func):
return "client_%s_id_" % self.resource_type.lower()
def GetValidGLArg(self, func):
+ if self.resource_type == "Sync":
+ return "reinterpret_cast<GLsync>(kService%sId)" % self.resource_type
return "kService%sId" % self.resource_type
@@ -7462,6 +7832,7 @@ class Function(object):
'Manual': ManualHandler(),
'PUT': PUTHandler(),
'PUTn': PUTnHandler(),
+ 'PUTSTR': PUTSTRHandler(),
'PUTXn': PUTXnHandler(),
'StateSet': StateSetHandler(),
'StateSetRGBAlpha': StateSetRGBAlphaHandler(),
@@ -7653,7 +8024,7 @@ class Function(object):
return arg
return None
- def __MaybePrependComma(self, arg_string, add_comma):
+ def _MaybePrependComma(self, arg_string, add_comma):
"""Adds a comma if arg_string is not empty and add_comma is true."""
comma = ""
if add_comma and len(arg_string):
@@ -7665,14 +8036,14 @@ class Function(object):
args = self.GetOriginalArgs()
arg_string = ", ".join(
["%s %s%s" % (arg.type, prefix, arg.name) for arg in args])
- return self.__MaybePrependComma(arg_string, add_comma)
+ return self._MaybePrependComma(arg_string, add_comma)
def MakeOriginalArgString(self, prefix, add_comma = False, separator = ", "):
"""Gets the list of arguments as they are in GL."""
args = self.GetOriginalArgs()
arg_string = separator.join(
["%s%s" % (prefix, arg.name) for arg in args])
- return self.__MaybePrependComma(arg_string, add_comma)
+ return self._MaybePrependComma(arg_string, add_comma)
def MakeTypedHelperArgString(self, prefix, add_comma = False):
"""Gets a list of typed GL arguments after removing unneeded arguments."""
@@ -7683,7 +8054,7 @@ class Function(object):
prefix,
arg.name,
) for arg in args if not arg.IsConstant()])
- return self.__MaybePrependComma(arg_string, add_comma)
+ return self._MaybePrependComma(arg_string, add_comma)
def MakeHelperArgString(self, prefix, add_comma = False, separator = ", "):
"""Gets a list of GL arguments after removing unneeded arguments."""
@@ -7691,7 +8062,7 @@ class Function(object):
arg_string = separator.join(
["%s%s" % (prefix, arg.name)
for arg in args if not arg.IsConstant()])
- return self.__MaybePrependComma(arg_string, add_comma)
+ return self._MaybePrependComma(arg_string, add_comma)
def MakeTypedPepperArgString(self, prefix):
"""Gets a list of arguments as they need to be for Pepper."""
@@ -7740,28 +8111,28 @@ class Function(object):
args = self.GetCmdArgs()
arg_string = ", ".join(
["%s %s%s" % (arg.type, prefix, arg.name) for arg in args])
- return self.__MaybePrependComma(arg_string, add_comma)
+ return self._MaybePrependComma(arg_string, add_comma)
def MakeCmdArgString(self, prefix, add_comma = False):
"""Gets the list of arguments as they need to be for command buffers."""
args = self.GetCmdArgs()
arg_string = ", ".join(
["%s%s" % (prefix, arg.name) for arg in args])
- return self.__MaybePrependComma(arg_string, add_comma)
+ return self._MaybePrependComma(arg_string, add_comma)
def MakeTypedInitString(self, prefix, add_comma = False):
"""Gets a typed list of arguments as they need to be for cmd Init/Set."""
args = self.GetInitArgs()
arg_string = ", ".join(
["%s %s%s" % (arg.type, prefix, arg.name) for arg in args])
- return self.__MaybePrependComma(arg_string, add_comma)
+ return self._MaybePrependComma(arg_string, add_comma)
def MakeInitString(self, prefix, add_comma = False):
"""Gets the list of arguments as they need to be for cmd Init/Set."""
args = self.GetInitArgs()
arg_string = ", ".join(
["%s%s" % (prefix, arg.name) for arg in args])
- return self.__MaybePrependComma(arg_string, add_comma)
+ return self._MaybePrependComma(arg_string, add_comma)
def MakeLogArgString(self):
"""Makes a string of the arguments for the LOG macros"""
@@ -8069,9 +8440,17 @@ class BucketFunction(Function):
self.type_handler.WriteBucketHandlerImplementation(self, file)
def WriteServiceUnitTest(self, file, *extras):
- """Writes the service implementation for a command."""
+ """Overridden from Function"""
self.type_handler.WriteBucketServiceUnitTest(self, file, *extras)
+ def MakeOriginalArgString(self, prefix, add_comma = False, separator = ", "):
+ """Overridden from Function"""
+ args = self.GetOriginalArgs()
+ arg_string = separator.join(
+ ["%s%s" % (prefix, arg.name[0:-10] if arg.name.endswith("_bucket_id")
+ else arg.name) for arg in args])
+ return super(BucketFunction, self)._MaybePrependComma(arg_string, add_comma)
+
def CreateArg(arg_string):
"""Creates an Argument."""
@@ -8092,6 +8471,8 @@ def CreateArg(arg_string):
return ResourceIdArgument(arg_parts[-1], " ".join(arg_parts[0:-1]))
elif arg_parts[0].startswith('GLenum') and len(arg_parts[0]) > 6:
return EnumArgument(arg_parts[-1], " ".join(arg_parts[0:-1]))
+ elif arg_parts[0].startswith('GLbitfield') and len(arg_parts[0]) > 10:
+ return BitFieldArgument(arg_parts[-1], " ".join(arg_parts[0:-1]))
elif arg_parts[0].startswith('GLboolean') and len(arg_parts[0]) > 9:
return ValidatedBoolArgument(arg_parts[-1], " ".join(arg_parts[0:-1]))
elif arg_parts[0].startswith('GLboolean'):

Powered by Google App Engine
This is Rietveld 408576698