Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1487)

Unified Diff: gpu/command_buffer/build_gles2_cmd_buffer.py

Issue 276873002: Clarify function info object usage in the command buffer generator (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@00-cmd-buffer-refactor--put-data-type
Patch Set: rebase Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 95aac878b79705883eb56db478cebd89d97c76e2..8f6cf77257a775b20f732e4fddd4315b88bccc9d 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"""
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698