| 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 922c1f9488ae28991361e313a3fd3e92d75b142d..577861a1d0d108368157550d4fb93ee350ed8e86 100755
|
| --- a/gpu/command_buffer/build_gles2_cmd_buffer.py
|
| +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
|
| @@ -1372,8 +1372,7 @@ _NAMED_TYPE_INFO = {
|
| 'type': 'GLenum',
|
| 'is_complete': True,
|
| 'valid': [
|
| - #TODO(zmo): avoid using the direct number.
|
| - '0x9117', # GL_SYNC_GPU_COMMANDS_COMPLETE
|
| + 'GL_SYNC_GPU_COMMANDS_COMPLETE',
|
| ],
|
| 'invalid': [
|
| '0',
|
| @@ -2029,7 +2028,16 @@ _FUNCTION_INFO = {
|
| 'cmd_args':
|
| 'GLidProgram program, uint32_t name_bucket_id, GLint* location',
|
| 'result': ['GLint'],
|
| - 'error_return': -1, # http://www.opengl.org/sdk/docs/man/xhtml/glGetAttribLocation.xml
|
| + 'error_return': -1,
|
| + },
|
| + 'GetFragDataLocation': {
|
| + 'type': 'Custom',
|
| + 'data_transfer_methods': ['shm'],
|
| + 'cmd_args':
|
| + 'GLidProgram program, uint32_t name_bucket_id, GLint* location',
|
| + 'result': ['GLint'],
|
| + 'error_return': -1,
|
| + 'unsafe': True,
|
| },
|
| 'GetBooleanv': {
|
| 'type': 'GETn',
|
| @@ -2441,7 +2449,6 @@ _FUNCTION_INFO = {
|
| 'type': 'PUTSTR',
|
| 'decoder_func': 'DoShaderSource',
|
| 'data_transfer_methods': ['bucket'],
|
| - 'client_test': False,
|
| 'cmd_args':
|
| 'GLuint shader, const char** str',
|
| 'pepper_args':
|
| @@ -3840,7 +3847,7 @@ TEST_F(GLES2ImplementationTest, %(name)sInvalidConstantArg%(invalid_index)d) {
|
| })
|
| else:
|
| if client_test != False:
|
| - file.Write("// TODO: Implement unit test for %s\n" % func.name)
|
| + file.Write("// TODO(zmo): Implement unit test for %s\n" % func.name)
|
|
|
| def WriteDestinationInitalizationValidation(self, func, file):
|
| """Writes the client side destintion initialization validation."""
|
| @@ -6507,6 +6514,245 @@ class PUTSTRHandler(ArrayArgTypeHandler):
|
| file.Write("}\n")
|
| file.Write("\n")
|
|
|
| + def WriteGLES2ImplementationUnitTest(self, func, file):
|
| + """Overrriden from TypeHandler."""
|
| + code = """
|
| +TEST_F(GLES2ImplementationTest, %(name)s) {
|
| + const uint32 kBucketId = GLES2Implementation::kResultBucketId;
|
| + const char* kString1 = "happy";
|
| + const char* kString2 = "ending";
|
| + const size_t kString1Size = ::strlen(kString1) + 1;
|
| + const size_t kString2Size = ::strlen(kString2) + 1;
|
| + const size_t kHeaderSize = sizeof(GLint) * 3;
|
| + const size_t kSourceSize = kHeaderSize + kString1Size + kString2Size;
|
| + const size_t kPaddedHeaderSize =
|
| + transfer_buffer_->RoundToAlignment(kHeaderSize);
|
| + const size_t kPaddedString1Size =
|
| + transfer_buffer_->RoundToAlignment(kString1Size);
|
| + const size_t kPaddedString2Size =
|
| + transfer_buffer_->RoundToAlignment(kString2Size);
|
| + struct Cmds {
|
| + cmd::SetBucketSize set_bucket_size;
|
| + cmd::SetBucketData set_bucket_header;
|
| + cmd::SetToken set_token1;
|
| + cmd::SetBucketData set_bucket_data1;
|
| + cmd::SetToken set_token2;
|
| + cmd::SetBucketData set_bucket_data2;
|
| + cmd::SetToken set_token3;
|
| + cmds::ShaderSourceBucket shader_source_bucket;
|
| + cmd::SetBucketSize clear_bucket_size;
|
| + };
|
| +
|
| + ExpectedMemoryInfo mem0 = GetExpectedMemory(kPaddedHeaderSize);
|
| + ExpectedMemoryInfo mem1 = GetExpectedMemory(kPaddedString1Size);
|
| + ExpectedMemoryInfo mem2 = GetExpectedMemory(kPaddedString2Size);
|
| +
|
| + Cmds expected;
|
| + expected.set_bucket_size.Init(kBucketId, kSourceSize);
|
| + expected.set_bucket_header.Init(
|
| + kBucketId, 0, kHeaderSize, mem0.id, mem0.offset);
|
| + expected.set_token1.Init(GetNextToken());
|
| + expected.set_bucket_data1.Init(
|
| + kBucketId, kHeaderSize, kString1Size, mem1.id, mem1.offset);
|
| + expected.set_token2.Init(GetNextToken());
|
| + expected.set_bucket_data2.Init(
|
| + kBucketId, kHeaderSize + kString1Size, kString2Size, mem2.id,
|
| + mem2.offset);
|
| + expected.set_token3.Init(GetNextToken());
|
| + expected.shader_source_bucket.Init(%(cmd_args)s, kBucketId);
|
| + expected.clear_bucket_size.Init(kBucketId, 0);
|
| + const char* kStrings[] = { kString1, kString2 };
|
| + gl_->%(name)s(%(gl_args)s);
|
| + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
|
| +}
|
| +"""
|
| + gl_args = []
|
| + cmd_args = []
|
| + for arg in func.GetOriginalArgs():
|
| + if arg == self.__GetDataArg(func):
|
| + gl_args.append('kStrings')
|
| + elif arg == self.__GetLengthArg(func):
|
| + gl_args.append('NULL')
|
| + elif arg.name == 'count':
|
| + gl_args.append('2')
|
| + else:
|
| + gl_args.append(arg.GetValidClientSideArg(func))
|
| + cmd_args.append(arg.GetValidClientSideArg(func))
|
| + file.Write(code % {
|
| + 'name': func.name,
|
| + 'gl_args': ", ".join(gl_args),
|
| + 'cmd_args': ", ".join(cmd_args),
|
| + })
|
| +
|
| + if self.__GetLengthArg(func) == None:
|
| + return
|
| + code = """
|
| +TEST_F(GLES2ImplementationTest, %(name)sWithLength) {
|
| + const uint32 kBucketId = GLES2Implementation::kResultBucketId;
|
| + const char* kString = "foobar******";
|
| + const size_t kStringSize = 6; // We only need "foobar".
|
| + const size_t kHeaderSize = sizeof(GLint) * 2;
|
| + const size_t kSourceSize = kHeaderSize + kStringSize + 1;
|
| + const size_t kPaddedHeaderSize =
|
| + transfer_buffer_->RoundToAlignment(kHeaderSize);
|
| + const size_t kPaddedStringSize =
|
| + transfer_buffer_->RoundToAlignment(kStringSize + 1);
|
| + struct Cmds {
|
| + cmd::SetBucketSize set_bucket_size;
|
| + cmd::SetBucketData set_bucket_header;
|
| + cmd::SetToken set_token1;
|
| + cmd::SetBucketData set_bucket_data;
|
| + cmd::SetToken set_token2;
|
| + cmds::ShaderSourceBucket shader_source_bucket;
|
| + cmd::SetBucketSize clear_bucket_size;
|
| + };
|
| +
|
| + ExpectedMemoryInfo mem0 = GetExpectedMemory(kPaddedHeaderSize);
|
| + ExpectedMemoryInfo mem1 = GetExpectedMemory(kPaddedStringSize);
|
| +
|
| + Cmds expected;
|
| + expected.set_bucket_size.Init(kBucketId, kSourceSize);
|
| + expected.set_bucket_header.Init(
|
| + kBucketId, 0, kHeaderSize, mem0.id, mem0.offset);
|
| + expected.set_token1.Init(GetNextToken());
|
| + expected.set_bucket_data.Init(
|
| + kBucketId, kHeaderSize, kStringSize + 1, mem1.id, mem1.offset);
|
| + expected.set_token2.Init(GetNextToken());
|
| + expected.shader_source_bucket.Init(%(cmd_args)s, kBucketId);
|
| + expected.clear_bucket_size.Init(kBucketId, 0);
|
| + const char* kStrings[] = { kString };
|
| + const GLint kLength[] = { kStringSize };
|
| + gl_->%(name)s(%(gl_args)s);
|
| + EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
|
| +}
|
| +"""
|
| + gl_args = []
|
| + for arg in func.GetOriginalArgs():
|
| + if arg == self.__GetDataArg(func):
|
| + gl_args.append('kStrings')
|
| + elif arg == self.__GetLengthArg(func):
|
| + gl_args.append('kLength')
|
| + elif arg.name == 'count':
|
| + gl_args.append('1')
|
| + else:
|
| + gl_args.append(arg.GetValidClientSideArg(func))
|
| + file.Write(code % {
|
| + 'name': func.name,
|
| + 'gl_args': ", ".join(gl_args),
|
| + 'cmd_args': ", ".join(cmd_args),
|
| + })
|
| +
|
| + def WriteBucketServiceUnitTest(self, func, file, *extras):
|
| + """Overrriden from TypeHandler."""
|
| + cmd_args = []
|
| + cmd_args_with_invalid_id = []
|
| + for index, arg in enumerate(func.GetOriginalArgs()):
|
| + if (arg == self.__GetLengthArg(func) or
|
| + arg == self.__GetDataArg(func) or arg.name == 'count'):
|
| + continue
|
| + if index == 0: # Resource ID arg
|
| + cmd_args.append(arg.GetValidArg(func))
|
| + cmd_args_with_invalid_id.append('kInvalidClientId')
|
| + else:
|
| + cmd_args.append(arg.GetValidArg(func))
|
| + cmd_args_with_invalid_id.append(arg.GetValidArg(func))
|
| +
|
| + test = """
|
| +TEST_P(%(test_name)s, %(name)sValidArgs) {
|
| + const uint32 kBucketId = 123;
|
| + const char kSource0[] = "hello";
|
| + const char* kSource[] = { kSource0 };
|
| + const char kValidStrEnd = 0;
|
| + SetBucketAsCStrings(kBucketId, 1, kSource, 1, kValidStrEnd);
|
| + cmds::%(name)s cmd;
|
| + cmd.Init(%(cmd_args)s, kBucketId);
|
| + decoder_->set_unsafe_es3_apis_enabled(true);
|
| + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));"""
|
| + if func.IsUnsafe():
|
| + test += """
|
| + decoder_->set_unsafe_es3_apis_enabled(false);
|
| + EXPECT_EQ(error::kUnknownCommand, ExecuteCmd(cmd));
|
| +"""
|
| + test += """
|
| +}
|
| +"""
|
| + self.WriteValidUnitTest(func, file, test, {
|
| + 'cmd_args': ", ".join(cmd_args),
|
| + }, *extras)
|
| +
|
| + test = """
|
| +TEST_P(%(test_name)s, %(name)sInvalidArgs) {
|
| + const uint32 kBucketId = 123;
|
| + const char kSource0[] = "hello";
|
| + const char* kSource[] = { kSource0 };
|
| + const char kValidStrEnd = 0;
|
| + decoder_->set_unsafe_es3_apis_enabled(true);
|
| + cmds::%(name)s cmd;
|
| + // Test no bucket.
|
| + cmd.Init(%(cmd_args)s, kBucketId);
|
| + EXPECT_NE(error::kNoError, ExecuteCmd(cmd));
|
| + // Test invalid client.
|
| + SetBucketAsCStrings(kBucketId, 1, kSource, 1, kValidStrEnd);
|
| + cmd.Init(%(cmd_args_with_invalid_id)s, kBucketId);
|
| + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
|
| + EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
|
| +}
|
| +"""
|
| + self.WriteValidUnitTest(func, file, test, {
|
| + 'cmd_args': ", ".join(cmd_args),
|
| + 'cmd_args_with_invalid_id': ", ".join(cmd_args_with_invalid_id),
|
| + }, *extras)
|
| +
|
| + test = """
|
| +TEST_P(%(test_name)s, %(name)sInvalidHeader) {
|
| + const uint32 kBucketId = 123;
|
| + const char kSource0[] = "hello";
|
| + const char* kSource[] = { kSource0 };
|
| + const char kValidStrEnd = 0;
|
| + const GLsizei kCount = static_cast<GLsizei>(arraysize(kSource));
|
| + const GLsizei kTests[] = {
|
| + kCount,
|
| + 0,
|
| + std::numeric_limits<GLsizei>::max(),
|
| + -1,
|
| + kCount,
|
| + };
|
| + decoder_->set_unsafe_es3_apis_enabled(true);
|
| + for (size_t ii = 0; ii < arraysize(kTests); ++ii) {
|
| + SetBucketAsCStrings(kBucketId, 1, kSource, kTests[ii], kValidStrEnd);
|
| + cmds::%(name)s cmd;
|
| + cmd.Init(%(cmd_args)s, kBucketId);
|
| + if (kTests[ii] == kCount) {
|
| + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
|
| + } else {
|
| + EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd));
|
| + }
|
| + }
|
| + EXPECT_EQ(GL_NO_ERROR, GetGLError());
|
| +}
|
| +"""
|
| + self.WriteValidUnitTest(func, file, test, {
|
| + 'cmd_args': ", ".join(cmd_args),
|
| + }, *extras)
|
| +
|
| + test = """
|
| +TEST_P(%(test_name)s, %(name)sInvalidStringEnding) {
|
| + const uint32 kBucketId = 123;
|
| + const char kSource0[] = "hello";
|
| + const char* kSource[] = { kSource0 };
|
| + const char kInvalidStrEnd = '*';
|
| + SetBucketAsCStrings(kBucketId, 1, kSource, 1, kInvalidStrEnd);
|
| + cmds::%(name)s cmd;
|
| + cmd.Init(%(cmd_args)s, kBucketId);
|
| + decoder_->set_unsafe_es3_apis_enabled(true);
|
| + EXPECT_EQ(error::kInvalidArguments, ExecuteCmd(cmd));
|
| + EXPECT_EQ(GL_NO_ERROR, GetGLError());
|
| +}
|
| +"""
|
| + self.WriteValidUnitTest(func, file, test, {
|
| + 'cmd_args': ", ".join(cmd_args),
|
| + }, *extras)
|
| +
|
|
|
| class PUTXnHandler(ArrayArgTypeHandler):
|
| """Handler for glUniform?f functions."""
|
| @@ -7539,39 +7785,6 @@ class ImmediatePointerArgument(Argument):
|
| return "static_cast<const void*>(%s)" % self.name
|
|
|
|
|
| -class BucketPointerArgument(Argument):
|
| - """A class that represents an bucket argument to a function."""
|
| -
|
| - def __init__(self, name, type):
|
| - Argument.__init__(self, name, type)
|
| -
|
| - def AddCmdArgs(self, args):
|
| - """Overridden from Argument."""
|
| - pass
|
| -
|
| - def WriteGetCode(self, file):
|
| - """Overridden from Argument."""
|
| - file.Write(
|
| - " %s %s = bucket->GetData(0, data_size);\n" %
|
| - (self.type, self.name))
|
| -
|
| - def WriteValidationCode(self, file, func):
|
| - """Overridden from Argument."""
|
| - pass
|
| -
|
| - def GetImmediateVersion(self):
|
| - """Overridden from Argument."""
|
| - return None
|
| -
|
| - def WriteDestinationInitalizationValidation(self, file, func):
|
| - """Overridden from Argument."""
|
| - self.WriteDestinationInitalizationValidatationIfNeeded(file, func)
|
| -
|
| - def GetLogArg(self):
|
| - """Overridden from Argument."""
|
| - return "static_cast<const void*>(%s)" % self.name
|
| -
|
| -
|
| class PointerArgument(Argument):
|
| """A class that represents a pointer argument to a function."""
|
|
|
| @@ -7579,11 +7792,11 @@ class PointerArgument(Argument):
|
| Argument.__init__(self, name, type)
|
|
|
| def IsPointer(self):
|
| - """Returns true if argument is a pointer."""
|
| + """Overridden from Argument."""
|
| return True
|
|
|
| def IsPointer2D(self):
|
| - """Returns true if argument is a 2D pointer."""
|
| + """Overridden from Argument."""
|
| return self.type.count('*') == 2
|
|
|
| def GetPointedType(self):
|
| @@ -7661,12 +7874,53 @@ class PointerArgument(Argument):
|
| self.WriteDestinationInitalizationValidatationIfNeeded(file, func)
|
|
|
|
|
| +class BucketPointerArgument(PointerArgument):
|
| + """A class that represents an bucket argument to a function."""
|
| +
|
| + def __init__(self, name, type):
|
| + Argument.__init__(self, name, type)
|
| +
|
| + def AddCmdArgs(self, args):
|
| + """Overridden from Argument."""
|
| + pass
|
| +
|
| + def WriteGetCode(self, file):
|
| + """Overridden from Argument."""
|
| + file.Write(
|
| + " %s %s = bucket->GetData(0, data_size);\n" %
|
| + (self.type, self.name))
|
| +
|
| + def WriteValidationCode(self, file, func):
|
| + """Overridden from Argument."""
|
| + pass
|
| +
|
| + def GetImmediateVersion(self):
|
| + """Overridden from Argument."""
|
| + return None
|
| +
|
| + def WriteDestinationInitalizationValidation(self, file, func):
|
| + """Overridden from Argument."""
|
| + self.WriteDestinationInitalizationValidatationIfNeeded(file, func)
|
| +
|
| + def GetLogArg(self):
|
| + """Overridden from Argument."""
|
| + return "static_cast<const void*>(%s)" % self.name
|
| +
|
| +
|
| class InputStringBucketArgument(Argument):
|
| """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")
|
|
|
| + def IsPointer(self):
|
| + """Overridden from Argument."""
|
| + return True
|
| +
|
| + def IsPointer2D(self):
|
| + """Overridden from Argument."""
|
| + return False
|
| +
|
|
|
| class InputStringArrayBucketArgument(Argument):
|
| """A string array input argument where the strings are passed in a bucket."""
|
| @@ -7732,6 +7986,14 @@ class InputStringArrayBucketArgument(Argument):
|
| def GetValidGLArg(self, func):
|
| return "_"
|
|
|
| + def IsPointer(self):
|
| + """Overridden from Argument."""
|
| + return True
|
| +
|
| + def IsPointer2D(self):
|
| + """Overridden from Argument."""
|
| + return True
|
| +
|
|
|
| class ResourceIdArgument(Argument):
|
| """A class that represents a resource id argument to a function."""
|
| @@ -8635,6 +8897,15 @@ class GLGenerator(object):
|
| def WriteFormat(self, filename):
|
| """Writes the command buffer format"""
|
| file = CHeaderWriter(filename)
|
| + # Forward declaration of a few enums used in constant argument
|
| + # to avoid including GL header files.
|
| + enum_defines = {
|
| + 'GL_SYNC_GPU_COMMANDS_COMPLETE': 0x9117,
|
| + }
|
| + file.Write('\n')
|
| + for enum in enum_defines:
|
| + file.Write("#define %s 0x%x\n" % (enum, enum_defines[enum]))
|
| + file.Write('\n')
|
| for func in self.functions:
|
| if True:
|
| #gen_cmd = func.GetInfo('gen_cmd')
|
|
|