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

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

Powered by Google App Engine
This is Rietveld 408576698