diff options
Diffstat (limited to 'ui')
-rw-r--r-- | ui/gfx/gl/generate_bindings.py | 220 | ||||
-rw-r--r-- | ui/gfx/gl/gl.gyp | 5 | ||||
-rw-r--r-- | ui/gfx/gl/gl_bindings_skia_in_process.cc | 9 | ||||
-rw-r--r-- | ui/gfx/gl/gl_context.cc | 11 | ||||
-rw-r--r-- | ui/gfx/gl/gl_context.h | 5 | ||||
-rw-r--r-- | ui/gfx/gl/gl_context_cgl.cc | 5 | ||||
-rw-r--r-- | ui/gfx/gl/gl_context_egl.cc | 5 | ||||
-rw-r--r-- | ui/gfx/gl/gl_context_glx.cc | 5 | ||||
-rw-r--r-- | ui/gfx/gl/gl_context_osmesa.cc | 5 | ||||
-rw-r--r-- | ui/gfx/gl/gl_context_wgl.cc | 5 | ||||
-rw-r--r-- | ui/gfx/gl/gl_implementation.cc | 34 | ||||
-rw-r--r-- | ui/gfx/gl/gl_implementation.h | 11 | ||||
-rw-r--r-- | ui/gfx/gl/gl_implementation_linux.cc | 25 | ||||
-rw-r--r-- | ui/gfx/gl/gl_implementation_mac.cc | 20 | ||||
-rw-r--r-- | ui/gfx/gl/gl_implementation_win.cc | 25 | ||||
-rw-r--r-- | ui/gfx/gl/gl_interface.h | 8 |
16 files changed, 361 insertions, 37 deletions
diff --git a/ui/gfx/gl/generate_bindings.py b/ui/gfx/gl/generate_bindings.py index 9d5ecf8..6260a8e 100644 --- a/ui/gfx/gl/generate_bindings.py +++ b/ui/gfx/gl/generate_bindings.py @@ -7,6 +7,7 @@ """code generator for GL/GLES extension wrangler.""" import os +import collections import re import sys @@ -19,7 +20,7 @@ GL_FUNCTIONS = [ ['void', ['glBindBuffer'], 'GLenum target, GLuint buffer'], ['void', ['glBindFragDataLocation'], 'GLuint program, GLuint colorNumber, const char* name'], -['void', ['glBindFragDataLocationIndexedARB'], +['void', ['glBindFragDataLocationIndexed'], 'GLuint program, GLuint colorNumber, GLuint index, const char* name'], ['void', ['glBindFramebufferEXT', 'glBindFramebuffer'], 'GLenum target, GLuint framebuffer'], @@ -33,11 +34,11 @@ GL_FUNCTIONS = [ ['void', ['glBlendFunc'], 'GLenum sfactor, GLenum dfactor'], ['void', ['glBlendFuncSeparate'], 'GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha'], -['void', ['glBlitFramebufferEXT', 'BlitFramebuffer'], +['void', ['glBlitFramebufferEXT', 'glBlitFramebuffer'], 'GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, ' 'GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, ' 'GLbitfield mask, GLenum filter'], -['void', ['glBlitFramebufferANGLE', 'BlitFramebuffer'], +['void', ['glBlitFramebufferANGLE', 'glBlitFramebuffer'], 'GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, ' 'GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, ' 'GLbitfield mask, GLenum filter'], @@ -181,7 +182,7 @@ GL_FUNCTIONS = [ ['GLboolean', ['glIsTexture'], 'GLuint texture'], ['void', ['glLineWidth'], 'GLfloat width'], ['void', ['glLinkProgram'], 'GLuint program'], -['void*', ['glMapBuffer'], 'GLenum target, GLenum access'], +['void*', ['glMapBuffer', 'glMapBufferOES'], 'GLenum target, GLenum access'], ['void', ['glPixelStorei'], 'GLenum pname, GLint param'], ['void', ['glPolygonOffset'], 'GLfloat factor, GLfloat units'], ['void', ['glQueryCounter'], 'GLuint id, GLenum target'], @@ -251,7 +252,7 @@ GL_FUNCTIONS = [ 'GLint location, GLsizei count, GLboolean transpose, const GLfloat* value'], ['void', ['glUniformMatrix4fv'], 'GLint location, GLsizei count, GLboolean transpose, const GLfloat* value'], -['GLboolean', ['glUnmapBuffer'], 'GLenum target'], +['GLboolean', ['glUnmapBuffer', 'glUnmapBufferOES'], 'GLenum target'], ['void', ['glUseProgram'], 'GLuint program'], ['void', ['glValidateProgram'], 'GLuint program'], ['void', ['glVertexAttrib1f'], 'GLuint indx, GLfloat x'], @@ -465,11 +466,14 @@ GLX_FUNCTIONS = [ ] FUNCTION_SETS = [ - [GL_FUNCTIONS, 'gl'], - [OSMESA_FUNCTIONS, 'osmesa'], - [EGL_FUNCTIONS, 'egl'], - [WGL_FUNCTIONS, 'wgl'], - [GLX_FUNCTIONS, 'glx'], + [GL_FUNCTIONS, 'gl', ['../../../third_party/mesa/MesaLib/include/GL/glext.h', + '../../../gpu/GLES2/gl2ext.h']], + [OSMESA_FUNCTIONS, 'osmesa', []], + [EGL_FUNCTIONS, 'egl', ['../../../gpu/EGL/eglext.h']], + [WGL_FUNCTIONS, 'wgl', [ + '../../../third_party/mesa/MesaLib/include/GL/wglext.h']], + [GLX_FUNCTIONS, 'glx', [ + '../../../third_party/mesa/MesaLib/include/GL/glxext.h']], ] def GenerateHeader(file, functions, set_name): @@ -489,7 +493,11 @@ def GenerateHeader(file, functions, set_name): file.write('\n') file.write('namespace gfx {\n') file.write('\n') + file.write('class GLContext;\n') + file.write('\n') file.write('void InitializeGLBindings%s();\n' % set_name.upper()) + file.write('void InitializeGLExtensionBindings%s(GLContext* context);\n' % + set_name.upper()) file.write('void InitializeDebugGLBindings%s();\n' % set_name.upper()) # Write typedefs for function pointer types. Always use the GL name for the @@ -519,7 +527,7 @@ def GenerateHeader(file, functions, set_name): set_name.upper()) -def GenerateSource(file, functions, set_name): +def GenerateSource(file, functions, set_name, used_extension_functions): """Generates gl_binding_autogen_x.cc""" # Write file header. @@ -530,12 +538,16 @@ def GenerateSource(file, functions, set_name): file.write('// This file is automatically generated.\n') file.write('\n') file.write('#include "ui/gfx/gl/gl_bindings.h"\n') + file.write('#include "ui/gfx/gl/gl_context.h"\n') file.write('#include "ui/gfx/gl/gl_implementation.h"\n') # Write definitions of function pointers. file.write('\n') file.write('namespace gfx {\n') file.write('\n') + file.write('static bool g_debugBindingsInitialized;\n') + file.write('static void UpdateDebugGLExtensionBindings();\n') + file.write('\n') for [return_type, names, arguments] in functions: file.write('%sProc g_%s;\n' % (names[0], names[0])) @@ -543,18 +555,45 @@ def GenerateSource(file, functions, set_name): for [return_type, names, arguments] in functions: file.write('static %sProc g_debug_%s;\n' % (names[0], names[0])) - # Write function to initialize the function pointers. + # Write function to initialize the core function pointers. The code assumes + # any non-NULL pointer returned by GetGLCoreProcAddress() is valid, although + # it may be overwritten by an extension function pointer later. file.write('\n') file.write('void InitializeGLBindings%s() {\n' % set_name.upper()) for [return_type, names, arguments] in functions: - for name in names: - file.write(' if (!g_%s)\n' % names[0]) + for i, name in enumerate(names): + if i: + file.write(' if (!g_%s)\n ' % names[0]) file.write( - ' g_%s = reinterpret_cast<%sProc>(GetGLProcAddress("%s"));\n' % + ' g_%s = reinterpret_cast<%sProc>(GetGLCoreProcAddress("%s"));\n' % (names[0], names[0], name)) file.write('}\n') file.write('\n') + # Write function to initialize the extension function pointers. This function + # uses a current context to query which extensions are actually supported. + file.write('void InitializeGLExtensionBindings%s(GLContext* context) {\n' % + set_name.upper()) + file.write(' DCHECK(context && context->IsCurrent(NULL));\n') + for extension, ext_functions in used_extension_functions: + file.write(' if (context->HasExtension("%s")) {\n' % extension) + queried_entry_points = set() + for entry_point_name, function_name in ext_functions: + # Replace the pointer unconditionally unless this extension has several + # alternatives for the same entry point (e.g., + # GL_ARB_blend_func_extended). + if entry_point_name in queried_entry_points: + file.write(' if (!g_%s)\n ' % entry_point_name) + file.write( + ' g_%s = reinterpret_cast<%sProc>(GetGLProcAddress("%s"));\n' % + (entry_point_name, entry_point_name, function_name)) + queried_entry_points.add(entry_point_name) + file.write(' }\n') + file.write(' if (g_debugBindingsInitialized)\n') + file.write(' UpdateDebugGLExtensionBindings();\n') + file.write('}\n') + file.write('\n') + # Write logging wrappers for each function. file.write('extern "C" {\n') for [return_type, names, arguments] in functions: @@ -597,19 +636,31 @@ def GenerateSource(file, functions, set_name): file.write('}\n') file.write('} // extern "C"\n') - # Write function to initialize the function pointers. + # Write function to initialize the debug function pointers. file.write('\n') file.write('void InitializeDebugGLBindings%s() {\n' % set_name.upper()) for [return_type, names, arguments] in functions: - for name in names: - file.write(' if (!g_debug_%s) {\n' % names[0]) - file.write(' g_debug_%s = g_%s;\n' % (names[0], names[0])) - file.write(' g_%s = Debug_%s;\n' % (names[0], names[0])) - file.write(' }\n') + file.write(' if (!g_debug_%s) {\n' % names[0]) + file.write(' g_debug_%s = g_%s;\n' % (names[0], names[0])) + file.write(' g_%s = Debug_%s;\n' % (names[0], names[0])) + file.write(' }\n') + file.write(' g_debugBindingsInitialized = true;\n') file.write('}\n') + + # Write function to update the debug function pointers to extension functions + # after the extensions have been initialized. file.write('\n') + file.write('static void UpdateDebugGLExtensionBindings() {\n') + for extension, ext_functions in used_extension_functions: + for name, _ in ext_functions: + file.write(' if (g_debug_%s != g_%s &&\n' % (name, name)) + file.write(' g_%s != Debug_%s) {\n' % (name, name)) + file.write(' g_debug_%s = g_%s;\n' % (name, name)) + file.write(' g_%s = Debug_%s;\n' % (name, name)) + file.write(' }\n') + file.write('}\n') - file.write( '} // namespace gfx\n') + file.write('} // namespace gfx\n') def GenerateMockSource(file, functions): @@ -646,18 +697,135 @@ def GenerateMockSource(file, functions): (function_name, argument_names)) file.write('}\n') + # Write an 'invalid' function to catch code calling through uninitialized + # function pointers or trying to interpret the return value of + # GLProcAddress(). + file.write('\n') + file.write('static void MockInvalidFunction() {\n') + file.write(' NOTREACHED();\n') + file.write('}\n') + # Write a function to lookup a mock GL function based on its name. file.write('\n') file.write('void* GL_BINDING_CALL GetMockGLProcAddress(const char* name) {\n') for [return_type, names, arguments] in functions: file.write(' if (strcmp(name, "%s") == 0)\n' % names[0]) file.write(' return reinterpret_cast<void*>(Mock_%s);\n' % names[0]) - file.write(' return NULL;\n') + # Always return a non-NULL pointer like some EGL implementations do. + file.write(' return reinterpret_cast<void*>(&MockInvalidFunction);\n') file.write('}\n'); file.write('\n') file.write('} // namespace gfx\n') +def ParseExtensionFunctionsFromHeader(header_file): + """Parse a C extension header file and return a map from extension names to + a list of functions. + + Args: + header_file: Line-iterable C header file. + Returns: + Map of extension name => functions. + """ + extension_start = re.compile(r'#define ([A-Z]+_[A-Z]+_[a-zA-Z]\w+) 1') + extension_function = re.compile(r'.+\s+([a-z]+\w+)\s*\(.+\);') + typedef = re.compile(r'typedef .*') + macro_start = re.compile(r'^#(if|ifdef|ifndef).*') + macro_end = re.compile(r'^#endif.*') + macro_depth = 0 + current_extension = None + current_extension_depth = 0 + extensions = collections.defaultdict(lambda: []) + for line in header_file: + if macro_start.match(line): + macro_depth += 1 + elif macro_end.match(line): + macro_depth -= 1 + if macro_depth < current_extension_depth: + current_extension = None + match = extension_start.match(line) + if match: + current_extension = match.group(1) + current_extension_depth = macro_depth + assert current_extension not in extensions, \ + "Duplicate extension: " + current_extension + match = extension_function.match(line) + if match and current_extension and not typedef.match(line): + extensions[current_extension].append(match.group(1)) + return extensions + +def GetExtensionFunctions(extension_headers): + """Parse extension functions from a list of header files. + + Args: + extension_headers: List of header file names. + Returns: + Map of extension name => list of functions. + """ + extensions = {} + for header in extension_headers: + extensions.update(ParseExtensionFunctionsFromHeader(open(header))) + return extensions + +def GetFunctionToExtensionMap(extensions): + """Construct map from a function names to extensions which define the + function. + + Args: + extensions: Map of extension name => functions. + Returns: + Map of function name => extension name. + """ + function_to_extension = {} + for extension, functions in extensions.items(): + for function in functions: + assert function not in function_to_extension, \ + "Duplicate function: " + function + function_to_extension[function] = extension + return function_to_extension + +def LooksLikeExtensionFunction(function): + """Heuristic to see if a function name is consistent with extension function + naming.""" + vendor = re.match(r'\w+?([A-Z][A-Z]+)$', function) + return vendor is not None and not vendor.group(1) in ['GL', 'API', 'DC'] + +def GetUsedExtensionFunctions(functions, extension_headers): + """Determine which functions belong to extensions. + + Args: + functions: List of (return type, function names, arguments). + extension_headers: List of header file names. + Returns: + List of (extension name, [function name alternatives]) sorted with least + preferred extensions first. + """ + # Parse known extensions. + extensions = GetExtensionFunctions(extension_headers) + functions_to_extensions = GetFunctionToExtensionMap(extensions) + + # Collect all used extension functions. + used_extension_functions = collections.defaultdict(lambda: []) + for [return_type, names, arguments] in functions: + for name in names: + # Make sure we know about all extension functions. + if (LooksLikeExtensionFunction(name) and + not name in functions_to_extensions): + raise RuntimeError('%s looks like an extension function but does not ' + 'belong to any of the known extensions.' % name) + if name in functions_to_extensions: + extension = functions_to_extensions[name] + used_extension_functions[extension].append((names[0], name)) + + def ExtensionSortKey(name): + # Prefer ratified extensions and EXTs. + preferences = ['_ARB_', '_OES_', '_EXT_', ''] + for i, category in enumerate(preferences): + if category in name: + return -i + used_extension_functions = sorted(used_extension_functions.items(), + key = lambda item: ExtensionSortKey(item[0])) + return used_extension_functions def main(argv): """This is the main function.""" @@ -667,7 +835,7 @@ def main(argv): else: dir = '.' - for [functions, set_name] in FUNCTION_SETS: + for [functions, set_name, extension_headers] in FUNCTION_SETS: header_file = open( os.path.join(dir, 'gl_bindings_autogen_%s.h' % set_name), 'wb') GenerateHeader(header_file, functions, set_name) @@ -675,7 +843,9 @@ def main(argv): source_file = open( os.path.join(dir, 'gl_bindings_autogen_%s.cc' % set_name), 'wb') - GenerateSource(source_file, functions, set_name) + used_extension_functions = GetUsedExtensionFunctions( + functions, extension_headers) + GenerateSource(source_file, functions, set_name, used_extension_functions) source_file.close() source_file = open(os.path.join(dir, 'gl_bindings_autogen_mock.cc'), 'wb') diff --git a/ui/gfx/gl/gl.gyp b/ui/gfx/gl/gl.gyp index f29f270..22e40b9 100644 --- a/ui/gfx/gl/gl.gyp +++ b/ui/gfx/gl/gl.gyp @@ -87,6 +87,11 @@ 'action_name': 'generate_gl_bindings', 'inputs': [ 'generate_bindings.py', + '../../../gpu/GLES2/gl2ext.h', + '../../../gpu/EGL/eglext.h', + '../../../third_party/mesa/MesaLib/include/GL/glext.h', + '../../../third_party/mesa/MesaLib/include/GL/glxext.h', + '../../../third_party/mesa/MesaLib/include/GL/wglext.h', ], 'outputs': [ '<(gl_binding_output_dir)/gl_bindings_autogen_egl.cc', diff --git a/ui/gfx/gl/gl_bindings_skia_in_process.cc b/ui/gfx/gl/gl_bindings_skia_in_process.cc index 1fafda0..0be194a 100644 --- a/ui/gfx/gl/gl_bindings_skia_in_process.cc +++ b/ui/gfx/gl/gl_bindings_skia_in_process.cc @@ -43,9 +43,9 @@ GLvoid StubGLBindFragDataLocation(GLuint program, GLuint colorNumber, glBindFragDataLocation(program, colorNumber, name); } -GLvoid StubGLBindFragDataLocationIndexedARB(GLuint program, GLuint colorNumber, - GLuint index, const GLchar * name) { - glBindFragDataLocationIndexedARB(program, colorNumber, index, name); +GLvoid StubGLBindFragDataLocationIndexed(GLuint program, GLuint colorNumber, + GLuint index, const GLchar * name) { + glBindFragDataLocationIndexed(program, colorNumber, index, name); } GLvoid StubGLBindFramebuffer(GLenum target, GLuint framebuffer) { @@ -661,9 +661,8 @@ GrGLInterface* CreateInProcessSkiaGLBinding() { interface->fMapBuffer = StubGLMapBuffer; interface->fUnmapBuffer = StubGLUnmapBuffer; interface->fBindFragDataLocationIndexed = - StubGLBindFragDataLocationIndexedARB; + StubGLBindFragDataLocationIndexed; return interface; } } // namespace gfx - diff --git a/ui/gfx/gl/gl_context.cc b/ui/gfx/gl/gl_context.cc index 6c25052e..6053bdb 100644 --- a/ui/gfx/gl/gl_context.cc +++ b/ui/gfx/gl/gl_context.cc @@ -81,4 +81,15 @@ bool GLContext::WasAllocatedUsingARBRobustness() { return false; } +bool GLContext::InitializeExtensionBindings() { + DCHECK(IsCurrent(NULL)); + static bool initialized = false; + if (initialized) + return initialized; + initialized = InitializeGLExtensionBindings(GetGLImplementation(), this); + if (!initialized) + LOG(ERROR) << "Could not initialize extension bindings."; + return initialized; +} + } // namespace gfx diff --git a/ui/gfx/gl/gl_context.h b/ui/gfx/gl/gl_context.h index 3046485..67fe57e 100644 --- a/ui/gfx/gl/gl_context.h +++ b/ui/gfx/gl/gl_context.h @@ -77,6 +77,11 @@ class GL_EXPORT GLContext : public base::RefCounted<GLContext> { virtual ~GLContext(); static void SetCurrent(GLContext* context, GLSurface* surface); + // Initialize function pointers to extension functions in the GL + // implementation. Should be called immediately after this context is made + // current. + bool InitializeExtensionBindings(); + private: scoped_refptr<GLShareGroup> share_group_; friend class base::RefCounted<GLContext>; diff --git a/ui/gfx/gl/gl_context_cgl.cc b/ui/gfx/gl/gl_context_cgl.cc index 0e96bd4..8790602 100644 --- a/ui/gfx/gl/gl_context_cgl.cc +++ b/ui/gfx/gl/gl_context_cgl.cc @@ -103,6 +103,11 @@ bool GLContextCGL::MakeCurrent(GLSurface* surface) { } SetCurrent(this, surface); + if (!InitializeExtensionBindings()) { + ReleaseCurrent(surface); + return false; + } + if (!surface->OnMakeCurrent(this)) { LOG(ERROR) << "Unable to make gl context current."; return false; diff --git a/ui/gfx/gl/gl_context_egl.cc b/ui/gfx/gl/gl_context_egl.cc index 6c69f79..d9b6950 100644 --- a/ui/gfx/gl/gl_context_egl.cc +++ b/ui/gfx/gl/gl_context_egl.cc @@ -96,6 +96,11 @@ bool GLContextEGL::MakeCurrent(GLSurface* surface) { } SetCurrent(this, surface); + if (!InitializeExtensionBindings()) { + ReleaseCurrent(surface); + return false; + } + if (!surface->OnMakeCurrent(this)) { LOG(ERROR) << "Could not make current."; return false; diff --git a/ui/gfx/gl/gl_context_glx.cc b/ui/gfx/gl/gl_context_glx.cc index 0f392e6..3e89981 100644 --- a/ui/gfx/gl/gl_context_glx.cc +++ b/ui/gfx/gl/gl_context_glx.cc @@ -178,6 +178,11 @@ bool GLContextGLX::MakeCurrent(GLSurface* surface) { } SetCurrent(this, surface); + if (!InitializeExtensionBindings()) { + ReleaseCurrent(surface); + return false; + } + if (!surface->OnMakeCurrent(this)) { LOG(ERROR) << "Could not make current."; return false; diff --git a/ui/gfx/gl/gl_context_osmesa.cc b/ui/gfx/gl/gl_context_osmesa.cc index df7766d..efa6d16 100644 --- a/ui/gfx/gl/gl_context_osmesa.cc +++ b/ui/gfx/gl/gl_context_osmesa.cc @@ -70,6 +70,11 @@ bool GLContextOSMesa::MakeCurrent(GLSurface* surface) { OSMesaPixelStore(OSMESA_Y_UP, 0); SetCurrent(this, surface); + if (!InitializeExtensionBindings()) { + ReleaseCurrent(surface); + return false; + } + if (!surface->OnMakeCurrent(this)) { LOG(ERROR) << "Could not make current."; return false; diff --git a/ui/gfx/gl/gl_context_wgl.cc b/ui/gfx/gl/gl_context_wgl.cc index 01506c0..87e50a3 100644 --- a/ui/gfx/gl/gl_context_wgl.cc +++ b/ui/gfx/gl/gl_context_wgl.cc @@ -83,6 +83,11 @@ bool GLContextWGL::MakeCurrent(GLSurface* surface) { } SetCurrent(this, surface); + if (!InitializeExtensionBindings()) { + ReleaseCurrent(surface); + return false; + } + if (!surface->OnMakeCurrent(this)) { LOG(ERROR) << "Could not make current."; return false; diff --git a/ui/gfx/gl/gl_implementation.cc b/ui/gfx/gl/gl_implementation.cc index 19cc91c..f7ad2ee 100644 --- a/ui/gfx/gl/gl_implementation.cc +++ b/ui/gfx/gl/gl_implementation.cc @@ -41,6 +41,21 @@ void CleanupNativeLibraries(void* unused) { g_libraries = NULL; } } + +bool ExportsCoreFunctionsFromGetProcAddress(GLImplementation implementation) { + switch (GetGLImplementation()) { + case kGLImplementationDesktopGL: + case kGLImplementationOSMesaGL: + case kGLImplementationMockGL: + return true; + case kGLImplementationEGLGLES2: + return false; + default: + NOTREACHED(); + return true; + } +} + } GLImplementation GetNamedGLImplementation(const std::string& name) { @@ -137,7 +152,7 @@ void SetGLGetProcAddressProc(GLGetProcAddressProc proc) { g_get_proc_address = proc; } -void* GetGLProcAddress(const char* name) { +void* GetGLCoreProcAddress(const char* name) { DCHECK(g_gl_implementation != kGLImplementationNone); if (g_libraries) { @@ -148,8 +163,8 @@ void* GetGLProcAddress(const char* name) { return proc; } } - - if (g_get_proc_address) { + if (ExportsCoreFunctionsFromGetProcAddress(g_gl_implementation) && + g_get_proc_address) { void* proc = g_get_proc_address(name); if (proc) return proc; @@ -158,4 +173,17 @@ void* GetGLProcAddress(const char* name) { return NULL; } +void* GetGLProcAddress(const char* name) { + DCHECK(g_gl_implementation != kGLImplementationNone); + + void* proc = GetGLCoreProcAddress(name); + if (!proc && g_get_proc_address) { + proc = g_get_proc_address(name); + if (proc) + return proc; + } + + return proc; +} + } // namespace gfx diff --git a/ui/gfx/gl/gl_implementation.h b/ui/gfx/gl/gl_implementation.h index 9024ca1..5d5ab55 100644 --- a/ui/gfx/gl/gl_implementation.h +++ b/ui/gfx/gl/gl_implementation.h @@ -15,6 +15,8 @@ namespace gfx { +class GLContext; + // The GL implementation currently in use. enum GLImplementation { kGLImplementationNone, @@ -33,6 +35,10 @@ typedef void* (*GLGetProcAddressProc)(const char* name); // Initialize a particular GL implementation. GL_EXPORT bool InitializeGLBindings(GLImplementation implementation); +// Initialize extension function bindings for a GL implementation. +GL_EXPORT bool InitializeGLExtensionBindings(GLImplementation implementation, + GLContext* context); + // Initialize Debug logging wrappers for GL bindings. void InitializeDebugGLBindings(); @@ -66,6 +72,11 @@ void AddGLNativeLibrary(base::NativeLibrary library); // Set an additional function that will be called to find GL entry points. void SetGLGetProcAddressProc(GLGetProcAddressProc proc); +// Find a core (non-extension) entry point in the current GL implementation. On +// EGL based implementations core entry points will not be queried through +// GLGetProcAddressProc. +void* GetGLCoreProcAddress(const char* name); + // Find an entry point in the current GL implementation. void* GetGLProcAddress(const char* name); diff --git a/ui/gfx/gl/gl_implementation_linux.cc b/ui/gfx/gl/gl_implementation_linux.cc index 568edeb..952e62e 100644 --- a/ui/gfx/gl/gl_implementation_linux.cc +++ b/ui/gfx/gl/gl_implementation_linux.cc @@ -179,6 +179,31 @@ bool InitializeGLBindings(GLImplementation implementation) { return true; } +bool InitializeGLExtensionBindings(GLImplementation implementation, + GLContext* context) { + switch (implementation) { + case kGLImplementationOSMesaGL: + InitializeGLExtensionBindingsGL(context); + InitializeGLExtensionBindingsOSMESA(context); + break; + case kGLImplementationDesktopGL: + InitializeGLExtensionBindingsGL(context); + InitializeGLExtensionBindingsGLX(context); + break; + case kGLImplementationEGLGLES2: + InitializeGLExtensionBindingsGL(context); + InitializeGLExtensionBindingsEGL(context); + break; + case kGLImplementationMockGL: + InitializeGLExtensionBindingsGL(context); + break; + default: + return false; + } + + return true; +} + void InitializeDebugGLBindings() { InitializeDebugGLBindingsEGL(); InitializeDebugGLBindingsGL(); diff --git a/ui/gfx/gl/gl_implementation_mac.cc b/ui/gfx/gl/gl_implementation_mac.cc index 780f6a7..24d2c4d 100644 --- a/ui/gfx/gl/gl_implementation_mac.cc +++ b/ui/gfx/gl/gl_implementation_mac.cc @@ -96,6 +96,26 @@ bool InitializeGLBindings(GLImplementation implementation) { return true; } +bool InitializeGLExtensionBindings(GLImplementation implementation, + GLContext* context) { + switch (implementation) { + case kGLImplementationOSMesaGL: + InitializeGLExtensionBindingsGL(context); + InitializeGLExtensionBindingsOSMESA(context); + break; + case kGLImplementationDesktopGL: + InitializeGLExtensionBindingsGL(context); + break; + case kGLImplementationMockGL: + InitializeGLExtensionBindingsGL(context); + break; + default: + return false; + } + + return true; +} + void InitializeDebugGLBindings() { InitializeDebugGLBindingsGL(); InitializeDebugGLBindingsOSMESA(); diff --git a/ui/gfx/gl/gl_implementation_win.cc b/ui/gfx/gl/gl_implementation_win.cc index de0ee31..7b74316 100644 --- a/ui/gfx/gl/gl_implementation_win.cc +++ b/ui/gfx/gl/gl_implementation_win.cc @@ -207,6 +207,31 @@ bool InitializeGLBindings(GLImplementation implementation) { return true; } +bool InitializeGLExtensionBindings(GLImplementation implementation, + GLContext* context) { + switch (implementation) { + case kGLImplementationOSMesaGL: + InitializeGLExtensionBindingsGL(context); + InitializeGLExtensionBindingsOSMESA(context); + break; + case kGLImplementationEGLGLES2: + InitializeGLExtensionBindingsGL(context); + InitializeGLExtensionBindingsEGL(context); + break; + case kGLImplementationDesktopGL: + InitializeGLExtensionBindingsGL(context); + InitializeGLExtensionBindingsWGL(context); + break; + case kGLImplementationMockGL: + InitializeGLExtensionBindingsGL(context); + break; + default: + return false; + } + + return true; +} + void InitializeDebugGLBindings() { InitializeDebugGLBindingsEGL(); InitializeDebugGLBindingsGL(); diff --git a/ui/gfx/gl/gl_interface.h b/ui/gfx/gl/gl_interface.h index 97363b7..5783e50 100644 --- a/ui/gfx/gl/gl_interface.h +++ b/ui/gfx/gl/gl_interface.h @@ -36,10 +36,10 @@ class GL_EXPORT GLInterface { virtual void BindBuffer(GLenum target, GLuint buffer) = 0; - virtual void BindFragDataLocationIndexedARB(GLuint program, - GLuint colorNumber, - GLuint index, - const char* name) = 0; + virtual void BindFragDataLocationIndexed(GLuint program, + GLuint colorNumber, + GLuint index, + const char* name) = 0; virtual void BindFragDataLocation(GLuint program, GLuint colorNumber, |