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

Side by Side Diff: ui/gfx/gl/generate_bindings.py

Issue 8381001: Split GL binding init into core and extension part (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Use existing glext.h/wglext.h/glxext.h headers from Mesa. Created 9 years, 1 month 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « gpu/command_buffer/common/gles2_cmd_format.h ('k') | ui/gfx/gl/gl_bindings_skia_in_process.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # 2 #
3 # Copyright (c) 2011 The Chromium Authors. All rights reserved. 3 # Copyright (c) 2011 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be 4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file. 5 # found in the LICENSE file.
6 6
7 """code generator for GL/GLES extension wrangler.""" 7 """code generator for GL/GLES extension wrangler."""
8 8
9 import os 9 import os
10 import collections
10 import re 11 import re
11 import sys 12 import sys
12 13
13 GL_FUNCTIONS = [ 14 GL_FUNCTIONS = [
14 ['void', ['glActiveTexture'], 'GLenum texture'], 15 ['void', ['glActiveTexture'], 'GLenum texture'],
15 ['void', ['glAttachShader'], 'GLuint program, GLuint shader'], 16 ['void', ['glAttachShader'], 'GLuint program, GLuint shader'],
16 ['void', ['glBeginQuery'], 'GLenum target, GLuint id'], 17 ['void', ['glBeginQuery'], 'GLenum target, GLuint id'],
17 ['void', ['glBindAttribLocation'], 18 ['void', ['glBindAttribLocation'],
18 'GLuint program, GLuint index, const char* name'], 19 'GLuint program, GLuint index, const char* name'],
19 ['void', ['glBindBuffer'], 'GLenum target, GLuint buffer'], 20 ['void', ['glBindBuffer'], 'GLenum target, GLuint buffer'],
20 ['void', ['glBindFragDataLocation'], 21 ['void', ['glBindFragDataLocation'],
21 'GLuint program, GLuint colorNumber, const char* name'], 22 'GLuint program, GLuint colorNumber, const char* name'],
22 ['void', ['glBindFragDataLocationIndexedARB'], 23 ['void', ['glBindFragDataLocationIndexed'],
23 'GLuint program, GLuint colorNumber, GLuint index, const char* name'], 24 'GLuint program, GLuint colorNumber, GLuint index, const char* name'],
24 ['void', ['glBindFramebufferEXT', 'glBindFramebuffer'], 25 ['void', ['glBindFramebufferEXT', 'glBindFramebuffer'],
25 'GLenum target, GLuint framebuffer'], 26 'GLenum target, GLuint framebuffer'],
26 ['void', ['glBindRenderbufferEXT', 'glBindRenderbuffer'], 27 ['void', ['glBindRenderbufferEXT', 'glBindRenderbuffer'],
27 'GLenum target, GLuint renderbuffer'], 28 'GLenum target, GLuint renderbuffer'],
28 ['void', ['glBindTexture'], 'GLenum target, GLuint texture'], 29 ['void', ['glBindTexture'], 'GLenum target, GLuint texture'],
29 ['void', ['glBlendColor'], 30 ['void', ['glBlendColor'],
30 'GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha'], 31 'GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha'],
31 ['void', ['glBlendEquation'], ' GLenum mode '], 32 ['void', ['glBlendEquation'], ' GLenum mode '],
32 ['void', ['glBlendEquationSeparate'], 'GLenum modeRGB, GLenum modeAlpha'], 33 ['void', ['glBlendEquationSeparate'], 'GLenum modeRGB, GLenum modeAlpha'],
33 ['void', ['glBlendFunc'], 'GLenum sfactor, GLenum dfactor'], 34 ['void', ['glBlendFunc'], 'GLenum sfactor, GLenum dfactor'],
34 ['void', ['glBlendFuncSeparate'], 35 ['void', ['glBlendFuncSeparate'],
35 'GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha'], 36 'GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha'],
36 ['void', ['glBlitFramebufferEXT', 'BlitFramebuffer'], 37 ['void', ['glBlitFramebufferEXT', 'glBlitFramebuffer'],
37 'GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, ' 38 'GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, '
38 'GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, ' 39 'GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, '
39 'GLbitfield mask, GLenum filter'], 40 'GLbitfield mask, GLenum filter'],
40 ['void', ['glBlitFramebufferANGLE', 'BlitFramebuffer'], 41 ['void', ['glBlitFramebufferANGLE', 'glBlitFramebuffer'],
41 'GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, ' 42 'GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, '
42 'GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, ' 43 'GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, '
43 'GLbitfield mask, GLenum filter'], 44 'GLbitfield mask, GLenum filter'],
44 ['void', ['glBufferData'], 45 ['void', ['glBufferData'],
45 'GLenum target, GLsizei size, const void* data, GLenum usage'], 46 'GLenum target, GLsizei size, const void* data, GLenum usage'],
46 ['void', ['glBufferSubData'], 47 ['void', ['glBufferSubData'],
47 'GLenum target, GLint offset, GLsizei size, const void* data'], 48 'GLenum target, GLint offset, GLsizei size, const void* data'],
48 ['GLenum', ['glCheckFramebufferStatusEXT', 49 ['GLenum', ['glCheckFramebufferStatusEXT',
49 'glCheckFramebufferStatus'], 'GLenum target'], 50 'glCheckFramebufferStatus'], 'GLenum target'],
50 ['void', ['glClear'], 'GLbitfield mask'], 51 ['void', ['glClear'], 'GLbitfield mask'],
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 ['GLboolean', ['glIsEnabled'], 'GLenum cap'], 175 ['GLboolean', ['glIsEnabled'], 'GLenum cap'],
175 ['GLboolean', ['glIsFramebufferEXT', 'glIsFramebuffer'], 176 ['GLboolean', ['glIsFramebufferEXT', 'glIsFramebuffer'],
176 'GLuint framebuffer'], 177 'GLuint framebuffer'],
177 ['GLboolean', ['glIsProgram'], 'GLuint program'], 178 ['GLboolean', ['glIsProgram'], 'GLuint program'],
178 ['GLboolean', ['glIsRenderbufferEXT', 'glIsRenderbuffer'], 179 ['GLboolean', ['glIsRenderbufferEXT', 'glIsRenderbuffer'],
179 'GLuint renderbuffer'], 180 'GLuint renderbuffer'],
180 ['GLboolean', ['glIsShader'], 'GLuint shader'], 181 ['GLboolean', ['glIsShader'], 'GLuint shader'],
181 ['GLboolean', ['glIsTexture'], 'GLuint texture'], 182 ['GLboolean', ['glIsTexture'], 'GLuint texture'],
182 ['void', ['glLineWidth'], 'GLfloat width'], 183 ['void', ['glLineWidth'], 'GLfloat width'],
183 ['void', ['glLinkProgram'], 'GLuint program'], 184 ['void', ['glLinkProgram'], 'GLuint program'],
184 ['void*', ['glMapBuffer'], 'GLenum target, GLenum access'], 185 ['void*', ['glMapBuffer', 'glMapBufferOES'], 'GLenum target, GLenum access'],
185 ['void', ['glPixelStorei'], 'GLenum pname, GLint param'], 186 ['void', ['glPixelStorei'], 'GLenum pname, GLint param'],
186 ['void', ['glPolygonOffset'], 'GLfloat factor, GLfloat units'], 187 ['void', ['glPolygonOffset'], 'GLfloat factor, GLfloat units'],
187 ['void', ['glQueryCounter'], 'GLuint id, GLenum target'], 188 ['void', ['glQueryCounter'], 'GLuint id, GLenum target'],
188 ['void', ['glReadBuffer'], 'GLenum src'], 189 ['void', ['glReadBuffer'], 'GLenum src'],
189 ['void', ['glReadPixels'], 190 ['void', ['glReadPixels'],
190 'GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, ' 191 'GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, '
191 'GLenum type, void* pixels'], 192 'GLenum type, void* pixels'],
192 ['void', ['glReleaseShaderCompiler'], 'void'], 193 ['void', ['glReleaseShaderCompiler'], 'void'],
193 ['void', ['glRenderbufferStorageMultisampleEXT', 194 ['void', ['glRenderbufferStorageMultisampleEXT',
194 'glRenderbufferStorageMultisample'], 195 'glRenderbufferStorageMultisample'],
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 'GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w'], 245 'GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w'],
245 ['void', ['glUniform4fv'], 'GLint location, GLsizei count, const GLfloat* v'], 246 ['void', ['glUniform4fv'], 'GLint location, GLsizei count, const GLfloat* v'],
246 ['void', ['glUniform4i'], 'GLint location, GLint x, GLint y, GLint z, GLint w'], 247 ['void', ['glUniform4i'], 'GLint location, GLint x, GLint y, GLint z, GLint w'],
247 ['void', ['glUniform4iv'], 'GLint location, GLsizei count, const GLint* v'], 248 ['void', ['glUniform4iv'], 'GLint location, GLsizei count, const GLint* v'],
248 ['void', ['glUniformMatrix2fv'], 249 ['void', ['glUniformMatrix2fv'],
249 'GLint location, GLsizei count, GLboolean transpose, const GLfloat* value'], 250 'GLint location, GLsizei count, GLboolean transpose, const GLfloat* value'],
250 ['void', ['glUniformMatrix3fv'], 251 ['void', ['glUniformMatrix3fv'],
251 'GLint location, GLsizei count, GLboolean transpose, const GLfloat* value'], 252 'GLint location, GLsizei count, GLboolean transpose, const GLfloat* value'],
252 ['void', ['glUniformMatrix4fv'], 253 ['void', ['glUniformMatrix4fv'],
253 'GLint location, GLsizei count, GLboolean transpose, const GLfloat* value'], 254 'GLint location, GLsizei count, GLboolean transpose, const GLfloat* value'],
254 ['GLboolean', ['glUnmapBuffer'], 'GLenum target'], 255 ['GLboolean', ['glUnmapBuffer', 'glUnmapBufferOES'], 'GLenum target'],
255 ['void', ['glUseProgram'], 'GLuint program'], 256 ['void', ['glUseProgram'], 'GLuint program'],
256 ['void', ['glValidateProgram'], 'GLuint program'], 257 ['void', ['glValidateProgram'], 'GLuint program'],
257 ['void', ['glVertexAttrib1f'], 'GLuint indx, GLfloat x'], 258 ['void', ['glVertexAttrib1f'], 'GLuint indx, GLfloat x'],
258 ['void', ['glVertexAttrib1fv'], 'GLuint indx, const GLfloat* values'], 259 ['void', ['glVertexAttrib1fv'], 'GLuint indx, const GLfloat* values'],
259 ['void', ['glVertexAttrib2f'], 'GLuint indx, GLfloat x, GLfloat y'], 260 ['void', ['glVertexAttrib2f'], 'GLuint indx, GLfloat x, GLfloat y'],
260 ['void', ['glVertexAttrib2fv'], 'GLuint indx, const GLfloat* values'], 261 ['void', ['glVertexAttrib2fv'], 'GLuint indx, const GLfloat* values'],
261 ['void', ['glVertexAttrib3f'], 'GLuint indx, GLfloat x, GLfloat y, GLfloat z'], 262 ['void', ['glVertexAttrib3f'], 'GLuint indx, GLfloat x, GLfloat y, GLfloat z'],
262 ['void', ['glVertexAttrib3fv'], 'GLuint indx, const GLfloat* values'], 263 ['void', ['glVertexAttrib3fv'], 'GLuint indx, const GLfloat* values'],
263 ['void', ['glVertexAttrib4f'], 264 ['void', ['glVertexAttrib4f'],
264 'GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w'], 265 'GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w'],
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 ['void', ['glXSwapIntervalEXT'], 457 ['void', ['glXSwapIntervalEXT'],
457 'Display* dpy, GLXDrawable drawable, int interval'], 458 'Display* dpy, GLXDrawable drawable, int interval'],
458 ['GLXFBConfig', ['glXGetFBConfigFromVisualSGIX'], 459 ['GLXFBConfig', ['glXGetFBConfigFromVisualSGIX'],
459 'Display* dpy, XVisualInfo* visualInfo'], 460 'Display* dpy, XVisualInfo* visualInfo'],
460 ['GLXContext', ['glXCreateContextAttribsARB'], 461 ['GLXContext', ['glXCreateContextAttribsARB'],
461 'Display* dpy, GLXFBConfig config, GLXContext share_context, int direct, ' 462 'Display* dpy, GLXFBConfig config, GLXContext share_context, int direct, '
462 'const int* attrib_list'], 463 'const int* attrib_list'],
463 ] 464 ]
464 465
465 FUNCTION_SETS = [ 466 FUNCTION_SETS = [
466 [GL_FUNCTIONS, 'gl'], 467 [GL_FUNCTIONS, 'gl', ['../../../third_party/mesa/MesaLib/include/GL/glext.h',
467 [OSMESA_FUNCTIONS, 'osmesa'], 468 '../../../gpu/GLES2/gl2ext.h']],
468 [EGL_FUNCTIONS, 'egl'], 469 [OSMESA_FUNCTIONS, 'osmesa', []],
469 [WGL_FUNCTIONS, 'wgl'], 470 [EGL_FUNCTIONS, 'egl', ['../../../gpu/EGL/eglext.h']],
470 [GLX_FUNCTIONS, 'glx'], 471 [WGL_FUNCTIONS, 'wgl', [
472 '../../../third_party/mesa/MesaLib/include/GL/wglext.h']],
473 [GLX_FUNCTIONS, 'glx', [
474 '../../../third_party/mesa/MesaLib/include/GL/glxext.h']],
471 ] 475 ]
472 476
473 def GenerateHeader(file, functions, set_name): 477 def GenerateHeader(file, functions, set_name):
474 """Generates gl_binding_autogen_x.h""" 478 """Generates gl_binding_autogen_x.h"""
475 479
476 # Write file header. 480 # Write file header.
477 file.write('// Copyright (c) 2011 The Chromium Authors. All rights reserved.\n ') 481 file.write('// Copyright (c) 2011 The Chromium Authors. All rights reserved.\n ')
478 file.write('// Use of this source code is governed by a BSD-style license that can be\n') 482 file.write('// Use of this source code is governed by a BSD-style license that can be\n')
479 file.write('// found in the LICENSE file.\n') 483 file.write('// found in the LICENSE file.\n')
480 file.write('\n') 484 file.write('\n')
481 file.write('// This file is automatically generated.\n') 485 file.write('// This file is automatically generated.\n')
482 file.write('\n') 486 file.write('\n')
483 file.write('#ifndef UI_GFX_GL_GL_BINDINGS_AUTOGEN_%s_H_\n' % set_name.upper()) 487 file.write('#ifndef UI_GFX_GL_GL_BINDINGS_AUTOGEN_%s_H_\n' % set_name.upper())
484 file.write('#define UI_GFX_GL_GL_BINDINGS_AUTOGEN_%s_H_\n' % set_name.upper()) 488 file.write('#define UI_GFX_GL_GL_BINDINGS_AUTOGEN_%s_H_\n' % set_name.upper())
485 489
486 # Write prototype for initialization function. 490 # Write prototype for initialization function.
487 file.write('\n') 491 file.write('\n')
488 file.write('namespace gfx {\n') 492 file.write('namespace gfx {\n')
489 file.write('\n') 493 file.write('\n')
494 file.write('class GLContext;\n')
495 file.write('\n')
490 file.write('void InitializeGLBindings%s();\n' % set_name.upper()) 496 file.write('void InitializeGLBindings%s();\n' % set_name.upper())
497 file.write('void InitializeGLExtensionBindings%s(GLContext* context);\n' %
498 set_name.upper())
491 file.write('void InitializeDebugGLBindings%s();\n' % set_name.upper()) 499 file.write('void InitializeDebugGLBindings%s();\n' % set_name.upper())
492 500
493 # Write typedefs for function pointer types. Always use the GL name for the 501 # Write typedefs for function pointer types. Always use the GL name for the
494 # typedef. 502 # typedef.
495 file.write('\n') 503 file.write('\n')
496 for [return_type, names, arguments] in functions: 504 for [return_type, names, arguments] in functions:
497 file.write('typedef %s (GL_BINDING_CALL *%sProc)(%s);\n' % 505 file.write('typedef %s (GL_BINDING_CALL *%sProc)(%s);\n' %
498 (return_type, names[0], arguments)) 506 (return_type, names[0], arguments))
499 507
500 # Write declarations for function pointers. Always use the GL name for the 508 # Write declarations for function pointers. Always use the GL name for the
501 # declaration. 509 # declaration.
502 file.write('\n') 510 file.write('\n')
503 for [return_type, names, arguments] in functions: 511 for [return_type, names, arguments] in functions:
504 file.write('GL_EXPORT extern %sProc g_%s;\n' % (names[0], names[0])) 512 file.write('GL_EXPORT extern %sProc g_%s;\n' % (names[0], names[0]))
505 file.write('\n') 513 file.write('\n')
506 file.write( '} // namespace gfx\n') 514 file.write( '} // namespace gfx\n')
507 515
508 # Write macros to invoke function pointers. Always use the GL name for the 516 # Write macros to invoke function pointers. Always use the GL name for the
509 # macro. 517 # macro.
510 file.write('\n') 518 file.write('\n')
511 for [return_type, names, arguments] in functions: 519 for [return_type, names, arguments] in functions:
512 file.write('#define %s ::gfx::g_%s\n' % 520 file.write('#define %s ::gfx::g_%s\n' %
513 (names[0], names[0])) 521 (names[0], names[0]))
514 522
515 file.write('\n') 523 file.write('\n')
516 file.write('#endif // UI_GFX_GL_GL_BINDINGS_AUTOGEN_%s_H_\n' % 524 file.write('#endif // UI_GFX_GL_GL_BINDINGS_AUTOGEN_%s_H_\n' %
517 set_name.upper()) 525 set_name.upper())
518 526
519 527
520 def GenerateSource(file, functions, set_name): 528 def GenerateSource(file, functions, set_name, used_extension_functions):
521 """Generates gl_binding_autogen_x.cc""" 529 """Generates gl_binding_autogen_x.cc"""
522 530
523 # Write file header. 531 # Write file header.
524 file.write('// Copyright (c) 2011 The Chromium Authors. All rights reserved.\n ') 532 file.write('// Copyright (c) 2011 The Chromium Authors. All rights reserved.\n ')
525 file.write('// Use of this source code is governed by a BSD-style license that can be\n') 533 file.write('// Use of this source code is governed by a BSD-style license that can be\n')
526 file.write('// found in the LICENSE file.\n') 534 file.write('// found in the LICENSE file.\n')
527 file.write('\n') 535 file.write('\n')
528 file.write('// This file is automatically generated.\n') 536 file.write('// This file is automatically generated.\n')
529 file.write('\n') 537 file.write('\n')
530 file.write('#include "ui/gfx/gl/gl_bindings.h"\n') 538 file.write('#include "ui/gfx/gl/gl_bindings.h"\n')
539 file.write('#include "ui/gfx/gl/gl_context.h"\n')
531 file.write('#include "ui/gfx/gl/gl_implementation.h"\n') 540 file.write('#include "ui/gfx/gl/gl_implementation.h"\n')
532 541
533 # Write definitions of function pointers. 542 # Write definitions of function pointers.
534 file.write('\n') 543 file.write('\n')
535 file.write('namespace gfx {\n') 544 file.write('namespace gfx {\n')
536 file.write('\n') 545 file.write('\n')
546 file.write('static bool g_debugBindingsInitialized;\n')
547 file.write('static void UpdateDebugGLExtensionBindings();\n')
548 file.write('\n')
537 for [return_type, names, arguments] in functions: 549 for [return_type, names, arguments] in functions:
538 file.write('%sProc g_%s;\n' % (names[0], names[0])) 550 file.write('%sProc g_%s;\n' % (names[0], names[0]))
539 551
540 file.write('\n') 552 file.write('\n')
541 for [return_type, names, arguments] in functions: 553 for [return_type, names, arguments] in functions:
542 file.write('static %sProc g_debug_%s;\n' % (names[0], names[0])) 554 file.write('static %sProc g_debug_%s;\n' % (names[0], names[0]))
543 555
544 # Write function to initialize the function pointers. 556 # Write function to initialize the core function pointers. The code assumes
557 # any non-NULL pointer returned by GetGLCoreProcAddress() is valid, although
558 # it may be overwritten by an extension function pointer later.
545 file.write('\n') 559 file.write('\n')
546 file.write('void InitializeGLBindings%s() {\n' % set_name.upper()) 560 file.write('void InitializeGLBindings%s() {\n' % set_name.upper())
547 for [return_type, names, arguments] in functions: 561 for [return_type, names, arguments] in functions:
548 for name in names: 562 for i, name in enumerate(names):
549 file.write(' if (!g_%s)\n' % names[0]) 563 if i:
564 file.write(' if (!g_%s)\n ' % names[0])
550 file.write( 565 file.write(
551 ' g_%s = reinterpret_cast<%sProc>(GetGLProcAddress("%s"));\n' % 566 ' g_%s = reinterpret_cast<%sProc>(GetGLCoreProcAddress("%s"));\n' %
552 (names[0], names[0], name)) 567 (names[0], names[0], name))
553 file.write('}\n') 568 file.write('}\n')
554 file.write('\n') 569 file.write('\n')
555 570
571 # Write function to initialize the extension function pointers. This function
572 # uses a current context to query which extensions are actually supported.
573 file.write('void InitializeGLExtensionBindings%s(GLContext* context) {\n' %
574 set_name.upper())
575 file.write(' DCHECK(context && context->IsCurrent(NULL));\n')
576 for extension, ext_functions in used_extension_functions:
577 file.write(' if (context->HasExtension("%s")) {\n' % extension)
578 queried_entry_points = set()
579 for entry_point_name, function_name in ext_functions:
580 # Replace the pointer unconditionally unless this extension has several
581 # alternatives for the same entry point (e.g.,
582 # GL_ARB_blend_func_extended).
583 if entry_point_name in queried_entry_points:
584 file.write(' if (!g_%s)\n ' % entry_point_name)
585 file.write(
586 ' g_%s = reinterpret_cast<%sProc>(GetGLProcAddress("%s"));\n' %
587 (entry_point_name, entry_point_name, function_name))
588 queried_entry_points.add(entry_point_name)
589 file.write(' }\n')
590 file.write(' if (g_debugBindingsInitialized)\n')
591 file.write(' UpdateDebugGLExtensionBindings();\n')
592 file.write('}\n')
593 file.write('\n')
594
556 # Write logging wrappers for each function. 595 # Write logging wrappers for each function.
557 file.write('extern "C" {\n') 596 file.write('extern "C" {\n')
558 for [return_type, names, arguments] in functions: 597 for [return_type, names, arguments] in functions:
559 file.write('\n') 598 file.write('\n')
560 file.write('static %s GL_BINDING_CALL Debug_%s(%s) {\n' % 599 file.write('static %s GL_BINDING_CALL Debug_%s(%s) {\n' %
561 (return_type, names[0], arguments)) 600 (return_type, names[0], arguments))
562 argument_names = re.sub(r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', 601 argument_names = re.sub(r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2',
563 arguments) 602 arguments)
564 argument_names = re.sub(r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', 603 argument_names = re.sub(r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2',
565 argument_names) 604 argument_names)
(...skipping 22 matching lines...) Expand all
588 else: 627 else:
589 file.write(' GL_SERVICE_LOG("%s" << "(" %s << ")");\n' % 628 file.write(' GL_SERVICE_LOG("%s" << "(" %s << ")");\n' %
590 (function_name, log_argument_names)) 629 (function_name, log_argument_names))
591 file.write(' %s result = g_debug_%s(%s);\n' % 630 file.write(' %s result = g_debug_%s(%s);\n' %
592 (return_type, function_name, argument_names)) 631 (return_type, function_name, argument_names))
593 file.write(' GL_SERVICE_LOG("GL_RESULT: " << result);\n'); 632 file.write(' GL_SERVICE_LOG("GL_RESULT: " << result);\n');
594 file.write(' return result;\n') 633 file.write(' return result;\n')
595 file.write('}\n') 634 file.write('}\n')
596 file.write('} // extern "C"\n') 635 file.write('} // extern "C"\n')
597 636
598 # Write function to initialize the function pointers. 637 # Write function to initialize the debug function pointers.
599 file.write('\n') 638 file.write('\n')
600 file.write('void InitializeDebugGLBindings%s() {\n' % set_name.upper()) 639 file.write('void InitializeDebugGLBindings%s() {\n' % set_name.upper())
601 for [return_type, names, arguments] in functions: 640 for [return_type, names, arguments] in functions:
602 for name in names: 641 file.write(' if (!g_debug_%s) {\n' % names[0])
603 file.write(' if (!g_debug_%s) {\n' % names[0]) 642 file.write(' g_debug_%s = g_%s;\n' % (names[0], names[0]))
604 file.write(' g_debug_%s = g_%s;\n' % (names[0], names[0])) 643 file.write(' g_%s = Debug_%s;\n' % (names[0], names[0]))
605 file.write(' g_%s = Debug_%s;\n' % (names[0], names[0])) 644 file.write(' }\n')
645 file.write(' g_debugBindingsInitialized = true;\n')
646 file.write('}\n')
647
648 # Write function to update the debug function pointers to extension functions
649 # after the extensions have been initialized.
650 file.write('\n')
651 file.write('static void UpdateDebugGLExtensionBindings() {\n')
652 for extension, ext_functions in used_extension_functions:
653 for name, _ in ext_functions:
654 file.write(' if (g_debug_%s != g_%s &&\n' % (name, name))
655 file.write(' g_%s != Debug_%s) {\n' % (name, name))
656 file.write(' g_debug_%s = g_%s;\n' % (name, name))
657 file.write(' g_%s = Debug_%s;\n' % (name, name))
606 file.write(' }\n') 658 file.write(' }\n')
607 file.write('}\n') 659 file.write('}\n')
608 file.write('\n')
609 660
610 file.write( '} // namespace gfx\n') 661 file.write('} // namespace gfx\n')
611 662
612 663
613 def GenerateMockSource(file, functions): 664 def GenerateMockSource(file, functions):
614 """Generates functions that invoke a mock GLInterface""" 665 """Generates functions that invoke a mock GLInterface"""
615 666
616 file.write('// Copyright (c) 2011 The Chromium Authors. All rights reserved.\n ') 667 file.write('// Copyright (c) 2011 The Chromium Authors. All rights reserved.\n ')
617 file.write('// Use of this source code is governed by a BSD-style license that can be\n') 668 file.write('// Use of this source code is governed by a BSD-style license that can be\n')
618 file.write('// found in the LICENSE file.\n') 669 file.write('// found in the LICENSE file.\n')
619 file.write('\n') 670 file.write('\n')
620 file.write('// This file is automatically generated.\n') 671 file.write('// This file is automatically generated.\n')
(...skipping 16 matching lines...) Expand all
637 argument_names = '' 688 argument_names = ''
638 function_name = names[0][2:] 689 function_name = names[0][2:]
639 if return_type == 'void': 690 if return_type == 'void':
640 file.write(' GLInterface::GetGLInterface()->%s(%s);\n' % 691 file.write(' GLInterface::GetGLInterface()->%s(%s);\n' %
641 (function_name, argument_names)) 692 (function_name, argument_names))
642 else: 693 else:
643 file.write(' return GLInterface::GetGLInterface()->%s(%s);\n' % 694 file.write(' return GLInterface::GetGLInterface()->%s(%s);\n' %
644 (function_name, argument_names)) 695 (function_name, argument_names))
645 file.write('}\n') 696 file.write('}\n')
646 697
698 # Write an 'invalid' function to catch code calling through uninitialized
699 # function pointers or trying to interpret the return value of
700 # GLProcAddress().
701 file.write('\n')
702 file.write('static void MockInvalidFunction() {\n')
703 file.write(' DCHECK(0);\n')
apatrick_chromium 2011/10/26 18:29:11 This could be NOTREACHED()
Sami 2011/10/27 13:46:06 Done.
704 file.write('}\n')
705
647 # Write a function to lookup a mock GL function based on its name. 706 # Write a function to lookup a mock GL function based on its name.
648 file.write('\n') 707 file.write('\n')
649 file.write('void* GL_BINDING_CALL GetMockGLProcAddress(const char* name) {\n') 708 file.write('void* GL_BINDING_CALL GetMockGLProcAddress(const char* name) {\n')
650 for [return_type, names, arguments] in functions: 709 for [return_type, names, arguments] in functions:
651 file.write(' if (strcmp(name, "%s") == 0)\n' % names[0]) 710 file.write(' if (strcmp(name, "%s") == 0)\n' % names[0])
652 file.write(' return reinterpret_cast<void*>(Mock_%s);\n' % names[0]) 711 file.write(' return reinterpret_cast<void*>(Mock_%s);\n' % names[0])
653 file.write(' return NULL;\n') 712 # Always return a non-NULL pointer like some EGL implementations do.
713 file.write(' return reinterpret_cast<void*>(&MockInvalidFunction);\n')
654 file.write('}\n'); 714 file.write('}\n');
655 715
656 file.write('\n') 716 file.write('\n')
657 file.write('} // namespace gfx\n') 717 file.write('} // namespace gfx\n')
658 718
719 def ParseExtensionFunctionsFromHeader(header_file):
720 """Parse a C extension header file and return a map from extension names to
721 a list of functions.
722
723 Args:
724 header_file: Line-iterable C header file.
725 Returns:
726 Map of extension name => functions.
727 """
728 extension_start = re.compile(r'#define ([A-Z]+_[A-Z]+_[a-zA-Z]\w+) 1')
729 extension_function = re.compile(r'.+\s+([a-z]+\w+)\s*\(.+\);')
730 typedef = re.compile(r'typedef .*')
731 macro_start = re.compile(r'^#(if|ifdef|ifndef).*')
732 macro_end = re.compile(r'^#endif.*')
733 macro_depth = 0
734 current_extension = None
735 current_extension_depth = 0
736 extensions = collections.defaultdict(lambda: [])
737 for line in header_file:
738 if macro_start.match(line):
739 macro_depth += 1
740 elif macro_end.match(line):
741 macro_depth -= 1
742 if macro_depth < current_extension_depth:
743 current_extension = None
744 match = extension_start.match(line)
745 if match:
746 current_extension = match.group(1)
747 current_extension_depth = macro_depth
748 assert current_extension not in extensions, \
749 "Duplicate extension: " + current_extension
750 match = extension_function.match(line)
751 if match and current_extension and not typedef.match(line):
752 extensions[current_extension].append(match.group(1))
753 return extensions
754
755 def GetExtensionFunctions(extension_headers):
756 """Parse extension functions from a list of header files.
757
758 Args:
759 extension_headers: List of header file names.
760 Returns:
761 Map of extension name => list of functions.
762 """
763 extensions = {}
764 for header in extension_headers:
765 extensions.update(ParseExtensionFunctionsFromHeader(open(header)))
766 return extensions
767
768 def GetFunctionToExtensionMap(extensions):
769 """Construct map from a function names to extensions which define the
770 function.
771
772 Args:
773 extensions: Map of extension name => functions.
774 Returns:
775 Map of function name => extension name.
776 """
777 function_to_extension = {}
778 for extension, functions in extensions.items():
779 for function in functions:
780 assert function not in function_to_extension, \
781 "Duplicate function: " + function
782 function_to_extension[function] = extension
783 return function_to_extension
784
785 def LooksLikeExtensionFunction(function):
786 """Heuristic to see if a function name is consistent with extension function
787 naming."""
788 vendor = re.match(r'\w+?([A-Z][A-Z]+)$', function)
789 return vendor is not None and not vendor.group(1) in ['GL', 'API', 'DC']
790
791 def GetUsedExtensionFunctions(functions, extension_headers):
792 """Determine which functions belong to extensions.
793
794 Args:
795 functions: List of (return type, function names, arguments).
796 extension_headers: List of header file names.
797 Returns:
798 List of (extension name, [function name alternatives]) sorted with least
799 preferred extensions first.
800 """
801 # Parse known extensions.
802 extensions = GetExtensionFunctions(extension_headers)
803 functions_to_extensions = GetFunctionToExtensionMap(extensions)
804
805 # Collect all used extension functions.
806 used_extension_functions = collections.defaultdict(lambda: [])
807 for [return_type, names, arguments] in functions:
808 for name in names:
809 # Make sure we know about all extension functions.
810 if (LooksLikeExtensionFunction(name) and
811 not name in functions_to_extensions):
812 raise RuntimeError('%s looks like an extension function but does not '
813 'belong to any of the known extensions.' % name)
814 if name in functions_to_extensions:
815 extension = functions_to_extensions[name]
816 used_extension_functions[extension].append((names[0], name))
817
818 def ExtensionSortKey(name):
819 # Prefer ratified extensions and EXTs.
820 preferences = ['_ARB_', '_OES_', '_EXT_', '']
821 for i, category in enumerate(preferences):
822 if category in name:
823 return -i
824 used_extension_functions = sorted(used_extension_functions.items(),
825 key = lambda item: ExtensionSortKey(item[0]))
826 return used_extension_functions
659 827
660 def main(argv): 828 def main(argv):
661 """This is the main function.""" 829 """This is the main function."""
662 830
663 if len(argv) >= 1: 831 if len(argv) >= 1:
664 dir = argv[0] 832 dir = argv[0]
665 else: 833 else:
666 dir = '.' 834 dir = '.'
667 835
668 for [functions, set_name] in FUNCTION_SETS: 836 for [functions, set_name, extension_headers] in FUNCTION_SETS:
669 header_file = open( 837 header_file = open(
670 os.path.join(dir, 'gl_bindings_autogen_%s.h' % set_name), 'wb') 838 os.path.join(dir, 'gl_bindings_autogen_%s.h' % set_name), 'wb')
671 GenerateHeader(header_file, functions, set_name) 839 GenerateHeader(header_file, functions, set_name)
672 header_file.close() 840 header_file.close()
673 841
674 source_file = open( 842 source_file = open(
675 os.path.join(dir, 'gl_bindings_autogen_%s.cc' % set_name), 'wb') 843 os.path.join(dir, 'gl_bindings_autogen_%s.cc' % set_name), 'wb')
676 GenerateSource(source_file, functions, set_name) 844 used_extension_functions = GetUsedExtensionFunctions(
845 functions, extension_headers)
846 GenerateSource(source_file, functions, set_name, used_extension_functions)
677 source_file.close() 847 source_file.close()
678 848
679 source_file = open(os.path.join(dir, 'gl_bindings_autogen_mock.cc'), 'wb') 849 source_file = open(os.path.join(dir, 'gl_bindings_autogen_mock.cc'), 'wb')
680 GenerateMockSource(source_file, GL_FUNCTIONS) 850 GenerateMockSource(source_file, GL_FUNCTIONS)
681 source_file.close() 851 source_file.close()
682 852
683 853
684 if __name__ == '__main__': 854 if __name__ == '__main__':
685 main(sys.argv[1:]) 855 main(sys.argv[1:])
OLDNEW
« no previous file with comments | « gpu/command_buffer/common/gles2_cmd_format.h ('k') | ui/gfx/gl/gl_bindings_skia_in_process.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698