| 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'):
|
|
|