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

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: Added dependencies to gl.gyp. Used NOT_REACHED() instead of DCHECK(0). 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.gyp » ('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 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 ['void', ['glXSwapIntervalEXT'], 459 ['void', ['glXSwapIntervalEXT'],
459 'Display* dpy, GLXDrawable drawable, int interval'], 460 'Display* dpy, GLXDrawable drawable, int interval'],
460 ['GLXFBConfig', ['glXGetFBConfigFromVisualSGIX'], 461 ['GLXFBConfig', ['glXGetFBConfigFromVisualSGIX'],
461 'Display* dpy, XVisualInfo* visualInfo'], 462 'Display* dpy, XVisualInfo* visualInfo'],
462 ['GLXContext', ['glXCreateContextAttribsARB'], 463 ['GLXContext', ['glXCreateContextAttribsARB'],
463 'Display* dpy, GLXFBConfig config, GLXContext share_context, int direct, ' 464 'Display* dpy, GLXFBConfig config, GLXContext share_context, int direct, '
464 'const int* attrib_list'], 465 'const int* attrib_list'],
465 ] 466 ]
466 467
467 FUNCTION_SETS = [ 468 FUNCTION_SETS = [
468 [GL_FUNCTIONS, 'gl'], 469 [GL_FUNCTIONS, 'gl', ['../../../third_party/mesa/MesaLib/include/GL/glext.h',
469 [OSMESA_FUNCTIONS, 'osmesa'], 470 '../../../gpu/GLES2/gl2ext.h']],
470 [EGL_FUNCTIONS, 'egl'], 471 [OSMESA_FUNCTIONS, 'osmesa', []],
471 [WGL_FUNCTIONS, 'wgl'], 472 [EGL_FUNCTIONS, 'egl', ['../../../gpu/EGL/eglext.h']],
472 [GLX_FUNCTIONS, 'glx'], 473 [WGL_FUNCTIONS, 'wgl', [
474 '../../../third_party/mesa/MesaLib/include/GL/wglext.h']],
475 [GLX_FUNCTIONS, 'glx', [
476 '../../../third_party/mesa/MesaLib/include/GL/glxext.h']],
473 ] 477 ]
474 478
475 def GenerateHeader(file, functions, set_name): 479 def GenerateHeader(file, functions, set_name):
476 """Generates gl_binding_autogen_x.h""" 480 """Generates gl_binding_autogen_x.h"""
477 481
478 # Write file header. 482 # Write file header.
479 file.write('// Copyright (c) 2011 The Chromium Authors. All rights reserved.\n ') 483 file.write('// Copyright (c) 2011 The Chromium Authors. All rights reserved.\n ')
480 file.write('// Use of this source code is governed by a BSD-style license that can be\n') 484 file.write('// Use of this source code is governed by a BSD-style license that can be\n')
481 file.write('// found in the LICENSE file.\n') 485 file.write('// found in the LICENSE file.\n')
482 file.write('\n') 486 file.write('\n')
483 file.write('// This file is automatically generated.\n') 487 file.write('// This file is automatically generated.\n')
484 file.write('\n') 488 file.write('\n')
485 file.write('#ifndef UI_GFX_GL_GL_BINDINGS_AUTOGEN_%s_H_\n' % set_name.upper()) 489 file.write('#ifndef UI_GFX_GL_GL_BINDINGS_AUTOGEN_%s_H_\n' % set_name.upper())
486 file.write('#define UI_GFX_GL_GL_BINDINGS_AUTOGEN_%s_H_\n' % set_name.upper()) 490 file.write('#define UI_GFX_GL_GL_BINDINGS_AUTOGEN_%s_H_\n' % set_name.upper())
487 491
488 # Write prototype for initialization function. 492 # Write prototype for initialization function.
489 file.write('\n') 493 file.write('\n')
490 file.write('namespace gfx {\n') 494 file.write('namespace gfx {\n')
491 file.write('\n') 495 file.write('\n')
496 file.write('class GLContext;\n')
497 file.write('\n')
492 file.write('void InitializeGLBindings%s();\n' % set_name.upper()) 498 file.write('void InitializeGLBindings%s();\n' % set_name.upper())
499 file.write('void InitializeGLExtensionBindings%s(GLContext* context);\n' %
500 set_name.upper())
493 file.write('void InitializeDebugGLBindings%s();\n' % set_name.upper()) 501 file.write('void InitializeDebugGLBindings%s();\n' % set_name.upper())
494 502
495 # Write typedefs for function pointer types. Always use the GL name for the 503 # Write typedefs for function pointer types. Always use the GL name for the
496 # typedef. 504 # typedef.
497 file.write('\n') 505 file.write('\n')
498 for [return_type, names, arguments] in functions: 506 for [return_type, names, arguments] in functions:
499 file.write('typedef %s (GL_BINDING_CALL *%sProc)(%s);\n' % 507 file.write('typedef %s (GL_BINDING_CALL *%sProc)(%s);\n' %
500 (return_type, names[0], arguments)) 508 (return_type, names[0], arguments))
501 509
502 # Write declarations for function pointers. Always use the GL name for the 510 # Write declarations for function pointers. Always use the GL name for the
503 # declaration. 511 # declaration.
504 file.write('\n') 512 file.write('\n')
505 for [return_type, names, arguments] in functions: 513 for [return_type, names, arguments] in functions:
506 file.write('GL_EXPORT extern %sProc g_%s;\n' % (names[0], names[0])) 514 file.write('GL_EXPORT extern %sProc g_%s;\n' % (names[0], names[0]))
507 file.write('\n') 515 file.write('\n')
508 file.write( '} // namespace gfx\n') 516 file.write( '} // namespace gfx\n')
509 517
510 # Write macros to invoke function pointers. Always use the GL name for the 518 # Write macros to invoke function pointers. Always use the GL name for the
511 # macro. 519 # macro.
512 file.write('\n') 520 file.write('\n')
513 for [return_type, names, arguments] in functions: 521 for [return_type, names, arguments] in functions:
514 file.write('#define %s ::gfx::g_%s\n' % 522 file.write('#define %s ::gfx::g_%s\n' %
515 (names[0], names[0])) 523 (names[0], names[0]))
516 524
517 file.write('\n') 525 file.write('\n')
518 file.write('#endif // UI_GFX_GL_GL_BINDINGS_AUTOGEN_%s_H_\n' % 526 file.write('#endif // UI_GFX_GL_GL_BINDINGS_AUTOGEN_%s_H_\n' %
519 set_name.upper()) 527 set_name.upper())
520 528
521 529
522 def GenerateSource(file, functions, set_name): 530 def GenerateSource(file, functions, set_name, used_extension_functions):
523 """Generates gl_binding_autogen_x.cc""" 531 """Generates gl_binding_autogen_x.cc"""
524 532
525 # Write file header. 533 # Write file header.
526 file.write('// Copyright (c) 2011 The Chromium Authors. All rights reserved.\n ') 534 file.write('// Copyright (c) 2011 The Chromium Authors. All rights reserved.\n ')
527 file.write('// Use of this source code is governed by a BSD-style license that can be\n') 535 file.write('// Use of this source code is governed by a BSD-style license that can be\n')
528 file.write('// found in the LICENSE file.\n') 536 file.write('// found in the LICENSE file.\n')
529 file.write('\n') 537 file.write('\n')
530 file.write('// This file is automatically generated.\n') 538 file.write('// This file is automatically generated.\n')
531 file.write('\n') 539 file.write('\n')
532 file.write('#include "ui/gfx/gl/gl_bindings.h"\n') 540 file.write('#include "ui/gfx/gl/gl_bindings.h"\n')
541 file.write('#include "ui/gfx/gl/gl_context.h"\n')
533 file.write('#include "ui/gfx/gl/gl_implementation.h"\n') 542 file.write('#include "ui/gfx/gl/gl_implementation.h"\n')
534 543
535 # Write definitions of function pointers. 544 # Write definitions of function pointers.
536 file.write('\n') 545 file.write('\n')
537 file.write('namespace gfx {\n') 546 file.write('namespace gfx {\n')
538 file.write('\n') 547 file.write('\n')
548 file.write('static bool g_debugBindingsInitialized;\n')
549 file.write('static void UpdateDebugGLExtensionBindings();\n')
550 file.write('\n')
539 for [return_type, names, arguments] in functions: 551 for [return_type, names, arguments] in functions:
540 file.write('%sProc g_%s;\n' % (names[0], names[0])) 552 file.write('%sProc g_%s;\n' % (names[0], names[0]))
541 553
542 file.write('\n') 554 file.write('\n')
543 for [return_type, names, arguments] in functions: 555 for [return_type, names, arguments] in functions:
544 file.write('static %sProc g_debug_%s;\n' % (names[0], names[0])) 556 file.write('static %sProc g_debug_%s;\n' % (names[0], names[0]))
545 557
546 # Write function to initialize the function pointers. 558 # Write function to initialize the core function pointers. The code assumes
559 # any non-NULL pointer returned by GetGLCoreProcAddress() is valid, although
560 # it may be overwritten by an extension function pointer later.
547 file.write('\n') 561 file.write('\n')
548 file.write('void InitializeGLBindings%s() {\n' % set_name.upper()) 562 file.write('void InitializeGLBindings%s() {\n' % set_name.upper())
549 for [return_type, names, arguments] in functions: 563 for [return_type, names, arguments] in functions:
550 for name in names: 564 for i, name in enumerate(names):
551 file.write(' if (!g_%s)\n' % names[0]) 565 if i:
566 file.write(' if (!g_%s)\n ' % names[0])
552 file.write( 567 file.write(
553 ' g_%s = reinterpret_cast<%sProc>(GetGLProcAddress("%s"));\n' % 568 ' g_%s = reinterpret_cast<%sProc>(GetGLCoreProcAddress("%s"));\n' %
554 (names[0], names[0], name)) 569 (names[0], names[0], name))
555 file.write('}\n') 570 file.write('}\n')
556 file.write('\n') 571 file.write('\n')
557 572
573 # Write function to initialize the extension function pointers. This function
574 # uses a current context to query which extensions are actually supported.
575 file.write('void InitializeGLExtensionBindings%s(GLContext* context) {\n' %
576 set_name.upper())
577 file.write(' DCHECK(context && context->IsCurrent(NULL));\n')
578 for extension, ext_functions in used_extension_functions:
579 file.write(' if (context->HasExtension("%s")) {\n' % extension)
580 queried_entry_points = set()
581 for entry_point_name, function_name in ext_functions:
582 # Replace the pointer unconditionally unless this extension has several
583 # alternatives for the same entry point (e.g.,
584 # GL_ARB_blend_func_extended).
585 if entry_point_name in queried_entry_points:
586 file.write(' if (!g_%s)\n ' % entry_point_name)
587 file.write(
588 ' g_%s = reinterpret_cast<%sProc>(GetGLProcAddress("%s"));\n' %
589 (entry_point_name, entry_point_name, function_name))
590 queried_entry_points.add(entry_point_name)
591 file.write(' }\n')
592 file.write(' if (g_debugBindingsInitialized)\n')
593 file.write(' UpdateDebugGLExtensionBindings();\n')
594 file.write('}\n')
595 file.write('\n')
596
558 # Write logging wrappers for each function. 597 # Write logging wrappers for each function.
559 file.write('extern "C" {\n') 598 file.write('extern "C" {\n')
560 for [return_type, names, arguments] in functions: 599 for [return_type, names, arguments] in functions:
561 file.write('\n') 600 file.write('\n')
562 file.write('static %s GL_BINDING_CALL Debug_%s(%s) {\n' % 601 file.write('static %s GL_BINDING_CALL Debug_%s(%s) {\n' %
563 (return_type, names[0], arguments)) 602 (return_type, names[0], 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 arguments) 604 arguments)
566 argument_names = re.sub(r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', 605 argument_names = re.sub(r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2',
567 argument_names) 606 argument_names)
(...skipping 22 matching lines...) Expand all
590 else: 629 else:
591 file.write(' GL_SERVICE_LOG("%s" << "(" %s << ")");\n' % 630 file.write(' GL_SERVICE_LOG("%s" << "(" %s << ")");\n' %
592 (function_name, log_argument_names)) 631 (function_name, log_argument_names))
593 file.write(' %s result = g_debug_%s(%s);\n' % 632 file.write(' %s result = g_debug_%s(%s);\n' %
594 (return_type, function_name, argument_names)) 633 (return_type, function_name, argument_names))
595 file.write(' GL_SERVICE_LOG("GL_RESULT: " << result);\n'); 634 file.write(' GL_SERVICE_LOG("GL_RESULT: " << result);\n');
596 file.write(' return result;\n') 635 file.write(' return result;\n')
597 file.write('}\n') 636 file.write('}\n')
598 file.write('} // extern "C"\n') 637 file.write('} // extern "C"\n')
599 638
600 # Write function to initialize the function pointers. 639 # Write function to initialize the debug function pointers.
601 file.write('\n') 640 file.write('\n')
602 file.write('void InitializeDebugGLBindings%s() {\n' % set_name.upper()) 641 file.write('void InitializeDebugGLBindings%s() {\n' % set_name.upper())
603 for [return_type, names, arguments] in functions: 642 for [return_type, names, arguments] in functions:
604 for name in names: 643 file.write(' if (!g_debug_%s) {\n' % names[0])
605 file.write(' if (!g_debug_%s) {\n' % names[0]) 644 file.write(' g_debug_%s = g_%s;\n' % (names[0], names[0]))
606 file.write(' g_debug_%s = g_%s;\n' % (names[0], names[0])) 645 file.write(' g_%s = Debug_%s;\n' % (names[0], names[0]))
607 file.write(' g_%s = Debug_%s;\n' % (names[0], names[0])) 646 file.write(' }\n')
647 file.write(' g_debugBindingsInitialized = true;\n')
648 file.write('}\n')
649
650 # Write function to update the debug function pointers to extension functions
651 # after the extensions have been initialized.
652 file.write('\n')
653 file.write('static void UpdateDebugGLExtensionBindings() {\n')
654 for extension, ext_functions in used_extension_functions:
655 for name, _ in ext_functions:
656 file.write(' if (g_debug_%s != g_%s &&\n' % (name, name))
657 file.write(' g_%s != Debug_%s) {\n' % (name, name))
658 file.write(' g_debug_%s = g_%s;\n' % (name, name))
659 file.write(' g_%s = Debug_%s;\n' % (name, name))
608 file.write(' }\n') 660 file.write(' }\n')
609 file.write('}\n') 661 file.write('}\n')
610 file.write('\n')
611 662
612 file.write( '} // namespace gfx\n') 663 file.write('} // namespace gfx\n')
613 664
614 665
615 def GenerateMockSource(file, functions): 666 def GenerateMockSource(file, functions):
616 """Generates functions that invoke a mock GLInterface""" 667 """Generates functions that invoke a mock GLInterface"""
617 668
618 file.write('// Copyright (c) 2011 The Chromium Authors. All rights reserved.\n ') 669 file.write('// Copyright (c) 2011 The Chromium Authors. All rights reserved.\n ')
619 file.write('// Use of this source code is governed by a BSD-style license that can be\n') 670 file.write('// Use of this source code is governed by a BSD-style license that can be\n')
620 file.write('// found in the LICENSE file.\n') 671 file.write('// found in the LICENSE file.\n')
621 file.write('\n') 672 file.write('\n')
622 file.write('// This file is automatically generated.\n') 673 file.write('// This file is automatically generated.\n')
(...skipping 16 matching lines...) Expand all
639 argument_names = '' 690 argument_names = ''
640 function_name = names[0][2:] 691 function_name = names[0][2:]
641 if return_type == 'void': 692 if return_type == 'void':
642 file.write(' GLInterface::GetGLInterface()->%s(%s);\n' % 693 file.write(' GLInterface::GetGLInterface()->%s(%s);\n' %
643 (function_name, argument_names)) 694 (function_name, argument_names))
644 else: 695 else:
645 file.write(' return GLInterface::GetGLInterface()->%s(%s);\n' % 696 file.write(' return GLInterface::GetGLInterface()->%s(%s);\n' %
646 (function_name, argument_names)) 697 (function_name, argument_names))
647 file.write('}\n') 698 file.write('}\n')
648 699
700 # Write an 'invalid' function to catch code calling through uninitialized
701 # function pointers or trying to interpret the return value of
702 # GLProcAddress().
703 file.write('\n')
704 file.write('static void MockInvalidFunction() {\n')
705 file.write(' NOTREACHED();\n')
706 file.write('}\n')
707
649 # Write a function to lookup a mock GL function based on its name. 708 # Write a function to lookup a mock GL function based on its name.
650 file.write('\n') 709 file.write('\n')
651 file.write('void* GL_BINDING_CALL GetMockGLProcAddress(const char* name) {\n') 710 file.write('void* GL_BINDING_CALL GetMockGLProcAddress(const char* name) {\n')
652 for [return_type, names, arguments] in functions: 711 for [return_type, names, arguments] in functions:
653 file.write(' if (strcmp(name, "%s") == 0)\n' % names[0]) 712 file.write(' if (strcmp(name, "%s") == 0)\n' % names[0])
654 file.write(' return reinterpret_cast<void*>(Mock_%s);\n' % names[0]) 713 file.write(' return reinterpret_cast<void*>(Mock_%s);\n' % names[0])
655 file.write(' return NULL;\n') 714 # Always return a non-NULL pointer like some EGL implementations do.
715 file.write(' return reinterpret_cast<void*>(&MockInvalidFunction);\n')
656 file.write('}\n'); 716 file.write('}\n');
657 717
658 file.write('\n') 718 file.write('\n')
659 file.write('} // namespace gfx\n') 719 file.write('} // namespace gfx\n')
660 720
721 def ParseExtensionFunctionsFromHeader(header_file):
722 """Parse a C extension header file and return a map from extension names to
723 a list of functions.
724
725 Args:
726 header_file: Line-iterable C header file.
727 Returns:
728 Map of extension name => functions.
729 """
730 extension_start = re.compile(r'#define ([A-Z]+_[A-Z]+_[a-zA-Z]\w+) 1')
731 extension_function = re.compile(r'.+\s+([a-z]+\w+)\s*\(.+\);')
732 typedef = re.compile(r'typedef .*')
733 macro_start = re.compile(r'^#(if|ifdef|ifndef).*')
734 macro_end = re.compile(r'^#endif.*')
735 macro_depth = 0
736 current_extension = None
737 current_extension_depth = 0
738 extensions = collections.defaultdict(lambda: [])
739 for line in header_file:
740 if macro_start.match(line):
741 macro_depth += 1
742 elif macro_end.match(line):
743 macro_depth -= 1
744 if macro_depth < current_extension_depth:
745 current_extension = None
746 match = extension_start.match(line)
747 if match:
748 current_extension = match.group(1)
749 current_extension_depth = macro_depth
750 assert current_extension not in extensions, \
751 "Duplicate extension: " + current_extension
752 match = extension_function.match(line)
753 if match and current_extension and not typedef.match(line):
754 extensions[current_extension].append(match.group(1))
755 return extensions
756
757 def GetExtensionFunctions(extension_headers):
758 """Parse extension functions from a list of header files.
759
760 Args:
761 extension_headers: List of header file names.
762 Returns:
763 Map of extension name => list of functions.
764 """
765 extensions = {}
766 for header in extension_headers:
767 extensions.update(ParseExtensionFunctionsFromHeader(open(header)))
768 return extensions
769
770 def GetFunctionToExtensionMap(extensions):
771 """Construct map from a function names to extensions which define the
772 function.
773
774 Args:
775 extensions: Map of extension name => functions.
776 Returns:
777 Map of function name => extension name.
778 """
779 function_to_extension = {}
780 for extension, functions in extensions.items():
781 for function in functions:
782 assert function not in function_to_extension, \
783 "Duplicate function: " + function
784 function_to_extension[function] = extension
785 return function_to_extension
786
787 def LooksLikeExtensionFunction(function):
788 """Heuristic to see if a function name is consistent with extension function
789 naming."""
790 vendor = re.match(r'\w+?([A-Z][A-Z]+)$', function)
791 return vendor is not None and not vendor.group(1) in ['GL', 'API', 'DC']
792
793 def GetUsedExtensionFunctions(functions, extension_headers):
794 """Determine which functions belong to extensions.
795
796 Args:
797 functions: List of (return type, function names, arguments).
798 extension_headers: List of header file names.
799 Returns:
800 List of (extension name, [function name alternatives]) sorted with least
801 preferred extensions first.
802 """
803 # Parse known extensions.
804 extensions = GetExtensionFunctions(extension_headers)
805 functions_to_extensions = GetFunctionToExtensionMap(extensions)
806
807 # Collect all used extension functions.
808 used_extension_functions = collections.defaultdict(lambda: [])
809 for [return_type, names, arguments] in functions:
810 for name in names:
811 # Make sure we know about all extension functions.
812 if (LooksLikeExtensionFunction(name) and
813 not name in functions_to_extensions):
814 raise RuntimeError('%s looks like an extension function but does not '
815 'belong to any of the known extensions.' % name)
816 if name in functions_to_extensions:
817 extension = functions_to_extensions[name]
818 used_extension_functions[extension].append((names[0], name))
819
820 def ExtensionSortKey(name):
821 # Prefer ratified extensions and EXTs.
822 preferences = ['_ARB_', '_OES_', '_EXT_', '']
823 for i, category in enumerate(preferences):
824 if category in name:
825 return -i
826 used_extension_functions = sorted(used_extension_functions.items(),
827 key = lambda item: ExtensionSortKey(item[0]))
828 return used_extension_functions
661 829
662 def main(argv): 830 def main(argv):
663 """This is the main function.""" 831 """This is the main function."""
664 832
665 if len(argv) >= 1: 833 if len(argv) >= 1:
666 dir = argv[0] 834 dir = argv[0]
667 else: 835 else:
668 dir = '.' 836 dir = '.'
669 837
670 for [functions, set_name] in FUNCTION_SETS: 838 for [functions, set_name, extension_headers] in FUNCTION_SETS:
671 header_file = open( 839 header_file = open(
672 os.path.join(dir, 'gl_bindings_autogen_%s.h' % set_name), 'wb') 840 os.path.join(dir, 'gl_bindings_autogen_%s.h' % set_name), 'wb')
673 GenerateHeader(header_file, functions, set_name) 841 GenerateHeader(header_file, functions, set_name)
674 header_file.close() 842 header_file.close()
675 843
676 source_file = open( 844 source_file = open(
677 os.path.join(dir, 'gl_bindings_autogen_%s.cc' % set_name), 'wb') 845 os.path.join(dir, 'gl_bindings_autogen_%s.cc' % set_name), 'wb')
678 GenerateSource(source_file, functions, set_name) 846 used_extension_functions = GetUsedExtensionFunctions(
847 functions, extension_headers)
848 GenerateSource(source_file, functions, set_name, used_extension_functions)
679 source_file.close() 849 source_file.close()
680 850
681 source_file = open(os.path.join(dir, 'gl_bindings_autogen_mock.cc'), 'wb') 851 source_file = open(os.path.join(dir, 'gl_bindings_autogen_mock.cc'), 'wb')
682 GenerateMockSource(source_file, GL_FUNCTIONS) 852 GenerateMockSource(source_file, GL_FUNCTIONS)
683 source_file.close() 853 source_file.close()
684 854
685 855
686 if __name__ == '__main__': 856 if __name__ == '__main__':
687 main(sys.argv[1:]) 857 main(sys.argv[1:])
OLDNEW
« no previous file with comments | « gpu/command_buffer/common/gles2_cmd_format.h ('k') | ui/gfx/gl/gl.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698