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 a9655a8be317ca6f17390c1c2994d2904cb7e4c5..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', |
@@ -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.""" |
@@ -6715,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" % |
@@ -6743,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": |
@@ -6773,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): |
@@ -7011,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): |
@@ -7028,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. |
@@ -7061,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.""" |
@@ -7196,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) |
@@ -7312,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. |
@@ -7323,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. |
@@ -7337,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. |
@@ -7584,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 |
@@ -8307,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'): |