| Index: gpu/command_buffer/build_gles2_cmd_buffer.py
|
| ===================================================================
|
| --- gpu/command_buffer/build_gles2_cmd_buffer.py (revision 40176)
|
| +++ gpu/command_buffer/build_gles2_cmd_buffer.py (working copy)
|
| @@ -839,9 +839,10 @@
|
| # data_type: The type of data the command uses. For PUTn or PUT types.
|
| # count: The number of units per element. For PUTn or PUT types.
|
| # unit_test: If False no unit test will be generated.
|
| +# expectation: If False the unit test will have no expected calls.
|
|
|
| _FUNCTION_INFO = {
|
| - 'ActiveTexture': {'decoder_func': 'DoActiveTexture'},
|
| + 'ActiveTexture': {'decoder_func': 'DoActiveTexture', 'expection': False},
|
| 'BindAttribLocation': {'type': 'GLchar'},
|
| 'BindBuffer': {'decoder_func': 'DoBindBuffer'},
|
| 'BindFramebuffer': {'decoder_func': 'glBindFramebufferEXT'},
|
| @@ -924,10 +925,17 @@
|
| 'needs_size': True,
|
| 'cmd_args':
|
| 'GLidProgram program, const char* name, NonImmediate GLint* location',
|
| + 'result': ['GLint'],
|
| },
|
| 'GetBooleanv': {'type': 'GETn'},
|
| 'GetBufferParameteriv': {'type': 'GETn'},
|
| - 'GetError': {'type': 'Is', 'decoder_func': 'GetGLError'},
|
| + 'GetError': {
|
| + 'type': 'Is',
|
| + 'decoder_func':
|
| + 'GetGLError',
|
| + 'impl_func': False,
|
| + 'result': ['GLenum'],
|
| + },
|
| 'GetFloatv': {'type': 'GETn'},
|
| 'GetFramebufferAttachmentParameteriv': {
|
| 'type': 'GETn',
|
| @@ -935,13 +943,21 @@
|
| },
|
| 'GetIntegerv': {'type': 'GETn'},
|
| 'GetProgramiv': {'type': 'GETn'},
|
| - 'GetProgramInfoLog': {'type': 'STRn'},
|
| + 'GetProgramInfoLog': {
|
| + 'type': 'STRn',
|
| + 'get_len_func': 'glGetProgramiv',
|
| + 'get_len_enum': 'GL_INFO_LOG_LENGTH',
|
| + },
|
| 'GetRenderbufferParameteriv': {
|
| 'type': 'GETn',
|
| 'decoder_func': 'glGetRenderbufferParameterivEXT',
|
| },
|
| - 'GetShaderiv': {'type': 'GETn'},
|
| - 'GetShaderInfoLog': {'type': 'STRn'},
|
| + 'GetShaderiv': {'type': 'GETn', 'decoder_func': 'DoGetShaderiv'},
|
| + 'GetShaderInfoLog': {
|
| + 'type': 'STRn',
|
| + 'get_len_func': 'glGetShaderiv',
|
| + 'get_len_enum': 'GL_INFO_LOG_LENGTH',
|
| + },
|
| 'GetShaderPrecisionFormat': {
|
| 'type': 'Custom',
|
| 'immediate': False,
|
| @@ -955,7 +971,17 @@
|
| 'int32 precision',
|
| ],
|
| },
|
| - 'GetShaderSource': {'type': 'STRn', 'decoder_func': 'DoGetShaderSource'},
|
| + 'GetShaderSource': {
|
| + 'type': 'STRn',
|
| + 'decoder_func': 'DoGetShaderSource',
|
| + 'get_len_func': 'DoGetShaderiv',
|
| + 'get_len_enum': 'GL_SHADER_SOURCE_LENGTH',
|
| + 'unit_test': False,
|
| + },
|
| + 'GetString': {
|
| + 'type': 'Custom',
|
| + 'cmd_args': 'GLenumStringType name, uint32 bucket_id',
|
| + },
|
| 'GetTexParameterfv': {'type': 'GETn'},
|
| 'GetTexParameteriv': {'type': 'GETn'},
|
| 'GetUniformfv': {
|
| @@ -974,6 +1000,7 @@
|
| 'needs_size': True,
|
| 'cmd_args':
|
| 'GLidProgram program, const char* name, NonImmediate GLint* location',
|
| + 'result': ['GLint'],
|
| },
|
| 'GetVertexAttribfv': {'type': 'GETn'},
|
| 'GetVertexAttribiv': {'type': 'GETn'},
|
| @@ -1172,6 +1199,8 @@
|
| class TypeHandler(object):
|
| """This class emits code for a particular type of function."""
|
|
|
| + _remove_expected_call_re = re.compile(r' EXPECT_CALL.*?;\n', re.S)
|
| +
|
| def __init__(self):
|
| pass
|
|
|
| @@ -1363,6 +1392,8 @@
|
|
|
| def WriteValidUnitTest(self, func, file, test, extra = {}):
|
| """Writes a valid unit test."""
|
| + if func.GetInfo('expection') == False:
|
| + test = self._remove_expected_call_re.sub('', test)
|
| name = func.name
|
| arg_strings = []
|
| count = 0
|
| @@ -1389,7 +1420,7 @@
|
| """Writes a invalid unit test."""
|
| arg_index = 0
|
| for arg in func.GetOriginalArgs():
|
| - num_invalid_values = arg.GetNumInvalidValues()
|
| + num_invalid_values = arg.GetNumInvalidValues(func)
|
| for value_index in range(0, num_invalid_values):
|
| arg_strings = []
|
| parse_result = "kNoError"
|
| @@ -1461,22 +1492,28 @@
|
| """Writes the validation code for an immediate version of a command."""
|
| pass
|
|
|
| + def WriteGLES2ImplementationDeclaration(self, func, file):
|
| + """Writes the GLES2 Implemention declaration."""
|
| + file.Write("%s %s(%s);\n" %
|
| + (func.return_type, func.original_name,
|
| + func.MakeTypedOriginalArgString("")))
|
| + file.Write("\n")
|
| +
|
| def WriteGLES2ImplementationHeader(self, func, file):
|
| - """Writes the GLES2 Implemention declaration."""
|
| + """Writes the GLES2 Implemention."""
|
| impl_func = func.GetInfo('impl_func')
|
| if func.can_auto_generate and (impl_func == None or impl_func == True):
|
| file.Write("%s %s(%s) {\n" %
|
| (func.return_type, func.original_name,
|
| func.MakeTypedOriginalArgString("")))
|
| + for arg in func.GetOriginalArgs():
|
| + arg.WriteClientSideValidationCode(file)
|
| file.Write(" helper_->%s(%s);\n" %
|
| (func.name, func.MakeOriginalArgString("")))
|
| file.Write("}\n")
|
| file.Write("\n")
|
| else:
|
| - file.Write("%s %s(%s);\n" %
|
| - (func.return_type, func.original_name,
|
| - func.MakeTypedOriginalArgString("")))
|
| - file.Write("\n")
|
| + self.WriteGLES2ImplementationDeclaration(func, file)
|
|
|
| def WriteImmediateCmdComputeSize(self, func, file):
|
| """Writes the size computation code for the immediate version of a cmd."""
|
| @@ -2989,6 +3026,8 @@
|
| """Overrriden from TypeHandler."""
|
| func.AddCmdArg(Argument("result_shm_id", 'uint32'))
|
| func.AddCmdArg(Argument("result_shm_offset", 'uint32'))
|
| + if func.GetInfo('result') == None:
|
| + func.AddInfo('result', ['uint32'])
|
|
|
| def WriteServiceUnitTest(self, func, file):
|
| """Overrriden from TypeHandler."""
|
| @@ -3044,20 +3083,26 @@
|
|
|
| def WriteGLES2ImplementationHeader(self, func, file):
|
| """Overrriden from TypeHandler."""
|
| - file.Write("%s %s(%s) {\n" %
|
| - (func.return_type, func.original_name,
|
| - func.MakeTypedOriginalArgString("")))
|
| - arg_string = func.MakeOriginalArgString("")
|
| - comma = ""
|
| - if len(arg_string) > 0:
|
| - comma = ", "
|
| - file.Write(" helper_->%s(%s%sresult_shm_id(), result_shm_offset());\n" %
|
| - (func.name, arg_string, comma))
|
| - file.Write(" WaitForCmd();\n")
|
| - file.Write(" return GetResultAs<%s>();\n" %
|
| - func.return_type)
|
| - file.Write("}\n")
|
| - file.Write("\n")
|
| + impl_func = func.GetInfo('impl_func')
|
| + if impl_func == None or impl_func == True:
|
| + file.Write("%s %s(%s) {\n" %
|
| + (func.return_type, func.original_name,
|
| + func.MakeTypedOriginalArgString("")))
|
| + file.Write(" typedef %s::Result Result;\n" % func.original_name)
|
| + file.Write(" Result* result = GetResultAs<Result*>();\n")
|
| + file.Write(" *result = 0;\n")
|
| + arg_string = func.MakeOriginalArgString("")
|
| + comma = ""
|
| + if len(arg_string) > 0:
|
| + comma = ", "
|
| + file.Write(" helper_->%s(%s%sresult_shm_id(), result_shm_offset());\n" %
|
| + (func.name, arg_string, comma))
|
| + file.Write(" WaitForCmd();\n")
|
| + file.Write(" return *result;\n")
|
| + file.Write("}\n")
|
| + file.Write("\n")
|
| + else:
|
| + self.WriteGLES2ImplementationDeclaration(func, file)
|
|
|
|
|
| class STRnHandler(TypeHandler):
|
| @@ -3066,18 +3111,95 @@
|
| def __init__(self):
|
| TypeHandler.__init__(self)
|
|
|
| + def InitFunction(self, func):
|
| + """Overrriden from TypeHandler."""
|
| + # remove all but the first cmd args.
|
| + cmd_args = func.GetCmdArgs()
|
| + func.ClearCmdArgs()
|
| + func.AddCmdArg(cmd_args[0])
|
| + # add on a bucket id.
|
| + func.AddCmdArg(Argument('bucket_id', 'uint32'))
|
| +
|
| def WriteGLES2ImplementationHeader(self, func, file):
|
| """Overrriden from TypeHandler."""
|
| - file.Write("// TODO(gman): Implement this\n")
|
| - TypeHandler.WriteGLES2ImplementationHeader(self, func, file)
|
| + code = """%(return_type)s %(func_name)s(%(args)s) {
|
| + helper_->SetBucketSize(kResultBucketId, 0);
|
| + helper_->%(func_name)s(%(id_name)s, kResultBucketId);
|
| + std::string str;
|
| + if (GetBucketAsString(kResultBucketId, &str)) {
|
| + GLsizei max_size =
|
| + std::min(static_cast<size_t>(%(bufsize_name)s) - 1, str.size());
|
| + if (%(length_name)s != NULL) {
|
| + *%(length_name)s = max_size;
|
| + }
|
| + memcpy(%(dest_name)s, str.c_str(), max_size);
|
| + %(dest_name)s[max_size] = '\\0';
|
| + }
|
| +}
|
| +"""
|
| + args = func.GetOriginalArgs()
|
| + file.Write(code % {
|
| + 'return_type': func.return_type,
|
| + 'func_name': func.original_name,
|
| + 'args': func.MakeTypedOriginalArgString(""),
|
| + 'id_name': args[0].name,
|
| + 'bufsize_name': args[1].name,
|
| + 'length_name': args[2].name,
|
| + 'dest_name': args[3].name,
|
| + })
|
|
|
| def WriteServiceUnitTest(self, func, file):
|
| """Overrriden from TypeHandler."""
|
| - file.Write("// TODO(gman): %s\n\n" % func.name)
|
| + valid_test = """
|
| +TEST_F(%(test_name)s, %(name)sValidArgs) {
|
| + const char* kInfo = "hello";
|
| + const uint32 kBucketId = 123;
|
| + SpecializedSetup<%(name)s, 0>();
|
| +%(expect_len_code)s
|
| + EXPECT_CALL(*gl_, %(gl_func_name)s(%(gl_args)s))
|
| + .WillOnce(DoAll(SetArgumentPointee<2>(strlen(kInfo)),
|
| + SetArrayArgument<3>(kInfo, kInfo + strlen(kInfo) + 1)));
|
| + %(name)s cmd;
|
| + cmd.Init(%(args)s);
|
| + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
|
| + CommonDecoder::Bucket* bucket = decoder_->GetBucket(kBucketId);
|
| + ASSERT_TRUE(bucket != NULL);
|
| + EXPECT_EQ(strlen(kInfo) + 1, bucket->size());
|
| + EXPECT_EQ(0, memcmp(bucket->GetData(0, bucket->size()), kInfo,
|
| + bucket->size()));
|
| +}
|
| +"""
|
| + args = func.GetOriginalArgs()
|
| + id_name = args[0].GetValidGLArg(0, 0)
|
| + get_len_func = func.GetInfo('get_len_func')
|
| + get_len_enum = func.GetInfo('get_len_enum')
|
| + sub = {
|
| + 'id_name': id_name,
|
| + 'get_len_func': get_len_func,
|
| + 'get_len_enum': get_len_enum,
|
| + 'gl_args': '%s, strlen(kInfo) + 1, _, _' % args[0].GetValidGLArg(0, 0),
|
| + 'args': '%s, kBucketId' % args[0].GetValidArg(0, 0),
|
| + 'expect_len_code': '',
|
| + }
|
| + if get_len_func[0:2] == 'gl':
|
| + sub['expect_len_code'] = (
|
| + " EXPECT_CALL(*gl_, %s(%s, %s, _))\n"
|
| + " .WillOnce(SetArgumentPointee<2>(strlen(kInfo)));") % (
|
| + get_len_func[2:], id_name, get_len_enum)
|
| + self.WriteValidUnitTest(func, file, valid_test, sub)
|
|
|
| - def WriteImmediateServiceUnitTest(self, func, file):
|
| - """Overrriden from TypeHandler."""
|
| - file.Write("// TODO(gman): %s\n\n" % func.name)
|
| + invalid_test = """
|
| +TEST_F(%(test_name)s, %(name)sInvalidArgs) {
|
| + const uint32 kBucketId = 123;
|
| + EXPECT_CALL(*gl_, %(gl_func_name)s(_, _, _, _))
|
| + .Times(0);
|
| + %(name)s cmd;
|
| + cmd.Init(kInvalidClientId, kBucketId);
|
| + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
|
| + EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
|
| +}
|
| +"""
|
| + self.WriteValidUnitTest(func, file, invalid_test)
|
|
|
| def WriteServiceImplementation(self, func, file):
|
| """Overrriden from TypeHandler."""
|
| @@ -3085,34 +3207,21 @@
|
| "error::Error 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 error::kOutOfBounds;\n"
|
| - " }\n"
|
| - " }\n")
|
| - dest_arg = args[-1]
|
| - bufsize_arg = args[-3]
|
| + args = func.GetCmdArgs()
|
| + id_arg = args[0]
|
| + bucket_arg = args[1]
|
| + id_arg.WriteGetCode(file)
|
| + bucket_arg.WriteGetCode(file)
|
| + id_arg.WriteValidationCode(file)
|
| + file.Write(" GLint len = 0;\n")
|
| + file.Write(" %s(%s, %s, &len);\n" % (
|
| + func.GetInfo('get_len_func'), id_arg.name,
|
| + func.GetInfo('get_len_enum')))
|
| + file.Write(" Bucket* bucket = CreateBucket(%s);\n" % bucket_arg.name)
|
| + file.Write(" bucket->SetSize(len + 1);\n");
|
| 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)
|
| + " %s(%s, len + 1, &len, bucket->GetDataAs<GLchar*>(0, len + 1));\n" %
|
| + (func.GetGLFunctionName(), id_arg.name))
|
| file.Write(" return error::kNoError;\n")
|
| file.Write("}\n")
|
| file.Write("\n")
|
| @@ -3169,7 +3278,7 @@
|
| def GetValidGLArg(self, offset, index):
|
| return str(offset + 1)
|
|
|
| - def GetNumInvalidValues(self):
|
| + def GetNumInvalidValues(self, func):
|
| """returns the number of invalid values to be tested."""
|
| return 0
|
|
|
| @@ -3184,12 +3293,12 @@
|
|
|
| def WriteValidationCode(self, file):
|
| """Writes the validation code for an argument."""
|
| - if self.type == 'GLsizei' or self.type == 'GLsizeiptr':
|
| - file.Write(" if (%s < 0) {\n" % self.name)
|
| - file.Write(" SetGLError(GL_INVALID_VALUE);\n")
|
| - file.Write(" return error::kNoError;\n")
|
| - file.Write(" }\n")
|
| + pass
|
|
|
| + def WriteClientSideValidationCode(self, file):
|
| + """Writes the validation code for an argument."""
|
| + pass
|
| +
|
| def WriteGetAddress(self, file):
|
| """Writes the code to get the address this argument refers to."""
|
| pass
|
| @@ -3200,21 +3309,37 @@
|
|
|
|
|
| class SizeArgument(Argument):
|
| + """class for GLsizei and GLsizeiptr."""
|
|
|
| def __init__(self, name, type):
|
| Argument.__init__(self, name, type)
|
|
|
| - def GetNumInvalidValues(self):
|
| + def GetNumInvalidValues(self, func):
|
| """overridden from Argument."""
|
| + if func.is_immediate:
|
| + return 0
|
| return 1
|
|
|
| def GetInvalidArg(self, offset, index):
|
| - """returns an invalid value and expected parse result by index."""
|
| + """overridden from Argument."""
|
| return ("-1", "kNoError", "GL_INVALID_VALUE")
|
|
|
| + def WriteValidationCode(self, file):
|
| + """overridden from Argument."""
|
| + file.Write(" if (%s < 0) {\n" % self.name)
|
| + file.Write(" SetGLError(GL_INVALID_VALUE);\n")
|
| + file.Write(" return error::kNoError;\n")
|
| + file.Write(" }\n")
|
|
|
| + def WriteClientSideValidationCode(self, file):
|
| + """overridden from Argument."""
|
| + file.Write(" if (%s < 0) {\n" % self.name)
|
| + file.Write(" SetGLError(GL_INVALID_VALUE);\n")
|
| + file.Write(" return;\n")
|
| + file.Write(" }\n")
|
| +
|
| class EnumBaseArgument(Argument):
|
| - """Base calss for EnumArgument, IntArgument and BoolArgument"""
|
| + """Base class for EnumArgument, IntArgument and BoolArgument"""
|
|
|
| def __init__(self, name, gl_type, type, gl_error):
|
| Argument.__init__(self, name, gl_type)
|
| @@ -3242,7 +3367,7 @@
|
| def GetValidGLArg(self, offset, index):
|
| return self.GetValidArg(offset, index)
|
|
|
| - def GetNumInvalidValues(self):
|
| + def GetNumInvalidValues(self, func):
|
| """returns the number of invalid values to be tested."""
|
| if 'invalid' in self.enum_info:
|
| invalid = self.enum_info['invalid']
|
| @@ -3256,8 +3381,8 @@
|
| num_invalid = len(invalid)
|
| if index >= num_invalid:
|
| index = num_invalid - 1
|
| - return (invalid[index], "kNoError", "GL_INVALID_ENUM")
|
| - return ("---ERROR1---", "kNoError", "GL_INVALID_ENUM")
|
| + return (invalid[index], "kNoError", self.gl_error)
|
| + return ("---ERROR1---", "kNoError", self.gl_error)
|
|
|
|
|
| class EnumArgument(EnumBaseArgument):
|
| @@ -3338,7 +3463,7 @@
|
| """Overridden from Argument."""
|
| return "reinterpret_cast<%s>(shared_memory_address_)" % self.type
|
|
|
| - def GetNumInvalidValues(self):
|
| + def GetNumInvalidValues(self, func):
|
| """Overridden from Argument."""
|
| return 2
|
|
|
| @@ -3440,6 +3565,7 @@
|
| self.init_args = init_args
|
| self.args_for_cmds = args_for_cmds
|
| self.type_handler.InitFunction(self)
|
| + self.is_immediate = False
|
|
|
| def IsType(self, type_name):
|
| """Returns true if function is a certain type."""
|
| @@ -3451,6 +3577,10 @@
|
| return getattr(self.info, name)
|
| return None
|
|
|
| + def AddInfo(self, name, value):
|
| + """Adds an info."""
|
| + setattr(self.info, name, value)
|
| +
|
| def GetGLFunctionName(self):
|
| """Gets the function to call to execute GL for this command."""
|
| if self.GetInfo('decoder_func'):
|
| @@ -3475,6 +3605,10 @@
|
| """Gets the command args for this function."""
|
| return self.cmd_args
|
|
|
| + def ClearCmdArgs(self):
|
| + """Clears the command args for this function."""
|
| + self.cmd_args = []
|
| +
|
| def GetInitArgs(self):
|
| """Gets the init args for this function."""
|
| return self.init_args
|
| @@ -3646,6 +3780,7 @@
|
| cmd_args,
|
| new_init_args,
|
| 0)
|
| + self.is_immediate = True
|
|
|
| def WriteServiceImplementation(self, file):
|
| """Overridden from Function"""
|
|
|