summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorkkinnunen@nvidia.com <kkinnunen@nvidia.com@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-13 08:27:21 +0000
committerkkinnunen@nvidia.com <kkinnunen@nvidia.com@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-13 08:27:21 +0000
commit03644191a0165b5629bef63830c6c83e77832cdb (patch)
treee4b14316bff7aaf31b1c89fbef7aaaf57021ac1b /gpu
parentdca94c767151817d051cc0e5114ad4800d77cecf (diff)
downloadchromium_src-03644191a0165b5629bef63830c6c83e77832cdb.zip
chromium_src-03644191a0165b5629bef63830c6c83e77832cdb.tar.gz
chromium_src-03644191a0165b5629bef63830c6c83e77832cdb.tar.bz2
Clarify function info object usage in the command buffer generator
Before, the Function objects (roughly corresponding to the commands being generated) would construct itself based on the function info object, parsed properties and many argument lists. The argument lists themselves were also constructed out of function info object and the parsed properties. Try to clarify this by following changes. Define that function info object is first parsed from the cmd_buffer_functions.txt file. Then the function info is possibly augmented by the optional object for the function info object table (_FUNCTION_INFO). Function objects are created solely on the function info object. Function constructor parses the function info object and constructs the needed properties, such as function type handlers, argument arrays and return value types. Function provides simple initialization function that the immediate and bucket subclasses can use to construct specialized versions of the command buffer command argument lists. Review URL: https://codereview.chromium.org/276873002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@270051 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rwxr-xr-xgpu/command_buffer/build_gles2_cmd_buffer.py347
1 files changed, 168 insertions, 179 deletions
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py
index 95aac87..8f6cf77 100755
--- a/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -1213,8 +1213,11 @@ _PEPPER_INTERFACES = [
{'name': 'DrawBuffers', 'dev': True},
]
-# This table specifies types and other special data for the commands that
-# will be generated.
+# A function info object specifies the type and other special data for the
+# command that will be generated. A base function info object is generated by
+# parsing the "cmd_buffer_functions.txt", one for each function in the
+# file. These function info objects can be augmented and their values can be
+# overridden by adding an object to the table below.
#
# Must match function names specified in "cmd_buffer_functions.txt".
#
@@ -4831,7 +4834,7 @@ TEST_P(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
}
"""
file.Write(code % (self.GetArrayType(func), self.GetArrayCount(func)))
- if func.is_immediate:
+ if func.IsImmediate():
file.Write(" if (data_size > immediate_data_size) {\n")
file.Write(" return error::kOutOfBounds;\n")
file.Write(" }\n")
@@ -5099,7 +5102,7 @@ TEST_P(%(test_name)s, %(name)sInvalidArgs%(arg_index)d_%(value_index)d) {
}
"""
file.Write(code % (self.GetArrayType(func), self.GetArrayCount(func)))
- if func.is_immediate:
+ if func.IsImmediate():
file.Write(" if (data_size > immediate_data_size) {\n")
file.Write(" return error::kOutOfBounds;\n")
file.Write(" }\n")
@@ -5773,18 +5776,6 @@ TEST_P(%(test_name)s, %(name)sInvalidArgs) {
"""Overrriden from TypeHandler."""
pass
-
-class FunctionInfo(object):
- """Holds info about a function."""
-
- def __init__(self, info, type_handler):
- for key in info:
- setattr(self, key, info[key])
- self.type_handler = type_handler
- if not 'type' in info:
- self.type = ''
-
-
class Argument(object):
"""A class that represents a function argument."""
@@ -5960,7 +5951,7 @@ class SizeArgument(Argument):
def GetNumInvalidValues(self, func):
"""overridden from Argument."""
- if func.is_immediate:
+ if func.IsImmediate():
return 0
return 1
@@ -6389,35 +6380,102 @@ class ResourceIdZeroArgument(Argument):
class Function(object):
"""A class that represents a function."""
- def __init__(self, original_name, name, info, return_type, original_args,
- args_for_cmds, cmd_args, init_args, num_pointer_args):
+ type_handlers = {
+ '': TypeHandler(),
+ 'Bind': BindHandler(),
+ 'Create': CreateHandler(),
+ 'Custom': CustomHandler(),
+ 'Data': DataHandler(),
+ 'Delete': DeleteHandler(),
+ 'DELn': DELnHandler(),
+ 'GENn': GENnHandler(),
+ 'GETn': GETnHandler(),
+ 'GLchar': GLcharHandler(),
+ 'GLcharN': GLcharNHandler(),
+ 'HandWritten': HandWrittenHandler(),
+ 'Is': IsHandler(),
+ 'Manual': ManualHandler(),
+ 'PUT': PUTHandler(),
+ 'PUTn': PUTnHandler(),
+ 'PUTXn': PUTXnHandler(),
+ 'StateSet': StateSetHandler(),
+ 'StateSetRGBAlpha': StateSetRGBAlphaHandler(),
+ 'StateSetFrontBack': StateSetFrontBackHandler(),
+ 'StateSetFrontBackSeparate': StateSetFrontBackSeparateHandler(),
+ 'StateSetNamedParameter': StateSetNamedParameter(),
+ 'STRn': STRnHandler(),
+ 'Todo': TodoHandler(),
+ }
+
+ def __init__(self, name, info):
self.name = name
- self.original_name = original_name
+ self.original_name = info['original_name']
+
+ self.original_args = self.ParseArgs(info['original_args'])
+
+ if 'cmd_args' in info:
+ self.args_for_cmds = self.ParseArgs(info['cmd_args'])
+ else:
+ self.args_for_cmds = self.original_args[:]
+
+ self.return_type = info['return_type']
+ if self.return_type != 'void':
+ self.return_arg = CreateArg(info['return_type'] + " result")
+ else:
+ self.return_arg = None
+
+ self.num_pointer_args = sum(
+ [1 for arg in self.args_for_cmds if arg.IsPointer()])
self.info = info
- self.type_handler = info.type_handler
- self.return_type = return_type
- self.original_args = original_args
- self.num_pointer_args = num_pointer_args
- self.can_auto_generate = num_pointer_args == 0 and return_type == "void"
- self.cmd_args = cmd_args
- self.init_args = init_args
+ self.type_handler = self.type_handlers[info['type']]
+ self.can_auto_generate = (self.num_pointer_args == 0 and
+ info['return_type'] == "void")
self.InitFunction()
- self.args_for_cmds = args_for_cmds
- self.is_immediate = False
+
+ def ParseArgs(self, arg_string):
+ """Parses a function arg string."""
+ args = []
+ parts = arg_string.split(',')
+ for arg_string in parts:
+ arg = CreateArg(arg_string)
+ if arg:
+ args.append(arg)
+ return args
def IsType(self, type_name):
"""Returns true if function is a certain type."""
- return self.info.type == type_name
+ return self.info['type'] == type_name
def InitFunction(self):
- """Calls the init function for the type handler."""
+ """Creates command args and calls the init function for the type handler.
+
+ Creates argument lists for command buffer commands, eg. self.cmd_args and
+ self.init_args.
+ Calls the type function initialization.
+ Override to create different kind of command buffer command argument lists.
+ """
+ self.cmd_args = []
+ for arg in self.args_for_cmds:
+ arg.AddCmdArgs(self.cmd_args)
+
+ self.init_args = []
+ for arg in self.args_for_cmds:
+ arg.AddInitArgs(self.init_args)
+
+ if self.return_arg:
+ self.init_args.append(self.return_arg)
+
self.type_handler.InitFunction(self)
- def GetInfo(self, name):
+ def IsImmediate(self):
+ """Returns whether the function is immediate data function or not."""
+ return False
+
+ def GetInfo(self, name, default = None):
"""Returns a value from the function info for this function."""
- if hasattr(self.info, name):
- return getattr(self.info, name)
- return None
+ if name in self.info:
+ return self.info[name]
+ return default
def GetValidArg(self, index):
"""Gets a valid arg from the function info if one exists."""
@@ -6428,7 +6486,7 @@ class Function(object):
def AddInfo(self, name, value):
"""Adds an info."""
- setattr(self.info, name, value)
+ self.info[name] = value
def IsCoreGLFunction(self):
return (not self.GetInfo('extension') and
@@ -6570,11 +6628,10 @@ class Function(object):
def WriteCmdFlag(self, file):
"""Writes the cmd cmd_flags constant."""
flags = []
- trace_level = 3 # By default trace only at the highest level
- if hasattr(self.info, 'trace_level'):
- if (self.info.trace_level < 0) or (self.info.trace_level > 3):
- raise KeyError("Unhandled trace_level: %d" % self.info.trace_level)
- trace_level = self.info.trace_level
+ # By default trace only at the highest level 3.
+ trace_level = int(self.GetInfo('trace_level', default = 3))
+ if trace_level not in xrange(0, 4):
+ raise KeyError("Unhandled trace_level: %d" % trace_level)
flags.append('CMD_FLAG_SET_TRACE_LEVEL(%d)' % trace_level)
@@ -6728,36 +6785,34 @@ class ImmediateFunction(Function):
"""A class that represnets an immediate function command."""
def __init__(self, func):
- new_args = []
- for arg in func.GetOriginalArgs():
+ Function.__init__(
+ self,
+ "%sImmediate" % func.name,
+ func.info)
+
+ def InitFunction(self):
+ # Override args in original_args and args_for_cmds with immediate versions
+ # of the args.
+
+ new_original_args = []
+ for arg in self.original_args:
new_arg = arg.GetImmediateVersion()
if new_arg:
- new_args.append(new_arg)
+ new_original_args.append(new_arg)
+ self.original_args = new_original_args
- cmd_args = []
new_args_for_cmds = []
- for arg in func.args_for_cmds:
+ for arg in self.args_for_cmds:
new_arg = arg.GetImmediateVersion()
if new_arg:
new_args_for_cmds.append(new_arg)
- new_arg.AddCmdArgs(cmd_args)
- new_init_args = []
- for arg in new_args_for_cmds:
- arg.AddInitArgs(new_init_args)
+ self.args_for_cmds = new_args_for_cmds
- Function.__init__(
- self,
- func.original_name,
- "%sImmediate" % func.name,
- func.info,
- func.return_type,
- new_args,
- new_args_for_cmds,
- cmd_args,
- new_init_args,
- 0)
- self.is_immediate = True
+ Function.InitFunction(self)
+
+ def IsImmediate(self):
+ return True
def WriteCommandDescription(self, file):
"""Overridden from Function"""
@@ -6813,39 +6868,31 @@ class BucketFunction(Function):
"""A class that represnets a bucket version of a function command."""
def __init__(self, func):
- new_args = []
- for arg in func.GetOriginalArgs():
+ Function.__init__(
+ self,
+ "%sBucket" % func.name,
+ func.info)
+
+ def InitFunction(self):
+ # Override args in original_args and args_for_cmds with bucket versions
+ # of the args.
+
+ new_original_args = []
+ for arg in self.original_args:
new_arg = arg.GetBucketVersion()
if new_arg:
- new_args.append(new_arg)
+ new_original_args.append(new_arg)
+ self.original_args = new_original_args
- cmd_args = []
new_args_for_cmds = []
- for arg in func.args_for_cmds:
+ for arg in self.args_for_cmds:
new_arg = arg.GetBucketVersion()
if new_arg:
new_args_for_cmds.append(new_arg)
- new_arg.AddCmdArgs(cmd_args)
- new_init_args = []
- for arg in new_args_for_cmds:
- arg.AddInitArgs(new_init_args)
+ self.args_for_cmds = new_args_for_cmds
- Function.__init__(
- self,
- func.original_name,
- "%sBucket" % func.name,
- func.info,
- func.return_type,
- new_args,
- new_args_for_cmds,
- cmd_args,
- new_init_args,
- 0)
-
-# def InitFunction(self):
-# """Overridden from Function"""
-# pass
+ Function.InitFunction(self)
def WriteCommandDescription(self, file):
"""Overridden from Function"""
@@ -6919,45 +6966,9 @@ class GLGenerator(object):
self.functions = []
self.verbose = verbose
self.errors = 0
- self._function_info = {}
- self._empty_type_handler = TypeHandler()
- self._empty_function_info = FunctionInfo({}, self._empty_type_handler)
self.pepper_interfaces = []
self.interface_info = {}
- self._type_handlers = {
- 'Bind': BindHandler(),
- 'Create': CreateHandler(),
- 'Custom': CustomHandler(),
- 'Data': DataHandler(),
- 'Delete': DeleteHandler(),
- 'DELn': DELnHandler(),
- 'GENn': GENnHandler(),
- 'GETn': GETnHandler(),
- 'GLchar': GLcharHandler(),
- 'GLcharN': GLcharNHandler(),
- 'HandWritten': HandWrittenHandler(),
- 'Is': IsHandler(),
- 'Manual': ManualHandler(),
- 'PUT': PUTHandler(),
- 'PUTn': PUTnHandler(),
- 'PUTXn': PUTXnHandler(),
- 'StateSet': StateSetHandler(),
- 'StateSetRGBAlpha': StateSetRGBAlphaHandler(),
- 'StateSetFrontBack': StateSetFrontBackHandler(),
- 'StateSetFrontBackSeparate': StateSetFrontBackSeparateHandler(),
- 'StateSetNamedParameter': StateSetNamedParameter(),
- 'STRn': STRnHandler(),
- 'Todo': TodoHandler(),
- }
-
- for func_name in _FUNCTION_INFO:
- info = _FUNCTION_INFO[func_name]
- type = ''
- if 'type' in info:
- type = info['type']
- self._function_info[func_name] = FunctionInfo(info,
- self.GetTypeHandler(type))
for interface in _PEPPER_INTERFACES:
interface = PepperInterface(interface)
self.pepper_interfaces.append(interface)
@@ -6967,20 +6978,17 @@ class GLGenerator(object):
"""Adds a function."""
self.functions.append(func)
- def GetTypeHandler(self, name):
- """Gets a type info for the given type."""
- if len(name):
- if name in self._type_handlers:
- return self._type_handlers[name]
- else:
- raise KeyError("no such type handler: %s" % name)
- return self._empty_type_handler
-
def GetFunctionInfo(self, name):
"""Gets a type info for the given function name."""
- if name in self._function_info:
- return self._function_info[name]
- return self._empty_function_info
+ if name in _FUNCTION_INFO:
+ func_info = _FUNCTION_INFO[name].copy()
+ else:
+ func_info = {}
+
+ if not 'type' in func_info:
+ func_info['type'] = ''
+
+ return func_info
def Log(self, msg):
"""Prints something if verbose is true."""
@@ -7008,22 +7016,6 @@ class GLGenerator(object):
file.Write("} // namespace gpu\n")
file.Write("\n")
- def ParseArgs(self, arg_string):
- """Parses a function arg string."""
- args = []
- num_pointer_args = 0
- parts = arg_string.split(',')
- is_gl_enum = False
- for arg_string in parts:
- if arg_string.startswith('GLenum '):
- is_gl_enum = True
- arg = CreateArg(arg_string)
- if arg:
- args.append(arg)
- if arg.IsPointer():
- num_pointer_args += 1
- return (args, num_pointer_args, is_gl_enum)
-
def ParseGLH(self, filename):
"""Parses the cmd_buffer_functions.txt file and extracts the functions"""
f = open(filename, "r")
@@ -7034,34 +7026,31 @@ class GLGenerator(object):
if match:
func_name = match.group(2)[2:]
func_info = self.GetFunctionInfo(func_name)
- if func_info.type != 'Noop':
- return_type = match.group(1).strip()
- arg_string = match.group(3)
- (args, num_pointer_args, is_gl_enum) = self.ParseArgs(arg_string)
- # comment in to find out which functions use bare enums.
- # if is_gl_enum:
- # self.Log("%s uses bare GLenum" % func_name)
- args_for_cmds = args
- if hasattr(func_info, 'cmd_args'):
- (args_for_cmds, num_pointer_args, is_gl_enum) = (
- self.ParseArgs(getattr(func_info, 'cmd_args')))
- cmd_args = []
- for arg in args_for_cmds:
- arg.AddCmdArgs(cmd_args)
- init_args = []
- for arg in args_for_cmds:
- arg.AddInitArgs(init_args)
- return_arg = CreateArg(return_type + " result")
- if return_arg:
- init_args.append(return_arg)
- f = Function(func_name, func_name, func_info, return_type, args,
- args_for_cmds, cmd_args, init_args, num_pointer_args)
- self.original_functions.append(f)
- gen_cmd = f.GetInfo('gen_cmd')
- if gen_cmd == True or gen_cmd == None:
- self.AddFunction(f)
- f.type_handler.AddImmediateFunction(self, f)
- f.type_handler.AddBucketFunction(self, f)
+ if func_info['type'] == 'Noop':
+ continue
+
+ parsed_func_info = {
+ 'original_name': func_name,
+ 'original_args': match.group(3),
+ 'return_type': match.group(1).strip(),
+ }
+
+ for k in parsed_func_info.keys():
+ if not k in func_info:
+ func_info[k] = parsed_func_info[k]
+
+ f = Function(func_name, func_info)
+ self.original_functions.append(f)
+
+ #for arg in f.GetOriginalArgs():
+ # if not isinstance(arg, EnumArgument) and arg.type == 'GLenum':
+ # self.Log("%s uses bare GLenum %s." % (func_name, arg.name))
+
+ gen_cmd = f.GetInfo('gen_cmd')
+ if gen_cmd == True or gen_cmd == None:
+ self.AddFunction(f)
+ f.type_handler.AddImmediateFunction(self, f)
+ f.type_handler.AddBucketFunction(self, f)
self.Log("Auto Generated Functions : %d" %
len([f for f in self.functions if f.can_auto_generate or
@@ -7073,7 +7062,7 @@ class GLGenerator(object):
self.Log("Non Auto Generated Functions: %d" % len(funcs))
for f in funcs:
- self.Log(" %-10s %-20s gl%s" % (f.info.type, f.return_type, f.name))
+ self.Log(" %-10s %-20s gl%s" % (f.info['type'], f.return_type, f.name))
def WriteCommandIds(self, filename):
"""Writes the command buffer format"""