OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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:])) |
OLD | NEW |