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

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

Issue 98643013: Take GL version and extensions correctly into account when binding functions (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Clarify code in generate_bindings.py according to feedback Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """code generator for GL/GLES extension wrangler.""" 6 """code generator for GL/GLES extension wrangler."""
7 7
8 import optparse 8 import optparse
9 import os 9 import os
10 import collections 10 import collections
11 import re 11 import re
12 import sys 12 import sys
13 13
14 """In case there are multiple versions of the same function, one that's listed
15 first takes priority if its conditions are met. If the function is an extension
16 function, finding the extension from the extension string is a condition for
17 binding it. The last version of the function is treated as a fallback option in
18 case no other versions were bound, so a non-null function pointer in the
19 bindings does not guarantee that the function is supported.
20
21 Function binding conditions can be specified manually by supplying a versions
22 array instead of the names array. Each version has the following keys:
23 name: Mandatory. Name of the function. Multiple versions can have the same
24 name but different conditions.
25 gl_versions: List of GL versions where the function is found.
26 extensions: Extensions where the function is found. If not specified, the
27 extensions are determined based on GL header files.
28 If the function exists in an extension header, you may specify
29 an empty array to prevent making that a condition for binding.
30
31 By default, the function gets its name from the first name in its names or
32 versions array. This can be overridden by supplying a 'known_as' key.
33 """
14 GL_FUNCTIONS = [ 34 GL_FUNCTIONS = [
15 { 'return_type': 'void', 35 { 'return_type': 'void',
16 'names': ['glActiveTexture'], 36 'names': ['glActiveTexture'],
17 'arguments': 'GLenum texture', }, 37 'arguments': 'GLenum texture', },
18 { 'return_type': 'void', 38 { 'return_type': 'void',
19 'names': ['glAttachShader'], 39 'names': ['glAttachShader'],
20 'arguments': 'GLuint program, GLuint shader', }, 40 'arguments': 'GLuint program, GLuint shader', },
21 { 'return_type': 'void', 41 { 'return_type': 'void',
22 'names': ['glBeginQuery'], 42 'names': ['glBeginQuery'],
23 'arguments': 'GLenum target, GLuint id', }, 43 'arguments': 'GLenum target, GLuint id', },
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 'arguments': 'GLenum target, ' 326 'arguments': 'GLenum target, '
307 'GLenum attachment, GLenum pname, GLint* params', }, 327 'GLenum attachment, GLenum pname, GLint* params', },
308 { 'return_type': 'GLenum', 328 { 'return_type': 'GLenum',
309 'names': ['glGetGraphicsResetStatusARB', 329 'names': ['glGetGraphicsResetStatusARB',
310 'glGetGraphicsResetStatusEXT'], 330 'glGetGraphicsResetStatusEXT'],
311 'arguments': 'void', }, 331 'arguments': 'void', },
312 { 'return_type': 'void', 332 { 'return_type': 'void',
313 'names': ['glGetIntegerv'], 333 'names': ['glGetIntegerv'],
314 'arguments': 'GLenum pname, GLint* params', }, 334 'arguments': 'GLenum pname, GLint* params', },
315 { 'return_type': 'void', 335 { 'return_type': 'void',
316 'names': ['glGetProgramBinary', 'glGetProgramBinaryOES'], 336 'known_as': 'glGetProgramBinary',
337 'versions': [{ 'name': 'glGetProgramBinaryOES' },
338 { 'name': 'glGetProgramBinary',
339 'extensions': ['GL_ARB_get_program_binary'] },
340 { 'name': 'glGetProgramBinary' }],
317 'arguments': 'GLuint program, GLsizei bufSize, GLsizei* length, ' 341 'arguments': 'GLuint program, GLsizei bufSize, GLsizei* length, '
318 'GLenum* binaryFormat, GLvoid* binary', 342 'GLenum* binaryFormat, GLvoid* binary' },
319 'other_extensions': ['ARB_get_program_binary',
320 'OES_get_program_binary'] },
321 { 'return_type': 'void', 343 { 'return_type': 'void',
322 'names': ['glGetProgramiv'], 344 'names': ['glGetProgramiv'],
323 'arguments': 'GLuint program, GLenum pname, GLint* params', }, 345 'arguments': 'GLuint program, GLenum pname, GLint* params', },
324 { 'return_type': 'void', 346 { 'return_type': 'void',
325 'names': ['glGetProgramInfoLog'], 347 'names': ['glGetProgramInfoLog'],
326 'arguments': 348 'arguments':
327 'GLuint program, GLsizei bufsize, GLsizei* length, char* infolog', }, 349 'GLuint program, GLsizei bufsize, GLsizei* length, char* infolog', },
328 { 'return_type': 'void', 350 { 'return_type': 'void',
329 'names': ['glGetQueryiv'], 351 'names': ['glGetQueryiv'],
330 'arguments': 'GLenum target, GLenum pname, GLint* params', }, 352 'arguments': 'GLenum target, GLenum pname, GLint* params', },
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 { 'return_type': 'GLboolean', 450 { 'return_type': 'GLboolean',
429 'names': ['glIsTexture'], 451 'names': ['glIsTexture'],
430 'arguments': 'GLuint texture', }, 452 'arguments': 'GLuint texture', },
431 { 'return_type': 'void', 453 { 'return_type': 'void',
432 'names': ['glLineWidth'], 454 'names': ['glLineWidth'],
433 'arguments': 'GLfloat width', }, 455 'arguments': 'GLfloat width', },
434 { 'return_type': 'void', 456 { 'return_type': 'void',
435 'names': ['glLinkProgram'], 457 'names': ['glLinkProgram'],
436 'arguments': 'GLuint program', }, 458 'arguments': 'GLuint program', },
437 { 'return_type': 'void*', 459 { 'return_type': 'void*',
438 'names': ['glMapBuffer', 'glMapBufferOES'], 460 'known_as': 'glMapBuffer',
461 'names': ['glMapBufferOES', 'glMapBuffer'],
439 'arguments': 'GLenum target, GLenum access', }, 462 'arguments': 'GLenum target, GLenum access', },
440 { 'return_type': 'void*', 463 { 'return_type': 'void*',
441 'names': ['glMapBufferRange'], 464 'names': ['glMapBufferRange'],
442 'arguments': 465 'arguments':
443 'GLenum target, GLintptr offset, GLsizeiptr length, GLenum access', }, 466 'GLenum target, GLintptr offset, GLsizeiptr length, GLenum access', },
444 { 'return_type': 'void', 467 { 'return_type': 'void',
445 'names': ['glFlushMappedBufferRange'], 468 'names': ['glFlushMappedBufferRange'],
446 'arguments': 'GLenum target, GLintptr offset, GLsizeiptr length', }, 469 'arguments': 'GLenum target, GLintptr offset, GLsizeiptr length', },
447 { 'return_type': 'void', 470 { 'return_type': 'void',
448 'names': ['glPixelStorei'], 471 'names': ['glPixelStorei'],
449 'arguments': 'GLenum pname, GLint param', }, 472 'arguments': 'GLenum pname, GLint param', },
450 { 'return_type': 'void', 473 { 'return_type': 'void',
451 'names': ['glPointParameteri'], 474 'names': ['glPointParameteri'],
452 'arguments': 'GLenum pname, GLint param', }, 475 'arguments': 'GLenum pname, GLint param', },
453 { 'return_type': 'void', 476 { 'return_type': 'void',
454 'names': ['glPolygonOffset'], 477 'names': ['glPolygonOffset'],
455 'arguments': 'GLfloat factor, GLfloat units', }, 478 'arguments': 'GLfloat factor, GLfloat units', },
456 { 'return_type': 'void', 479 { 'return_type': 'void',
457 'names': ['glProgramBinary', 'glProgramBinaryOES'], 480 'known_as': 'glProgramBinary',
481 'versions': [{ 'name': 'glProgramBinaryOES' },
482 { 'name': 'glProgramBinary',
483 'extensions': ['GL_ARB_get_program_binary'] },
484 { 'name': 'glProgramBinary' }],
458 'arguments': 'GLuint program, GLenum binaryFormat, ' 485 'arguments': 'GLuint program, GLenum binaryFormat, '
459 'const GLvoid* binary, GLsizei length', 486 'const GLvoid* binary, GLsizei length' },
460 'other_extensions': ['ARB_get_program_binary',
461 'OES_get_program_binary'] },
462 { 'return_type': 'void', 487 { 'return_type': 'void',
463 'names': ['glProgramParameteri'], 488 'versions': [{ 'name': 'glProgramParameteri',
464 'arguments': 'GLuint program, GLenum pname, GLint value', 489 'extensions': ['GL_ARB_get_program_binary'] },
465 'other_extensions': ['ARB_get_program_binary'] }, 490 { 'name': 'glProgramParameteri' }],
491 'arguments': 'GLuint program, GLenum pname, GLint value' },
466 { 'return_type': 'void', 492 { 'return_type': 'void',
467 'names': ['glQueryCounter'], 493 'names': ['glQueryCounter'],
468 'arguments': 'GLuint id, GLenum target', }, 494 'arguments': 'GLuint id, GLenum target', },
469 { 'return_type': 'void', 495 { 'return_type': 'void',
470 'names': ['glReadBuffer'], 496 'names': ['glReadBuffer'],
471 'arguments': 'GLenum src', }, 497 'arguments': 'GLenum src', },
472 { 'return_type': 'void', 498 { 'return_type': 'void',
473 'names': ['glReadPixels'], 499 'names': ['glReadPixels'],
474 'arguments': 500 'arguments':
475 'GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, ' 501 'GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, '
476 'GLenum type, void* pixels', }, 502 'GLenum type, void* pixels', },
477 { 'return_type': 'void', 503 { 'return_type': 'void',
478 'names': ['glReleaseShaderCompiler'], 504 'names': ['glReleaseShaderCompiler'],
479 'arguments': 'void', }, 505 'arguments': 'void', },
506 # Multisampling API is different in different GL versions, some require an
507 # explicit resolve step for renderbuffers and/or FBO texture attachments and
508 # some do not. Multiple alternatives might be present in a single
509 # implementation, which require different use of the API and may have
510 # different performance (explicit resolve performing worse, for example).
511 # So even though the function signature is the same across versions, we split
512 # their definitions so that the function to use can be chosen correctly at a
513 # higher level.
514 # TODO(oetuaho@nvidia.com): Some of these might still be possible to combine.
515 # This could also fix weirdness in the mock bindings that's caused by the same
516 # function name appearing multiple times.
517 # This is the ES3 function, which requires explicit resolve:
480 { 'return_type': 'void', 518 { 'return_type': 'void',
481 'names': ['glRenderbufferStorageMultisample'], 519 'names': ['glRenderbufferStorageMultisample'],
482 'arguments': 'GLenum target, GLsizei samples, GLenum internalformat, ' 520 'arguments': 'GLenum target, GLsizei samples, GLenum internalformat, '
483 'GLsizei width, GLsizei height', }, 521 'GLsizei width, GLsizei height', },
522 # In desktop GL, EXT and core versions both have an explicit resolve step,
523 # though desktop core GL implicitly resolves when drawing to a window.
524 # TODO(oetuaho@nvidia.com): Right now this function also doubles as ES2 EXT
525 # function, which has implicit resolve, and for which the fallback is wrong.
526 # Fix this.
484 { 'return_type': 'void', 527 { 'return_type': 'void',
485 'names': ['glRenderbufferStorageMultisampleEXT', 528 'names': ['glRenderbufferStorageMultisampleEXT',
486 'glRenderbufferStorageMultisample'], 529 'glRenderbufferStorageMultisample'],
487 'arguments': 'GLenum target, GLsizei samples, GLenum internalformat, ' 530 'arguments': 'GLenum target, GLsizei samples, GLenum internalformat, '
488 'GLsizei width, GLsizei height', }, 531 'GLsizei width, GLsizei height', },
489 { 'return_type': 'void', 532 { 'return_type': 'void',
490 'names': ['glRenderbufferStorageMultisampleANGLE', 533 'names': ['glRenderbufferStorageMultisampleANGLE',
491 'glRenderbufferStorageMultisample'], 534 'glRenderbufferStorageMultisample'],
492 'arguments': 'GLenum target, GLsizei samples, GLenum internalformat, ' 535 'arguments': 'GLenum target, GLsizei samples, GLenum internalformat, '
493 'GLsizei width, GLsizei height', }, 536 'GLsizei width, GLsizei height', },
(...skipping 10 matching lines...) Expand all
504 'arguments': 'GLclampf value, GLboolean invert', }, 547 'arguments': 'GLclampf value, GLboolean invert', },
505 { 'return_type': 'void', 548 { 'return_type': 'void',
506 'names': ['glScissor'], 549 'names': ['glScissor'],
507 'arguments': 'GLint x, GLint y, GLsizei width, GLsizei height', }, 550 'arguments': 'GLint x, GLint y, GLsizei width, GLsizei height', },
508 { 'return_type': 'void', 551 { 'return_type': 'void',
509 'names': ['glShaderBinary'], 552 'names': ['glShaderBinary'],
510 'arguments': 'GLsizei n, const GLuint* shaders, GLenum binaryformat, ' 553 'arguments': 'GLsizei n, const GLuint* shaders, GLenum binaryformat, '
511 'const void* binary, GLsizei length', }, 554 'const void* binary, GLsizei length', },
512 { 'return_type': 'void', 555 { 'return_type': 'void',
513 'names': ['glShaderSource'], 556 'names': ['glShaderSource'],
514 'arguments': 557 'arguments': 'GLuint shader, GLsizei count, const char* const* str, '
515 'GLuint shader, GLsizei count, const char* const* str, const GLint* length ', 558 'const GLint* length',
516 'logging_code': """ 559 'logging_code': """
517 GL_SERVICE_LOG_CODE_BLOCK({ 560 GL_SERVICE_LOG_CODE_BLOCK({
518 for (GLsizei ii = 0; ii < count; ++ii) { 561 for (GLsizei ii = 0; ii < count; ++ii) {
519 if (str[ii]) { 562 if (str[ii]) {
520 if (length && length[ii] >= 0) { 563 if (length && length[ii] >= 0) {
521 std::string source(str[ii], length[ii]); 564 std::string source(str[ii], length[ii]);
522 GL_SERVICE_LOG(" " << ii << ": ---\\n" << source << "\\n---"); 565 GL_SERVICE_LOG(" " << ii << ": ---\\n" << source << "\\n---");
523 } else { 566 } else {
524 GL_SERVICE_LOG(" " << ii << ": ---\\n" << str[ii] << "\\n---"); 567 GL_SERVICE_LOG(" " << ii << ": ---\\n" << str[ii] << "\\n---");
525 } 568 }
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
629 'GLboolean transpose, const GLfloat* value', }, 672 'GLboolean transpose, const GLfloat* value', },
630 { 'return_type': 'void', 673 { 'return_type': 'void',
631 'names': ['glUniformMatrix3fv'], 674 'names': ['glUniformMatrix3fv'],
632 'arguments': 'GLint location, GLsizei count, ' 675 'arguments': 'GLint location, GLsizei count, '
633 'GLboolean transpose, const GLfloat* value', }, 676 'GLboolean transpose, const GLfloat* value', },
634 { 'return_type': 'void', 677 { 'return_type': 'void',
635 'names': ['glUniformMatrix4fv'], 678 'names': ['glUniformMatrix4fv'],
636 'arguments': 'GLint location, GLsizei count, ' 679 'arguments': 'GLint location, GLsizei count, '
637 'GLboolean transpose, const GLfloat* value', }, 680 'GLboolean transpose, const GLfloat* value', },
638 { 'return_type': 'GLboolean', 681 { 'return_type': 'GLboolean',
639 'names': ['glUnmapBuffer', 'glUnmapBufferOES'], 682 'known_as': 'glUnmapBuffer',
683 'names': ['glUnmapBufferOES', 'glUnmapBuffer'],
640 'arguments': 'GLenum target', }, 684 'arguments': 'GLenum target', },
641 { 'return_type': 'void', 685 { 'return_type': 'void',
642 'names': ['glUseProgram'], 686 'names': ['glUseProgram'],
643 'arguments': 'GLuint program', }, 687 'arguments': 'GLuint program', },
644 { 'return_type': 'void', 688 { 'return_type': 'void',
645 'names': ['glValidateProgram'], 689 'names': ['glValidateProgram'],
646 'arguments': 'GLuint program', }, 690 'arguments': 'GLuint program', },
647 { 'return_type': 'void', 691 { 'return_type': 'void',
648 'names': ['glVertexAttrib1f'], 692 'names': ['glVertexAttrib1f'],
649 'arguments': 'GLuint indx, GLfloat x', }, 693 'arguments': 'GLuint indx, GLfloat x', },
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
705 { 'return_type': 'void', 749 { 'return_type': 'void',
706 'names': ['glGetSynciv'], 750 'names': ['glGetSynciv'],
707 'arguments': 751 'arguments':
708 'GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length,' 752 'GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length,'
709 'GLint* values', }, 753 'GLint* values', },
710 { 'return_type': 'GLenum', 754 { 'return_type': 'GLenum',
711 'names': ['glClientWaitSync'], 755 'names': ['glClientWaitSync'],
712 'arguments': 756 'arguments':
713 'GLsync sync, GLbitfield flags, GLuint64 timeout', }, 757 'GLsync sync, GLbitfield flags, GLuint64 timeout', },
714 { 'return_type': 'void', 758 { 'return_type': 'void',
715 'names': ['glDrawArraysInstancedANGLE', 'glDrawArraysInstancedARB'], 759 'known_as': 'glDrawArraysInstancedANGLE',
760 'names': ['glDrawArraysInstancedARB', 'glDrawArraysInstancedANGLE'],
716 'arguments': 'GLenum mode, GLint first, GLsizei count, GLsizei primcount', }, 761 'arguments': 'GLenum mode, GLint first, GLsizei count, GLsizei primcount', },
717 { 'return_type': 'void', 762 { 'return_type': 'void',
718 'names': ['glDrawElementsInstancedANGLE', 'glDrawElementsInstancedARB'], 763 'known_as': 'glDrawElementsInstancedANGLE',
764 'names': ['glDrawElementsInstancedARB', 'glDrawElementsInstancedANGLE'],
719 'arguments': 765 'arguments':
720 'GLenum mode, GLsizei count, GLenum type, const void* indices, ' 766 'GLenum mode, GLsizei count, GLenum type, const void* indices, '
721 'GLsizei primcount', }, 767 'GLsizei primcount', },
722 { 'return_type': 'void', 768 { 'return_type': 'void',
723 'names': ['glVertexAttribDivisorANGLE', 'glVertexAttribDivisorARB'], 769 'known_as': 'glVertexAttribDivisorANGLE',
770 'names': ['glVertexAttribDivisorARB', 'glVertexAttribDivisorANGLE'],
724 'arguments': 771 'arguments':
725 'GLuint index, GLuint divisor', }, 772 'GLuint index, GLuint divisor', },
726 { 'return_type': 'void', 773 { 'return_type': 'void',
727 'names': ['glGenVertexArraysOES', 774 'known_as': 'glGenVertexArraysOES',
728 'glGenVertexArraysAPPLE', 775 'versions': [{ 'name': 'glGenVertexArrays',
729 'glGenVertexArrays'], 776 'gl_versions': ['gl3', 'gl4'] },
730 'arguments': 'GLsizei n, GLuint* arrays', 777 { 'name': 'glGenVertexArrays',
731 'other_extensions': ['OES_vertex_array_object', 778 'extensions': ['GL_ARB_vertex_array_object'] },
732 'APPLE_vertex_array_object', 779 { 'name': 'glGenVertexArraysOES' },
733 'ARB_vertex_array_object'] }, 780 { 'name': 'glGenVertexArraysAPPLE',
781 'extensions': ['GL_APPLE_vertex_array_object'] }],
782 'arguments': 'GLsizei n, GLuint* arrays', },
734 { 'return_type': 'void', 783 { 'return_type': 'void',
735 'names': ['glDeleteVertexArraysOES', 784 'known_as': 'glDeleteVertexArraysOES',
736 'glDeleteVertexArraysAPPLE', 785 'versions': [{ 'name': 'glDeleteVertexArrays',
737 'glDeleteVertexArrays'], 786 'gl_versions': ['gl3', 'gl4'] },
738 'arguments': 'GLsizei n, const GLuint* arrays', 787 { 'name': 'glDeleteVertexArrays',
739 'other_extensions': ['OES_vertex_array_object', 788 'extensions': ['GL_ARB_vertex_array_object'] },
740 'APPLE_vertex_array_object', 789 { 'name': 'glDeleteVertexArraysOES' },
741 'ARB_vertex_array_object'] }, 790 { 'name': 'glDeleteVertexArraysAPPLE',
791 'extensions': ['GL_APPLE_vertex_array_object'] }],
792 'arguments': 'GLsizei n, const GLuint* arrays' },
742 { 'return_type': 'void', 793 { 'return_type': 'void',
743 'names': ['glBindVertexArrayOES', 794 'known_as': 'glBindVertexArrayOES',
744 'glBindVertexArrayAPPLE', 795 'versions': [{ 'name': 'glBindVertexArray',
745 'glBindVertexArray'], 796 'gl_versions': ['gl3', 'gl4'] },
746 'arguments': 'GLuint array', 797 { 'name': 'glBindVertexArray',
747 'other_extensions': ['OES_vertex_array_object', 798 'extensions': ['GL_ARB_vertex_array_object'] },
748 'APPLE_vertex_array_object', 799 { 'name': 'glBindVertexArrayOES' },
749 'ARB_vertex_array_object'] }, 800 { 'name': 'glBindVertexArrayAPPLE',
801 'extensions': ['GL_APPLE_vertex_array_object'] }],
802 'arguments': 'GLuint array' },
750 { 'return_type': 'GLboolean', 803 { 'return_type': 'GLboolean',
751 'names': ['glIsVertexArrayOES', 804 'known_as': 'glIsVertexArrayOES',
752 'glIsVertexArrayAPPLE', 805 'versions': [{ 'name': 'glIsVertexArray',
753 'glIsVertexArray'], 806 'gl_versions': ['gl3', 'gl4'] },
754 'arguments': 'GLuint array', 807 { 'name': 'glIsVertexArray',
755 'other_extensions': ['OES_vertex_array_object', 808 'extensions': ['GL_ARB_vertex_array_object'] },
756 'APPLE_vertex_array_object', 809 { 'name': 'glIsVertexArrayOES' },
757 'ARB_vertex_array_object'] }, 810 { 'name': 'glIsVertexArrayAPPLE',
811 'extensions': ['GL_APPLE_vertex_array_object'] }],
812 'arguments': 'GLuint array' },
758 { 'return_type': 'void', 813 { 'return_type': 'void',
759 'names': ['glDiscardFramebufferEXT', 'glInvalidateFramebuffer'], 814 'known_as': 'glDiscardFramebufferEXT',
815 'versions': [{ 'name': 'glInvalidateFramebuffer',
816 'gl_versions': ['es3'],
817 'extensions': [] },
818 { 'name': 'glDiscardFramebufferEXT',
819 'gl_versions': ['es1', 'es2'] }],
760 'arguments': 'GLenum target, GLsizei numAttachments, ' 820 'arguments': 'GLenum target, GLsizei numAttachments, '
761 'const GLenum* attachments' }, 821 'const GLenum* attachments' },
762 ] 822 ]
763 823
764 GL_NULLDRAW_FUNCTIONS = [ 824 GL_NULLDRAW_FUNCTIONS = [
765 { 'return_type': 'void', 825 { 'return_type': 'void',
766 'names': ['glClear'], 826 'names': ['glClear'],
767 'arguments': 'GLbitfield mask', }, 827 'arguments': 'GLbitfield mask', },
768 { 'return_type': 'void', 828 { 'return_type': 'void',
769 'names': ['glDrawArrays'], 829 'names': ['glDrawArrays'],
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
838 'EGLint* num_config', }, 898 'EGLint* num_config', },
839 { 'return_type': 'EGLBoolean', 899 { 'return_type': 'EGLBoolean',
840 'names': ['eglChooseConfig'], 900 'names': ['eglChooseConfig'],
841 'arguments': 'EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs, ' 901 'arguments': 'EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs, '
842 'EGLint config_size, EGLint* num_config', }, 902 'EGLint config_size, EGLint* num_config', },
843 { 'return_type': 'EGLBoolean', 903 { 'return_type': 'EGLBoolean',
844 'names': ['eglGetConfigAttrib'], 904 'names': ['eglGetConfigAttrib'],
845 'arguments': 905 'arguments':
846 'EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint* value', }, 906 'EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint* value', },
847 { 'return_type': 'EGLImageKHR', 907 { 'return_type': 'EGLImageKHR',
848 'names': ['eglCreateImageKHR'], 908 'versions': [{ 'name': 'eglCreateImageKHR',
909 'extensions': ['EGL_KHR_image_base'] }],
849 'arguments': 910 'arguments':
850 'EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, ' 911 'EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, '
851 'const EGLint* attrib_list', 912 'const EGLint* attrib_list' },
852 'other_extensions': ['EGL_KHR_image_base'] },
853 { 'return_type': 'EGLBoolean', 913 { 'return_type': 'EGLBoolean',
854 'names': ['eglDestroyImageKHR'], 914 'versions': [{ 'name' : 'eglDestroyImageKHR',
855 'arguments': 'EGLDisplay dpy, EGLImageKHR image', 915 'extensions': ['EGL_KHR_image_base'] }],
856 'other_extensions': ['EGL_KHR_image_base'] }, 916 'arguments': 'EGLDisplay dpy, EGLImageKHR image' },
857 { 'return_type': 'EGLSurface', 917 { 'return_type': 'EGLSurface',
858 'names': ['eglCreateWindowSurface'], 918 'names': ['eglCreateWindowSurface'],
859 'arguments': 'EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, ' 919 'arguments': 'EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, '
860 'const EGLint* attrib_list', }, 920 'const EGLint* attrib_list', },
861 { 'return_type': 'EGLSurface', 921 { 'return_type': 'EGLSurface',
862 'names': ['eglCreatePbufferSurface'], 922 'names': ['eglCreatePbufferSurface'],
863 'arguments': 'EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list', }, 923 'arguments': 'EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list', },
864 { 'return_type': 'EGLSurface', 924 { 'return_type': 'EGLSurface',
865 'names': ['eglCreatePixmapSurface'], 925 'names': ['eglCreatePixmapSurface'],
866 'arguments': 'EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, ' 926 'arguments': 'EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, '
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
944 'arguments': 'const char* procname', }, 1004 'arguments': 'const char* procname', },
945 { 'return_type': 'EGLBoolean', 1005 { 'return_type': 'EGLBoolean',
946 'names': ['eglPostSubBufferNV'], 1006 'names': ['eglPostSubBufferNV'],
947 'arguments': 'EGLDisplay dpy, EGLSurface surface, ' 1007 'arguments': 'EGLDisplay dpy, EGLSurface surface, '
948 'EGLint x, EGLint y, EGLint width, EGLint height', }, 1008 'EGLint x, EGLint y, EGLint width, EGLint height', },
949 { 'return_type': 'EGLBoolean', 1009 { 'return_type': 'EGLBoolean',
950 'names': ['eglQuerySurfacePointerANGLE'], 1010 'names': ['eglQuerySurfacePointerANGLE'],
951 'arguments': 1011 'arguments':
952 'EGLDisplay dpy, EGLSurface surface, EGLint attribute, void** value', }, 1012 'EGLDisplay dpy, EGLSurface surface, EGLint attribute, void** value', },
953 { 'return_type': 'EGLSyncKHR', 1013 { 'return_type': 'EGLSyncKHR',
954 'names': ['eglCreateSyncKHR'], 1014 'versions': [{ 'name': 'eglCreateSyncKHR',
955 'arguments': 'EGLDisplay dpy, EGLenum type, const EGLint* attrib_list', 1015 'extensions': ['EGL_KHR_fence_sync'] }],
956 'other_extensions': ['EGL_KHR_fence_sync'] }, 1016 'arguments': 'EGLDisplay dpy, EGLenum type, const EGLint* attrib_list' },
957 { 'return_type': 'EGLint', 1017 { 'return_type': 'EGLint',
958 'names': ['eglClientWaitSyncKHR'], 1018 'versions': [{ 'name': 'eglClientWaitSyncKHR',
1019 'extensions': ['EGL_KHR_fence_sync'] }],
959 'arguments': 'EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, ' 1020 'arguments': 'EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, '
960 'EGLTimeKHR timeout', 1021 'EGLTimeKHR timeout' },
961 'other_extensions': ['EGL_KHR_fence_sync'] },
962 { 'return_type': 'EGLBoolean', 1022 { 'return_type': 'EGLBoolean',
963 'names': ['eglGetSyncAttribKHR'], 1023 'versions': [{ 'name': 'eglGetSyncAttribKHR',
1024 'extensions': ['EGL_KHR_fence_sync'] }],
964 'arguments': 'EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, ' 1025 'arguments': 'EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, '
965 'EGLint* value', 1026 'EGLint* value' },
966 'other_extensions': ['EGL_KHR_fence_sync'] },
967 { 'return_type': 'EGLBoolean', 1027 { 'return_type': 'EGLBoolean',
968 'names': ['eglDestroySyncKHR'], 1028 'versions': [{ 'name': 'eglDestroySyncKHR',
969 'arguments': 'EGLDisplay dpy, EGLSyncKHR sync', 1029 'extensions': ['EGL_KHR_fence_sync'] }],
970 'other_extensions': ['EGL_KHR_fence_sync'] }, 1030 'arguments': 'EGLDisplay dpy, EGLSyncKHR sync' },
971 { 'return_type': 'EGLBoolean', 1031 { 'return_type': 'EGLBoolean',
972 'names': ['eglGetSyncValuesCHROMIUM'], 1032 'names': ['eglGetSyncValuesCHROMIUM'],
973 'arguments': 1033 'arguments':
974 'EGLDisplay dpy, EGLSurface surface, ' 1034 'EGLDisplay dpy, EGLSurface surface, '
975 'EGLuint64CHROMIUM* ust, EGLuint64CHROMIUM* msc, ' 1035 'EGLuint64CHROMIUM* ust, EGLuint64CHROMIUM* msc, '
976 'EGLuint64CHROMIUM* sbc', }, 1036 'EGLuint64CHROMIUM* sbc', },
977 { 'return_type': 'EGLint', 1037 { 'return_type': 'EGLint',
978 'names': ['eglWaitSyncKHR'], 1038 'versions': [{ 'name': 'eglWaitSyncKHR',
979 'arguments': 'EGLDisplay dpy, EGLSyncKHR sync, EGLint flags', 1039 'extensions': ['EGL_KHR_fence_sync'] }],
980 'other_extensions': ['EGL_KHR_wait_sync'] }, 1040 'arguments': 'EGLDisplay dpy, EGLSyncKHR sync, EGLint flags' }
981 ] 1041 ]
982 1042
983 WGL_FUNCTIONS = [ 1043 WGL_FUNCTIONS = [
984 { 'return_type': 'HGLRC', 1044 { 'return_type': 'HGLRC',
985 'names': ['wglCreateContext'], 1045 'names': ['wglCreateContext'],
986 'arguments': 'HDC hdc', }, 1046 'arguments': 'HDC hdc', },
987 { 'return_type': 'HGLRC', 1047 { 'return_type': 'HGLRC',
988 'names': ['wglCreateLayerContext'], 1048 'names': ['wglCreateLayerContext'],
989 'arguments': 'HDC hdc, int iLayerPlane', }, 1049 'arguments': 'HDC hdc, int iLayerPlane', },
990 { 'return_type': 'BOOL', 1050 { 'return_type': 'BOOL',
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
1220 ], 1280 ],
1221 [ 1281 [
1222 'EGL_ANGLE_d3d_share_handle_client_buffer', 1282 'EGL_ANGLE_d3d_share_handle_client_buffer',
1223 'EGL_ANGLE_surface_d3d_texture_2d_share_handle', 1283 'EGL_ANGLE_surface_d3d_texture_2d_share_handle',
1224 ], 1284 ],
1225 ], 1285 ],
1226 [WGL_FUNCTIONS, [], 'wgl', ['GL/wglext.h'], []], 1286 [WGL_FUNCTIONS, [], 'wgl', ['GL/wglext.h'], []],
1227 [GLX_FUNCTIONS, [], 'glx', ['GL/glx.h', 'GL/glxext.h'], []], 1287 [GLX_FUNCTIONS, [], 'glx', ['GL/glx.h', 'GL/glxext.h'], []],
1228 ] 1288 ]
1229 1289
1230 def GenerateHeader(file, functions, set_name, used_extension_functions): 1290 def GenerateHeader(file, functions, set_name, used_extensions):
1231 """Generates gl_bindings_autogen_x.h""" 1291 """Generates gl_bindings_autogen_x.h"""
1232 1292
1233 # Write file header. 1293 # Write file header.
1234 file.write( 1294 file.write(
1235 """// Copyright (c) 2012 The Chromium Authors. All rights reserved. 1295 """// Copyright (c) 2012 The Chromium Authors. All rights reserved.
1236 // Use of this source code is governed by a BSD-style license that can be 1296 // Use of this source code is governed by a BSD-style license that can be
1237 // found in the LICENSE file. 1297 // found in the LICENSE file.
1238 1298
1239 // This file is automatically generated. 1299 // This file is automatically generated.
1240 1300
1241 #ifndef UI_GFX_GL_GL_BINDINGS_AUTOGEN_%(name)s_H_ 1301 #ifndef UI_GFX_GL_GL_BINDINGS_AUTOGEN_%(name)s_H_
1242 #define UI_GFX_GL_GL_BINDINGS_AUTOGEN_%(name)s_H_ 1302 #define UI_GFX_GL_GL_BINDINGS_AUTOGEN_%(name)s_H_
1243 1303
1244 namespace gfx { 1304 namespace gfx {
1245 1305
1246 class GLContext; 1306 class GLContext;
1247 1307
1248 """ % {'name': set_name.upper()}) 1308 """ % {'name': set_name.upper()})
1249 1309
1250 # Write typedefs for function pointer types. Always use the GL name for the 1310 # Write typedefs for function pointer types. Always use the GL name for the
1251 # typedef. 1311 # typedef.
1252 file.write('\n') 1312 file.write('\n')
1253 for func in functions: 1313 for func in functions:
1254 file.write('typedef %s (GL_BINDING_CALL *%sProc)(%s);\n' % 1314 file.write('typedef %s (GL_BINDING_CALL *%sProc)(%s);\n' %
1255 (func['return_type'], func['names'][0], func['arguments'])) 1315 (func['return_type'], func['known_as'], func['arguments']))
1256 1316
1257 # Write declarations for booleans indicating which extensions are available. 1317 # Write declarations for booleans indicating which extensions are available.
1258 file.write('\n') 1318 file.write('\n')
1259 file.write("struct Extensions%s {\n" % set_name.upper()) 1319 file.write("struct Extensions%s {\n" % set_name.upper())
1260 for extension, ext_functions in used_extension_functions: 1320 for extension in sorted(used_extensions):
1261 file.write(' bool b_%s;\n' % extension) 1321 file.write(' bool b_%s;\n' % extension)
1262 file.write('};\n') 1322 file.write('};\n')
1263 file.write('\n') 1323 file.write('\n')
1264 1324
1265 # Write Procs struct. 1325 # Write Procs struct.
1266 file.write("struct Procs%s {\n" % set_name.upper()) 1326 file.write("struct Procs%s {\n" % set_name.upper())
1267 for func in functions: 1327 for func in functions:
1268 file.write(' %sProc %sFn;\n' % (func['names'][0], func['names'][0])) 1328 file.write(' %sProc %sFn;\n' % (func['known_as'], func['known_as']))
1269 file.write('};\n') 1329 file.write('};\n')
1270 file.write('\n') 1330 file.write('\n')
1271 1331
1272 # Write Api class. 1332 # Write Api class.
1273 file.write( 1333 file.write(
1274 """class GL_EXPORT %(name)sApi { 1334 """class GL_EXPORT %(name)sApi {
1275 public: 1335 public:
1276 %(name)sApi(); 1336 %(name)sApi();
1277 virtual ~%(name)sApi(); 1337 virtual ~%(name)sApi();
1278 1338
1279 """ % {'name': set_name.upper()}) 1339 """ % {'name': set_name.upper()})
1280 for func in functions: 1340 for func in functions:
1281 file.write(' virtual %s %sFn(%s) = 0;\n' % 1341 file.write(' virtual %s %sFn(%s) = 0;\n' %
1282 (func['return_type'], func['names'][0], func['arguments'])) 1342 (func['return_type'], func['known_as'], func['arguments']))
1283 file.write('};\n') 1343 file.write('};\n')
1284 file.write('\n') 1344 file.write('\n')
1285 1345
1286 file.write( '} // namespace gfx\n') 1346 file.write( '} // namespace gfx\n')
1287 1347
1288 # Write macros to invoke function pointers. Always use the GL name for the 1348 # Write macros to invoke function pointers. Always use the GL name for the
1289 # macro. 1349 # macro.
1290 file.write('\n') 1350 file.write('\n')
1291 for func in functions: 1351 for func in functions:
1292 file.write('#define %s ::gfx::g_current_%s_context->%sFn\n' % 1352 file.write('#define %s ::gfx::g_current_%s_context->%sFn\n' %
1293 (func['names'][0], set_name.lower(), func['names'][0])) 1353 (func['known_as'], set_name.lower(), func['known_as']))
1294 1354
1295 file.write('\n') 1355 file.write('\n')
1296 file.write('#endif // UI_GFX_GL_GL_BINDINGS_AUTOGEN_%s_H_\n' % 1356 file.write('#endif // UI_GFX_GL_GL_BINDINGS_AUTOGEN_%s_H_\n' %
1297 set_name.upper()) 1357 set_name.upper())
1298 1358
1299 1359
1300 def GenerateAPIHeader(file, functions, set_name, used_extension_functions): 1360 def GenerateAPIHeader(file, functions, set_name):
1301 """Generates gl_bindings_api_autogen_x.h""" 1361 """Generates gl_bindings_api_autogen_x.h"""
1302 1362
1303 # Write file header. 1363 # Write file header.
1304 file.write( 1364 file.write(
1305 """// Copyright (c) 2012 The Chromium Authors. All rights reserved. 1365 """// Copyright (c) 2012 The Chromium Authors. All rights reserved.
1306 // Use of this source code is governed by a BSD-style license that can be 1366 // Use of this source code is governed by a BSD-style license that can be
1307 // found in the LICENSE file. 1367 // found in the LICENSE file.
1308 1368
1309 // This file is automatically generated. 1369 // This file is automatically generated.
1310 1370
1311 """ % {'name': set_name.upper()}) 1371 """ % {'name': set_name.upper()})
1312 1372
1313 # Write API declaration. 1373 # Write API declaration.
1314 for func in functions: 1374 for func in functions:
1315 file.write(' virtual %s %sFn(%s) OVERRIDE;\n' % 1375 file.write(' virtual %s %sFn(%s) OVERRIDE;\n' %
1316 (func['return_type'], func['names'][0], func['arguments'])) 1376 (func['return_type'], func['known_as'], func['arguments']))
1317 1377
1318 file.write('\n') 1378 file.write('\n')
1319 1379
1320 1380
1321 def GenerateMockHeader(file, functions, set_name, used_extension_functions): 1381 def GenerateMockHeader(file, functions, set_name):
1322 """Generates gl_mock_autogen_x.h""" 1382 """Generates gl_mock_autogen_x.h"""
1323 1383
1324 # Write file header. 1384 # Write file header.
1325 file.write( 1385 file.write(
1326 """// Copyright (c) 2012 The Chromium Authors. All rights reserved. 1386 """// Copyright (c) 2012 The Chromium Authors. All rights reserved.
1327 // Use of this source code is governed by a BSD-style license that can be 1387 // Use of this source code is governed by a BSD-style license that can be
1328 // found in the LICENSE file. 1388 // found in the LICENSE file.
1329 1389
1330 // This file is automatically generated. 1390 // This file is automatically generated.
1331 1391
1332 """ % {'name': set_name.upper()}) 1392 """ % {'name': set_name.upper()})
1333 1393
1334 # Write API declaration. 1394 # Write API declaration.
1335 for func in functions: 1395 for func in functions:
1336 args = func['arguments'] 1396 args = func['arguments']
1337 if args == 'void': 1397 if args == 'void':
1338 args = '' 1398 args = ''
1339 arg_count = 0 1399 arg_count = 0
1340 if len(args): 1400 if len(args):
1341 arg_count = func['arguments'].count(',') + 1 1401 arg_count = func['arguments'].count(',') + 1
1342 file.write(' MOCK_METHOD%d(%s, %s(%s));\n' % 1402 file.write(' MOCK_METHOD%d(%s, %s(%s));\n' %
1343 (arg_count, func['names'][0][2:], func['return_type'], args)) 1403 (arg_count, func['known_as'][2:], func['return_type'], args))
1344 1404
1345 file.write('\n') 1405 file.write('\n')
1346 1406
1347 1407
1348 def GenerateInterfaceHeader( 1408 def GenerateInterfaceHeader(file, functions, set_name):
1349 file, functions, set_name, used_extension_functions):
1350 """Generates gl_interface_autogen_x.h""" 1409 """Generates gl_interface_autogen_x.h"""
1351 1410
1352 # Write file header. 1411 # Write file header.
1353 file.write( 1412 file.write(
1354 """// Copyright (c) 2012 The Chromium Authors. All rights reserved. 1413 """// Copyright (c) 2012 The Chromium Authors. All rights reserved.
1355 // Use of this source code is governed by a BSD-style license that can be 1414 // Use of this source code is governed by a BSD-style license that can be
1356 // found in the LICENSE file. 1415 // found in the LICENSE file.
1357 1416
1358 // This file is automatically generated. 1417 // This file is automatically generated.
1359 1418
1360 """ % {'name': set_name.upper()}) 1419 """ % {'name': set_name.upper()})
1361 1420
1362 # Write API declaration. 1421 # Write API declaration.
1363 for func in functions: 1422 for func in functions:
1364 args = func['arguments'] 1423 args = func['arguments']
1365 if args == 'void': 1424 if args == 'void':
1366 args = '' 1425 args = ''
1367 file.write(' virtual %s %s(%s) = 0;\n' % 1426 file.write(' virtual %s %s(%s) = 0;\n' %
1368 (func['return_type'], func['names'][0][2:], args)) 1427 (func['return_type'], func['known_as'][2:], args))
1369 1428
1370 file.write('\n') 1429 file.write('\n')
1371 1430
1372 1431
1373 def GenerateSource( 1432 def GenerateSource(
1374 file, functions, nulldraw_functions, set_name, used_extension_functions): 1433 file, functions, nulldraw_functions, set_name, used_extensions):
1375 """Generates gl_bindings_autogen_x.cc""" 1434 """Generates gl_bindings_autogen_x.cc"""
1376 1435
1377 # Write file header. 1436 # Write file header.
1378 file.write( 1437 file.write(
1379 """// Copyright (c) 2011 The Chromium Authors. All rights reserved. 1438 """// Copyright (c) 2011 The Chromium Authors. All rights reserved.
1380 // Use of this source code is governed by a BSD-style license that can be 1439 // Use of this source code is governed by a BSD-style license that can be
1381 // found in the LICENSE file. 1440 // found in the LICENSE file.
1382 1441
1383 // This file is automatically generated. 1442 // This file is automatically generated.
1384 1443
1385 #include <string> 1444 #include <string>
1386 #include "base/debug/trace_event.h" 1445 #include "base/debug/trace_event.h"
1387 #include "gpu/command_buffer/common/gles2_cmd_utils.h" 1446 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
1388 #include "ui/gl/gl_bindings.h" 1447 #include "ui/gl/gl_bindings.h"
1389 #include "ui/gl/gl_context.h" 1448 #include "ui/gl/gl_context.h"
1390 #include "ui/gl/gl_implementation.h" 1449 #include "ui/gl/gl_implementation.h"
1450 #include "ui/gl/gl_version_info.h"
1391 #include "ui/gl/gl_%s_api_implementation.h" 1451 #include "ui/gl/gl_%s_api_implementation.h"
1392 1452
1393 using gpu::gles2::GLES2Util; 1453 using gpu::gles2::GLES2Util;
1394 1454
1395 namespace gfx { 1455 namespace gfx {
1396 """ % set_name.lower()) 1456 """ % set_name.lower())
1397 1457
1398 # Write definitions of function pointers.
1399 file.write('\n') 1458 file.write('\n')
1400 file.write('static bool g_debugBindingsInitialized;\n') 1459 file.write('static bool g_debugBindingsInitialized;\n')
1401 file.write('Driver%s g_driver_%s;\n' % (set_name.upper(), set_name.lower())) 1460 file.write('Driver%s g_driver_%s;\n' % (set_name.upper(), set_name.lower()))
1402 file.write('\n') 1461 file.write('\n')
1403 1462
1404 # Write function to initialize the core function pointers. The code assumes 1463 # Write stub functions that take the place of some functions before a context
1405 # any non-NULL pointer returned by GetGLCoreProcAddress() is valid, although 1464 # is initialized. This is done to provide clear asserts on debug build and to
1406 # it may be overwritten by an extension function pointer later. 1465 # avoid crashing in case of a bug on release build.
1407 file.write('\n') 1466 file.write('\n')
1408 file.write('void Driver%s::InitializeBindings() {\n' % 1467 for func in functions:
1468 unique_names = set([version['name'] for version in func['versions']])
1469 if len(unique_names) > 1:
1470 file.write('%s %sNotBound(%s) {\n' %
1471 (func['return_type'], func['known_as'], func['arguments']))
1472 file.write(' NOTREACHED();\n')
1473 return_type = func['return_type'].lower()
1474 # Returning 0 works for booleans, integers and pointers.
1475 if return_type != 'void':
1476 file.write(' return 0;\n')
1477 file.write('}\n')
1478
1479 # Write function to initialize the function pointers that are always the same
1480 # and to initialize bindings where choice of the function depends on the
1481 # extension string or the GL version to point to stub functions.
1482 file.write('\n')
1483 file.write('void Driver%s::InitializeStaticBindings() {\n' %
1409 set_name.upper()) 1484 set_name.upper())
1485
1486 def WriteFuncBinding(file, known_as, version_name):
1487 file.write(
1488 ' fn.%sFn = reinterpret_cast<%sProc>(GetGLProcAddress("%s"));\n' %
1489 (known_as, known_as, version_name))
1490
1410 for func in functions: 1491 for func in functions:
1411 first_name = func['names'][0] 1492 unique_names = set([version['name'] for version in func['versions']])
1412 for i, name in enumerate(func['names']): 1493 if len(unique_names) == 1:
1413 if i: 1494 WriteFuncBinding(file, func['known_as'], func['known_as'])
1414 file.write(' if (!fn.%sFn)\n ' % first_name) 1495 else:
1415 file.write( 1496 file.write(' fn.%sFn = reinterpret_cast<%sProc>(%sNotBound);\n' %
1416 ' fn.%sFn = reinterpret_cast<%sProc>(' 1497 (func['known_as'], func['known_as'], func['known_as']))
1417 'GetGLCoreProcAddress("%s"));\n' % 1498
1418 (first_name, first_name, name))
1419 file.write('}\n') 1499 file.write('}\n')
1420 file.write('\n') 1500 file.write('\n')
1421 1501
1422 # Write function to initialize the extension function pointers. This function 1502 # Write function to initialize bindings where choice of the function depends
1423 # uses a current context to query which extensions are actually supported. 1503 # on the extension string or the GL version.
1424 file.write("""void Driver%s::InitializeExtensionBindings( 1504 file.write("""void Driver%s::InitializeDynamicBindings(GLContext* context) {
1425 GLContext* context) { 1505 DCHECK(context && context->IsCurrent(NULL));
1506 const GLVersionInfo* ver ALLOW_UNUSED = context->GetVersionInfo();
1507 std::string extensions ALLOW_UNUSED = context->GetExtensions();
1508 extensions += " ";
1509
1426 """ % set_name.upper()) 1510 """ % set_name.upper())
1427 file.write(' DCHECK(context && context->IsCurrent(NULL));\n') 1511 for extension in sorted(used_extensions):
1428 for extension, ext_functions in used_extension_functions: 1512 # Extra space at the end of the extension name is intentional, it is used
1429 file.write(' ext.b_%s = context->HasExtension("%s");\n' % 1513 # as a separator
1514 file.write(' ext.b_%s = extensions.find("%s ") != std::string::npos;\n' %
1430 (extension, extension)) 1515 (extension, extension))
1431 file.write(' if (ext.b_%s) {\n' % 1516
1432 (extension)) 1517 def WrapOr(cond):
1433 queried_entry_points = set() 1518 if ' || ' in cond:
1434 for entry_point_name, function_name in ext_functions: 1519 return '(%s)' % cond
1435 # Replace the pointer unconditionally unless this extension has several 1520 return cond
1436 # alternatives for the same entry point (e.g., 1521
1437 # GL_ARB_blend_func_extended). 1522 def WrapAnd(cond):
1438 if entry_point_name in queried_entry_points: 1523 if ' && ' in cond:
1439 file.write(' if (!fn.%sFn)\n ' % entry_point_name) 1524 return '(%s)' % cond
1440 file.write( 1525 return cond
1441 ' fn.%sFn = reinterpret_cast<%sProc>(GetGLProcAddress("%s"));\n' % 1526
1442 (entry_point_name, entry_point_name, function_name)) 1527 def VersionCondition(version):
1443 queried_entry_points.add(entry_point_name) 1528 conditions = []
1444 file.write(' }\n') 1529 if 'gl_versions' in version:
1530 gl_versions = version['gl_versions']
1531 version_cond = ' || '.join(['ver->is_%s' % gl for gl in gl_versions])
1532 conditions.append(WrapOr(version_cond))
1533 if 'extensions' in version and version['extensions']:
1534 ext_cond = ' || '.join(['ext.b_%s' % e for e in version['extensions']])
1535 conditions.append(WrapOr(ext_cond))
1536 return ' && '.join(conditions)
1537
1538 def WriteConditionalFuncBinding(file, func):
1539 # Functions with only one version are always bound unconditionally
1540 assert len(func['versions']) > 1
1541 known_as = func['known_as']
1542 i = 0
1543 first_version = True
1544 while i < len(func['versions']):
1545 version = func['versions'][i]
1546 cond = VersionCondition(version)
1547 combined_conditions = [WrapAnd(cond)]
1548 last_version = i + 1 == len(func['versions'])
1549 while not last_version and \
1550 func['versions'][i + 1]['name'] == version['name']:
1551 i += 1
1552 combinable_cond = VersionCondition(func['versions'][i])
1553 combined_conditions.append(WrapAnd(combinable_cond))
1554 last_version = i + 1 == len(func['versions'])
1555 if len(combined_conditions) > 1:
1556 if [1 for cond in combined_conditions if cond == '']:
1557 cond = ''
1558 else:
1559 cond = ' || '.join(combined_conditions)
1560 # Don't make the last possible binding conditional on anything else but
1561 # that the function isn't already bound to avoid verbose specification
1562 # of functions which have both ARB and core versions with the same name,
1563 # and to be able to bind to mock extension functions in unit tests which
1564 # call InitializeDynamicGLBindings with a stub context that doesn't have
1565 # extensions in its extension string.
1566 # TODO(oetuaho@nvidia.com): Get rid of the fallback.
1567 # http://crbug.com/325668
1568 if cond != '' and not last_version:
1569 if not first_version:
1570 file.write(' if (!fn.%sFn && (%s))\n ' % (known_as, cond))
1571 else:
1572 file.write(' if (%s)\n ' % cond)
1573 elif not first_version:
1574 file.write(' if (!fn.%sFn)\n ' % known_as)
1575 WriteFuncBinding(file, known_as, version['name'])
1576 i += 1
1577 first_version = False
1578
1579 for func in functions:
1580 unique_names = set([version['name'] for version in func['versions']])
1581 if len(unique_names) > 1:
1582 file.write('\n')
1583 file.write(' fn.%sFn = 0;\n' % func['known_as'])
1584 file.write(' debug_fn.%sFn = 0;\n' % func['known_as'])
1585 WriteConditionalFuncBinding(file, func)
1586
1587 # Some new function pointers have been added, so update them in debug bindings
1588 file.write('\n')
1445 file.write(' if (g_debugBindingsInitialized)\n') 1589 file.write(' if (g_debugBindingsInitialized)\n')
1446 file.write(' UpdateDebugExtensionBindings();\n') 1590 file.write(' InitializeDebugBindings();\n')
1447 file.write('}\n') 1591 file.write('}\n')
1448 file.write('\n') 1592 file.write('\n')
1449 1593
1450 # Write empty stubs for functions that want one. 1594 # Write empty stubs for functions that want one.
1451 file.write('extern "C" {\n') 1595 file.write('extern "C" {\n')
1452 for func in nulldraw_functions: 1596 for func in nulldraw_functions:
1453 names = func['names'] 1597 known_as = func['known_as']
1454 return_type = func['return_type'] 1598 return_type = func['return_type']
1455 arguments = func['arguments'] 1599 arguments = func['arguments']
1456 file.write('\n') 1600 file.write('\n')
1457 file.write('static %s GL_BINDING_CALL Stub_%s(%s) {}\n' % 1601 file.write('static %s GL_BINDING_CALL Stub_%s(%s) {}\n' %
1458 (return_type, names[0], arguments)) 1602 (return_type, known_as, arguments))
1459 file.write('} // extern "C"\n') 1603 file.write('} // extern "C"\n')
1460 1604
1461 # Write logging wrappers for each function. 1605 # Write logging wrappers for each function.
1462 file.write('extern "C" {\n') 1606 file.write('extern "C" {\n')
1463 for func in functions: 1607 for func in functions:
1464 names = func['names']
1465 return_type = func['return_type'] 1608 return_type = func['return_type']
1466 arguments = func['arguments'] 1609 arguments = func['arguments']
1467 file.write('\n') 1610 file.write('\n')
1468 file.write('static %s GL_BINDING_CALL Debug_%s(%s) {\n' % 1611 file.write('static %s GL_BINDING_CALL Debug_%s(%s) {\n' %
1469 (return_type, names[0], arguments)) 1612 (return_type, func['known_as'], arguments))
1470 argument_names = re.sub( 1613 argument_names = re.sub(
1471 r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', arguments) 1614 r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', arguments)
1472 argument_names = re.sub( 1615 argument_names = re.sub(
1473 r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', argument_names) 1616 r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', argument_names)
1474 log_argument_names = re.sub( 1617 log_argument_names = re.sub(
1475 r'const char\* ([a-zA-Z0-9_]+)', r'CONSTCHAR_\1', arguments) 1618 r'const char\* ([a-zA-Z0-9_]+)', r'CONSTCHAR_\1', arguments)
1476 log_argument_names = re.sub( 1619 log_argument_names = re.sub(
1477 r'(const )?[a-zA-Z0-9_]+\* ([a-zA-Z0-9_]+)', 1620 r'(const )?[a-zA-Z0-9_]+\* ([a-zA-Z0-9_]+)',
1478 r'CONSTVOID_\2', log_argument_names) 1621 r'CONSTVOID_\2', log_argument_names)
1479 log_argument_names = re.sub( 1622 log_argument_names = re.sub(
1480 r'(?<!E)GLenum ([a-zA-Z0-9_]+)', r'GLenum_\1', log_argument_names) 1623 r'(?<!E)GLenum ([a-zA-Z0-9_]+)', r'GLenum_\1', log_argument_names)
1481 log_argument_names = re.sub( 1624 log_argument_names = re.sub(
1482 r'(?<!E)GLboolean ([a-zA-Z0-9_]+)', r'GLboolean_\1', log_argument_names) 1625 r'(?<!E)GLboolean ([a-zA-Z0-9_]+)', r'GLboolean_\1', log_argument_names)
1483 log_argument_names = re.sub( 1626 log_argument_names = re.sub(
1484 r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', 1627 r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2',
1485 log_argument_names) 1628 log_argument_names)
1486 log_argument_names = re.sub( 1629 log_argument_names = re.sub(
1487 r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', 1630 r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2',
1488 log_argument_names) 1631 log_argument_names)
1489 log_argument_names = re.sub( 1632 log_argument_names = re.sub(
1490 r'CONSTVOID_([a-zA-Z0-9_]+)', 1633 r'CONSTVOID_([a-zA-Z0-9_]+)',
1491 r'static_cast<const void*>(\1)', log_argument_names); 1634 r'static_cast<const void*>(\1)', log_argument_names)
1492 log_argument_names = re.sub( 1635 log_argument_names = re.sub(
1493 r'CONSTCHAR_([a-zA-Z0-9_]+)', r'\1', log_argument_names); 1636 r'CONSTCHAR_([a-zA-Z0-9_]+)', r'\1', log_argument_names)
1494 log_argument_names = re.sub( 1637 log_argument_names = re.sub(
1495 r'GLenum_([a-zA-Z0-9_]+)', r'GLES2Util::GetStringEnum(\1)', 1638 r'GLenum_([a-zA-Z0-9_]+)', r'GLES2Util::GetStringEnum(\1)',
1496 log_argument_names) 1639 log_argument_names)
1497 log_argument_names = re.sub( 1640 log_argument_names = re.sub(
1498 r'GLboolean_([a-zA-Z0-9_]+)', r'GLES2Util::GetStringBool(\1)', 1641 r'GLboolean_([a-zA-Z0-9_]+)', r'GLES2Util::GetStringBool(\1)',
1499 log_argument_names) 1642 log_argument_names)
1500 log_argument_names = log_argument_names.replace(',', ' << ", " <<') 1643 log_argument_names = log_argument_names.replace(',', ' << ", " <<')
1501 if argument_names == 'void' or argument_names == '': 1644 if argument_names == 'void' or argument_names == '':
1502 argument_names = '' 1645 argument_names = ''
1503 log_argument_names = '' 1646 log_argument_names = ''
1504 else: 1647 else:
1505 log_argument_names = " << " + log_argument_names 1648 log_argument_names = " << " + log_argument_names
1506 function_name = names[0] 1649 function_name = func['known_as']
1507 if return_type == 'void': 1650 if return_type == 'void':
1508 file.write(' GL_SERVICE_LOG("%s" << "(" %s << ")");\n' % 1651 file.write(' GL_SERVICE_LOG("%s" << "(" %s << ")");\n' %
1509 (function_name, log_argument_names)) 1652 (function_name, log_argument_names))
1510 file.write(' g_driver_%s.debug_fn.%sFn(%s);\n' % 1653 file.write(' g_driver_%s.debug_fn.%sFn(%s);\n' %
1511 (set_name.lower(), function_name, argument_names)) 1654 (set_name.lower(), function_name, argument_names))
1512 if 'logging_code' in func: 1655 if 'logging_code' in func:
1513 file.write("%s\n" % func['logging_code']) 1656 file.write("%s\n" % func['logging_code'])
1514 else: 1657 else:
1515 file.write(' GL_SERVICE_LOG("%s" << "(" %s << ")");\n' % 1658 file.write(' GL_SERVICE_LOG("%s" << "(" %s << ")");\n' %
1516 (function_name, log_argument_names)) 1659 (function_name, log_argument_names))
1517 file.write(' %s result = g_driver_%s.debug_fn.%sFn(%s);\n' % 1660 file.write(' %s result = g_driver_%s.debug_fn.%sFn(%s);\n' %
1518 (return_type, set_name.lower(), function_name, argument_names)) 1661 (return_type, set_name.lower(), function_name, argument_names))
1519 if 'logging_code' in func: 1662 if 'logging_code' in func:
1520 file.write("%s\n" % func['logging_code']) 1663 file.write("%s\n" % func['logging_code'])
1521 else: 1664 else:
1522 file.write(' GL_SERVICE_LOG("GL_RESULT: " << result);\n'); 1665 file.write(' GL_SERVICE_LOG("GL_RESULT: " << result);\n')
1523 file.write(' return result;\n') 1666 file.write(' return result;\n')
1524 file.write('}\n') 1667 file.write('}\n')
1525 file.write('} // extern "C"\n') 1668 file.write('} // extern "C"\n')
1526 1669
1527 # Write function to initialize the debug function pointers. 1670 # Write function to initialize the debug function pointers.
1528 file.write('\n') 1671 file.write('\n')
1529 file.write('void Driver%s::InitializeDebugBindings() {\n' % 1672 file.write('void Driver%s::InitializeDebugBindings() {\n' %
1530 set_name.upper()) 1673 set_name.upper())
1531 for func in functions: 1674 for func in functions:
1532 first_name = func['names'][0] 1675 first_name = func['known_as']
1533 file.write(' if (!debug_fn.%sFn) {\n' % first_name) 1676 file.write(' if (!debug_fn.%sFn) {\n' % first_name)
1534 file.write(' debug_fn.%sFn = fn.%sFn;\n' % (first_name, first_name)) 1677 file.write(' debug_fn.%sFn = fn.%sFn;\n' % (first_name, first_name))
1535 file.write(' fn.%sFn = Debug_%s;\n' % (first_name, first_name)) 1678 file.write(' fn.%sFn = Debug_%s;\n' % (first_name, first_name))
1536 file.write(' }\n') 1679 file.write(' }\n')
1537 file.write(' g_debugBindingsInitialized = true;\n') 1680 file.write(' g_debugBindingsInitialized = true;\n')
1538 file.write('}\n') 1681 file.write('}\n')
1539 1682
1540 # Write function to initialize the nulldraw function pointers. 1683 # Write function to initialize the nulldraw function pointers.
1541 if nulldraw_functions: 1684 if nulldraw_functions:
1542 file.write('\n') 1685 file.write('\n')
1543 file.write('void Driver%s::InitializeNullDrawBindings() {\n' % 1686 file.write('void Driver%s::InitializeNullDrawBindings() {\n' %
1544 set_name.upper()) 1687 set_name.upper())
1545 1688
1546 for func in nulldraw_functions: 1689 for func in nulldraw_functions:
1547 first_name = func['names'][0] 1690 first_name = func['known_as']
1548 file.write(' fn.%sFn = Stub_%s;\n' % (first_name, first_name)) 1691 file.write(' fn.%sFn = Stub_%s;\n' % (first_name, first_name))
1549 file.write('}\n') 1692 file.write('}\n')
1550 1693
1551 # Write function to update the debug function pointers to extension functions
1552 # after the extensions have been initialized.
1553 file.write('\n')
1554 file.write('void Driver%s::UpdateDebugExtensionBindings() {\n' %
1555 set_name.upper())
1556 for extension, ext_functions in used_extension_functions:
1557 for name, _ in ext_functions:
1558 file.write(' if (debug_fn.%sFn != fn.%sFn &&\n' % (name, name))
1559 file.write(' fn.%sFn != Debug_%s) {\n' % (name, name))
1560 file.write(' debug_fn.%sFn = fn.%sFn;\n' % (name, name))
1561 file.write(' fn.%sFn = Debug_%s;\n' % (name, name))
1562 file.write(' }\n')
1563 file.write('}\n')
1564
1565 # Write function to clear all function pointers. 1694 # Write function to clear all function pointers.
1566 file.write('\n') 1695 file.write('\n')
1567 file.write("""void Driver%s::ClearBindings() { 1696 file.write("""void Driver%s::ClearBindings() {
1568 memset(this, 0, sizeof(*this)); 1697 memset(this, 0, sizeof(*this));
1569 } 1698 }
1570 """ % set_name.upper()) 1699 """ % set_name.upper())
1571 1700
1572 # Write GLApiBase functions 1701 # Write GLApiBase functions
1573 for func in functions: 1702 for func in functions:
1574 names = func['names'] 1703 function_name = func['known_as']
1575 return_type = func['return_type'] 1704 return_type = func['return_type']
1576 arguments = func['arguments'] 1705 arguments = func['arguments']
1577 file.write('\n') 1706 file.write('\n')
1578 file.write('%s %sApiBase::%sFn(%s) {\n' % 1707 file.write('%s %sApiBase::%sFn(%s) {\n' %
1579 (return_type, set_name.upper(), names[0], arguments)) 1708 (return_type, set_name.upper(), function_name, arguments))
1580 argument_names = re.sub( 1709 argument_names = re.sub(
1581 r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', arguments) 1710 r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', arguments)
1582 argument_names = re.sub( 1711 argument_names = re.sub(
1583 r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', argument_names) 1712 r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', argument_names)
1584 if argument_names == 'void' or argument_names == '': 1713 if argument_names == 'void' or argument_names == '':
1585 argument_names = '' 1714 argument_names = ''
1586 function_name = names[0]
1587 if return_type == 'void': 1715 if return_type == 'void':
1588 file.write(' driver_->fn.%sFn(%s);\n' % 1716 file.write(' driver_->fn.%sFn(%s);\n' %
1589 (function_name, argument_names)) 1717 (function_name, argument_names))
1590 else: 1718 else:
1591 file.write(' return driver_->fn.%sFn(%s);\n' % 1719 file.write(' return driver_->fn.%sFn(%s);\n' %
1592 (function_name, argument_names)) 1720 (function_name, argument_names))
1593 file.write('}\n') 1721 file.write('}\n')
1594 1722
1595 # Write TraceGLApi functions 1723 # Write TraceGLApi functions
1596 for func in functions: 1724 for func in functions:
1597 names = func['names'] 1725 function_name = func['known_as']
1598 return_type = func['return_type'] 1726 return_type = func['return_type']
1599 arguments = func['arguments'] 1727 arguments = func['arguments']
1600 file.write('\n') 1728 file.write('\n')
1601 file.write('%s Trace%sApi::%sFn(%s) {\n' % 1729 file.write('%s Trace%sApi::%sFn(%s) {\n' %
1602 (return_type, set_name.upper(), names[0], arguments)) 1730 (return_type, set_name.upper(), function_name, arguments))
1603 argument_names = re.sub( 1731 argument_names = re.sub(
1604 r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', arguments) 1732 r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', arguments)
1605 argument_names = re.sub( 1733 argument_names = re.sub(
1606 r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', argument_names) 1734 r'(const )?[a-zA-Z0-9_]+\** ([a-zA-Z0-9_]+)', r'\2', argument_names)
1607 if argument_names == 'void' or argument_names == '': 1735 if argument_names == 'void' or argument_names == '':
1608 argument_names = '' 1736 argument_names = ''
1609 function_name = names[0]
1610 file.write(' TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::%s")\n' % 1737 file.write(' TRACE_EVENT_BINARY_EFFICIENT0("gpu", "TraceGLAPI::%s")\n' %
1611 function_name) 1738 function_name)
1612 if return_type == 'void': 1739 if return_type == 'void':
1613 file.write(' %s_api_->%sFn(%s);\n' % 1740 file.write(' %s_api_->%sFn(%s);\n' %
1614 (set_name.lower(), function_name, argument_names)) 1741 (set_name.lower(), function_name, argument_names))
1615 else: 1742 else:
1616 file.write(' return %s_api_->%sFn(%s);\n' % 1743 file.write(' return %s_api_->%sFn(%s);\n' %
1617 (set_name.lower(), function_name, argument_names)) 1744 (set_name.lower(), function_name, argument_names))
1618 file.write('}\n') 1745 file.write('}\n')
1619 1746
(...skipping 14 matching lines...) Expand all
1634 #include <string.h> 1761 #include <string.h>
1635 1762
1636 #include "ui/gl/gl_interface.h" 1763 #include "ui/gl/gl_interface.h"
1637 1764
1638 namespace gfx { 1765 namespace gfx {
1639 """) 1766 """)
1640 # Write function that trampoline into the GLInterface. 1767 # Write function that trampoline into the GLInterface.
1641 for func in functions: 1768 for func in functions:
1642 file.write('\n') 1769 file.write('\n')
1643 file.write('%s GL_BINDING_CALL Mock_%s(%s) {\n' % 1770 file.write('%s GL_BINDING_CALL Mock_%s(%s) {\n' %
1644 (func['return_type'], func['names'][0], func['arguments'])) 1771 (func['return_type'], func['known_as'], func['arguments']))
1645 argument_names = re.sub(r'(const )?[a-zA-Z0-9]+((\s*const\s*)?\*)* ([a-zA-Z0 -9]+)', r'\4', 1772 arg_re = r'(const )?[a-zA-Z0-9]+((\s*const\s*)?\*)* ([a-zA-Z0-9]+)'
1646 func['arguments']) 1773 argument_names = re.sub(arg_re, r'\4', func['arguments'])
1647 if argument_names == 'void': 1774 if argument_names == 'void':
1648 argument_names = '' 1775 argument_names = ''
1649 function_name = func['names'][0][2:] 1776 function_name = func['known_as'][2:]
1650 if func['return_type'] == 'void': 1777 if func['return_type'] == 'void':
1651 file.write(' GLInterface::GetGLInterface()->%s(%s);\n' % 1778 file.write(' GLInterface::GetGLInterface()->%s(%s);\n' %
1652 (function_name, argument_names)) 1779 (function_name, argument_names))
1653 else: 1780 else:
1654 file.write(' return GLInterface::GetGLInterface()->%s(%s);\n' % 1781 file.write(' return GLInterface::GetGLInterface()->%s(%s);\n' %
1655 (function_name, argument_names)) 1782 (function_name, argument_names))
1656 file.write('}\n') 1783 file.write('}\n')
1657 1784
1658 # Write an 'invalid' function to catch code calling through uninitialized 1785 # Write an 'invalid' function to catch code calling through uninitialized
1659 # function pointers or trying to interpret the return value of 1786 # function pointers or trying to interpret the return value of
1660 # GLProcAddress(). 1787 # GLProcAddress().
1661 file.write('\n') 1788 file.write('\n')
1662 file.write('static void MockInvalidFunction() {\n') 1789 file.write('static void MockInvalidFunction() {\n')
1663 file.write(' NOTREACHED();\n') 1790 file.write(' NOTREACHED();\n')
1664 file.write('}\n') 1791 file.write('}\n')
1665 1792
1666 # Write a function to lookup a mock GL function based on its name. 1793 # Write a function to lookup a mock GL function based on its name.
1667 file.write('\n') 1794 file.write('\n')
1668 file.write('void* GL_BINDING_CALL GetMockGLProcAddress(const char* name) {\n') 1795 file.write('void* GL_BINDING_CALL GetMockGLProcAddress(const char* name) {\n')
1669 for func in functions: 1796 for func in functions:
1670 first_name = func['names'][0] 1797 unique_names = set([version['name'] for version in func['versions']])
1671 file.write(' if (strcmp(name, "%s") == 0)\n' % first_name) 1798 for name in unique_names:
1672 file.write(' return reinterpret_cast<void*>(Mock_%s);\n' % first_name) 1799 file.write(' if (strcmp(name, "%s") == 0)\n' % name)
1800 file.write(
1801 ' return reinterpret_cast<void*>(Mock_%s);\n' % func['known_as'])
1673 # Always return a non-NULL pointer like some EGL implementations do. 1802 # Always return a non-NULL pointer like some EGL implementations do.
1674 file.write(' return reinterpret_cast<void*>(&MockInvalidFunction);\n') 1803 file.write(' return reinterpret_cast<void*>(&MockInvalidFunction);\n')
1675 file.write('}\n'); 1804 file.write('}\n')
1676 1805
1677 file.write('\n') 1806 file.write('\n')
1678 file.write('} // namespace gfx\n') 1807 file.write('} // namespace gfx\n')
1679 1808
1680 1809
1681 def ParseExtensionFunctionsFromHeader(header_file): 1810 def ParseExtensionFunctionsFromHeader(header_file):
1682 """Parse a C extension header file and return a map from extension names to 1811 """Parse a C extension header file and return a map from extension names to
1683 a list of functions. 1812 a list of functions.
1684 1813
1685 Args: 1814 Args:
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1748 return function_to_extensions 1877 return function_to_extensions
1749 1878
1750 1879
1751 def LooksLikeExtensionFunction(function): 1880 def LooksLikeExtensionFunction(function):
1752 """Heuristic to see if a function name is consistent with extension function 1881 """Heuristic to see if a function name is consistent with extension function
1753 naming.""" 1882 naming."""
1754 vendor = re.match(r'\w+?([A-Z][A-Z]+)$', function) 1883 vendor = re.match(r'\w+?([A-Z][A-Z]+)$', function)
1755 return vendor is not None and not vendor.group(1) in ['GL', 'API', 'DC'] 1884 return vendor is not None and not vendor.group(1) in ['GL', 'API', 'DC']
1756 1885
1757 1886
1758 def GetUsedExtensionFunctions(functions, extension_headers, extra_extensions): 1887 def FillExtensionsFromHeaders(functions, extension_headers, extra_extensions):
1759 """Determine which functions belong to extensions. 1888 """Determine which functions belong to extensions based on extension headers,
1889 and fill in this information to the functions table for functions that don't
1890 already have the information.
1760 1891
1761 Args: 1892 Args:
1762 functions: List of (return type, function names, arguments). 1893 functions: List of (return type, function versions, arguments).
1763 extension_headers: List of header file names. 1894 extension_headers: List of header file names.
1895 extra_extensions: Extensions to add to the list.
1764 Returns: 1896 Returns:
1765 List of (extension name, [function name alternatives]) sorted with least 1897 Set of used extensions.
1766 preferred extensions first.
1767 """ 1898 """
1768 # Parse known extensions. 1899 # Parse known extensions.
1769 extensions = GetExtensionFunctions(extension_headers) 1900 extensions = GetExtensionFunctions(extension_headers)
1770 functions_to_extensions = GetFunctionToExtensionMap(extensions) 1901 functions_to_extensions = GetFunctionToExtensionMap(extensions)
1771 1902
1772 # Collect all used extension functions. 1903 # Fill in the extension information.
1773 used_extension_functions = collections.defaultdict(lambda: []) 1904 used_extensions = set()
1774 for func in functions: 1905 for func in functions:
1775 for name in func['names']: 1906 for version in func['versions']:
1776 # Make sure we know about all extension functions. 1907 name = version['name']
1777 if (LooksLikeExtensionFunction(name) and 1908 # Make sure we know about all extensions and extension functions.
1778 not name in functions_to_extensions): 1909 if 'extensions' in version:
1910 used_extensions.update(version['extensions'])
1911 elif name in functions_to_extensions:
1912 # If there are multiple versions with the same name, assume that they
1913 # already have all the correct conditions, we can't just blindly add
1914 # the same extension conditions to all of them
1915 if len([v for v in func['versions'] if v['name'] == name]) == 1:
1916 version['extensions'] = functions_to_extensions[name]
1917 used_extensions.update(version['extensions'])
1918 elif LooksLikeExtensionFunction(name):
1779 raise RuntimeError('%s looks like an extension function but does not ' 1919 raise RuntimeError('%s looks like an extension function but does not '
1780 'belong to any of the known extensions.' % name) 1920 'belong to any of the known extensions.' % name)
1781 if name in functions_to_extensions:
1782 extensions = functions_to_extensions[name][:]
1783 if 'other_extensions' in func:
1784 extensions.extend(func['other_extensions'])
1785 for extension in extensions:
1786 used_extension_functions[extension].append((func['names'][0], name))
1787 1921
1788 # Add extensions that do not have any functions. 1922 # Add extensions that do not have any functions.
1789 used_extension_functions.update(dict( 1923 used_extensions.update(extra_extensions)
1790 [(e, []) for e in extra_extensions if e not in used_extension_functions]))
1791 1924
1792 def ExtensionSortKey(name): 1925 return used_extensions
1793 # Prefer ratified extensions and EXTs.
1794 preferences = ['_ARB_', '_OES_', '_EXT_', '']
1795 for i, category in enumerate(preferences):
1796 if category in name:
1797 return -i
1798 used_extension_functions = sorted(used_extension_functions.items(),
1799 key = lambda item: ExtensionSortKey(item[0]))
1800 return used_extension_functions
1801 1926
1802 1927
1803 def ResolveHeader(header, header_paths): 1928 def ResolveHeader(header, header_paths):
1804 paths = header_paths.split(':') 1929 paths = header_paths.split(':')
1805 1930
1806 # Always use a path for Chromium-specific extensions. They are extracted 1931 # Always use a path for Chromium-specific extensions. They are extracted
1807 # to separate files. 1932 # to separate files.
1808 paths.append('.') 1933 paths.append('.')
1809 paths.append('../../gpu') 1934 paths.append('../../gpu')
1810 1935
(...skipping 19 matching lines...) Expand all
1830 parser.add_option('--header-paths') 1955 parser.add_option('--header-paths')
1831 1956
1832 options, args = parser.parse_args(argv) 1957 options, args = parser.parse_args(argv)
1833 1958
1834 if options.inputs: 1959 if options.inputs:
1835 for [_, _, _, headers, _] in FUNCTION_SETS: 1960 for [_, _, _, headers, _] in FUNCTION_SETS:
1836 for header in headers: 1961 for header in headers:
1837 print ResolveHeader(header, options.header_paths) 1962 print ResolveHeader(header, options.header_paths)
1838 return 0 1963 return 0
1839 1964
1965 directory = '.'
1840 if len(args) >= 1: 1966 if len(args) >= 1:
1841 dir = args[0] 1967 directory = args[0]
1842 else:
1843 dir = '.'
1844 1968
1845 for [functions, 1969 for [functions,
1846 nulldraw_functions, 1970 nulldraw_functions,
1847 set_name, 1971 set_name,
1848 extension_headers, 1972 extension_headers,
1849 extensions] in FUNCTION_SETS: 1973 extensions] in FUNCTION_SETS:
1974 # Function names can be specified in two ways (list of unique names or list
1975 # of versions with different binding conditions). Fill in the data to the
1976 # versions list in case it is missing, so that can be used from here on:
1977 for func in functions + nulldraw_functions:
1978 assert 'versions' in func or 'names' in func, 'Function with no names'
1979 if 'versions' not in func:
1980 func['versions'] = [{'name': n} for n in func['names']]
1981 # Use the first version's name unless otherwise specified
1982 if 'known_as' not in func:
1983 func['known_as'] = func['versions'][0]['name']
no sievers 2014/01/14 23:16:01 Should we null out func['names'] here somewhere to
oetuaho-nv 2014/01/15 15:50:25 That should typically make the build fail when run
1984
1850 extension_headers = [ResolveHeader(h, options.header_paths) 1985 extension_headers = [ResolveHeader(h, options.header_paths)
1851 for h in extension_headers] 1986 for h in extension_headers]
1852 used_extension_functions = GetUsedExtensionFunctions( 1987 used_extensions = FillExtensionsFromHeaders(
1853 functions, extension_headers, extensions) 1988 functions, extension_headers, extensions)
1854 1989
1855 header_file = open( 1990 header_file = open(
1856 os.path.join(dir, 'gl_bindings_autogen_%s.h' % set_name), 'wb') 1991 os.path.join(directory, 'gl_bindings_autogen_%s.h' % set_name), 'wb')
1857 GenerateHeader(header_file, functions, set_name, used_extension_functions) 1992 GenerateHeader(header_file, functions, set_name, used_extensions)
1858 header_file.close() 1993 header_file.close()
1859 1994
1860 header_file = open( 1995 header_file = open(
1861 os.path.join(dir, 'gl_bindings_api_autogen_%s.h' % set_name), 'wb') 1996 os.path.join(directory, 'gl_bindings_api_autogen_%s.h' % set_name),
1862 GenerateAPIHeader( 1997 'wb')
1863 header_file, functions, set_name, used_extension_functions) 1998 GenerateAPIHeader(header_file, functions, set_name)
1864 header_file.close() 1999 header_file.close()
1865 2000
1866 source_file = open( 2001 source_file = open(
1867 os.path.join(dir, 'gl_bindings_autogen_%s.cc' % set_name), 'wb') 2002 os.path.join(directory, 'gl_bindings_autogen_%s.cc' % set_name), 'wb')
1868 GenerateSource(source_file, 2003 GenerateSource(source_file,
1869 functions, 2004 functions,
1870 nulldraw_functions, 2005 nulldraw_functions,
1871 set_name, 2006 set_name,
1872 used_extension_functions) 2007 used_extensions)
1873 source_file.close() 2008 source_file.close()
1874 2009
1875 header_file = open( 2010 header_file = open(
1876 os.path.join(dir, 'gl_interface_autogen_%s.h' % set_name), 'wb') 2011 os.path.join(directory, 'gl_interface_autogen_%s.h' % set_name), 'wb')
1877 GenerateInterfaceHeader( 2012 GenerateInterfaceHeader(header_file, functions, set_name)
1878 header_file, functions, set_name, used_extension_functions)
1879 header_file.close() 2013 header_file.close()
1880 2014
1881 header_file = open( 2015 header_file = open(
1882 os.path.join(dir, 'gl_mock_autogen_%s.h' % set_name), 'wb') 2016 os.path.join(directory, 'gl_mock_autogen_%s.h' % set_name), 'wb')
1883 GenerateMockHeader( 2017 GenerateMockHeader(header_file, functions, set_name)
1884 header_file, functions, set_name, used_extension_functions)
1885 header_file.close() 2018 header_file.close()
1886 2019
1887 source_file = open(os.path.join(dir, 'gl_bindings_autogen_mock.cc'), 'wb') 2020 source_file = open(os.path.join(directory, 'gl_bindings_autogen_mock.cc'),
2021 'wb')
1888 GenerateMockSource(source_file, GL_FUNCTIONS) 2022 GenerateMockSource(source_file, GL_FUNCTIONS)
1889 source_file.close() 2023 source_file.close()
1890 return 0 2024 return 0
1891 2025
1892 2026
1893 if __name__ == '__main__': 2027 if __name__ == '__main__':
1894 sys.exit(main(sys.argv[1:])) 2028 sys.exit(main(sys.argv[1:]))
OLDNEW
« no previous file with comments | « ui/compositor/test/test_suite.cc ('k') | ui/gl/gl.gyp » ('j') | ui/gl/gl_implementation_win.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698