diff options
author | dmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-30 18:35:59 +0000 |
---|---|---|
committer | dmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-09-30 18:35:59 +0000 |
commit | 4e46a73c1185a737a525585b25c5e27cb22e405e (patch) | |
tree | 105b1c4aedadf30271df1a74ef80a1622e0705bf /gpu | |
parent | 0a2686150c957ec46a1a9bdb3ae864c87a665c95 (diff) | |
download | chromium_src-4e46a73c1185a737a525585b25c5e27cb22e405e.zip chromium_src-4e46a73c1185a737a525585b25c5e27cb22e405e.tar.gz chromium_src-4e46a73c1185a737a525585b25c5e27cb22e405e.tar.bz2 |
PPAPI: Make GLES2 calls resilient to bad/dead resources.
Currently, if PPB_OpenGLES2 is passed a bad resource, or if a bad resource is
set prior to OpenGLES2 calls, our code happily dereferences a NULL pointer.
This CL tries to address that by handling failure in a way that's consistent
with our other Pepper interfaces.
It also appears that the "old" approach to locking would end up locking twice
per call. Once to get the PPB_GLES2Impl, then unlocked, and then locked
again inside the LockingCommandBuffer (meaning that the PPB_GLES2Impl
might not actually be valid at the time we dereference it!!). This change
simplifies that and removes the old/hacky way of locking.
BUG=275815
Review URL: https://codereview.chromium.org/24466004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@226017 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rwxr-xr-x | gpu/command_buffer/build_gles2_cmd_buffer.py | 79 |
1 files changed, 60 insertions, 19 deletions
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index f4c7e5b..83700f6 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py @@ -1212,6 +1212,10 @@ _PEPPER_INTERFACES = [ # valid_args: A dictionary of argument indices to args to use in unit tests # when they can not be automatically determined. # pepper_interface: The pepper interface that is used for this extension +# pepper_args: A string representing the argument list (what would appear in +# C/C++ between the parentheses for the function declaration) +# that the Pepper API expects for this function. Use this only if +# the stable Pepper API differs from the GLES2 argument list. # invalid_test: False if no invalid test needed. # shadowed: True = the value is shadowed so no glGetXXX call will be made. # first_element_only: For PUT types, True if only the first element of an @@ -1627,6 +1631,7 @@ _FUNCTION_INFO = { 'cmd_args': 'GLidProgram program, const char* name, NonImmediate GLint* location', 'result': ['GLint'], + 'error_return': -1, # http://www.opengl.org/sdk/docs/man/xhtml/glGetAttribLocation.xml }, 'GetBooleanv': { 'type': 'GETn', @@ -1778,6 +1783,7 @@ _FUNCTION_INFO = { 'cmd_args': 'GLidProgram program, const char* name, NonImmediate GLint* location', 'result': ['GLint'], + 'error_return': -1, # http://www.opengl.org/sdk/docs/man/xhtml/glGetUniformLocation.xml }, 'GetVertexAttribfv': { 'type': 'GETn', @@ -1941,6 +1947,8 @@ _FUNCTION_INFO = { 'client_test': False, 'cmd_args': 'GLuint shader, const char* data', + 'pepper_args': + 'GLuint shader, GLsizei count, const char** str, const GLint* length', }, 'StencilMask': { 'type': 'StateSetFrontBack', @@ -2305,6 +2313,7 @@ _FUNCTION_INFO = { }, 'BindUniformLocationCHROMIUM': { 'type': 'GLchar', + 'extension': True, 'bucket': True, 'needs_size': True, 'gl_test_func': 'DoBindUniformLocationCHROMIUM', @@ -2313,20 +2322,24 @@ _FUNCTION_INFO = { 'type': 'GLcharN', 'decoder_func': 'DoInsertEventMarkerEXT', 'expectation': False, + 'extension': True, }, 'PushGroupMarkerEXT': { 'type': 'GLcharN', 'decoder_func': 'DoPushGroupMarkerEXT', 'expectation': False, + 'extension': True, }, 'PopGroupMarkerEXT': { 'decoder_func': 'DoPopGroupMarkerEXT', 'expectation': False, + 'extension': True, 'impl_func': False, }, 'GenVertexArraysOES': { 'type': 'GENn', + 'extension': True, 'gl_test_func': 'glGenVertexArraysOES', 'resource_type': 'VertexArray', 'resource_types': 'VertexArrays', @@ -2334,6 +2347,7 @@ _FUNCTION_INFO = { }, 'BindVertexArrayOES': { 'type': 'Bind', + 'extension': True, 'gl_test_func': 'glBindVertexArrayOES', 'decoder_func': 'DoBindVertexArrayOES', 'gen_func': 'GenVertexArraysOES', @@ -2342,6 +2356,7 @@ _FUNCTION_INFO = { }, 'DeleteVertexArraysOES': { 'type': 'DELn', + 'extension': True, 'gl_test_func': 'glDeleteVertexArraysOES', 'resource_type': 'VertexArray', 'resource_types': 'VertexArrays', @@ -2349,6 +2364,7 @@ _FUNCTION_INFO = { }, 'IsVertexArrayOES': { 'type': 'Is', + 'extension': True, 'gl_test_func': 'glIsVertexArrayOES', 'decoder_func': 'DoIsVertexArrayOES', 'expectation': False, @@ -6394,7 +6410,7 @@ class Function(object): """Gets the last original argument to this function.""" return self.original_args[len(self.original_args) - 1] - def __GetArgList(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): @@ -6402,46 +6418,53 @@ class Function(object): return "%s%s" % (comma, arg_string) def MakeTypedOriginalArgString(self, prefix, add_comma = False): - """Gets a list of arguments as they arg in GL.""" + """Gets a list of arguments as they are in GL.""" args = self.GetOriginalArgs() arg_string = ", ".join( ["%s %s%s" % (arg.type, prefix, arg.name) for arg in args]) - return self.__GetArgList(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.__GetArgList(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.""" + if self.GetInfo("pepper_args"): + return self.GetInfo("pepper_args") + else: + return self.MakeTypedOriginalArgString(prefix, False) def MakeTypedCmdArgString(self, prefix, add_comma = False): """Gets a typed list of arguments as they need to be for command buffers.""" args = self.GetCmdArgs() arg_string = ", ".join( ["%s %s%s" % (arg.type, prefix, arg.name) for arg in args]) - return self.__GetArgList(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.__GetArgList(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.__GetArgList(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.__GetArgList(arg_string, add_comma) + return self.__MaybePrependComma(arg_string, add_comma) def MakeLogArgString(self): """Makes a string of the arguments for the LOG macros""" @@ -7593,7 +7616,7 @@ const size_t GLES2Util::enum_to_string_table_len_ = if not func.InPepperInterface(interface): continue - original_arg = func.MakeTypedOriginalArgString("") + original_arg = func.MakeTypedPepperArgString("") context_arg = "PP_Resource context" if len(original_arg): arg = context_arg + ", " + original_arg @@ -7621,31 +7644,49 @@ const size_t GLES2Util::enum_to_string_table_len_ = file.Write("namespace ppapi {\n\n") file.Write("namespace {\n\n") - file.Write("gpu::gles2::GLES2Implementation*" - " GetGLES(PP_Resource context) {\n") - file.Write(" thunk::EnterResource<thunk::PPB_Graphics3D_API>" - " enter_g3d(context, false);\n") - file.Write(" DCHECK(enter_g3d.succeeded());\n") - file.Write(" return static_cast<PPB_Graphics3D_Shared*>" - "(enter_g3d.object())->gles2_impl();\n") - file.Write("}\n\n") + file.Write("typedef thunk::EnterResource<thunk::PPB_Graphics3D_API>" + " Enter3D;\n\n") + + file.Write("gpu::gles2::GLES2Implementation* ToGles2Impl(Enter3D*" + " enter) {\n") + file.Write(" DCHECK(enter);\n") + file.Write(" DCHECK(enter->succeeded());\n") + file.Write(" return static_cast<PPB_Graphics3D_Shared*>(enter->object())->" + "gles2_impl();\n"); + file.Write("}\n\n"); for func in self.original_functions: if not func.InAnyPepperExtension(): continue - original_arg = func.MakeTypedOriginalArgString("") + original_arg = func.MakeTypedPepperArgString("") context_arg = "PP_Resource context_id" if len(original_arg): arg = context_arg + ", " + original_arg else: arg = context_arg file.Write("%s %s(%s) {\n" % (func.return_type, func.name, arg)) + file.Write(" Enter3D enter(context_id, true);\n") + file.Write(" if (enter.succeeded()) {\n") return_str = "" if func.return_type == "void" else "return " - file.Write(" %sGetGLES(context_id)->%s(%s);\n" % + file.Write(" %sToGles2Impl(&enter)->%s(%s);\n" % (return_str, func.original_name, func.MakeOriginalArgString(""))) + file.Write(" }") + if func.return_type == "void": + file.Write("\n") + else: + file.Write(" else {\n") + error_return = "0" + if func.GetInfo("error_return"): + error_return = func.GetInfo("error_return") + elif func.return_type == "GLboolean": + error_return = "GL_FALSE" + elif "*" in func.return_type: + error_return = "NULL" + file.Write(" return %s;\n" % error_return) + file.Write(" }\n") file.Write("}\n\n") file.Write("} // namespace\n") |