1#!/usr/bin/python3 2# 3# Copyright 2017 The ANGLE Project Authors. All rights reserved. 4# Use of this source code is governed by a BSD-style license that can be 5# found in the LICENSE file. 6# 7# generate_entry_points.py: 8# Generates the OpenGL bindings and entry point layers for ANGLE. 9# NOTE: don't run this script directly. Run scripts/run_code_generation.py. 10 11import sys, os, pprint, json 12import fnmatch 13import registry_xml 14from registry_xml import apis, script_relative, strip_api_prefix, api_enums 15 16# Paths 17CL_STUBS_HEADER_PATH = "../src/libGLESv2/cl_stubs_autogen.h" 18EGL_GET_LABELED_OBJECT_DATA_PATH = "../src/libGLESv2/egl_get_labeled_object_data.json" 19EGL_STUBS_HEADER_PATH = "../src/libGLESv2/egl_stubs_autogen.h" 20EGL_EXT_STUBS_HEADER_PATH = "../src/libGLESv2/egl_ext_stubs_autogen.h" 21 22# List of GLES1 extensions for which we don't need to add Context.h decls. 23GLES1_NO_CONTEXT_DECL_EXTENSIONS = [ 24 "GL_OES_framebuffer_object", 25] 26 27# This is a list of exceptions for entry points which don't want to have 28# the EVENT macro. This is required for some debug marker entry points. 29NO_EVENT_MARKER_EXCEPTIONS_LIST = sorted([ 30 "glPushGroupMarkerEXT", 31 "glPopGroupMarkerEXT", 32 "glInsertEventMarkerEXT", 33]) 34 35ALIASING_EXCEPTIONS = [ 36 # glRenderbufferStorageMultisampleEXT aliases 37 # glRenderbufferStorageMultisample on desktop GL, and is marked as such in 38 # the registry. However, that is not correct for GLES where this entry 39 # point comes from GL_EXT_multisampled_render_to_texture which is never 40 # promoted to core GLES. 41 'renderbufferStorageMultisampleEXT', 42 # Other entry points where the extension behavior is not identical to core 43 # behavior. 44 'drawArraysInstancedBaseInstanceANGLE', 45 'drawElementsInstancedBaseVertexBaseInstanceANGLE', 46 'logicOpANGLE', 47] 48 49# These are the entry points which potentially are used first by an application 50# and require that the back ends are initialized before the front end is called. 51INIT_DICT = { 52 "clGetPlatformIDs": "false", 53 "clGetPlatformInfo": "false", 54 "clGetDeviceIDs": "false", 55 "clCreateContext": "false", 56 "clCreateContextFromType": "false", 57 "clIcdGetPlatformIDsKHR": "true", 58} 59 60# These are the only entry points that are allowed while pixel local storage is active. 61PLS_ALLOW_LIST = { 62 "ActiveTexture", 63 "BindBuffer", 64 "BindBufferBase", 65 "BindBufferRange", 66 "BindSampler", 67 "BindTexture", 68 "BindVertexArray", 69 "BufferData", 70 "BufferSubData", 71 "CheckFramebufferStatus", 72 "ClipControlEXT", 73 "CullFace", 74 "DepthFunc", 75 "DepthMask", 76 "DepthRangef", 77 "Disable", 78 "DisableVertexAttribArray", 79 "DispatchComputeIndirect", 80 "Enable", 81 "EnableClientState", 82 "EnableVertexAttribArray", 83 "EndPixelLocalStorageANGLE", 84 "FramebufferPixelLocalStorageInterruptANGLE", 85 "FrontFace", 86 "MapBufferRange", 87 "PixelLocalStorageBarrierANGLE", 88 "Scissor", 89 "StencilFunc", 90 "StencilFuncSeparate", 91 "StencilMask", 92 "StencilMaskSeparate", 93 "StencilOp", 94 "StencilOpSeparate", 95 "UnmapBuffer", 96 "UseProgram", 97 "ValidateProgram", 98 "Viewport", 99 "ProvokingVertexANGLE", 100 "FenceSync", 101 "FlushMappedBufferRange", 102} 103PLS_ALLOW_WILDCARDS = [ 104 "BlendEquationSeparatei*", 105 "BlendEquationi*", 106 "BlendFuncSeparatei*", 107 "BlendFunci*", 108 "ClearBuffer*", 109 "ColorMaski*", 110 "DebugMessageCallback*", 111 "DebugMessageControl*", 112 "DebugMessageInsert*", 113 "Delete*", 114 "Disablei*", 115 "DrawArrays*", 116 "DrawElements*", 117 "DrawRangeElements*", 118 "Enablei*", 119 "Gen*", 120 "Get*", 121 "Is*", 122 "ObjectLabel*", 123 "ObjectPtrLabel*", 124 "PolygonMode*", 125 "PolygonOffset*", 126 "PopDebugGroup*", 127 "PushDebugGroup*", 128 "SamplerParameter*", 129 "TexParameter*", 130 "Uniform*", 131 "VertexAttrib*", 132] 133 134# These are the entry points which purely set state in the current context with 135# no interaction with the other contexts, including through shared resources. 136# As a result, they don't require the share group lock. 137CONTEXT_PRIVATE_LIST = [ 138 'glActiveTexture', 139 'glBlendColor', 140 'glClearColor', 141 'glClearDepthf', 142 'glClearStencil', 143 'glClipControl', 144 'glColorMask', 145 'glColorMaski', 146 'glCoverageModulation', 147 'glCullFace', 148 'glDepthFunc', 149 'glDepthMask', 150 'glDepthRangef', 151 'glDisable', 152 'glDisablei', 153 'glEnable', 154 'glEnablei', 155 'glFrontFace', 156 'glHint', 157 'glIsEnabled', 158 'glIsEnabledi', 159 'glLineWidth', 160 'glLogicOpANGLE', 161 'glMinSampleShading', 162 'glPatchParameteri', 163 'glPixelStorei', 164 'glPolygonMode', 165 'glPolygonModeNV', 166 'glPolygonOffset', 167 'glPolygonOffsetClamp', 168 'glPrimitiveBoundingBox', 169 'glProvokingVertex', 170 'glSampleCoverage', 171 'glSampleMaski', 172 'glScissor', 173 'glShadingRate', 174 'glStencilFunc', 175 'glStencilFuncSeparate', 176 'glStencilMask', 177 'glStencilMaskSeparate', 178 'glStencilOp', 179 'glStencilOpSeparate', 180 'glViewport', 181 # GLES1 entry points 182 'glAlphaFunc', 183 'glAlphaFuncx', 184 'glClearColorx', 185 'glClearDepthx', 186 'glColor4f', 187 'glColor4ub', 188 'glColor4x', 189 'glDepthRangex', 190 'glLineWidthx', 191 'glLoadIdentity', 192 'glLogicOp', 193 'glMatrixMode', 194 'glPointSize', 195 'glPointSizex', 196 'glPopMatrix', 197 'glPolygonOffsetx', 198 'glPushMatrix', 199 'glSampleCoveragex', 200 'glShadeModel', 201] 202CONTEXT_PRIVATE_WILDCARDS = [ 203 'glBlendFunc*', 204 'glBlendEquation*', 205 'glVertexAttrib[1-4]*', 206 'glVertexAttribI[1-4]*', 207 'glVertexAttribP[1-4]*', 208 'glVertexAttribL[1-4]*', 209 # GLES1 entry points 210 'glClipPlane[fx]', 211 'glGetClipPlane[fx]', 212 'glFog[fx]*', 213 'glFrustum[fx]', 214 'glGetLight[fx]v', 215 'glGetMaterial[fx]v', 216 'glGetTexEnv[fix]v', 217 'glLoadMatrix[fx]', 218 'glLight[fx]*', 219 'glLightModel[fx]*', 220 'glMaterial[fx]*', 221 'glMultMatrix[fx]', 222 'glMultiTexCoord4[fx]', 223 'glNormal3[fx]', 224 'glOrtho[fx]', 225 'glPointParameter[fx]*', 226 'glRotate[fx]', 227 'glScale[fx]', 228 'glTexEnv[fix]*', 229 'glTranslate[fx]', 230] 231 232TEMPLATE_ENTRY_POINT_HEADER = """\ 233// GENERATED FILE - DO NOT EDIT. 234// Generated by {script_name} using data from {data_source_name}. 235// 236// Copyright 2020 The ANGLE Project Authors. All rights reserved. 237// Use of this source code is governed by a BSD-style license that can be 238// found in the LICENSE file. 239// 240// entry_points_{annotation_lower}_autogen.h: 241// Defines the {comment} entry points. 242 243#ifndef {lib}_ENTRY_POINTS_{annotation_upper}_AUTOGEN_H_ 244#define {lib}_ENTRY_POINTS_{annotation_upper}_AUTOGEN_H_ 245 246{includes} 247 248{entry_points} 249 250#endif // {lib}_ENTRY_POINTS_{annotation_upper}_AUTOGEN_H_ 251""" 252 253TEMPLATE_ENTRY_POINT_SOURCE = """\ 254// GENERATED FILE - DO NOT EDIT. 255// Generated by {script_name} using data from {data_source_name}. 256// 257// Copyright 2020 The ANGLE Project Authors. All rights reserved. 258// Use of this source code is governed by a BSD-style license that can be 259// found in the LICENSE file. 260// 261// entry_points_{annotation_lower}_autogen.cpp: 262// Defines the {comment} entry points. 263 264{includes} 265 266{entry_points} 267""" 268 269TEMPLATE_ENTRY_POINTS_ENUM_HEADER = """\ 270// GENERATED FILE - DO NOT EDIT. 271// Generated by {script_name} using data from {data_source_name}. 272// 273// Copyright 2020 The ANGLE Project Authors. All rights reserved. 274// Use of this source code is governed by a BSD-style license that can be 275// found in the LICENSE file. 276// 277// entry_points_enum_autogen.h: 278// Defines the {lib} entry points enumeration. 279 280#ifndef COMMON_ENTRYPOINTSENUM_AUTOGEN_H_ 281#define COMMON_ENTRYPOINTSENUM_AUTOGEN_H_ 282 283namespace angle 284{{ 285enum class EntryPoint 286{{ 287{entry_points_list} 288}}; 289 290const char *GetEntryPointName(EntryPoint ep); 291}} // namespace angle 292#endif // COMMON_ENTRY_POINTS_ENUM_AUTOGEN_H_ 293""" 294 295TEMPLATE_ENTRY_POINTS_NAME_CASE = """\ 296 case EntryPoint::{enum}: 297 return "{cmd}";""" 298 299TEMPLATE_ENTRY_POINTS_ENUM_SOURCE = """\ 300// GENERATED FILE - DO NOT EDIT. 301// Generated by {script_name} using data from {data_source_name}. 302// 303// Copyright 2020 The ANGLE Project Authors. All rights reserved. 304// Use of this source code is governed by a BSD-style license that can be 305// found in the LICENSE file. 306// 307// entry_points_enum_autogen.cpp: 308// Helper methods for the {lib} entry points enumeration. 309 310#include "common/entry_points_enum_autogen.h" 311 312#include "common/debug.h" 313 314namespace angle 315{{ 316const char *GetEntryPointName(EntryPoint ep) 317{{ 318 switch (ep) 319 {{ 320{entry_points_name_cases} 321 default: 322 UNREACHABLE(); 323 return "error"; 324 }} 325}} 326}} // namespace angle 327""" 328 329TEMPLATE_LIB_ENTRY_POINT_SOURCE = """\ 330// GENERATED FILE - DO NOT EDIT. 331// Generated by {script_name} using data from {data_source_name}. 332// 333// Copyright 2020 The ANGLE Project Authors. All rights reserved. 334// Use of this source code is governed by a BSD-style license that can be 335// found in the LICENSE file. 336// 337// {lib_name}_autogen.cpp: Implements the exported {lib_description} functions. 338 339{includes} 340extern "C" {{ 341{entry_points} 342}} // extern "C" 343""" 344 345TEMPLATE_ENTRY_POINT_DECL = """{angle_export}{return_type} {export_def} {name}({params});""" 346 347TEMPLATE_GLES_ENTRY_POINT_NO_RETURN = """\ 348void GL_APIENTRY GL_{name}({params}) 349{{ 350 Context *context = {context_getter}; 351 {event_comment}EVENT(context, GL{name}, "context = %d{comma_if_needed}{format_params}", CID(context){comma_if_needed}{pass_params}); 352 353 if ({valid_context_check}) 354 {{{packed_gl_enum_conversions} 355 {context_lock} 356 bool isCallValid = (context->skipValidation() || {validation_expression}); 357 if (isCallValid) 358 {{ 359 context->{name_lower_no_suffix}({internal_params}); 360 }} 361 ANGLE_CAPTURE_GL({name}, isCallValid, {gl_capture_params}); 362 }} 363 else 364 {{ 365 {constext_lost_error_generator} 366 }} 367 {epilog} 368}} 369""" 370 371TEMPLATE_GLES_CONTEXT_PRIVATE_ENTRY_POINT_NO_RETURN = """\ 372void GL_APIENTRY GL_{name}({params}) 373{{ 374 Context *context = {context_getter}; 375 {event_comment}EVENT(context, GL{name}, "context = %d{comma_if_needed}{format_params}", CID(context){comma_if_needed}{pass_params}); 376 377 if ({valid_context_check}) 378 {{{packed_gl_enum_conversions} 379 bool isCallValid = (context->skipValidation() || {validation_expression}); 380 if (isCallValid) 381 {{ 382 ContextPrivate{name_no_suffix}({context_private_internal_params}); 383 }} 384 ANGLE_CAPTURE_GL({name}, isCallValid, {gl_capture_params}); 385 }} 386 else 387 {{ 388 {constext_lost_error_generator} 389 }} 390 ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any()); 391}} 392""" 393 394TEMPLATE_GLES_ENTRY_POINT_WITH_RETURN = """\ 395{return_type} GL_APIENTRY GL_{name}({params}) 396{{ 397 Context *context = {context_getter}; 398 {event_comment}EVENT(context, GL{name}, "context = %d{comma_if_needed}{format_params}", CID(context){comma_if_needed}{pass_params}); 399 400 {return_type} returnValue; 401 if ({valid_context_check}) 402 {{{packed_gl_enum_conversions} 403 {context_lock} 404 bool isCallValid = (context->skipValidation() || {validation_expression}); 405 if (isCallValid) 406 {{ 407 returnValue = context->{name_lower_no_suffix}({internal_params}); 408 }} 409 else 410 {{ 411 returnValue = GetDefaultReturnValue<angle::EntryPoint::GL{name}, {return_type}>(); 412 }} 413 ANGLE_CAPTURE_GL({name}, isCallValid, {gl_capture_params}, returnValue); 414 }} 415 else 416 {{ 417 {constext_lost_error_generator} 418 returnValue = GetDefaultReturnValue<angle::EntryPoint::GL{name}, {return_type}>(); 419 }} 420 {epilog} 421 return returnValue; 422}} 423""" 424 425TEMPLATE_GLES_CONTEXT_PRIVATE_ENTRY_POINT_WITH_RETURN = """\ 426{return_type} GL_APIENTRY GL_{name}({params}) 427{{ 428 Context *context = {context_getter}; 429 {event_comment}EVENT(context, GL{name}, "context = %d{comma_if_needed}{format_params}", CID(context){comma_if_needed}{pass_params}); 430 431 {return_type} returnValue; 432 if ({valid_context_check}) 433 {{{packed_gl_enum_conversions} 434 bool isCallValid = (context->skipValidation() || {validation_expression}); 435 if (isCallValid) 436 {{ 437 returnValue = ContextPrivate{name_no_suffix}({context_private_internal_params}); 438 }} 439 else 440 {{ 441 returnValue = GetDefaultReturnValue<angle::EntryPoint::GL{name}, {return_type}>(); 442 }} 443 ANGLE_CAPTURE_GL({name}, isCallValid, {gl_capture_params}, returnValue); 444 }} 445 else 446 {{ 447 {constext_lost_error_generator} 448 returnValue = GetDefaultReturnValue<angle::EntryPoint::GL{name}, {return_type}>(); 449 }} 450 ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any()); 451 return returnValue; 452}} 453""" 454 455TEMPLATE_EGL_ENTRY_POINT_NO_RETURN = """\ 456void EGLAPIENTRY EGL_{name}({params}) 457{{ 458 {preamble} 459 Thread *thread = egl::GetCurrentThread(); 460 {{ 461 ANGLE_SCOPED_GLOBAL_LOCK(); 462 EGL_EVENT({name}, "{format_params}"{comma_if_needed}{pass_params}); 463 464 {packed_gl_enum_conversions} 465 466 {{ 467 ANGLE_EGL_SCOPED_CONTEXT_LOCK({name}, thread{comma_if_needed_context_lock}{internal_context_lock_params}); 468 if (IsEGLValidationEnabled()) 469 {{ 470 ANGLE_EGL_VALIDATE_VOID(thread, {name}, {labeled_object}, {internal_params}); 471 }} 472 else 473 {{ 474 {attrib_map_init} 475 }} 476 477 {name}(thread{comma_if_needed}{internal_params}); 478 }} 479 480 ANGLE_CAPTURE_EGL({name}, true, {egl_capture_params}); 481 }} 482 {epilog} 483}} 484""" 485 486TEMPLATE_EGL_ENTRY_POINT_WITH_RETURN = """\ 487{return_type} EGLAPIENTRY EGL_{name}({params}) 488{{ 489 {preamble} 490 Thread *thread = egl::GetCurrentThread(); 491 {return_type} returnValue; 492 {{ 493 ANGLE_SCOPED_GLOBAL_LOCK(); 494 EGL_EVENT({name}, "{format_params}"{comma_if_needed}{pass_params}); 495 496 {packed_gl_enum_conversions} 497 498 {{ 499 ANGLE_EGL_SCOPED_CONTEXT_LOCK({name}, thread{comma_if_needed_context_lock}{internal_context_lock_params}); 500 if (IsEGLValidationEnabled()) 501 {{ 502 ANGLE_EGL_VALIDATE(thread, {name}, {labeled_object}, {return_type}{comma_if_needed}{internal_params}); 503 }} 504 else 505 {{ 506 {attrib_map_init} 507 }} 508 509 returnValue = {name}(thread{comma_if_needed}{internal_params}); 510 }} 511 512 ANGLE_CAPTURE_EGL({name}, true, {egl_capture_params}, returnValue); 513 }} 514 {epilog} 515 return returnValue; 516}} 517""" 518 519TEMPLATE_EGL_ENTRY_POINT_WITH_RETURN_NO_LOCKS = """\ 520{return_type} EGLAPIENTRY EGL_{name}({params}) 521{{ 522 {preamble} 523 Thread *thread = egl::GetCurrentThread(); 524 {return_type} returnValue; 525 526 EGL_EVENT({name}, "{format_params}"{comma_if_needed}{pass_params}); 527 528 {packed_gl_enum_conversions} 529 530 if (IsEGLValidationEnabled()) 531 {{ 532 ANGLE_EGL_VALIDATE(thread, {name}, {labeled_object}, {return_type}{comma_if_needed}{internal_params}); 533 }} 534 else 535 {{ 536 {attrib_map_init} 537 }} 538 539 returnValue = {name}(thread{comma_if_needed}{internal_params}); 540 541 ANGLE_CAPTURE_EGL({name}, true, {egl_capture_params}, returnValue); 542 543 {epilog} 544 return returnValue; 545}} 546""" 547 548TEMPLATE_CL_ENTRY_POINT_NO_RETURN = """\ 549void CL_API_CALL cl{name}({params}) 550{{ 551 CL_EVENT({name}, "{format_params}"{comma_if_needed}{pass_params}); 552 553 {packed_gl_enum_conversions} 554 555 ANGLE_CL_VALIDATE_VOID({name}{comma_if_needed}{internal_params}); 556 557 cl::gClErrorTls = CL_SUCCESS; 558 {name}({internal_params}); 559}} 560""" 561 562TEMPLATE_CL_ENTRY_POINT_WITH_RETURN_ERROR = """\ 563cl_int CL_API_CALL cl{name}({params}) 564{{{initialization} 565 CL_EVENT({name}, "{format_params}"{comma_if_needed}{pass_params}); 566 567 {packed_gl_enum_conversions} 568 569 ANGLE_CL_VALIDATE_ERROR({name}{comma_if_needed}{internal_params}); 570 571 cl::gClErrorTls = CL_SUCCESS; 572 return {name}({internal_params}); 573}} 574""" 575 576TEMPLATE_CL_ENTRY_POINT_WITH_ERRCODE_RET = """\ 577{return_type} CL_API_CALL cl{name}({params}) 578{{{initialization} 579 CL_EVENT({name}, "{format_params}"{comma_if_needed}{pass_params}); 580 581 {packed_gl_enum_conversions} 582 583 ANGLE_CL_VALIDATE_ERRCODE_RET({name}{comma_if_needed}{internal_params}); 584 585 cl::gClErrorTls = CL_SUCCESS; 586 {return_type} object = {name}({internal_params}); 587 588 ASSERT((cl::gClErrorTls == CL_SUCCESS) == (object != nullptr)); 589 if (errcode_ret != nullptr) 590 {{ 591 *errcode_ret = cl::gClErrorTls; 592 }} 593 return object; 594}} 595""" 596 597TEMPLATE_CL_ENTRY_POINT_WITH_RETURN_POINTER = """\ 598{return_type} CL_API_CALL cl{name}({params}) 599{{{initialization} 600 CL_EVENT({name}, "{format_params}"{comma_if_needed}{pass_params}); 601 602 {packed_gl_enum_conversions} 603 604 cl::gClErrorTls = CL_SUCCESS; 605 ANGLE_CL_VALIDATE_POINTER({name}{comma_if_needed}{internal_params}); 606 607 return {name}({internal_params}); 608}} 609""" 610 611TEMPLATE_CL_STUBS_HEADER = """\ 612// GENERATED FILE - DO NOT EDIT. 613// Generated by {script_name} using data from {data_source_name}. 614// 615// Copyright 2021 The ANGLE Project Authors. All rights reserved. 616// Use of this source code is governed by a BSD-style license that can be 617// found in the LICENSE file. 618// 619// {annotation_lower}_stubs_autogen.h: Stubs for {title} entry points. 620 621#ifndef LIBGLESV2_{annotation_upper}_STUBS_AUTOGEN_H_ 622#define LIBGLESV2_{annotation_upper}_STUBS_AUTOGEN_H_ 623 624#include "libANGLE/cl_types.h" 625 626namespace cl 627{{ 628{stubs} 629}} // namespace cl 630#endif // LIBGLESV2_{annotation_upper}_STUBS_AUTOGEN_H_ 631""" 632 633TEMPLATE_EGL_STUBS_HEADER = """\ 634// GENERATED FILE - DO NOT EDIT. 635// Generated by {script_name} using data from {data_source_name}. 636// 637// Copyright 2020 The ANGLE Project Authors. All rights reserved. 638// Use of this source code is governed by a BSD-style license that can be 639// found in the LICENSE file. 640// 641// {annotation_lower}_stubs_autogen.h: Stubs for {title} entry points. 642 643#ifndef LIBGLESV2_{annotation_upper}_STUBS_AUTOGEN_H_ 644#define LIBGLESV2_{annotation_upper}_STUBS_AUTOGEN_H_ 645 646#include <EGL/egl.h> 647#include <EGL/eglext.h> 648 649#include "common/PackedEnums.h" 650#include "common/PackedEGLEnums_autogen.h" 651 652namespace gl 653{{ 654class Context; 655}} // namespace gl 656 657namespace egl 658{{ 659class AttributeMap; 660class Device; 661class Display; 662class Image; 663class Stream; 664class Surface; 665class Sync; 666class Thread; 667struct Config; 668 669{stubs} 670}} // namespace egl 671#endif // LIBGLESV2_{annotation_upper}_STUBS_AUTOGEN_H_ 672""" 673 674CONTEXT_HEADER = """\ 675// GENERATED FILE - DO NOT EDIT. 676// Generated by {script_name} using data from {data_source_name}. 677// 678// Copyright 2020 The ANGLE Project Authors. All rights reserved. 679// Use of this source code is governed by a BSD-style license that can be 680// found in the LICENSE file. 681// 682// Context_{annotation_lower}_autogen.h: Creates a macro for interfaces in Context. 683 684#ifndef ANGLE_CONTEXT_{annotation_upper}_AUTOGEN_H_ 685#define ANGLE_CONTEXT_{annotation_upper}_AUTOGEN_H_ 686 687#define ANGLE_{annotation_upper}_CONTEXT_API \\ 688{interface} 689 690#endif // ANGLE_CONTEXT_API_{version}_AUTOGEN_H_ 691""" 692 693CONTEXT_DECL_FORMAT = """ {return_type} {name_lower_no_suffix}({internal_params}){maybe_const}; \\""" 694 695TEMPLATE_CL_ENTRY_POINT_EXPORT = """\ 696{return_type} CL_API_CALL cl{name}({params}) 697{{ 698 return cl::GetDispatch().cl{name}({internal_params}); 699}} 700""" 701 702TEMPLATE_GL_ENTRY_POINT_EXPORT = """\ 703{return_type} GL_APIENTRY gl{name}({params}) 704{{ 705 return GL_{name}({internal_params}); 706}} 707""" 708 709TEMPLATE_EGL_ENTRY_POINT_EXPORT = """\ 710{return_type} EGLAPIENTRY egl{name}({params}) 711{{ 712 EnsureEGLLoaded(); 713 return EGL_{name}({internal_params}); 714}} 715""" 716 717TEMPLATE_GLX_ENTRY_POINT_EXPORT = """\ 718{return_type} GLXENTRY {name}({params}) 719{{ 720 return GLX_{name}({internal_params}); 721}} 722""" 723 724TEMPLATE_GLEXT_FUNCTION_POINTER = """typedef {return_type}(GL_APIENTRYP PFN{name_upper}PROC)({params});""" 725TEMPLATE_GLEXT_FUNCTION_PROTOTYPE = """{apicall} {return_type}GL_APIENTRY {name}({params});""" 726 727TEMPLATE_GL_VALIDATION_HEADER = """\ 728// GENERATED FILE - DO NOT EDIT. 729// Generated by {script_name} using data from {data_source_name}. 730// 731// Copyright 2020 The ANGLE Project Authors. All rights reserved. 732// Use of this source code is governed by a BSD-style license that can be 733// found in the LICENSE file. 734// 735// validation{annotation}_autogen.h: 736// Validation functions for the OpenGL {comment} entry points. 737 738#ifndef LIBANGLE_VALIDATION_{annotation}_AUTOGEN_H_ 739#define LIBANGLE_VALIDATION_{annotation}_AUTOGEN_H_ 740 741#include "common/entry_points_enum_autogen.h" 742#include "common/PackedEnums.h" 743 744namespace gl 745{{ 746class Context; 747class PrivateState; 748class ErrorSet; 749 750{prototypes} 751}} // namespace gl 752 753#endif // LIBANGLE_VALIDATION_{annotation}_AUTOGEN_H_ 754""" 755 756TEMPLATE_CL_VALIDATION_HEADER = """\ 757// GENERATED FILE - DO NOT EDIT. 758// Generated by {script_name} using data from {data_source_name}. 759// 760// Copyright 2021 The ANGLE Project Authors. All rights reserved. 761// Use of this source code is governed by a BSD-style license that can be 762// found in the LICENSE file. 763// 764// validation{annotation}_autogen.h: 765// Validation functions for the {comment} entry points. 766 767#ifndef LIBANGLE_VALIDATION_{annotation}_AUTOGEN_H_ 768#define LIBANGLE_VALIDATION_{annotation}_AUTOGEN_H_ 769 770#include "libANGLE/validationCL.h" 771 772namespace cl 773{{ 774{prototypes} 775}} // namespace cl 776 777#endif // LIBANGLE_VALIDATION_{annotation}_AUTOGEN_H_ 778""" 779 780TEMPLATE_EGL_VALIDATION_HEADER = """\ 781// GENERATED FILE - DO NOT EDIT. 782// Generated by {script_name} using data from {data_source_name}. 783// 784// Copyright 2020 The ANGLE Project Authors. All rights reserved. 785// Use of this source code is governed by a BSD-style license that can be 786// found in the LICENSE file. 787// 788// validation{annotation}_autogen.h: 789// Validation functions for the {comment} entry points. 790 791#ifndef LIBANGLE_VALIDATION_{annotation}_AUTOGEN_H_ 792#define LIBANGLE_VALIDATION_{annotation}_AUTOGEN_H_ 793 794#include "libANGLE/validationEGL.h" 795 796namespace egl 797{{ 798{prototypes} 799}} // namespace egl 800 801#endif // LIBANGLE_VALIDATION_{annotation}_AUTOGEN_H_ 802""" 803 804TEMPLATE_CONTEXT_PRIVATE_CALL_HEADER = """\ 805// GENERATED FILE - DO NOT EDIT. 806// Generated by {script_name} using data from {data_source_name}. 807// 808// Copyright 2023 The ANGLE Project Authors. All rights reserved. 809// Use of this source code is governed by a BSD-style license that can be 810// found in the LICENSE file. 811// 812// context_private_call_{annotation}_autogen.h: 813// Helpers that set/get state that is entirely privately accessed by the context. 814 815#ifndef LIBANGLE_CONTEXT_PRIVATE_CALL_{annotation}_AUTOGEN_H_ 816#define LIBANGLE_CONTEXT_PRIVATE_CALL_{annotation}_AUTOGEN_H_ 817 818#include "libANGLE/Context.h" 819 820namespace gl 821{{ 822{prototypes} 823}} // namespace gl 824 825#endif // LIBANGLE_CONTEXT_PRIVATE_CALL_{annotation}_AUTOGEN_H_ 826""" 827 828TEMPLATE_EGL_CONTEXT_LOCK_HEADER = """\ 829// GENERATED FILE - DO NOT EDIT. 830// Generated by {script_name} using data from {data_source_name}. 831// 832// Copyright 2023 The ANGLE Project Authors. All rights reserved. 833// Use of this source code is governed by a BSD-style license that can be 834// found in the LICENSE file. 835// 836// {annotation_lower}_context_lock_autogen.h: 837// Context Lock functions for the {comment} entry points. 838 839#ifndef LIBGLESV2_{annotation_upper}_CONTEXT_LOCK_AUTOGEN_H_ 840#define LIBGLESV2_{annotation_upper}_CONTEXT_LOCK_AUTOGEN_H_ 841 842#include "libGLESv2/global_state.h" 843 844namespace egl 845{{ 846{prototypes} 847}} // namespace egl 848 849#endif // LIBGLESV2_{annotation_upper}_CONTEXT_LOCK_AUTOGEN_H_ 850""" 851 852TEMPLATE_CAPTURE_HEADER = """\ 853// GENERATED FILE - DO NOT EDIT. 854// Generated by {script_name} using data from {data_source_name}. 855// 856// Copyright 2020 The ANGLE Project Authors. All rights reserved. 857// Use of this source code is governed by a BSD-style license that can be 858// found in the LICENSE file. 859// 860// capture_{annotation_lower}_autogen.h: 861// Capture functions for the OpenGL ES {comment} entry points. 862 863#ifndef LIBANGLE_CAPTURE_{annotation_upper}_AUTOGEN_H_ 864#define LIBANGLE_CAPTURE_{annotation_upper}_AUTOGEN_H_ 865 866#include "common/PackedEnums.h" 867#include "libANGLE/capture/FrameCapture.h" 868 869namespace {namespace} 870{{ 871{prototypes} 872}} // namespace {namespace} 873 874#endif // LIBANGLE_CAPTURE_{annotation_upper}_AUTOGEN_H_ 875""" 876 877TEMPLATE_CAPTURE_SOURCE = """\ 878// GENERATED FILE - DO NOT EDIT. 879// Generated by {script_name} using data from {data_source_name}. 880// 881// Copyright 2020 The ANGLE Project Authors. All rights reserved. 882// Use of this source code is governed by a BSD-style license that can be 883// found in the LICENSE file. 884// 885// capture_{annotation_with_dash}_autogen.cpp: 886// Capture functions for the OpenGL ES {comment} entry points. 887 888#include "libANGLE/capture/capture_{annotation_with_dash}_autogen.h" 889 890#include "common/gl_enum_utils.h" 891#include "libANGLE/Context.h" 892#include "libANGLE/capture/FrameCapture.h" 893#include "libANGLE/validation{annotation_no_dash}.h" 894 895using namespace angle; 896 897namespace {namespace} 898{{ 899{capture_methods} 900}} // namespace {namespace} 901""" 902 903TEMPLATE_CAPTURE_METHOD_WITH_RETURN_VALUE = """\ 904CallCapture Capture{short_name}({params_with_type}, {return_value_type_original} returnValue) 905{{ 906 ParamBuffer paramBuffer; 907 908 {parameter_captures} 909 910 ParamCapture returnValueCapture("returnValue", ParamType::T{return_value_type_custom}); 911 InitParamValue(ParamType::T{return_value_type_custom}, returnValue, &returnValueCapture.value); 912 paramBuffer.addReturnValue(std::move(returnValueCapture)); 913 914 return CallCapture(angle::EntryPoint::{api_upper}{short_name}, std::move(paramBuffer)); 915}} 916""" 917 918TEMPLATE_CAPTURE_METHOD_NO_RETURN_VALUE = """\ 919CallCapture Capture{short_name}({params_with_type}) 920{{ 921 ParamBuffer paramBuffer; 922 923 {parameter_captures} 924 925 return CallCapture(angle::EntryPoint::{api_upper}{short_name}, std::move(paramBuffer)); 926}} 927""" 928 929TEMPLATE_PARAMETER_CAPTURE_VALUE = """paramBuffer.addValueParam("{name}", ParamType::T{type}, {name});""" 930 931TEMPLATE_PARAMETER_CAPTURE_GL_ENUM = """paramBuffer.addEnumParam("{name}", {api_enum}::{group}, ParamType::T{type}, {name});""" 932 933TEMPLATE_PARAMETER_CAPTURE_POINTER = """ 934 if (isCallValid) 935 {{ 936 ParamCapture {name}Param("{name}", ParamType::T{type}); 937 InitParamValue(ParamType::T{type}, {name}, &{name}Param.value); 938 {capture_name}({params}, &{name}Param); 939 paramBuffer.addParam(std::move({name}Param)); 940 }} 941 else 942 {{ 943 ParamCapture {name}Param("{name}", ParamType::T{type}); 944 InitParamValue(ParamType::T{type}, static_cast<{cast_type}>(nullptr), &{name}Param.value); 945 paramBuffer.addParam(std::move({name}Param)); 946 }} 947""" 948 949TEMPLATE_PARAMETER_CAPTURE_POINTER_FUNC = """void {name}({params});""" 950 951TEMPLATE_CAPTURE_REPLAY_SOURCE = """\ 952// GENERATED FILE - DO NOT EDIT. 953// Generated by {script_name} using data from {data_source_name}. 954// 955// Copyright 2020 The ANGLE Project Authors. All rights reserved. 956// Use of this source code is governed by a BSD-style license that can be 957// found in the LICENSE file. 958// 959// frame_capture_replay_autogen.cpp: 960// Replay captured GL calls. 961 962#include "angle_trace_gl.h" 963#include "common/debug.h" 964#include "common/frame_capture_utils.h" 965#include "frame_capture_test_utils.h" 966 967namespace angle 968{{ 969void ReplayTraceFunctionCall(const CallCapture &call, const TraceFunctionMap &customFunctions) 970{{ 971 const ParamBuffer ¶ms = call.params; 972 const std::vector<ParamCapture> &captures = params.getParamCaptures(); 973 974 switch (call.entryPoint) 975 {{ 976{call_replay_cases} 977 default: 978 ASSERT(!call.customFunctionName.empty()); 979 ReplayCustomFunctionCall(call, customFunctions); 980 break; 981 }} 982}} 983 984}} // namespace angle 985 986""" 987 988TEMPLATE_REPLAY_CALL_CASE = """\ 989 case angle::EntryPoint::{enum}: 990 {call}({params}); 991 break; 992""" 993 994POINTER_FORMAT = "0x%016\" PRIxPTR \"" 995UNSIGNED_LONG_LONG_FORMAT = "%llu" 996HEX_LONG_LONG_FORMAT = "0x%llX" 997 998FORMAT_DICT = { 999 "GLbitfield": "%s", 1000 "GLboolean": "%s", 1001 "GLbyte": "%d", 1002 "GLclampx": "0x%X", 1003 "GLDEBUGPROC": POINTER_FORMAT, 1004 "GLDEBUGPROCKHR": POINTER_FORMAT, 1005 "GLdouble": "%f", 1006 "GLeglClientBufferEXT": POINTER_FORMAT, 1007 "GLeglImageOES": POINTER_FORMAT, 1008 "GLenum": "%s", 1009 "GLfixed": "0x%X", 1010 "GLfloat": "%f", 1011 "GLint": "%d", 1012 "GLintptr": UNSIGNED_LONG_LONG_FORMAT, 1013 "GLshort": "%d", 1014 "GLsizei": "%d", 1015 "GLsizeiptr": UNSIGNED_LONG_LONG_FORMAT, 1016 "GLsync": POINTER_FORMAT, 1017 "GLubyte": "%d", 1018 "GLuint": "%u", 1019 "GLuint64": UNSIGNED_LONG_LONG_FORMAT, 1020 "GLushort": "%u", 1021 "int": "%d", 1022 # EGL-specific types 1023 "EGLBoolean": "%u", 1024 "EGLConfig": POINTER_FORMAT, 1025 "EGLContext": POINTER_FORMAT, 1026 "EGLDisplay": POINTER_FORMAT, 1027 "EGLSurface": POINTER_FORMAT, 1028 "EGLSync": POINTER_FORMAT, 1029 "EGLNativeDisplayType": POINTER_FORMAT, 1030 "EGLNativePixmapType": POINTER_FORMAT, 1031 "EGLNativeWindowType": POINTER_FORMAT, 1032 "EGLClientBuffer": POINTER_FORMAT, 1033 "EGLenum": "0x%X", 1034 "EGLint": "%d", 1035 "EGLImage": POINTER_FORMAT, 1036 "EGLTime": UNSIGNED_LONG_LONG_FORMAT, 1037 "EGLGetBlobFuncANDROID": POINTER_FORMAT, 1038 "EGLSetBlobFuncANDROID": POINTER_FORMAT, 1039 "EGLuint64KHR": UNSIGNED_LONG_LONG_FORMAT, 1040 "EGLSyncKHR": POINTER_FORMAT, 1041 "EGLnsecsANDROID": UNSIGNED_LONG_LONG_FORMAT, 1042 "EGLDeviceEXT": POINTER_FORMAT, 1043 "EGLDEBUGPROCKHR": POINTER_FORMAT, 1044 "EGLObjectKHR": POINTER_FORMAT, 1045 "EGLLabelKHR": POINTER_FORMAT, 1046 "EGLTimeKHR": UNSIGNED_LONG_LONG_FORMAT, 1047 "EGLImageKHR": POINTER_FORMAT, 1048 "EGLStreamKHR": POINTER_FORMAT, 1049 "EGLFrameTokenANGLE": HEX_LONG_LONG_FORMAT, 1050 # WGL-specific types 1051 "BOOL": "%u", 1052 "DWORD": POINTER_FORMAT, 1053 "FLOAT": "%f", 1054 "HDC": POINTER_FORMAT, 1055 "HENHMETAFILE": POINTER_FORMAT, 1056 "HGLRC": POINTER_FORMAT, 1057 "LPCSTR": POINTER_FORMAT, 1058 "LPGLYPHMETRICSFLOAT": POINTER_FORMAT, 1059 "UINT": "%u", 1060 # CL-specific types 1061 "size_t": "%zu", 1062 "cl_char": "%hhd", 1063 "cl_uchar": "%hhu", 1064 "cl_short": "%hd", 1065 "cl_ushort": "%hu", 1066 "cl_int": "%d", 1067 "cl_uint": "%u", 1068 "cl_long": "%lld", 1069 "cl_ulong": "%llu", 1070 "cl_half": "%hu", 1071 "cl_float": "%f", 1072 "cl_double": "%f", 1073 "cl_platform_id": POINTER_FORMAT, 1074 "cl_device_id": POINTER_FORMAT, 1075 "cl_context": POINTER_FORMAT, 1076 "cl_command_queue": POINTER_FORMAT, 1077 "cl_mem": POINTER_FORMAT, 1078 "cl_program": POINTER_FORMAT, 1079 "cl_kernel": POINTER_FORMAT, 1080 "cl_event": POINTER_FORMAT, 1081 "cl_sampler": POINTER_FORMAT, 1082 "cl_bool": "%u", 1083 "cl_bitfield": "%llu", 1084 "cl_properties": "%llu", 1085 "cl_device_type": "%llu", 1086 "cl_platform_info": "%u", 1087 "cl_device_info": "%u", 1088 "cl_device_fp_config": "%llu", 1089 "cl_device_mem_cache_type": "%u", 1090 "cl_device_local_mem_type": "%u", 1091 "cl_device_exec_capabilities": "%llu", 1092 "cl_device_svm_capabilities": "%llu", 1093 "cl_command_queue_properties": "%llu", 1094 "cl_device_partition_property": "%zu", 1095 "cl_device_affinity_domain": "%llu", 1096 "cl_context_properties": "%zu", 1097 "cl_context_info": "%u", 1098 "cl_queue_properties": "%llu", 1099 "cl_command_queue_info": "%u", 1100 "cl_channel_order": "%u", 1101 "cl_channel_type": "%u", 1102 "cl_mem_flags": "%llu", 1103 "cl_svm_mem_flags": "%llu", 1104 "cl_mem_object_type": "%u", 1105 "cl_mem_info": "%u", 1106 "cl_mem_migration_flags": "%llu", 1107 "cl_mem_properties": "%llu", 1108 "cl_image_info": "%u", 1109 "cl_buffer_create_type": "%u", 1110 "cl_addressing_mode": "%u", 1111 "cl_filter_mode": "%u", 1112 "cl_sampler_info": "%u", 1113 "cl_map_flags": "%llu", 1114 "cl_pipe_properties": "%zu", 1115 "cl_pipe_info": "%u", 1116 "cl_program_info": "%u", 1117 "cl_program_build_info": "%u", 1118 "cl_program_binary_type": "%u", 1119 "cl_build_status": "%d", 1120 "cl_kernel_info": "%u", 1121 "cl_kernel_arg_info": "%u", 1122 "cl_kernel_arg_address_qualifier": "%u", 1123 "cl_kernel_arg_access_qualifier": "%u", 1124 "cl_kernel_arg_type_qualifier": "%llu", 1125 "cl_kernel_work_group_info": "%u", 1126 "cl_kernel_sub_group_info": "%u", 1127 "cl_event_info": "%u", 1128 "cl_command_type": "%u", 1129 "cl_profiling_info": "%u", 1130 "cl_sampler_properties": "%llu", 1131 "cl_kernel_exec_info": "%u", 1132 "cl_device_atomic_capabilities": "%llu", 1133 "cl_khronos_vendor_id": "%u", 1134 "cl_version": "%u", 1135 "cl_device_device_enqueue_capabilities": "%llu", 1136} 1137 1138TEMPLATE_HEADER_INCLUDES = """\ 1139#include <GLES{major}/gl{major}{minor}.h> 1140#include <export.h>""" 1141 1142TEMPLATE_SOURCES_INCLUDES = """\ 1143#include "libGLESv2/entry_points_{header_version}_autogen.h" 1144 1145#include "common/entry_points_enum_autogen.h" 1146#include "common/gl_enum_utils.h" 1147#include "libANGLE/Context.h" 1148#include "libANGLE/Context.inl.h" 1149#include "libANGLE/context_private_call_gles_autogen.h" 1150#include "libANGLE/capture/capture_{header_version}_autogen.h" 1151#include "libANGLE/validation{validation_header_version}.h" 1152#include "libANGLE/entry_points_utils.h" 1153#include "libGLESv2/global_state.h" 1154 1155using namespace gl; 1156""" 1157 1158GLES_EXT_HEADER_INCLUDES = TEMPLATE_HEADER_INCLUDES.format( 1159 major="", minor="") + """ 1160#include <GLES/glext.h> 1161#include <GLES2/gl2.h> 1162#include <GLES2/gl2ext.h> 1163#include <GLES3/gl32.h> 1164""" 1165 1166GLES_EXT_SOURCE_INCLUDES = TEMPLATE_SOURCES_INCLUDES.format( 1167 header_version="gles_ext", validation_header_version="ESEXT") + """ 1168#include "libANGLE/capture/capture_gles_1_0_autogen.h" 1169#include "libANGLE/capture/capture_gles_2_0_autogen.h" 1170#include "libANGLE/capture/capture_gles_3_0_autogen.h" 1171#include "libANGLE/capture/capture_gles_3_1_autogen.h" 1172#include "libANGLE/capture/capture_gles_3_2_autogen.h" 1173#include "libANGLE/validationES1.h" 1174#include "libANGLE/validationES2.h" 1175#include "libANGLE/validationES3.h" 1176#include "libANGLE/validationES31.h" 1177#include "libANGLE/validationES32.h" 1178 1179using namespace gl; 1180""" 1181 1182DESKTOP_GL_HEADER_INCLUDES = """\ 1183#include <export.h> 1184#include "angle_gl.h" 1185""" 1186 1187TEMPLATE_DESKTOP_GL_SOURCE_INCLUDES = """\ 1188#include "libGLESv2/entry_points_{0}_autogen.h" 1189 1190#include "common/gl_enum_utils.h" 1191#include "libANGLE/Context.h" 1192#include "libANGLE/Context.inl.h" 1193#include "libANGLE/context_private_call_gles_autogen.h" 1194#include "libANGLE/context_private_call_gl_autogen.h" 1195#include "libANGLE/capture/capture_gl_{1}_autogen.h" 1196#include "libANGLE/validationEGL.h" 1197#include "libANGLE/validationES.h" 1198#include "libANGLE/validationES1.h" 1199#include "libANGLE/validationES2.h" 1200#include "libANGLE/validationES3.h" 1201#include "libANGLE/validationES31.h" 1202#include "libANGLE/validationES32.h" 1203#include "libANGLE/validationESEXT.h" 1204#include "libANGLE/validationGL{1}_autogen.h" 1205#include "libANGLE/entry_points_utils.h" 1206#include "libGLESv2/global_state.h" 1207 1208using namespace gl; 1209""" 1210 1211EGL_HEADER_INCLUDES = """\ 1212#include <EGL/egl.h> 1213#include <export.h> 1214""" 1215 1216EGL_SOURCE_INCLUDES = """\ 1217#include "libGLESv2/entry_points_egl_autogen.h" 1218#include "libGLESv2/entry_points_egl_ext_autogen.h" 1219 1220#include "libANGLE/capture/capture_egl_autogen.h" 1221#include "libANGLE/entry_points_utils.h" 1222#include "libANGLE/validationEGL_autogen.h" 1223#include "libGLESv2/egl_context_lock_impl.h" 1224#include "libGLESv2/egl_stubs_autogen.h" 1225#include "libGLESv2/egl_ext_stubs_autogen.h" 1226#include "libGLESv2/global_state.h" 1227 1228using namespace egl; 1229""" 1230 1231EGL_EXT_HEADER_INCLUDES = """\ 1232#include <EGL/egl.h> 1233#include <EGL/eglext.h> 1234#include <export.h> 1235""" 1236 1237EGL_EXT_SOURCE_INCLUDES = """\ 1238#include "libGLESv2/entry_points_egl_ext_autogen.h" 1239 1240#include "libANGLE/capture/capture_egl_autogen.h" 1241#include "libANGLE/entry_points_utils.h" 1242#include "libANGLE/validationEGL_autogen.h" 1243#include "libGLESv2/egl_context_lock_impl.h" 1244#include "libGLESv2/egl_ext_stubs_autogen.h" 1245#include "libGLESv2/global_state.h" 1246 1247using namespace egl; 1248""" 1249 1250LIBCL_EXPORT_INCLUDES = """ 1251#include "libOpenCL/dispatch.h" 1252""" 1253 1254LIBGLESV2_EXPORT_INCLUDES = """ 1255#include "angle_gl.h" 1256 1257#include "libGLESv2/entry_points_gles_1_0_autogen.h" 1258#include "libGLESv2/entry_points_gles_2_0_autogen.h" 1259#include "libGLESv2/entry_points_gles_3_0_autogen.h" 1260#include "libGLESv2/entry_points_gles_3_1_autogen.h" 1261#include "libGLESv2/entry_points_gles_3_2_autogen.h" 1262#include "libGLESv2/entry_points_gles_ext_autogen.h" 1263 1264#if defined(ANGLE_ENABLE_GL_DESKTOP_FRONTEND) 1265# include "libGLESv2/entry_points_gl_1_autogen.h" 1266# include "libGLESv2/entry_points_gl_2_autogen.h" 1267# include "libGLESv2/entry_points_gl_3_autogen.h" 1268# include "libGLESv2/entry_points_gl_4_autogen.h" 1269#endif 1270 1271#include "common/event_tracer.h" 1272""" 1273 1274LIBEGL_EXPORT_INCLUDES_AND_PREAMBLE = """ 1275#include "anglebase/no_destructor.h" 1276#include "common/system_utils.h" 1277 1278#include <memory> 1279 1280#if defined(ANGLE_USE_EGL_LOADER) 1281# include "libEGL/egl_loader_autogen.h" 1282#else 1283# include "libGLESv2/entry_points_egl_autogen.h" 1284# include "libGLESv2/entry_points_egl_ext_autogen.h" 1285#endif // defined(ANGLE_USE_EGL_LOADER) 1286 1287namespace 1288{ 1289#if defined(ANGLE_USE_EGL_LOADER) 1290bool gLoaded = false; 1291void *gEntryPointsLib = nullptr; 1292 1293GenericProc KHRONOS_APIENTRY GlobalLoad(const char *symbol) 1294{ 1295 return reinterpret_cast<GenericProc>(angle::GetLibrarySymbol(gEntryPointsLib, symbol)); 1296} 1297 1298void EnsureEGLLoaded() 1299{ 1300 if (gLoaded) 1301 { 1302 return; 1303 } 1304 1305 std::string errorOut; 1306 gEntryPointsLib = OpenSystemLibraryAndGetError(ANGLE_DISPATCH_LIBRARY, angle::SearchType::ModuleDir, &errorOut); 1307 if (gEntryPointsLib) 1308 { 1309 LoadLibEGL_EGL(GlobalLoad); 1310 gLoaded = true; 1311 } 1312 else 1313 { 1314 fprintf(stderr, "Error loading EGL entry points: %s\\n", errorOut.c_str()); 1315 } 1316} 1317#else 1318void EnsureEGLLoaded() {} 1319#endif // defined(ANGLE_USE_EGL_LOADER) 1320} // anonymous namespace 1321""" 1322 1323LIBCL_HEADER_INCLUDES = """\ 1324#include "angle_cl.h" 1325""" 1326 1327LIBCL_SOURCE_INCLUDES = """\ 1328#include "libGLESv2/entry_points_cl_autogen.h" 1329 1330#include "libANGLE/validationCL_autogen.h" 1331#include "libGLESv2/cl_stubs_autogen.h" 1332#include "libGLESv2/entry_points_cl_utils.h" 1333""" 1334 1335TEMPLATE_EVENT_COMMENT = """\ 1336 // Don't run the EVENT() macro on the EXT_debug_marker entry points. 1337 // It can interfere with the debug events being set by the caller. 1338 // """ 1339 1340TEMPLATE_CAPTURE_PROTO = "angle::CallCapture Capture%s(%s);" 1341 1342TEMPLATE_VALIDATION_PROTO = "%s Validate%s(%s);" 1343 1344TEMPLATE_CONTEXT_PRIVATE_CALL_PROTO = "%s ContextPrivate%s(%s);" 1345 1346TEMPLATE_CONTEXT_LOCK_PROTO = "ScopedContextMutexLock GetContextLock_%s(%s);" 1347 1348TEMPLATE_WINDOWS_DEF_FILE = """\ 1349; GENERATED FILE - DO NOT EDIT. 1350; Generated by {script_name} using data from {data_source_name}. 1351; 1352; Copyright 2020 The ANGLE Project Authors. All rights reserved. 1353; Use of this source code is governed by a BSD-style license that can be 1354; found in the LICENSE file. 1355LIBRARY {lib} 1356EXPORTS 1357{exports} 1358""" 1359 1360TEMPLATE_FRAME_CAPTURE_UTILS_HEADER = """\ 1361// GENERATED FILE - DO NOT EDIT. 1362// Generated by {script_name} using data from {data_source_name}. 1363// 1364// Copyright 2020 The ANGLE Project Authors. All rights reserved. 1365// Use of this source code is governed by a BSD-style license that can be 1366// found in the LICENSE file. 1367// 1368// frame_capture_utils_autogen.h: 1369// ANGLE Frame capture types and helper functions. 1370 1371#ifndef COMMON_FRAME_CAPTURE_UTILS_AUTOGEN_H_ 1372#define COMMON_FRAME_CAPTURE_UTILS_AUTOGEN_H_ 1373 1374#include "common/PackedEnums.h" 1375 1376namespace angle 1377{{ 1378enum class ParamType 1379{{ 1380 {param_types} 1381}}; 1382 1383constexpr uint32_t kParamTypeCount = {param_type_count}; 1384 1385union ParamValue 1386{{ 1387 {param_union_values} 1388}}; 1389 1390template <ParamType PType, typename T> 1391T GetParamVal(const ParamValue &value); 1392 1393{get_param_val_specializations} 1394 1395template <ParamType PType, typename T> 1396T GetParamVal(const ParamValue &value) 1397{{ 1398 UNREACHABLE(); 1399 return T(); 1400}} 1401 1402template <typename T> 1403T AccessParamValue(ParamType paramType, const ParamValue &value) 1404{{ 1405 switch (paramType) 1406 {{ 1407{access_param_value_cases} 1408 }} 1409 UNREACHABLE(); 1410 return T(); 1411}} 1412 1413template <ParamType PType, typename T> 1414void SetParamVal(T valueIn, ParamValue *valueOut); 1415 1416{set_param_val_specializations} 1417 1418template <ParamType PType, typename T> 1419void SetParamVal(T valueIn, ParamValue *valueOut) 1420{{ 1421 UNREACHABLE(); 1422}} 1423 1424template <typename T> 1425void InitParamValue(ParamType paramType, T valueIn, ParamValue *valueOut) 1426{{ 1427 switch (paramType) 1428 {{ 1429{init_param_value_cases} 1430 }} 1431}} 1432 1433struct CallCapture; 1434struct ParamCapture; 1435 1436void WriteParamCaptureReplay(std::ostream &os, const CallCapture &call, const ParamCapture ¶m); 1437const char *ParamTypeToString(ParamType paramType); 1438 1439enum class ResourceIDType 1440{{ 1441 {resource_id_types} 1442}}; 1443 1444ResourceIDType GetResourceIDTypeFromParamType(ParamType paramType); 1445const char *GetResourceIDTypeName(ResourceIDType resourceIDType); 1446 1447template <typename ResourceType> 1448struct GetResourceIDTypeFromType; 1449 1450{type_to_resource_id_type_structs} 1451}} // namespace angle 1452 1453#endif // COMMON_FRAME_CAPTURE_UTILS_AUTOGEN_H_ 1454""" 1455 1456TEMPLATE_FRAME_CAPTURE_UTILS_SOURCE = """\ 1457// GENERATED FILE - DO NOT EDIT. 1458// Generated by {script_name} using data from {data_source_name}. 1459// 1460// Copyright 2020 The ANGLE Project Authors. All rights reserved. 1461// Use of this source code is governed by a BSD-style license that can be 1462// found in the LICENSE file. 1463// 1464// frame_capture_utils_autogen.cpp: 1465// ANGLE Frame capture types and helper functions. 1466 1467#include "common/frame_capture_utils_autogen.h" 1468 1469#include "common/frame_capture_utils.h" 1470 1471namespace angle 1472{{ 1473void WriteParamCaptureReplay(std::ostream &os, const CallCapture &call, const ParamCapture ¶m) 1474{{ 1475 switch (param.type) 1476 {{ 1477{write_param_type_to_stream_cases} 1478 default: 1479 os << "unknown"; 1480 break; 1481 }} 1482}} 1483 1484const char *ParamTypeToString(ParamType paramType) 1485{{ 1486 switch (paramType) 1487 {{ 1488{param_type_to_string_cases} 1489 default: 1490 UNREACHABLE(); 1491 return "unknown"; 1492 }} 1493}} 1494 1495ResourceIDType GetResourceIDTypeFromParamType(ParamType paramType) 1496{{ 1497 switch (paramType) 1498 {{ 1499{param_type_resource_id_cases} 1500 default: 1501 return ResourceIDType::InvalidEnum; 1502 }} 1503}} 1504 1505const char *GetResourceIDTypeName(ResourceIDType resourceIDType) 1506{{ 1507 switch (resourceIDType) 1508 {{ 1509{resource_id_type_name_cases} 1510 default: 1511 UNREACHABLE(); 1512 return "GetResourceIDTypeName error"; 1513 }} 1514}} 1515}} // namespace angle 1516""" 1517 1518TEMPLATE_GET_PARAM_VAL_SPECIALIZATION = """\ 1519template <> 1520inline {type} GetParamVal<ParamType::T{enum}, {type}>(const ParamValue &value) 1521{{ 1522 return value.{union_name}; 1523}}""" 1524 1525TEMPLATE_ACCESS_PARAM_VALUE_CASE = """\ 1526 case ParamType::T{enum}: 1527 return GetParamVal<ParamType::T{enum}, T>(value);""" 1528 1529TEMPLATE_SET_PARAM_VAL_SPECIALIZATION = """\ 1530template <> 1531inline void SetParamVal<ParamType::T{enum}>({type} valueIn, ParamValue *valueOut) 1532{{ 1533 valueOut->{union_name} = valueIn; 1534}}""" 1535 1536TEMPLATE_INIT_PARAM_VALUE_CASE = """\ 1537 case ParamType::T{enum}: 1538 SetParamVal<ParamType::T{enum}>(valueIn, valueOut); 1539 break;""" 1540 1541TEMPLATE_WRITE_PARAM_TYPE_TO_STREAM_CASE = """\ 1542 case ParamType::T{enum_in}: 1543 WriteParamValueReplay<ParamType::T{enum_out}>(os, call, param.value.{union_name}); 1544 break;""" 1545 1546TEMPLATE_PARAM_TYPE_TO_STRING_CASE = """\ 1547 case ParamType::T{enum}: 1548 return "{type}";""" 1549 1550TEMPLATE_PARAM_TYPE_TO_RESOURCE_ID_TYPE_CASE = """\ 1551 case ParamType::T{enum}: 1552 return ResourceIDType::{resource_id_type};""" 1553 1554TEMPLATE_RESOURCE_ID_TYPE_NAME_CASE = """\ 1555 case ResourceIDType::{resource_id_type}: 1556 return "{resource_id_type}";""" 1557 1558CL_PACKED_TYPES = { 1559 # Enums 1560 "cl_platform_info": "PlatformInfo", 1561 "cl_device_info": "DeviceInfo", 1562 "cl_context_info": "ContextInfo", 1563 "cl_command_queue_info": "CommandQueueInfo", 1564 "cl_mem_object_type": "MemObjectType", 1565 "cl_mem_info": "MemInfo", 1566 "cl_image_info": "ImageInfo", 1567 "cl_pipe_info": "PipeInfo", 1568 "cl_addressing_mode": "AddressingMode", 1569 "cl_filter_mode": "FilterMode", 1570 "cl_sampler_info": "SamplerInfo", 1571 "cl_program_info": "ProgramInfo", 1572 "cl_program_build_info": "ProgramBuildInfo", 1573 "cl_kernel_info": "KernelInfo", 1574 "cl_kernel_arg_info": "KernelArgInfo", 1575 "cl_kernel_work_group_info": "KernelWorkGroupInfo", 1576 "cl_kernel_sub_group_info": "KernelSubGroupInfo", 1577 "cl_kernel_exec_info": "KernelExecInfo", 1578 "cl_event_info": "EventInfo", 1579 "cl_profiling_info": "ProfilingInfo", 1580 # Bit fields 1581 "cl_device_type": "DeviceType", 1582 "cl_device_fp_config": "DeviceFpConfig", 1583 "cl_device_exec_capabilities": "DeviceExecCapabilities", 1584 "cl_device_svm_capabilities": "DeviceSvmCapabilities", 1585 "cl_command_queue_properties": "CommandQueueProperties", 1586 "cl_device_affinity_domain": "DeviceAffinityDomain", 1587 "cl_mem_flags": "MemFlags", 1588 "cl_svm_mem_flags": "SVM_MemFlags", 1589 "cl_mem_migration_flags": "MemMigrationFlags", 1590 "cl_map_flags": "MapFlags", 1591 "cl_kernel_arg_type_qualifier": "KernelArgTypeQualifier", 1592 "cl_device_atomic_capabilities": "DeviceAtomicCapabilities", 1593 "cl_device_device_enqueue_capabilities": "DeviceEnqueueCapabilities", 1594} 1595 1596EGL_PACKED_TYPES = { 1597 "EGLContext": "gl::ContextID", 1598 "EGLConfig": "egl::Config *", 1599 "EGLDeviceEXT": "egl::Device *", 1600 "EGLDisplay": "egl::Display *", 1601 "EGLImage": "ImageID", 1602 "EGLImageKHR": "ImageID", 1603 "EGLStreamKHR": "egl::Stream *", 1604 "EGLSurface": "SurfaceID", 1605 "EGLSync": "egl::SyncID", 1606 "EGLSyncKHR": "egl::SyncID", 1607} 1608 1609CAPTURE_BLOCKLIST = ['eglGetProcAddress'] 1610 1611 1612def is_aliasing_excepted(api, cmd_name): 1613 # For simplicity, strip the prefix gl and lower the case of the first 1614 # letter. This makes sure that all variants of the cmd_name that reach 1615 # here end up looking similar for the sake of looking up in ALIASING_EXCEPTIONS 1616 cmd_name = cmd_name[2:] if cmd_name.startswith('gl') else cmd_name 1617 cmd_name = cmd_name[0].lower() + cmd_name[1:] 1618 return api == apis.GLES and cmd_name in ALIASING_EXCEPTIONS 1619 1620 1621def is_allowed_with_active_pixel_local_storage(name): 1622 return name in PLS_ALLOW_LIST or any( 1623 [fnmatch.fnmatchcase(name, entry) for entry in PLS_ALLOW_WILDCARDS]) 1624 1625 1626def is_context_private_state_command(api, name): 1627 name = strip_suffix(api, name) 1628 return name in CONTEXT_PRIVATE_LIST or any( 1629 [fnmatch.fnmatchcase(name, entry) for entry in CONTEXT_PRIVATE_WILDCARDS]) 1630 1631 1632def is_lockless_egl_entry_point(cmd_name): 1633 if cmd_name in [ 1634 "eglGetError", "eglGetCurrentContext", "eglGetCurrentSurface", "eglGetCurrentDisplay" 1635 ]: 1636 return True 1637 return False 1638 1639 1640def get_validation_expression(api, cmd_name, entry_point_name, internal_params, is_gles1): 1641 name = strip_api_prefix(cmd_name) 1642 private_params = ["context->getPrivateState()", "context->getMutableErrorSetForValidation()"] 1643 extra_params = private_params if is_context_private_state_command(api, 1644 cmd_name) else ["context"] 1645 expr = "Validate{name}({params})".format( 1646 name=name, params=", ".join(extra_params + [entry_point_name] + internal_params)) 1647 if not is_gles1 and not is_allowed_with_active_pixel_local_storage(name): 1648 expr = "(ValidatePixelLocalStorageInactive({extra_params}, {entry_point_name}) && {expr})".format( 1649 extra_params=", ".join(private_params), entry_point_name=entry_point_name, expr=expr) 1650 return expr 1651 1652 1653def entry_point_export(api): 1654 if api == apis.CL: 1655 return "" 1656 return "ANGLE_EXPORT " 1657 1658 1659def entry_point_prefix(api): 1660 if api == apis.CL: 1661 return "cl" 1662 if api == apis.GLES: 1663 return "GL_" 1664 return api + "_" 1665 1666 1667def get_api_entry_def(api): 1668 if api == apis.EGL: 1669 return "EGLAPIENTRY" 1670 elif api == apis.CL: 1671 return "CL_API_CALL" 1672 else: 1673 return "GL_APIENTRY" 1674 1675 1676def get_stubs_header_template(api): 1677 if api == apis.CL: 1678 return TEMPLATE_CL_STUBS_HEADER 1679 elif api == apis.EGL: 1680 return TEMPLATE_EGL_STUBS_HEADER 1681 else: 1682 return "" 1683 1684 1685def format_entry_point_decl(api, cmd_name, proto, params): 1686 comma_if_needed = ", " if len(params) > 0 else "" 1687 stripped = strip_api_prefix(cmd_name) 1688 return TEMPLATE_ENTRY_POINT_DECL.format( 1689 angle_export=entry_point_export(api), 1690 export_def=get_api_entry_def(api), 1691 name="%s%s" % (entry_point_prefix(api), stripped), 1692 return_type=proto[:-len(cmd_name)].strip(), 1693 params=", ".join(params), 1694 comma_if_needed=comma_if_needed) 1695 1696 1697# Returns index range of identifier in function parameter 1698def find_name_range(param): 1699 1700 def is_allowed_in_identifier(char): 1701 return char.isalpha() or char.isdigit() or char == "_" 1702 1703 # If type is a function declaration, only search in first parentheses 1704 left_paren = param.find("(") 1705 if left_paren >= 0: 1706 min = left_paren + 1 1707 end = param.index(")") 1708 else: 1709 min = 0 1710 end = len(param) 1711 1712 # Find last identifier in search range 1713 while end > min and not is_allowed_in_identifier(param[end - 1]): 1714 end -= 1 1715 if end == min: 1716 raise ValueError 1717 start = end - 1 1718 while start > min and is_allowed_in_identifier(param[start - 1]): 1719 start -= 1 1720 return start, end 1721 1722 1723def just_the_type(param): 1724 start, end = find_name_range(param) 1725 return param[:start].strip() + param[end:].strip() 1726 1727 1728def just_the_name(param): 1729 start, end = find_name_range(param) 1730 return param[start:end] 1731 1732 1733def make_param(param_type, param_name): 1734 1735 def insert_name(param_type, param_name, pos): 1736 return param_type[:pos] + " " + param_name + param_type[pos:] 1737 1738 # If type is a function declaration, insert identifier before first closing parentheses 1739 left_paren = param_type.find("(") 1740 if left_paren >= 0: 1741 right_paren = param_type.index(")") 1742 return insert_name(param_type, param_name, right_paren) 1743 1744 # If type is an array declaration, insert identifier before brackets 1745 brackets = param_type.find("[") 1746 if brackets >= 0: 1747 return insert_name(param_type, param_name, brackets) 1748 1749 # Otherwise just append identifier 1750 return param_type + " " + param_name 1751 1752 1753def just_the_type_packed(param, entry): 1754 name = just_the_name(param) 1755 if name in entry: 1756 return entry[name] 1757 else: 1758 return just_the_type(param) 1759 1760 1761def just_the_name_packed(param, reserved_set): 1762 name = just_the_name(param) 1763 if name in reserved_set: 1764 return name + 'Packed' 1765 else: 1766 return name 1767 1768 1769def is_unsigned_long_format(fmt): 1770 return fmt == UNSIGNED_LONG_LONG_FORMAT or fmt == HEX_LONG_LONG_FORMAT 1771 1772 1773def param_print_argument(api, command_node, param): 1774 name_only = just_the_name(param) 1775 type_only = just_the_type(param) 1776 1777 if "*" not in param and type_only not in FORMAT_DICT: 1778 print(" ".join(param)) 1779 raise Exception("Missing '%s %s' from '%s' entry point" % 1780 (type_only, name_only, registry_xml.get_cmd_name(command_node))) 1781 1782 if "*" in param or FORMAT_DICT[type_only] == POINTER_FORMAT: 1783 return "(uintptr_t)%s" % name_only 1784 1785 if is_unsigned_long_format(FORMAT_DICT[type_only]): 1786 return "static_cast<unsigned long long>(%s)" % name_only 1787 1788 if type_only == "GLboolean": 1789 return "GLbooleanToString(%s)" % name_only 1790 1791 if type_only == "GLbitfield": 1792 group_name = find_gl_enum_group_in_command(command_node, name_only) 1793 return "GLbitfieldToString(%s::%s, %s).c_str()" % (api_enums[api], group_name, name_only) 1794 1795 if type_only == "GLenum": 1796 group_name = find_gl_enum_group_in_command(command_node, name_only) 1797 return "GLenumToString(%s::%s, %s)" % (api_enums[api], group_name, name_only) 1798 1799 return name_only 1800 1801 1802def param_format_string(param): 1803 if "*" in param: 1804 return just_the_name(param) + " = 0x%016\" PRIxPTR \"" 1805 else: 1806 type_only = just_the_type(param) 1807 if type_only not in FORMAT_DICT: 1808 raise Exception(type_only + " is not a known type in 'FORMAT_DICT'") 1809 1810 return just_the_name(param) + " = " + FORMAT_DICT[type_only] 1811 1812 1813def is_context_lost_acceptable_cmd(cmd_name): 1814 lost_context_acceptable_cmds = [ 1815 "glGetError", 1816 "glGetSync", 1817 "glGetQueryObjecti", 1818 "glGetProgramiv", 1819 "glGetGraphicsResetStatus", 1820 "glGetShaderiv", 1821 ] 1822 1823 for context_lost_entry_pont in lost_context_acceptable_cmds: 1824 if cmd_name.startswith(context_lost_entry_pont): 1825 return True 1826 return False 1827 1828 1829def get_context_getter_function(cmd_name): 1830 if is_context_lost_acceptable_cmd(cmd_name): 1831 return "GetGlobalContext()" 1832 1833 return "GetValidGlobalContext()" 1834 1835 1836def get_valid_context_check(cmd_name): 1837 return "context" 1838 1839 1840def get_constext_lost_error_generator(cmd_name): 1841 # Don't generate context lost errors on commands that accept lost contexts 1842 if is_context_lost_acceptable_cmd(cmd_name): 1843 return "" 1844 1845 return "GenerateContextLostErrorOnCurrentGlobalContext();" 1846 1847 1848def strip_suffix_always(api, name): 1849 for suffix in registry_xml.strip_suffixes: 1850 if name.endswith(suffix): 1851 name = name[0:-len(suffix)] 1852 return name 1853 1854 1855def strip_suffix(api, name): 1856 # For commands where aliasing is excepted, keep the suffix 1857 if is_aliasing_excepted(api, name): 1858 return name 1859 1860 return strip_suffix_always(api, name) 1861 1862 1863def find_gl_enum_group_in_command(command_node, param_name): 1864 group_name = None 1865 for param_node in command_node.findall('./param'): 1866 if param_node.find('./name').text == param_name: 1867 group_name = param_node.attrib.get('group', None) 1868 break 1869 1870 if group_name is None or group_name in registry_xml.unsupported_enum_group_names: 1871 group_name = registry_xml.default_enum_group_name 1872 1873 return group_name 1874 1875 1876def get_packed_enums(api, cmd_packed_gl_enums, cmd_name, packed_param_types, params): 1877 # Always strip the suffix when querying packed enums. 1878 result = cmd_packed_gl_enums.get(strip_suffix_always(api, cmd_name), {}) 1879 for param in params: 1880 param_type = just_the_type(param) 1881 if param_type in packed_param_types: 1882 result[just_the_name(param)] = packed_param_types[param_type] 1883 return result 1884 1885 1886def get_def_template(api, cmd_name, return_type, has_errcode_ret): 1887 if return_type == "void": 1888 if api == apis.EGL: 1889 return TEMPLATE_EGL_ENTRY_POINT_NO_RETURN 1890 elif api == apis.CL: 1891 return TEMPLATE_CL_ENTRY_POINT_NO_RETURN 1892 elif is_context_private_state_command(api, cmd_name): 1893 return TEMPLATE_GLES_CONTEXT_PRIVATE_ENTRY_POINT_NO_RETURN 1894 else: 1895 return TEMPLATE_GLES_ENTRY_POINT_NO_RETURN 1896 elif return_type == "cl_int": 1897 return TEMPLATE_CL_ENTRY_POINT_WITH_RETURN_ERROR 1898 else: 1899 if api == apis.EGL: 1900 if is_lockless_egl_entry_point(cmd_name): 1901 return TEMPLATE_EGL_ENTRY_POINT_WITH_RETURN_NO_LOCKS 1902 else: 1903 return TEMPLATE_EGL_ENTRY_POINT_WITH_RETURN 1904 elif api == apis.CL: 1905 if has_errcode_ret: 1906 return TEMPLATE_CL_ENTRY_POINT_WITH_ERRCODE_RET 1907 else: 1908 return TEMPLATE_CL_ENTRY_POINT_WITH_RETURN_POINTER 1909 elif is_context_private_state_command(api, cmd_name): 1910 return TEMPLATE_GLES_CONTEXT_PRIVATE_ENTRY_POINT_WITH_RETURN 1911 else: 1912 return TEMPLATE_GLES_ENTRY_POINT_WITH_RETURN 1913 1914 1915def format_entry_point_def(api, command_node, cmd_name, proto, params, cmd_packed_enums, 1916 packed_param_types, ep_to_object, is_gles1): 1917 packed_enums = get_packed_enums(api, cmd_packed_enums, cmd_name, packed_param_types, params) 1918 internal_params = [just_the_name_packed(param, packed_enums) for param in params] 1919 if internal_params and internal_params[-1] == "errcode_ret": 1920 internal_params.pop() 1921 has_errcode_ret = True 1922 else: 1923 has_errcode_ret = False 1924 1925 internal_context_lock_params = [ 1926 just_the_name_packed(param, packed_enums) for param in params if just_the_type_packed( 1927 param, packed_enums) in ["Thread *", "egl::Display *", "gl::ContextID"] or 1928 just_the_name_packed(param, packed_enums) in ["attribute"] 1929 ] 1930 1931 packed_gl_enum_conversions = [] 1932 1933 # egl::AttributeMap objects do not convert the raw input parameters to a map until they are 1934 # validated because it is possible to have unterminated attribute lists if one of the 1935 # attributes is invalid. 1936 # When validation is disabled, force the conversion from attribute list to map using 1937 # initializeWithoutValidation. 1938 attrib_map_init = [] 1939 1940 for param in params: 1941 name = just_the_name(param) 1942 1943 if name in packed_enums: 1944 internal_name = name + "Packed" 1945 internal_type = packed_enums[name] 1946 packed_gl_enum_conversions += [ 1947 "\n " + internal_type + " " + internal_name + " = PackParam<" + 1948 internal_type + ">(" + name + ");" 1949 ] 1950 1951 if 'AttributeMap' in internal_type: 1952 attrib_map_init.append(internal_name + ".initializeWithoutValidation();") 1953 1954 pass_params = [param_print_argument(api, command_node, param) for param in params] 1955 format_params = [param_format_string(param) for param in params] 1956 return_type = proto[:-len(cmd_name)].strip() 1957 initialization = "InitBackEnds(%s);\n" % INIT_DICT[cmd_name] if cmd_name in INIT_DICT else "" 1958 event_comment = TEMPLATE_EVENT_COMMENT if cmd_name in NO_EVENT_MARKER_EXCEPTIONS_LIST else "" 1959 name_no_suffix = strip_suffix(api, cmd_name[2:]) 1960 name_lower_no_suffix = name_no_suffix[0:1].lower() + name_no_suffix[1:] 1961 entry_point_name = "angle::EntryPoint::GL" + strip_api_prefix(cmd_name) 1962 1963 format_params = { 1964 "name": 1965 strip_api_prefix(cmd_name), 1966 "name_no_suffix": 1967 name_no_suffix, 1968 "name_lower_no_suffix": 1969 name_lower_no_suffix, 1970 "return_type": 1971 return_type, 1972 "params": 1973 ", ".join(params), 1974 "internal_params": 1975 ", ".join(internal_params), 1976 "attrib_map_init": 1977 "\n".join(attrib_map_init), 1978 "context_private_internal_params": 1979 ", ".join( 1980 ["context->getMutablePrivateState()", "context->getMutablePrivateStateCache()"] + 1981 internal_params), 1982 "internal_context_lock_params": 1983 ", ".join(internal_context_lock_params), 1984 "initialization": 1985 initialization, 1986 "packed_gl_enum_conversions": 1987 "".join(packed_gl_enum_conversions), 1988 "pass_params": 1989 ", ".join(pass_params), 1990 "comma_if_needed": 1991 ", " if len(params) > 0 else "", 1992 "comma_if_needed_context_lock": 1993 ", " if len(internal_context_lock_params) > 0 else "", 1994 "gl_capture_params": 1995 ", ".join(["context"] + internal_params), 1996 "egl_capture_params": 1997 ", ".join(["thread"] + internal_params), 1998 "validation_expression": 1999 get_validation_expression(api, cmd_name, entry_point_name, internal_params, is_gles1), 2000 "format_params": 2001 ", ".join(format_params), 2002 "context_getter": 2003 get_context_getter_function(cmd_name), 2004 "valid_context_check": 2005 get_valid_context_check(cmd_name), 2006 "constext_lost_error_generator": 2007 get_constext_lost_error_generator(cmd_name), 2008 "event_comment": 2009 event_comment, 2010 "labeled_object": 2011 get_egl_entry_point_labeled_object(ep_to_object, cmd_name, params, packed_enums), 2012 "context_lock": 2013 get_context_lock(api, cmd_name), 2014 "preamble": 2015 get_preamble(api, cmd_name, params), 2016 "epilog": 2017 get_epilog(api, cmd_name), 2018 } 2019 2020 template = get_def_template(api, cmd_name, return_type, has_errcode_ret) 2021 return template.format(**format_params) 2022 2023 2024def get_capture_param_type_name(param_type): 2025 pointer_count = param_type.count("*") 2026 is_const = "const" in param_type.split() 2027 2028 param_type = param_type.replace("*", "") 2029 param_type = param_type.replace("&", "") 2030 param_type = param_type.replace("const", "") 2031 param_type = param_type.replace("struct", "") 2032 param_type = param_type.replace("egl::", 2033 "egl_" if pointer_count or param_type == 'egl::SyncID' else "") 2034 param_type = param_type.replace("gl::", "") 2035 param_type = param_type.strip() 2036 2037 if is_const and param_type != 'AttributeMap': 2038 param_type += "Const" 2039 for x in range(pointer_count): 2040 param_type += "Pointer" 2041 2042 return param_type 2043 2044 2045def format_capture_method(api, command, cmd_name, proto, params, all_param_types, 2046 capture_pointer_funcs, cmd_packed_gl_enums, packed_param_types): 2047 2048 context_param_typed = 'egl::Thread *thread' if api == apis.EGL else 'const State &glState' 2049 context_param_name = 'thread' if api == apis.EGL else 'glState' 2050 2051 packed_gl_enums = get_packed_enums(api, cmd_packed_gl_enums, cmd_name, packed_param_types, 2052 params) 2053 2054 params_with_type = get_internal_params(api, cmd_name, 2055 [context_param_typed, "bool isCallValid"] + params, 2056 cmd_packed_gl_enums, packed_param_types) 2057 params_just_name = ", ".join( 2058 [context_param_name, "isCallValid"] + 2059 [just_the_name_packed(param, packed_gl_enums) for param in params]) 2060 2061 parameter_captures = [] 2062 for param in params: 2063 2064 param_name = just_the_name_packed(param, packed_gl_enums) 2065 param_type = just_the_type_packed(param, packed_gl_enums).strip() 2066 2067 if 'AttributeMap' in param_type: 2068 capture = 'paramBuffer.addParam(CaptureAttributeMap(%s));' % param_name 2069 parameter_captures += [capture] 2070 continue 2071 2072 pointer_count = param_type.count("*") 2073 capture_param_type = get_capture_param_type_name(param_type) 2074 2075 # With EGL capture, we don't currently support capturing specific pointer params. 2076 if pointer_count > 0 and api != apis.EGL: 2077 params = params_just_name 2078 capture_name = "Capture%s_%s" % (strip_api_prefix(cmd_name), param_name) 2079 capture = TEMPLATE_PARAMETER_CAPTURE_POINTER.format( 2080 name=param_name, 2081 type=capture_param_type, 2082 capture_name=capture_name, 2083 params=params, 2084 cast_type=param_type) 2085 2086 capture_pointer_func = TEMPLATE_PARAMETER_CAPTURE_POINTER_FUNC.format( 2087 name=capture_name, params=params_with_type + ", angle::ParamCapture *paramCapture") 2088 capture_pointer_funcs += [capture_pointer_func] 2089 elif capture_param_type in ('GLenum', 'GLbitfield'): 2090 gl_enum_group = find_gl_enum_group_in_command(command, param_name) 2091 capture = TEMPLATE_PARAMETER_CAPTURE_GL_ENUM.format( 2092 name=param_name, 2093 type=capture_param_type, 2094 api_enum=api_enums[api], 2095 group=gl_enum_group) 2096 else: 2097 capture = TEMPLATE_PARAMETER_CAPTURE_VALUE.format( 2098 name=param_name, type=capture_param_type) 2099 2100 # For specific methods we can't easily parse their types. Work around this by omitting 2101 # parameter captures, but keeping the capture method as a mostly empty stub. 2102 if cmd_name not in CAPTURE_BLOCKLIST: 2103 all_param_types.add(capture_param_type) 2104 parameter_captures += [capture] 2105 2106 return_type = proto[:-len(cmd_name)].strip() 2107 capture_return_type = get_capture_param_type_name(return_type) 2108 if capture_return_type != 'void': 2109 if cmd_name in CAPTURE_BLOCKLIST: 2110 params_with_type += ", %s returnValue" % capture_return_type 2111 else: 2112 all_param_types.add(capture_return_type) 2113 2114 format_args = { 2115 "api_upper": "EGL" if api == apis.EGL else "GL", 2116 "full_name": cmd_name, 2117 "short_name": strip_api_prefix(cmd_name), 2118 "params_with_type": params_with_type, 2119 "params_just_name": params_just_name, 2120 "parameter_captures": "\n ".join(parameter_captures), 2121 "return_value_type_original": return_type, 2122 "return_value_type_custom": capture_return_type, 2123 } 2124 2125 if return_type == "void" or cmd_name in CAPTURE_BLOCKLIST: 2126 return TEMPLATE_CAPTURE_METHOD_NO_RETURN_VALUE.format(**format_args) 2127 else: 2128 return TEMPLATE_CAPTURE_METHOD_WITH_RETURN_VALUE.format(**format_args) 2129 2130 2131def const_pointer_type(param, packed_gl_enums): 2132 type = just_the_type_packed(param, packed_gl_enums) 2133 if just_the_name(param) == "errcode_ret" or type == "ErrorSet *" or "(" in type: 2134 return type 2135 elif "**" in type and "const" not in type: 2136 return type.replace("**", "* const *") 2137 elif "*" in type and "const" not in type: 2138 return type.replace("*", "*const ") if "[]" in type else "const " + type 2139 else: 2140 return type 2141 2142 2143def get_internal_params(api, cmd_name, params, cmd_packed_gl_enums, packed_param_types): 2144 packed_gl_enums = get_packed_enums(api, cmd_packed_gl_enums, cmd_name, packed_param_types, 2145 params) 2146 return ", ".join([ 2147 make_param( 2148 just_the_type_packed(param, packed_gl_enums), 2149 just_the_name_packed(param, packed_gl_enums)) for param in params 2150 ]) 2151 2152 2153def get_validation_params(api, cmd_name, params, cmd_packed_gl_enums, packed_param_types): 2154 packed_gl_enums = get_packed_enums(api, cmd_packed_gl_enums, cmd_name, packed_param_types, 2155 params) 2156 last = -1 if params and just_the_name(params[-1]) == "errcode_ret" else None 2157 return ", ".join([ 2158 make_param( 2159 const_pointer_type(param, packed_gl_enums), 2160 just_the_name_packed(param, packed_gl_enums)) for param in params[:last] 2161 ]) 2162 2163 2164def get_context_private_call_params(api, cmd_name, params, cmd_packed_gl_enums, 2165 packed_param_types): 2166 packed_gl_enums = get_packed_enums(api, cmd_packed_gl_enums, cmd_name, packed_param_types, 2167 params) 2168 return ", ".join([ 2169 make_param( 2170 just_the_type_packed(param, packed_gl_enums), 2171 just_the_name_packed(param, packed_gl_enums)) for param in params 2172 ]) 2173 2174 2175def get_context_lock_params(api, cmd_name, params, cmd_packed_gl_enums, packed_param_types): 2176 packed_gl_enums = get_packed_enums(api, cmd_packed_gl_enums, cmd_name, packed_param_types, 2177 params) 2178 return ", ".join([ 2179 make_param( 2180 just_the_type_packed(param, packed_gl_enums), 2181 just_the_name_packed(param, packed_gl_enums)) 2182 for param in params 2183 if just_the_type_packed( 2184 param, packed_gl_enums) in ["Thread *", "egl::Display *", "gl::ContextID"] or 2185 just_the_name_packed(param, packed_gl_enums) in ["attribute"] 2186 ]) 2187 2188 2189def format_context_decl(api, cmd_name, proto, params, template, cmd_packed_gl_enums, 2190 packed_param_types): 2191 internal_params = get_internal_params(api, cmd_name, params, cmd_packed_gl_enums, 2192 packed_param_types) 2193 2194 return_type = proto[:-len(cmd_name)].strip() 2195 name_lower_no_suffix = cmd_name[2:3].lower() + cmd_name[3:] 2196 name_lower_no_suffix = strip_suffix(api, name_lower_no_suffix) 2197 maybe_const = " const" if name_lower_no_suffix.startswith( 2198 "is") and name_lower_no_suffix[2].isupper() else "" 2199 2200 return template.format( 2201 return_type=return_type, 2202 name_lower_no_suffix=name_lower_no_suffix, 2203 internal_params=internal_params, 2204 maybe_const=maybe_const) 2205 2206 2207def format_entry_point_export(cmd_name, proto, params, template): 2208 internal_params = [just_the_name(param) for param in params] 2209 return_type = proto[:-len(cmd_name)].strip() 2210 2211 return template.format( 2212 name=strip_api_prefix(cmd_name), 2213 return_type=return_type, 2214 params=", ".join(params), 2215 internal_params=", ".join(internal_params)) 2216 2217 2218def format_validation_proto(api, cmd_name, params, cmd_packed_gl_enums, packed_param_types): 2219 if api == apis.CL: 2220 return_type = "cl_int" 2221 else: 2222 return_type = "bool" 2223 if api in [apis.GL, apis.GLES]: 2224 with_extra_params = ["const PrivateState &state", 2225 "ErrorSet *errors"] if is_context_private_state_command( 2226 api, cmd_name) else ["Context *context"] 2227 with_extra_params += ["angle::EntryPoint entryPoint"] + params 2228 elif api == apis.EGL: 2229 with_extra_params = ["ValidationContext *val"] + params 2230 else: 2231 with_extra_params = params 2232 internal_params = get_validation_params(api, cmd_name, with_extra_params, cmd_packed_gl_enums, 2233 packed_param_types) 2234 return TEMPLATE_VALIDATION_PROTO % (return_type, strip_api_prefix(cmd_name), internal_params) 2235 2236 2237def format_context_private_call_proto(api, cmd_name, proto, params, cmd_packed_gl_enums, 2238 packed_param_types): 2239 with_extra_params = ["PrivateState *privateState", "PrivateStateCache *privateStateCache" 2240 ] + params 2241 packed_enums = get_packed_enums(api, cmd_packed_gl_enums, cmd_name, packed_param_types, 2242 with_extra_params) 2243 internal_params = get_context_private_call_params(api, cmd_name, with_extra_params, 2244 cmd_packed_gl_enums, packed_param_types) 2245 stripped_name = strip_suffix(api, strip_api_prefix(cmd_name)) 2246 return_type = proto[:-len(cmd_name)].strip() 2247 return TEMPLATE_CONTEXT_PRIVATE_CALL_PROTO % (return_type, stripped_name, 2248 internal_params), stripped_name 2249 2250 2251def format_context_lock_proto(api, cmd_name, params, cmd_packed_gl_enums, packed_param_types): 2252 with_extra_params = ["Thread *thread"] + params 2253 internal_params = get_context_lock_params(api, cmd_name, with_extra_params, 2254 cmd_packed_gl_enums, packed_param_types) 2255 return TEMPLATE_CONTEXT_LOCK_PROTO % (strip_api_prefix(cmd_name), internal_params) 2256 2257 2258def format_capture_proto(api, cmd_name, proto, params, cmd_packed_gl_enums, packed_param_types): 2259 context_param_typed = 'egl::Thread *thread' if api == apis.EGL else 'const State &glState' 2260 internal_params = get_internal_params(api, cmd_name, 2261 [context_param_typed, "bool isCallValid"] + params, 2262 cmd_packed_gl_enums, packed_param_types) 2263 return_type = proto[:-len(cmd_name)].strip() 2264 if return_type != "void": 2265 internal_params += ", %s returnValue" % return_type 2266 return TEMPLATE_CAPTURE_PROTO % (strip_api_prefix(cmd_name), internal_params) 2267 2268 2269def path_to(folder, file): 2270 return os.path.join(script_relative(".."), "src", folder, file) 2271 2272 2273class ANGLEEntryPoints(registry_xml.EntryPoints): 2274 2275 def __init__(self, 2276 api, 2277 xml, 2278 commands, 2279 all_param_types, 2280 cmd_packed_enums, 2281 export_template=TEMPLATE_GL_ENTRY_POINT_EXPORT, 2282 packed_param_types=[], 2283 ep_to_object={}, 2284 is_gles1=False): 2285 super().__init__(api, xml, commands) 2286 2287 self.decls = [] 2288 self.defs = [] 2289 self.export_defs = [] 2290 self.validation_protos = [] 2291 self.context_private_call_protos = [] 2292 self.context_private_call_functions = [] 2293 self.context_lock_protos = [] 2294 self.capture_protos = [] 2295 self.capture_methods = [] 2296 self.capture_pointer_funcs = [] 2297 2298 for (cmd_name, command_node, param_text, proto_text) in self.get_infos(): 2299 self.decls.append(format_entry_point_decl(self.api, cmd_name, proto_text, param_text)) 2300 self.defs.append( 2301 format_entry_point_def(self.api, command_node, cmd_name, proto_text, param_text, 2302 cmd_packed_enums, packed_param_types, ep_to_object, 2303 is_gles1)) 2304 2305 self.export_defs.append( 2306 format_entry_point_export(cmd_name, proto_text, param_text, export_template)) 2307 2308 self.validation_protos.append( 2309 format_validation_proto(self.api, cmd_name, param_text, cmd_packed_enums, 2310 packed_param_types)) 2311 2312 if is_context_private_state_command(self.api, cmd_name): 2313 proto, function = format_context_private_call_proto(self.api, cmd_name, proto_text, 2314 param_text, cmd_packed_enums, 2315 packed_param_types) 2316 self.context_private_call_protos.append(proto) 2317 self.context_private_call_functions.append(function) 2318 2319 if api == apis.EGL: 2320 self.context_lock_protos.append( 2321 format_context_lock_proto(api, cmd_name, param_text, cmd_packed_enums, 2322 packed_param_types)) 2323 2324 self.capture_protos.append( 2325 format_capture_proto(self.api, cmd_name, proto_text, param_text, cmd_packed_enums, 2326 packed_param_types)) 2327 self.capture_methods.append( 2328 format_capture_method(self.api, command_node, cmd_name, proto_text, param_text, 2329 all_param_types, self.capture_pointer_funcs, 2330 cmd_packed_enums, packed_param_types)) 2331 2332 # Ensure we store GLint64 in the param types for use with the replay interpreter. 2333 all_param_types.add('GLint64') 2334 2335 2336class GLEntryPoints(ANGLEEntryPoints): 2337 2338 all_param_types = set() 2339 2340 def __init__(self, api, xml, commands, is_gles1=False): 2341 super().__init__( 2342 api, 2343 xml, 2344 commands, 2345 GLEntryPoints.all_param_types, 2346 GLEntryPoints.get_packed_enums(), 2347 is_gles1=is_gles1) 2348 2349 _packed_enums = None 2350 2351 @classmethod 2352 def get_packed_enums(cls): 2353 if not cls._packed_enums: 2354 with open(script_relative('entry_point_packed_gl_enums.json')) as f: 2355 cls._packed_enums = json.loads(f.read()) 2356 return cls._packed_enums 2357 2358 2359class EGLEntryPoints(ANGLEEntryPoints): 2360 2361 all_param_types = set() 2362 2363 def __init__(self, xml, commands): 2364 super().__init__( 2365 apis.EGL, 2366 xml, 2367 commands, 2368 EGLEntryPoints.all_param_types, 2369 EGLEntryPoints.get_packed_enums(), 2370 export_template=TEMPLATE_EGL_ENTRY_POINT_EXPORT, 2371 packed_param_types=EGL_PACKED_TYPES, 2372 ep_to_object=EGLEntryPoints._get_ep_to_object()) 2373 2374 _ep_to_object = None 2375 2376 @classmethod 2377 def _get_ep_to_object(cls): 2378 2379 if cls._ep_to_object: 2380 return cls._ep_to_object 2381 2382 with open(EGL_GET_LABELED_OBJECT_DATA_PATH) as f: 2383 try: 2384 spec_json = json.loads(f.read()) 2385 except ValueError: 2386 raise Exception("Could not decode JSON from %s" % EGL_GET_LABELED_OBJECT_DATA_PATH) 2387 2388 # Construct a mapping from EP to type. Fill in the gaps with Display/None. 2389 cls._ep_to_object = {} 2390 2391 for category, eps in spec_json.items(): 2392 if category == 'description': 2393 continue 2394 for ep in eps: 2395 cls._ep_to_object[ep] = category 2396 2397 return cls._ep_to_object 2398 2399 _packed_enums = None 2400 2401 @classmethod 2402 def get_packed_enums(cls): 2403 if not cls._packed_enums: 2404 with open(script_relative('entry_point_packed_egl_enums.json')) as f: 2405 cls._packed_enums = json.loads(f.read()) 2406 return cls._packed_enums 2407 2408 2409class GLXEntryPoints(ANGLEEntryPoints): 2410 2411 all_param_types = set() 2412 2413 def __init__(self, xml, commands): 2414 super().__init__( 2415 apis.GLX, 2416 xml, 2417 commands, 2418 GLXEntryPoints.all_param_types, 2419 GLXEntryPoints.get_packed_enums(), 2420 export_template=TEMPLATE_GLX_ENTRY_POINT_EXPORT, 2421 packed_param_types=GLX_PACKED_TYPES) 2422 2423 2424class CLEntryPoints(ANGLEEntryPoints): 2425 2426 all_param_types = set() 2427 2428 def __init__(self, xml, commands): 2429 super().__init__( 2430 apis.CL, 2431 xml, 2432 commands, 2433 CLEntryPoints.all_param_types, 2434 CLEntryPoints.get_packed_enums(), 2435 export_template=TEMPLATE_CL_ENTRY_POINT_EXPORT, 2436 packed_param_types=CL_PACKED_TYPES) 2437 2438 @classmethod 2439 def get_packed_enums(cls): 2440 return {} 2441 2442 2443def get_decls(api, 2444 formatter, 2445 all_commands, 2446 gles_commands, 2447 already_included, 2448 cmd_packed_gl_enums, 2449 packed_param_types=[]): 2450 decls = [] 2451 for command in all_commands: 2452 proto = command.find('proto') 2453 cmd_name = proto.find('name').text 2454 2455 if cmd_name not in gles_commands: 2456 continue 2457 2458 name_no_suffix = strip_suffix(api, cmd_name) 2459 if name_no_suffix in already_included: 2460 continue 2461 2462 # Don't generate Context::entryPoint declarations for entry points that 2463 # directly access the context-private state. 2464 if is_context_private_state_command(api, cmd_name): 2465 continue 2466 2467 param_text = ["".join(param.itertext()) for param in command.findall('param')] 2468 proto_text = "".join(proto.itertext()) 2469 decls.append( 2470 format_context_decl(api, cmd_name, proto_text, param_text, formatter, 2471 cmd_packed_gl_enums, packed_param_types)) 2472 2473 return decls 2474 2475 2476def get_glext_decls(all_commands, gles_commands, version): 2477 glext_ptrs = [] 2478 glext_protos = [] 2479 is_gles1 = False 2480 2481 if (version == ""): 2482 is_gles1 = True 2483 2484 for command in all_commands: 2485 proto = command.find('proto') 2486 cmd_name = proto.find('name').text 2487 2488 if cmd_name not in gles_commands: 2489 continue 2490 2491 param_text = ["".join(param.itertext()) for param in command.findall('param')] 2492 proto_text = "".join(proto.itertext()) 2493 2494 return_type = proto_text[:-len(cmd_name)] 2495 params = ", ".join(param_text) 2496 2497 format_params = { 2498 "apicall": "GL_API" if is_gles1 else "GL_APICALL", 2499 "name": cmd_name, 2500 "name_upper": cmd_name.upper(), 2501 "return_type": return_type, 2502 "params": params, 2503 } 2504 2505 glext_ptrs.append(TEMPLATE_GLEXT_FUNCTION_POINTER.format(**format_params)) 2506 glext_protos.append(TEMPLATE_GLEXT_FUNCTION_PROTOTYPE.format(**format_params)) 2507 2508 return glext_ptrs, glext_protos 2509 2510 2511def write_file(annotation, comment, template, entry_points, suffix, includes, lib, file): 2512 2513 content = template.format( 2514 script_name=os.path.basename(sys.argv[0]), 2515 data_source_name=file, 2516 annotation_lower=annotation.lower(), 2517 annotation_upper=annotation.upper(), 2518 comment=comment, 2519 lib=lib.upper(), 2520 includes=includes, 2521 entry_points=entry_points) 2522 2523 path = path_to(lib, "entry_points_{}_autogen.{}".format(annotation.lower(), suffix)) 2524 2525 with open(path, "w") as out: 2526 out.write(content) 2527 out.close() 2528 2529 2530def write_export_files(entry_points, includes, source, lib_name, lib_description, lib_dir=None): 2531 content = TEMPLATE_LIB_ENTRY_POINT_SOURCE.format( 2532 script_name=os.path.basename(sys.argv[0]), 2533 data_source_name=source, 2534 lib_name=lib_name, 2535 lib_description=lib_description, 2536 includes=includes, 2537 entry_points=entry_points, 2538 ) 2539 2540 path = path_to(lib_name if not lib_dir else lib_dir, "{}_autogen.cpp".format(lib_name)) 2541 2542 with open(path, "w") as out: 2543 out.write(content) 2544 out.close() 2545 2546 2547def write_context_api_decls(decls, api): 2548 for (major, minor), version_decls in sorted(decls['core'].items()): 2549 if minor == "X": 2550 annotation = '{}_{}'.format(api, major) 2551 version = str(major) 2552 else: 2553 annotation = '{}_{}_{}'.format(api, major, minor) 2554 version = '{}_{}'.format(major, minor) 2555 content = CONTEXT_HEADER.format( 2556 annotation_lower=annotation.lower(), 2557 annotation_upper=annotation.upper(), 2558 script_name=os.path.basename(sys.argv[0]), 2559 data_source_name="gl.xml", 2560 version=version, 2561 interface="\n".join(version_decls)) 2562 2563 path = path_to("libANGLE", "Context_%s_autogen.h" % annotation.lower()) 2564 2565 with open(path, "w") as out: 2566 out.write(content) 2567 out.close() 2568 2569 if 'exts' in decls.keys(): 2570 interface_lines = [] 2571 for annotation in decls['exts'].keys(): 2572 interface_lines.append("\\\n /* " + annotation + " */ \\\n\\") 2573 2574 for extname in sorted(decls['exts'][annotation].keys()): 2575 interface_lines.append(" /* " + extname + " */ \\") 2576 interface_lines.extend(decls['exts'][annotation][extname]) 2577 2578 content = CONTEXT_HEADER.format( 2579 annotation_lower='gles_ext', 2580 annotation_upper='GLES_EXT', 2581 script_name=os.path.basename(sys.argv[0]), 2582 data_source_name="gl.xml", 2583 version='EXT', 2584 interface="\n".join(interface_lines)) 2585 2586 path = path_to("libANGLE", "Context_gles_ext_autogen.h") 2587 2588 with open(path, "w") as out: 2589 out.write(content) 2590 out.close() 2591 2592 2593def write_validation_header(annotation, comment, protos, source, template): 2594 content = template.format( 2595 script_name=os.path.basename(sys.argv[0]), 2596 data_source_name=source, 2597 annotation=annotation, 2598 comment=comment, 2599 prototypes="\n".join(protos)) 2600 2601 path = path_to("libANGLE", "validation%s_autogen.h" % annotation) 2602 2603 with open(path, "w") as out: 2604 out.write(content) 2605 out.close() 2606 2607 2608def write_context_private_call_header(annotation, protos, source, template): 2609 content = TEMPLATE_CONTEXT_PRIVATE_CALL_HEADER.format( 2610 script_name=os.path.basename(sys.argv[0]), 2611 data_source_name=source, 2612 annotation=annotation, 2613 prototypes="\n".join(protos)) 2614 2615 path = path_to("libANGLE", "context_private_call_%s_autogen.h" % annotation) 2616 2617 with open(path, "w") as out: 2618 out.write(content) 2619 out.close() 2620 2621 2622def write_context_lock_header(annotation, comment, protos, source, template): 2623 content = template.format( 2624 script_name=os.path.basename(sys.argv[0]), 2625 data_source_name=source, 2626 annotation_lower=annotation.lower(), 2627 annotation_upper=annotation.upper(), 2628 comment=comment, 2629 prototypes="\n".join(protos)) 2630 2631 path = path_to("libGLESv2", "%s_context_lock_autogen.h" % annotation.lower()) 2632 2633 with open(path, "w") as out: 2634 out.write(content) 2635 out.close() 2636 2637 2638def write_gl_validation_header(annotation, comment, protos, source): 2639 return write_validation_header(annotation, comment, protos, source, 2640 TEMPLATE_GL_VALIDATION_HEADER) 2641 2642 2643def write_capture_header(api, annotation, comment, protos, capture_pointer_funcs): 2644 ns = 'egl' if api == apis.EGL else 'gl' 2645 combined_protos = ["\n// Method Captures\n"] + protos 2646 if capture_pointer_funcs: 2647 combined_protos += ["\n// Parameter Captures\n"] + capture_pointer_funcs 2648 content = TEMPLATE_CAPTURE_HEADER.format( 2649 script_name=os.path.basename(sys.argv[0]), 2650 data_source_name="%s.xml and %s_angle_ext.xml" % (ns, ns), 2651 annotation_lower=annotation.lower(), 2652 annotation_upper=annotation.upper(), 2653 comment=comment, 2654 namespace=ns, 2655 prototypes="\n".join(combined_protos)) 2656 2657 path = path_to(os.path.join("libANGLE", "capture"), "capture_%s_autogen.h" % annotation) 2658 2659 with open(path, "w") as out: 2660 out.write(content) 2661 out.close() 2662 2663 2664def write_capture_source(api, annotation_with_dash, annotation_no_dash, comment, capture_methods): 2665 ns = 'egl' if api == apis.EGL else 'gl' 2666 content = TEMPLATE_CAPTURE_SOURCE.format( 2667 script_name=os.path.basename(sys.argv[0]), 2668 data_source_name="%s.xml and %s_angle_ext.xml" % (ns, ns), 2669 annotation_with_dash=annotation_with_dash, 2670 annotation_no_dash=annotation_no_dash, 2671 comment=comment, 2672 namespace=ns, 2673 capture_methods="\n".join(capture_methods)) 2674 2675 path = path_to( 2676 os.path.join("libANGLE", "capture"), "capture_%s_autogen.cpp" % annotation_with_dash) 2677 2678 with open(path, "w") as out: 2679 out.write(content) 2680 out.close() 2681 2682 2683def is_packed_enum_param_type(param_type): 2684 return not param_type.startswith("GL") and not param_type.startswith( 2685 "EGL") and "void" not in param_type 2686 2687 2688def add_namespace(param_type): 2689 param_type = param_type.strip() 2690 2691 if param_type == 'AHardwareBufferConstPointer' or param_type == 'charConstPointer': 2692 return param_type 2693 2694 # ANGLE namespaced EGL types 2695 egl_namespace = [ 2696 'CompositorTiming', 2697 'ObjectType', 2698 'Timestamp', 2699 ] + list(EGL_PACKED_TYPES.values()) 2700 2701 if param_type[0:2] == "GL" or param_type[0:3] == "EGL" or "void" in param_type: 2702 return param_type 2703 2704 if param_type.startswith('gl_'): 2705 return param_type.replace('gl_', 'gl::') 2706 elif param_type.startswith('egl_'): 2707 return param_type.replace('egl_', 'egl::') 2708 elif param_type.startswith('wl_'): 2709 return param_type 2710 elif param_type in egl_namespace: 2711 return "egl::" + param_type 2712 else: 2713 return "gl::" + param_type 2714 2715 2716def get_gl_pointer_type(param_type): 2717 2718 if "ConstPointerPointer" in param_type: 2719 return "const " + param_type.replace("ConstPointerPointer", "") + " * const *" 2720 2721 if "ConstPointer" in param_type: 2722 return "const " + param_type.replace("ConstPointer", "") + " *" 2723 2724 if "PointerPointer" in param_type: 2725 return param_type.replace("PointerPointer", "") + " **" 2726 2727 if "Pointer" in param_type: 2728 return param_type.replace("Pointer", "") + " *" 2729 2730 return param_type 2731 2732 2733def get_param_type_type(param_type): 2734 param_type = add_namespace(param_type) 2735 return get_gl_pointer_type(param_type) 2736 2737 2738def is_id_type(t): 2739 return t.endswith('ID') and not t.endswith('ANDROID') 2740 2741 2742def is_id_pointer_type(t): 2743 return t.endswith("IDConstPointer") or t.endswith("IDPointer") and not 'ANDROID' in t 2744 2745 2746def get_gl_param_type_type(param_type): 2747 if is_packed_enum_param_type(param_type): 2748 base_type = param_type.replace("Pointer", "").replace("Const", "") 2749 if is_id_type(base_type): 2750 replace_type = "GLuint" 2751 else: 2752 replace_type = "GLenum" 2753 param_type = param_type.replace(base_type, replace_type) 2754 return get_gl_pointer_type(param_type) 2755 2756 2757def get_param_type_union_name(param_type): 2758 return param_type + "Val" 2759 2760 2761def format_param_type_union_type(param_type): 2762 return "%s %s;" % (get_param_type_type(param_type), get_param_type_union_name(param_type)) 2763 2764 2765def format_get_param_val_specialization(param_type): 2766 return TEMPLATE_GET_PARAM_VAL_SPECIALIZATION.format( 2767 enum=param_type, 2768 type=get_param_type_type(param_type), 2769 union_name=get_param_type_union_name(param_type)) 2770 2771 2772def format_access_param_value_case(param_type): 2773 return TEMPLATE_ACCESS_PARAM_VALUE_CASE.format(enum=param_type) 2774 2775 2776def format_set_param_val_specialization(param_type): 2777 return TEMPLATE_SET_PARAM_VAL_SPECIALIZATION.format( 2778 enum=param_type, 2779 type=get_param_type_type(param_type), 2780 union_name=get_param_type_union_name(param_type)) 2781 2782 2783def format_init_param_value_case(param_type): 2784 return TEMPLATE_INIT_PARAM_VALUE_CASE.format(enum=param_type) 2785 2786 2787def format_write_param_type_to_stream_case(param_type): 2788 return TEMPLATE_WRITE_PARAM_TYPE_TO_STREAM_CASE.format( 2789 enum_in=param_type, enum_out=param_type, union_name=get_param_type_union_name(param_type)) 2790 2791 2792def get_resource_id_types(all_param_types): 2793 return [t[:-2] for t in filter(lambda t: is_id_type(t), all_param_types)] 2794 2795 2796def format_resource_id_types(all_param_types): 2797 resource_id_types = get_resource_id_types(all_param_types) 2798 resource_id_types += ["EnumCount", "InvalidEnum = EnumCount"] 2799 resource_id_types = ",\n ".join(resource_id_types) 2800 return resource_id_types 2801 2802 2803def format_resource_id_convert_structs(all_param_types): 2804 templ = """\ 2805template <> 2806struct GetResourceIDTypeFromType<%s> 2807{ 2808 static constexpr ResourceIDType IDType = ResourceIDType::%s; 2809}; 2810""" 2811 resource_id_types = get_resource_id_types(all_param_types) 2812 convert_struct_strings = [templ % (add_namespace('%sID' % id), id) for id in resource_id_types] 2813 return "\n".join(convert_struct_strings) 2814 2815 2816def write_capture_helper_header(all_param_types): 2817 2818 param_types = "\n ".join(["T%s," % t for t in all_param_types]) 2819 param_union_values = "\n ".join([format_param_type_union_type(t) for t in all_param_types]) 2820 get_param_val_specializations = "\n\n".join( 2821 [format_get_param_val_specialization(t) for t in all_param_types]) 2822 access_param_value_cases = "\n".join( 2823 [format_access_param_value_case(t) for t in all_param_types]) 2824 set_param_val_specializations = "\n\n".join( 2825 [format_set_param_val_specialization(t) for t in all_param_types]) 2826 init_param_value_cases = "\n".join([format_init_param_value_case(t) for t in all_param_types]) 2827 resource_id_types = format_resource_id_types(all_param_types) 2828 convert_structs = format_resource_id_convert_structs(all_param_types) 2829 2830 content = TEMPLATE_FRAME_CAPTURE_UTILS_HEADER.format( 2831 script_name=os.path.basename(sys.argv[0]), 2832 data_source_name="gl.xml and gl_angle_ext.xml", 2833 param_types=param_types, 2834 param_type_count=len(all_param_types), 2835 param_union_values=param_union_values, 2836 get_param_val_specializations=get_param_val_specializations, 2837 access_param_value_cases=access_param_value_cases, 2838 set_param_val_specializations=set_param_val_specializations, 2839 init_param_value_cases=init_param_value_cases, 2840 resource_id_types=resource_id_types, 2841 type_to_resource_id_type_structs=convert_structs) 2842 2843 path = path_to("common", "frame_capture_utils_autogen.h") 2844 2845 with open(path, "w") as out: 2846 out.write(content) 2847 out.close() 2848 2849 2850def format_param_type_to_string_case(param_type): 2851 return TEMPLATE_PARAM_TYPE_TO_STRING_CASE.format( 2852 enum=param_type, type=get_gl_param_type_type(param_type)) 2853 2854 2855def get_resource_id_type_from_param_type(param_type): 2856 if param_type.endswith("ConstPointer"): 2857 return param_type.replace("ConstPointer", "")[:-2] 2858 if param_type.endswith("Pointer"): 2859 return param_type.replace("Pointer", "")[:-2] 2860 return param_type[:-2] 2861 2862 2863def format_param_type_to_resource_id_type_case(param_type): 2864 return TEMPLATE_PARAM_TYPE_TO_RESOURCE_ID_TYPE_CASE.format( 2865 enum=param_type, resource_id_type=get_resource_id_type_from_param_type(param_type)) 2866 2867 2868def format_param_type_resource_id_cases(all_param_types): 2869 id_types = filter(lambda t: is_id_type(t) or is_id_pointer_type(t), all_param_types) 2870 return "\n".join([format_param_type_to_resource_id_type_case(t) for t in id_types]) 2871 2872 2873def format_resource_id_type_name_case(resource_id_type): 2874 return TEMPLATE_RESOURCE_ID_TYPE_NAME_CASE.format(resource_id_type=resource_id_type) 2875 2876 2877def write_capture_helper_source(all_param_types): 2878 2879 write_param_type_to_stream_cases = "\n".join( 2880 [format_write_param_type_to_stream_case(t) for t in all_param_types]) 2881 param_type_to_string_cases = "\n".join( 2882 [format_param_type_to_string_case(t) for t in all_param_types]) 2883 2884 param_type_resource_id_cases = format_param_type_resource_id_cases(all_param_types) 2885 2886 resource_id_types = get_resource_id_types(all_param_types) 2887 resource_id_type_name_cases = "\n".join( 2888 [format_resource_id_type_name_case(t) for t in resource_id_types]) 2889 2890 content = TEMPLATE_FRAME_CAPTURE_UTILS_SOURCE.format( 2891 script_name=os.path.basename(sys.argv[0]), 2892 data_source_name="gl.xml and gl_angle_ext.xml", 2893 write_param_type_to_stream_cases=write_param_type_to_stream_cases, 2894 param_type_to_string_cases=param_type_to_string_cases, 2895 param_type_resource_id_cases=param_type_resource_id_cases, 2896 resource_id_type_name_cases=resource_id_type_name_cases) 2897 2898 path = path_to("common", "frame_capture_utils_autogen.cpp") 2899 2900 with open(path, "w") as out: 2901 out.write(content) 2902 out.close() 2903 2904 2905def get_command_params_text(command_node, cmd_name): 2906 param_text_list = list() 2907 for param_node in command_node.findall('param'): 2908 param_text_list.append("".join(param_node.itertext())) 2909 return param_text_list 2910 2911 2912def is_get_pointer_command(command_name): 2913 return command_name.endswith('Pointerv') and command_name.startswith('glGet') 2914 2915 2916def remove_id_suffix(t): 2917 return t[:-2] if is_id_type(t) else t 2918 2919 2920def format_replay_params(api, command_name, param_text_list, packed_enums, resource_id_types): 2921 param_access_strs = list() 2922 for i, param_text in enumerate(param_text_list): 2923 param_type = just_the_type(param_text) 2924 if param_type in EGL_PACKED_TYPES: 2925 param_type = 'void *' 2926 param_name = just_the_name(param_text) 2927 capture_type = get_capture_param_type_name(param_type) 2928 union_name = get_param_type_union_name(capture_type) 2929 param_access = 'captures[%d].value.%s' % (i, union_name) 2930 # Workaround for https://github.com/KhronosGroup/OpenGL-Registry/issues/545 2931 if command_name == 'glCreateShaderProgramvEXT' and i == 2: 2932 param_access = 'const_cast<const char **>(%s)' % param_access 2933 else: 2934 cmd_no_suffix = strip_suffix(api, command_name) 2935 if cmd_no_suffix in packed_enums and param_name in packed_enums[cmd_no_suffix]: 2936 packed_type = remove_id_suffix(packed_enums[cmd_no_suffix][param_name]) 2937 if packed_type == 'Sync': 2938 param_access = 'gSyncMap2[captures[%d].value.GLuintVal]' % i 2939 elif packed_type in resource_id_types: 2940 param_access = 'g%sMap[%s]' % (packed_type, param_access) 2941 elif packed_type == 'UniformLocation': 2942 param_access = 'gUniformLocations[gCurrentProgram][%s]' % param_access 2943 elif packed_type == 'egl::Image': 2944 param_access = 'gEGLImageMap2[captures[%d].value.GLuintVal]' % i 2945 elif packed_type == 'egl::Sync': 2946 param_access = 'gEGLSyncMap[captures[%d].value.egl_SyncIDVal]' % i 2947 param_access_strs.append(param_access) 2948 return ', '.join(param_access_strs) 2949 2950 2951def format_capture_replay_call_case(api, command_to_param_types_mapping, gl_packed_enums, 2952 resource_id_types): 2953 call_list = list() 2954 for command_name, cmd_param_texts in sorted(command_to_param_types_mapping.items()): 2955 entry_point_name = strip_api_prefix(command_name) 2956 2957 call_list.append( 2958 TEMPLATE_REPLAY_CALL_CASE.format( 2959 enum=('EGL' if api == 'EGL' else 'GL') + entry_point_name, 2960 params=format_replay_params(api, command_name, cmd_param_texts, gl_packed_enums, 2961 resource_id_types), 2962 call=command_name, 2963 )) 2964 2965 return ''.join(call_list) 2966 2967 2968def write_capture_replay_source(gl_command_nodes, gl_command_names, gl_packed_enums, 2969 egl_command_nodes, egl_command_names, egl_packed_enums, 2970 resource_id_types): 2971 2972 call_replay_cases = '' 2973 2974 for api, nodes, names, packed_enums in [ 2975 (apis.GLES, gl_command_nodes, gl_command_names, gl_packed_enums), 2976 (apis.EGL, egl_command_nodes, egl_command_names, egl_packed_enums) 2977 ]: 2978 command_to_param_types_mapping = dict() 2979 all_commands_names = set(names) 2980 for command_node in nodes: 2981 command_name = command_node.find('proto').find('name').text 2982 if command_name not in all_commands_names: 2983 continue 2984 command_to_param_types_mapping[command_name] = get_command_params_text( 2985 command_node, command_name) 2986 2987 call_replay_cases += format_capture_replay_call_case(api, command_to_param_types_mapping, 2988 packed_enums, resource_id_types) 2989 2990 source_content = TEMPLATE_CAPTURE_REPLAY_SOURCE.format( 2991 script_name=os.path.basename(sys.argv[0]), 2992 data_source_name="gl.xml and gl_angle_ext.xml", 2993 call_replay_cases=call_replay_cases, 2994 ) 2995 source_file_path = registry_xml.script_relative( 2996 "../util/capture/frame_capture_replay_autogen.cpp") 2997 with open(source_file_path, 'w') as f: 2998 f.write(source_content) 2999 3000 3001def write_windows_def_file(data_source_name, lib, libexport, folder, exports): 3002 3003 content = TEMPLATE_WINDOWS_DEF_FILE.format( 3004 script_name=os.path.basename(sys.argv[0]), 3005 data_source_name=data_source_name, 3006 exports="\n".join(exports), 3007 lib=libexport) 3008 3009 path = path_to(folder, "%s_autogen.def" % lib) 3010 3011 with open(path, "w") as out: 3012 out.write(content) 3013 out.close() 3014 3015 3016def get_exports(commands, fmt=None): 3017 if fmt: 3018 return [" %s" % fmt(cmd) for cmd in sorted(commands)] 3019 else: 3020 return [" %s" % cmd for cmd in sorted(commands)] 3021 3022 3023# Get EGL exports 3024def get_egl_exports(): 3025 3026 egl = registry_xml.RegistryXML('egl.xml', 'egl_angle_ext.xml') 3027 exports = [] 3028 3029 capser = lambda fn: "EGL_" + fn[3:] 3030 3031 for major, minor in registry_xml.EGL_VERSIONS: 3032 annotation = "{}_{}".format(major, minor) 3033 name_prefix = "EGL_VERSION_" 3034 3035 feature_name = "{}{}".format(name_prefix, annotation) 3036 3037 egl.AddCommands(feature_name, annotation) 3038 3039 commands = egl.commands[annotation] 3040 3041 if len(commands) == 0: 3042 continue 3043 3044 exports.append("\n ; EGL %d.%d" % (major, minor)) 3045 exports += get_exports(commands, capser) 3046 3047 egl.AddExtensionCommands(registry_xml.supported_egl_extensions, ['egl']) 3048 3049 for extension_name, ext_cmd_names in sorted(egl.ext_data.items()): 3050 3051 if len(ext_cmd_names) == 0: 3052 continue 3053 3054 exports.append("\n ; %s" % extension_name) 3055 exports += get_exports(ext_cmd_names, capser) 3056 3057 return exports 3058 3059 3060# Construct a mapping from an EGL EP to object function 3061def get_egl_entry_point_labeled_object(ep_to_object, cmd_stripped, params, packed_enums): 3062 3063 if not ep_to_object: 3064 return "" 3065 3066 # Finds a packed parameter name in a list of params 3067 def find_param(params, type_name, packed_enums): 3068 for param in params: 3069 if just_the_type_packed(param, packed_enums).split(' ')[0] == type_name: 3070 return just_the_name_packed(param, packed_enums) 3071 return None 3072 3073 display_param = find_param(params, "egl::Display", packed_enums) 3074 3075 # For entry points not listed in the JSON file, they default to an EGLDisplay or nothing. 3076 if cmd_stripped not in ep_to_object: 3077 if display_param: 3078 return "GetDisplayIfValid(%s)" % display_param 3079 return "nullptr" 3080 3081 # We first handle a few special cases for certain type categories. 3082 category = ep_to_object[cmd_stripped] 3083 if category == "Thread": 3084 return "GetThreadIfValid(thread)" 3085 found_param = find_param(params, category, packed_enums) 3086 if category == "Context" and not found_param: 3087 return "GetContextIfValid(thread->getDisplay(), thread->getContext())" 3088 assert found_param, "Did not find %s for %s: %s" % (category, cmd_stripped, str(params)) 3089 if category == "Device": 3090 return "GetDeviceIfValid(%s)" % found_param 3091 if category == "LabeledObject": 3092 object_type_param = find_param(params, "ObjectType", packed_enums) 3093 return "GetLabeledObjectIfValid(thread, %s, %s, %s)" % (display_param, object_type_param, 3094 found_param) 3095 3096 # We then handle the general case which handles the rest of the type categories. 3097 return "Get%sIfValid(%s, %s)" % (category, display_param, found_param) 3098 3099 3100def disable_share_group_lock(api, cmd_name): 3101 if cmd_name == 'glBindBuffer': 3102 # This function looks up the ID in the buffer manager, 3103 # access to which is thread-safe for buffers. 3104 return True 3105 3106 if api == apis.GLES and cmd_name.startswith('glUniform'): 3107 # Thread safety of glUniform1/2/3/4 and glUniformMatrix* calls is defined by the backend, 3108 # frontend only does validation. 3109 keep_locked = [ 3110 # Might set samplers: 3111 'glUniform1i', 3112 'glUniform1iv', 3113 # More complex state change with notifications: 3114 'glUniformBlockBinding', 3115 ] 3116 return cmd_name not in keep_locked 3117 3118 return False 3119 3120 3121def get_context_lock(api, cmd_name): 3122 # EGLImage related commands need to access EGLImage and Display which should 3123 # be protected with global lock 3124 # Also handles ContextMutex merging when "angle_enable_context_mutex" is true. 3125 if api == apis.GLES and cmd_name.startswith("glEGLImage"): 3126 return "SCOPED_EGL_IMAGE_SHARE_CONTEXT_LOCK(context, imagePacked);" 3127 3128 # Certain commands do not need to hold the share group lock. Both 3129 # validation and their implementation in the context are limited to 3130 # context-local state. 3131 if disable_share_group_lock(api, cmd_name): 3132 return "" 3133 3134 return "SCOPED_SHARE_CONTEXT_LOCK(context);" 3135 3136 3137def get_prepare_swap_buffers_call(api, cmd_name, params): 3138 if cmd_name not in [ 3139 "eglSwapBuffers", 3140 "eglSwapBuffersWithDamageKHR", 3141 "eglSwapBuffersWithFrameTokenANGLE", 3142 "eglQuerySurface", 3143 "eglQuerySurface64KHR", 3144 ]: 3145 return "" 3146 3147 passed_params = [None, None] 3148 3149 for param in params: 3150 param_type = just_the_type(param) 3151 if param_type == "EGLDisplay": 3152 passed_params[0] = param 3153 if param_type == "EGLSurface": 3154 passed_params[1] = param 3155 3156 prepareCall = "ANGLE_EGLBOOLEAN_TRY(EGL_PrepareSwapBuffersANGLE(%s));" % (", ".join( 3157 [just_the_name(param) for param in passed_params])) 3158 3159 # For eglQuerySurface, the prepare call is only needed for EGL_BUFFER_AGE 3160 if cmd_name in ["eglQuerySurface", "eglQuerySurface64KHR"]: 3161 prepareCall = "if (attribute == EGL_BUFFER_AGE_EXT) {" + prepareCall + "}" 3162 3163 return prepareCall 3164 3165 3166def get_preamble(api, cmd_name, params): 3167 preamble = "" 3168 preamble += get_prepare_swap_buffers_call(api, cmd_name, params) 3169 # TODO: others? 3170 return preamble 3171 3172 3173def get_unlocked_tail_call(api, cmd_name): 3174 # Only the following can generate tail calls: 3175 # 3176 # - eglDestroySurface, eglMakeCurrent and eglReleaseThread -> May destroy 3177 # VkSurfaceKHR in tail call 3178 # - eglCreateWindowSurface and eglCreatePlatformWindowSurface[EXT] -> May 3179 # destroy VkSurfaceKHR in tail call if surface initialization fails 3180 # 3181 # - eglPrepareSwapBuffersANGLE -> Calls vkAcquireNextImageKHR in tail call 3182 # 3183 # - eglSwapBuffers, eglSwapBuffersWithDamageKHR and 3184 # eglSwapBuffersWithFrameTokenANGLE -> May throttle the CPU in tail call or 3185 # calls native EGL function 3186 # 3187 # - eglClientWaitSyncKHR, eglClientWaitSync, glClientWaitSync, 3188 # glFinishFenceNV -> May wait on fence in tail call or call native EGL function 3189 # 3190 # - glTexImage2D, glTexImage3D, glTexSubImage2D, glTexSubImage3D, 3191 # glCompressedTexImage2D, glCompressedTexImage3D, 3192 # glCompressedTexSubImage2D, glCompressedTexSubImage3D -> May perform the 3193 # data upload on the host in tail call 3194 # 3195 # - glCompileShader and glLinkProgram -> May perform the compilation / link 3196 # in tail call 3197 # 3198 # - eglCreateSync, eglCreateImage, eglDestroySync, eglDestroyImage, 3199 # eglGetCompositorTimingANDROID, eglGetFrameTimestampsANDROID -> Calls 3200 # native EGL function in tail call 3201 # 3202 if (cmd_name in [ 3203 'eglDestroySurface', 'eglMakeCurrent', 'eglReleaseThread', 'eglCreateWindowSurface', 3204 'eglCreatePlatformWindowSurface', 'eglCreatePlatformWindowSurfaceEXT', 3205 'eglPrepareSwapBuffersANGLE', 'eglSwapBuffersWithFrameTokenANGLE', 'glFinishFenceNV', 3206 'glCompileShader', 'glLinkProgram' 3207 ] or cmd_name.startswith('glTexImage2D') or cmd_name.startswith('glTexImage3D') or 3208 cmd_name.startswith('glTexSubImage2D') or cmd_name.startswith('glTexSubImage3D') or 3209 cmd_name.startswith('glCompressedTexImage2D') or 3210 cmd_name.startswith('glCompressedTexImage3D') or 3211 cmd_name.startswith('glCompressedTexSubImage2D') or 3212 cmd_name.startswith('glCompressedTexSubImage3D')): 3213 return 'egl::Display::GetCurrentThreadUnlockedTailCall()->run(nullptr);' 3214 3215 if cmd_name in [ 3216 'eglClientWaitSyncKHR', 3217 'eglClientWaitSync', 3218 'eglCreateImageKHR', 3219 'eglCreateImage', 3220 'eglCreateSyncKHR', 3221 'eglCreateSync', 3222 'eglDestroySyncKHR', 3223 'eglDestroySync', 3224 'eglGetCompositorTimingANDROID', 3225 'eglGetFrameTimestampsANDROID', 3226 'eglSwapBuffers', 3227 'eglSwapBuffersWithDamageKHR', 3228 'eglWaitSyncKHR', 3229 'eglWaitSync', 3230 'glClientWaitSync', 3231 ]: 3232 return 'egl::Display::GetCurrentThreadUnlockedTailCall()->run(&returnValue);' 3233 3234 # Otherwise assert that no tail calls where generated 3235 return 'ASSERT(!egl::Display::GetCurrentThreadUnlockedTailCall()->any());' 3236 3237 3238def get_epilog(api, cmd_name): 3239 epilog = get_unlocked_tail_call(api, cmd_name) 3240 return epilog 3241 3242 3243def write_stubs_header(api, annotation, title, data_source, out_file, all_commands, commands, 3244 cmd_packed_egl_enums, packed_param_types): 3245 3246 stubs = [] 3247 3248 for command in all_commands: 3249 proto = command.find('proto') 3250 cmd_name = proto.find('name').text 3251 3252 if cmd_name not in commands: 3253 continue 3254 3255 proto_text = "".join(proto.itertext()) 3256 3257 params = [] if api == apis.CL else ["Thread *thread"] 3258 params += ["".join(param.itertext()) for param in command.findall('param')] 3259 if params and just_the_name(params[-1]) == "errcode_ret": 3260 # Using TLS object for CL error handling, no longer a need for errcode_ret 3261 del params[-1] 3262 return_type = proto_text[:-len(cmd_name)].strip() 3263 3264 internal_params = get_internal_params(api, cmd_name, params, cmd_packed_egl_enums, 3265 packed_param_types) 3266 stubs.append("%s %s(%s);" % (return_type, strip_api_prefix(cmd_name), internal_params)) 3267 3268 args = { 3269 "annotation_lower": annotation.lower(), 3270 "annotation_upper": annotation.upper(), 3271 "data_source_name": data_source, 3272 "script_name": os.path.basename(sys.argv[0]), 3273 "stubs": "\n".join(stubs), 3274 "title": title, 3275 } 3276 3277 output = get_stubs_header_template(api).format(**args) 3278 3279 with open(out_file, "w") as f: 3280 f.write(output) 3281 3282 3283def main(): 3284 3285 # auto_script parameters. 3286 if len(sys.argv) > 1: 3287 inputs = [ 3288 'entry_point_packed_egl_enums.json', 'entry_point_packed_gl_enums.json', 3289 EGL_GET_LABELED_OBJECT_DATA_PATH 3290 ] + registry_xml.xml_inputs 3291 outputs = [ 3292 CL_STUBS_HEADER_PATH, 3293 EGL_STUBS_HEADER_PATH, 3294 EGL_EXT_STUBS_HEADER_PATH, 3295 '../src/libOpenCL/libOpenCL_autogen.cpp', 3296 '../src/common/entry_points_enum_autogen.cpp', 3297 '../src/common/entry_points_enum_autogen.h', 3298 '../src/common/frame_capture_utils_autogen.cpp', 3299 '../src/common/frame_capture_utils_autogen.h', 3300 '../src/libANGLE/Context_gl_1_autogen.h', 3301 '../src/libANGLE/Context_gl_2_autogen.h', 3302 '../src/libANGLE/Context_gl_3_autogen.h', 3303 '../src/libANGLE/Context_gl_4_autogen.h', 3304 '../src/libANGLE/Context_gles_1_0_autogen.h', 3305 '../src/libANGLE/Context_gles_2_0_autogen.h', 3306 '../src/libANGLE/Context_gles_3_0_autogen.h', 3307 '../src/libANGLE/Context_gles_3_1_autogen.h', 3308 '../src/libANGLE/Context_gles_3_2_autogen.h', 3309 '../src/libANGLE/Context_gles_ext_autogen.h', 3310 '../src/libANGLE/context_private_call_gles_autogen.h', 3311 '../src/libANGLE/context_private_call_gl_autogen.h', 3312 '../src/libANGLE/capture/capture_egl_autogen.cpp', 3313 '../src/libANGLE/capture/capture_egl_autogen.h', 3314 '../src/libANGLE/capture/capture_gl_1_autogen.cpp', 3315 '../src/libANGLE/capture/capture_gl_1_autogen.h', 3316 '../src/libANGLE/capture/capture_gl_2_autogen.cpp', 3317 '../src/libANGLE/capture/capture_gl_2_autogen.h', 3318 '../src/libANGLE/capture/capture_gl_3_autogen.cpp', 3319 '../src/libANGLE/capture/capture_gl_3_autogen.h', 3320 '../src/libANGLE/capture/capture_gl_4_autogen.cpp', 3321 '../src/libANGLE/capture/capture_gl_4_autogen.h', 3322 '../src/libANGLE/capture/capture_gles_1_0_autogen.cpp', 3323 '../src/libANGLE/capture/capture_gles_1_0_autogen.h', 3324 '../src/libANGLE/capture/capture_gles_2_0_autogen.cpp', 3325 '../src/libANGLE/capture/capture_gles_2_0_autogen.h', 3326 '../src/libANGLE/capture/capture_gles_3_0_autogen.cpp', 3327 '../src/libANGLE/capture/capture_gles_3_0_autogen.h', 3328 '../src/libANGLE/capture/capture_gles_3_1_autogen.cpp', 3329 '../src/libANGLE/capture/capture_gles_3_1_autogen.h', 3330 '../src/libANGLE/capture/capture_gles_3_2_autogen.cpp', 3331 '../src/libANGLE/capture/capture_gles_3_2_autogen.h', 3332 '../src/libANGLE/capture/capture_gles_ext_autogen.cpp', 3333 '../src/libANGLE/capture/capture_gles_ext_autogen.h', 3334 '../src/libANGLE/validationCL_autogen.h', 3335 '../src/libANGLE/validationEGL_autogen.h', 3336 '../src/libANGLE/validationES1_autogen.h', 3337 '../src/libANGLE/validationES2_autogen.h', 3338 '../src/libANGLE/validationES31_autogen.h', 3339 '../src/libANGLE/validationES32_autogen.h', 3340 '../src/libANGLE/validationES3_autogen.h', 3341 '../src/libANGLE/validationESEXT_autogen.h', 3342 '../src/libANGLE/validationGL1_autogen.h', 3343 '../src/libANGLE/validationGL2_autogen.h', 3344 '../src/libANGLE/validationGL3_autogen.h', 3345 '../src/libANGLE/validationGL4_autogen.h', 3346 '../src/libEGL/libEGL_autogen.cpp', 3347 '../src/libEGL/libEGL_autogen.def', 3348 '../src/libGLESv2/entry_points_cl_autogen.cpp', 3349 '../src/libGLESv2/entry_points_cl_autogen.h', 3350 '../src/libGLESv2/entry_points_egl_autogen.cpp', 3351 '../src/libGLESv2/entry_points_egl_autogen.h', 3352 '../src/libGLESv2/entry_points_egl_ext_autogen.cpp', 3353 '../src/libGLESv2/entry_points_egl_ext_autogen.h', 3354 '../src/libGLESv2/entry_points_gles_1_0_autogen.cpp', 3355 '../src/libGLESv2/entry_points_gles_1_0_autogen.h', 3356 '../src/libGLESv2/entry_points_gles_2_0_autogen.cpp', 3357 '../src/libGLESv2/entry_points_gles_2_0_autogen.h', 3358 '../src/libGLESv2/entry_points_gles_3_0_autogen.cpp', 3359 '../src/libGLESv2/entry_points_gles_3_0_autogen.h', 3360 '../src/libGLESv2/entry_points_gles_3_1_autogen.cpp', 3361 '../src/libGLESv2/entry_points_gles_3_1_autogen.h', 3362 '../src/libGLESv2/entry_points_gles_3_2_autogen.cpp', 3363 '../src/libGLESv2/entry_points_gles_3_2_autogen.h', 3364 '../src/libGLESv2/entry_points_gles_ext_autogen.cpp', 3365 '../src/libGLESv2/entry_points_gles_ext_autogen.h', 3366 '../src/libGLESv2/libGLESv2_autogen.cpp', 3367 '../src/libGLESv2/libGLESv2_autogen.def', 3368 '../src/libGLESv2/libGLESv2_no_capture_autogen.def', 3369 '../src/libGLESv2/libGLESv2_with_capture_autogen.def', 3370 '../src/libGLESv2/entry_points_gl_1_autogen.cpp', 3371 '../src/libGLESv2/entry_points_gl_1_autogen.h', 3372 '../src/libGLESv2/entry_points_gl_2_autogen.cpp', 3373 '../src/libGLESv2/entry_points_gl_2_autogen.h', 3374 '../src/libGLESv2/entry_points_gl_3_autogen.cpp', 3375 '../src/libGLESv2/entry_points_gl_3_autogen.h', 3376 '../src/libGLESv2/entry_points_gl_4_autogen.cpp', 3377 '../src/libGLESv2/entry_points_gl_4_autogen.h', 3378 '../src/libGLESv2/egl_context_lock_autogen.h', 3379 '../util/capture/frame_capture_replay_autogen.cpp', 3380 ] 3381 3382 if sys.argv[1] == 'inputs': 3383 print(','.join(inputs)) 3384 elif sys.argv[1] == 'outputs': 3385 print(','.join(outputs)) 3386 else: 3387 print('Invalid script parameters') 3388 return 1 3389 return 0 3390 3391 glesdecls = {} 3392 glesdecls['core'] = {} 3393 glesdecls['exts'] = {} 3394 for ver in registry_xml.GLES_VERSIONS: 3395 glesdecls['core'][ver] = [] 3396 for ver in ['GLES1 Extensions', 'GLES2+ Extensions', 'ANGLE Extensions']: 3397 glesdecls['exts'][ver] = {} 3398 3399 libgles_ep_defs = [] 3400 libgles_ep_exports = [] 3401 3402 xml = registry_xml.RegistryXML('gl.xml', 'gl_angle_ext.xml') 3403 3404 # Stores core commands to keep track of duplicates 3405 all_commands_no_suffix = [] 3406 all_commands_with_suffix = [] 3407 3408 # Collect all context-private-state-accessing helper declarations 3409 context_private_call_gles_protos = [] 3410 context_private_call_gl_protos = [] 3411 context_private_call_functions = set() 3412 3413 # First run through the main GLES entry points. Since ES2+ is the primary use 3414 # case, we go through those first and then add ES1-only APIs at the end. 3415 for major_version, minor_version in registry_xml.GLES_VERSIONS: 3416 version = "{}_{}".format(major_version, minor_version) 3417 annotation = "GLES_{}".format(version) 3418 name_prefix = "GL_ES_VERSION_" 3419 3420 if major_version == 1: 3421 name_prefix = "GL_VERSION_ES_CM_" 3422 3423 comment = version.replace("_", ".") 3424 feature_name = "{}{}".format(name_prefix, version) 3425 3426 xml.AddCommands(feature_name, version) 3427 3428 version_commands = xml.commands[version] 3429 all_commands_no_suffix.extend(xml.commands[version]) 3430 all_commands_with_suffix.extend(xml.commands[version]) 3431 3432 eps = GLEntryPoints(apis.GLES, xml, version_commands, is_gles1=(major_version == 1)) 3433 eps.decls.insert(0, "extern \"C\" {") 3434 eps.decls.append("} // extern \"C\"") 3435 eps.defs.insert(0, "extern \"C\" {") 3436 eps.defs.append("} // extern \"C\"") 3437 3438 # Write the version as a comment before the first EP. 3439 libgles_ep_exports.append("\n ; OpenGL ES %s" % comment) 3440 3441 libgles_ep_defs += ["\n// OpenGL ES %s" % comment] + eps.export_defs 3442 libgles_ep_exports += get_exports(version_commands) 3443 3444 major_if_not_one = major_version if major_version != 1 else "" 3445 minor_if_not_zero = minor_version if minor_version != 0 else "" 3446 3447 header_includes = TEMPLATE_HEADER_INCLUDES.format( 3448 major=major_if_not_one, minor=minor_if_not_zero) 3449 3450 version_annotation = "%s%s" % (major_version, minor_if_not_zero) 3451 source_includes = TEMPLATE_SOURCES_INCLUDES.format( 3452 header_version=annotation.lower(), validation_header_version="ES" + version_annotation) 3453 3454 write_file(annotation, "GLES " + comment, TEMPLATE_ENTRY_POINT_HEADER, 3455 "\n".join(eps.decls), "h", header_includes, "libGLESv2", "gl.xml") 3456 write_file(annotation, "GLES " + comment, TEMPLATE_ENTRY_POINT_SOURCE, "\n".join(eps.defs), 3457 "cpp", source_includes, "libGLESv2", "gl.xml") 3458 3459 glesdecls['core'][(major_version, 3460 minor_version)] = get_decls(apis.GLES, CONTEXT_DECL_FORMAT, 3461 xml.all_commands, version_commands, [], 3462 GLEntryPoints.get_packed_enums()) 3463 3464 validation_annotation = "ES%s%s" % (major_version, minor_if_not_zero) 3465 write_gl_validation_header(validation_annotation, "ES %s" % comment, eps.validation_protos, 3466 "gl.xml and gl_angle_ext.xml") 3467 3468 context_private_call_gles_protos += eps.context_private_call_protos 3469 context_private_call_functions.update(eps.context_private_call_functions) 3470 3471 write_capture_header(apis.GLES, 'gles_' + version, comment, eps.capture_protos, 3472 eps.capture_pointer_funcs) 3473 write_capture_source(apis.GLES, 'gles_' + version, validation_annotation, comment, 3474 eps.capture_methods) 3475 3476 # After we finish with the main entry points, we process the extensions. 3477 extension_decls = ["extern \"C\" {"] 3478 extension_defs = ["extern \"C\" {"] 3479 extension_commands = [] 3480 3481 # Accumulated validation prototypes. 3482 ext_validation_protos = [] 3483 ext_capture_protos = [] 3484 ext_capture_methods = [] 3485 ext_capture_pointer_funcs = [] 3486 3487 for gles1ext in registry_xml.gles1_extensions: 3488 glesdecls['exts']['GLES1 Extensions'][gles1ext] = [] 3489 for glesext in registry_xml.gles_extensions: 3490 glesdecls['exts']['GLES2+ Extensions'][glesext] = [] 3491 for angle_ext in registry_xml.angle_extensions: 3492 glesdecls['exts']['ANGLE Extensions'][angle_ext] = [] 3493 3494 xml.AddExtensionCommands(registry_xml.supported_extensions, ['gles2', 'gles1']) 3495 3496 for extension_name, ext_cmd_names in sorted(xml.ext_data.items()): 3497 extension_commands.extend(xml.ext_data[extension_name]) 3498 3499 # Detect and filter duplicate extensions. 3500 is_gles1 = extension_name in registry_xml.gles1_extensions 3501 eps = GLEntryPoints(apis.GLES, xml, ext_cmd_names, is_gles1=is_gles1) 3502 3503 # Write the extension name as a comment before the first EP. 3504 comment = "\n// {}".format(extension_name) 3505 libgles_ep_exports.append("\n ; %s" % extension_name) 3506 3507 extension_defs += [comment] + eps.defs 3508 extension_decls += [comment] + eps.decls 3509 3510 # Avoid writing out entry points defined by a prior extension. 3511 for dupe in xml.ext_dupes[extension_name]: 3512 msg = "// {} is already defined.\n".format(strip_api_prefix(dupe)) 3513 extension_defs.append(msg) 3514 3515 ext_validation_protos += [comment] + eps.validation_protos 3516 ext_capture_protos += [comment] + eps.capture_protos 3517 ext_capture_methods += eps.capture_methods 3518 ext_capture_pointer_funcs += eps.capture_pointer_funcs 3519 3520 for proto, function in zip(eps.context_private_call_protos, 3521 eps.context_private_call_functions): 3522 if function not in context_private_call_functions: 3523 context_private_call_gles_protos.append(proto) 3524 context_private_call_functions.update(eps.context_private_call_functions) 3525 3526 libgles_ep_defs += [comment] + eps.export_defs 3527 libgles_ep_exports += get_exports(ext_cmd_names) 3528 3529 if (extension_name in registry_xml.gles1_extensions and 3530 extension_name not in GLES1_NO_CONTEXT_DECL_EXTENSIONS): 3531 glesdecls['exts']['GLES1 Extensions'][extension_name] = get_decls( 3532 apis.GLES, CONTEXT_DECL_FORMAT, xml.all_commands, ext_cmd_names, 3533 all_commands_no_suffix, GLEntryPoints.get_packed_enums()) 3534 if extension_name in registry_xml.gles_extensions: 3535 glesdecls['exts']['GLES2+ Extensions'][extension_name] = get_decls( 3536 apis.GLES, CONTEXT_DECL_FORMAT, xml.all_commands, ext_cmd_names, 3537 all_commands_no_suffix, GLEntryPoints.get_packed_enums()) 3538 if extension_name in registry_xml.angle_extensions: 3539 glesdecls['exts']['ANGLE Extensions'][extension_name] = get_decls( 3540 apis.GLES, CONTEXT_DECL_FORMAT, xml.all_commands, ext_cmd_names, 3541 all_commands_no_suffix, GLEntryPoints.get_packed_enums()) 3542 3543 write_context_private_call_header("gles", context_private_call_gles_protos, 3544 "gl.xml and gl_angle_ext.xml", 3545 TEMPLATE_CONTEXT_PRIVATE_CALL_HEADER) 3546 3547 for name in extension_commands: 3548 all_commands_with_suffix.append(name) 3549 all_commands_no_suffix.append(strip_suffix(apis.GLES, name)) 3550 3551 # Now we generate entry points for the desktop implementation 3552 desktop_gl_decls = {} 3553 desktop_gl_decls['core'] = {} 3554 for major, _ in registry_xml.DESKTOP_GL_VERSIONS: 3555 desktop_gl_decls['core'][(major, "X")] = [] 3556 3557 libgles_ep_defs.append('#if defined(ANGLE_ENABLE_GL_DESKTOP_FRONTEND)') 3558 libgl_ep_exports = libgles_ep_exports.copy() 3559 3560 glxml = registry_xml.RegistryXML('gl.xml') 3561 3562 for major_version in sorted( 3563 set([major for (major, minor) in registry_xml.DESKTOP_GL_VERSIONS])): 3564 is_major = lambda ver: ver[0] == major_version 3565 3566 ver_decls = ["extern \"C\" {"] 3567 ver_defs = ["extern \"C\" {"] 3568 validation_protos = [] 3569 capture_protos = [] 3570 capture_pointer_funcs = [] 3571 capture_defs = [] 3572 3573 for _, minor_version in filter(is_major, registry_xml.DESKTOP_GL_VERSIONS): 3574 version = "{}_{}".format(major_version, minor_version) 3575 annotation = "GL_{}".format(version) 3576 name_prefix = "GL_VERSION_" 3577 3578 comment = version.replace("_", ".") 3579 feature_name = "{}{}".format(name_prefix, version) 3580 3581 glxml.AddCommands(feature_name, version) 3582 3583 all_libgl_commands = glxml.commands[version] 3584 just_libgl_commands_suffix = [ 3585 cmd for cmd in all_libgl_commands if cmd not in all_commands_with_suffix 3586 ] 3587 3588 # Validation duplicates handled with suffix 3589 eps = GLEntryPoints(apis.GL, glxml, just_libgl_commands_suffix) 3590 3591 desktop_gl_decls['core'][(major_version, "X")] += get_decls( 3592 apis.GL, CONTEXT_DECL_FORMAT, glxml.all_commands, just_libgl_commands_suffix, 3593 all_commands_no_suffix, GLEntryPoints.get_packed_enums()) 3594 3595 # Write the version as a comment before the first EP. 3596 cpp_comment = "\n// GL %s" % comment 3597 def_comment = "\n ; GL %s" % comment 3598 3599 libgles_ep_defs += [cpp_comment] + eps.export_defs 3600 libgl_ep_exports += [def_comment] + get_exports(all_libgl_commands) 3601 validation_protos += [cpp_comment] + eps.validation_protos 3602 3603 for proto, function in zip(eps.context_private_call_protos, 3604 eps.context_private_call_functions): 3605 if function not in context_private_call_functions: 3606 context_private_call_gl_protos.append(proto) 3607 context_private_call_functions.update(eps.context_private_call_functions) 3608 3609 capture_protos += [cpp_comment] + eps.capture_protos 3610 capture_pointer_funcs += [cpp_comment] + eps.capture_pointer_funcs 3611 capture_defs += [cpp_comment] + eps.capture_methods 3612 ver_decls += [cpp_comment] + eps.decls 3613 ver_defs += [cpp_comment] + eps.defs 3614 3615 ver_decls.append("} // extern \"C\"") 3616 ver_defs.append("} // extern \"C\"") 3617 annotation = "GL_%d" % major_version 3618 name = "Desktop GL %s.x" % major_version 3619 3620 source_includes = TEMPLATE_DESKTOP_GL_SOURCE_INCLUDES.format(annotation.lower(), 3621 major_version) 3622 3623 # Entry point files 3624 write_file(annotation, name, TEMPLATE_ENTRY_POINT_HEADER, "\n".join(ver_decls), "h", 3625 DESKTOP_GL_HEADER_INCLUDES, "libGLESv2", "gl.xml") 3626 write_file(annotation, name, TEMPLATE_ENTRY_POINT_SOURCE, "\n".join(ver_defs), "cpp", 3627 source_includes, "libGLESv2", "gl.xml") 3628 3629 # Capture files 3630 write_capture_header(apis.GL, annotation.lower(), name, capture_protos, 3631 capture_pointer_funcs) 3632 write_capture_source(apis.GL, annotation.lower(), 'GL' + str(major_version) + '_autogen', 3633 name, capture_defs) 3634 3635 # Validation files 3636 write_gl_validation_header("GL%s" % major_version, name, validation_protos, "gl.xml") 3637 3638 libgles_ep_defs.append('#endif // defined(ANGLE_ENABLE_GL_DESKTOP_FRONTEND)') 3639 3640 write_context_private_call_header("gl", context_private_call_gl_protos, 3641 "gl.xml and gl_angle_ext.xml", 3642 TEMPLATE_CONTEXT_PRIVATE_CALL_HEADER) 3643 3644 # GLX 3645 glxxml = registry_xml.RegistryXML('glx.xml') 3646 glx_validation_protos = [] 3647 glx_decls = ["namespace glx\n{"] 3648 glx_defs = ["namespace glx\n{"] 3649 libglx_ep_defs = [] 3650 glx_commands = [] 3651 for major_version, minor_version in registry_xml.GLX_VERSIONS: 3652 version = "{}_{}".format(major_version, minor_version) 3653 annotation = "GLX_{}".format(version) 3654 name_prefix = "GLX_VERSION_" 3655 3656 comment = version.replace("_", ".") 3657 feature_name = "{}{}".format(name_prefix, version) 3658 3659 glxxml.AddCommands(feature_name, version) 3660 glx_version_commands = glxxml.commands[version] 3661 glx_commands += glx_version_commands 3662 3663 if not glx_version_commands: 3664 continue 3665 3666 3667 3668 # OpenCL 3669 clxml = registry_xml.RegistryXML('cl.xml') 3670 3671 cl_validation_protos = [] 3672 cl_decls = ["namespace cl\n{"] 3673 cl_defs = ["namespace cl\n{"] 3674 libcl_ep_defs = [] 3675 libcl_windows_def_exports = [] 3676 cl_commands = [] 3677 3678 for major_version, minor_version in registry_xml.CL_VERSIONS: 3679 version = "%d_%d" % (major_version, minor_version) 3680 annotation = "CL_%s" % version 3681 name_prefix = "CL_VERSION_" 3682 3683 comment = version.replace("_", ".") 3684 feature_name = "%s%s" % (name_prefix, version) 3685 3686 clxml.AddCommands(feature_name, version) 3687 3688 cl_version_commands = clxml.commands[version] 3689 cl_commands += cl_version_commands 3690 3691 # Spec revs may have no new commands. 3692 if not cl_version_commands: 3693 continue 3694 3695 eps = CLEntryPoints(clxml, cl_version_commands) 3696 3697 comment = "\n// CL %d.%d" % (major_version, minor_version) 3698 win_def_comment = "\n ; CL %d.%d" % (major_version, minor_version) 3699 3700 cl_decls += [comment] + eps.decls 3701 cl_defs += [comment] + eps.defs 3702 libcl_ep_defs += [comment] + eps.export_defs 3703 cl_validation_protos += [comment] + eps.validation_protos 3704 libcl_windows_def_exports += [win_def_comment] + get_exports(clxml.commands[version]) 3705 3706 clxml.AddExtensionCommands(registry_xml.supported_cl_extensions, ['cl']) 3707 for extension_name, ext_cmd_names in sorted(clxml.ext_data.items()): 3708 3709 # Extensions may have no new commands. 3710 if not ext_cmd_names: 3711 continue 3712 3713 # Detect and filter duplicate extensions. 3714 eps = CLEntryPoints(clxml, ext_cmd_names) 3715 3716 comment = "\n// %s" % extension_name 3717 win_def_comment = "\n ; %s" % (extension_name) 3718 3719 cl_commands += ext_cmd_names 3720 3721 cl_decls += [comment] + eps.decls 3722 cl_defs += [comment] + eps.defs 3723 libcl_ep_defs += [comment] + eps.export_defs 3724 cl_validation_protos += [comment] + eps.validation_protos 3725 libcl_windows_def_exports += [win_def_comment] + get_exports(ext_cmd_names) 3726 3727 # Avoid writing out entry points defined by a prior extension. 3728 for dupe in clxml.ext_dupes[extension_name]: 3729 msg = "// %s is already defined.\n" % strip_api_prefix(dupe) 3730 cl_defs.append(msg) 3731 3732 cl_decls.append("} // namespace cl") 3733 cl_defs.append("} // namespace cl") 3734 3735 write_file("cl", "CL", TEMPLATE_ENTRY_POINT_HEADER, "\n".join(cl_decls), "h", 3736 LIBCL_HEADER_INCLUDES, "libGLESv2", "cl.xml") 3737 write_file("cl", "CL", TEMPLATE_ENTRY_POINT_SOURCE, "\n".join(cl_defs), "cpp", 3738 LIBCL_SOURCE_INCLUDES, "libGLESv2", "cl.xml") 3739 write_validation_header("CL", "CL", cl_validation_protos, "cl.xml", 3740 TEMPLATE_CL_VALIDATION_HEADER) 3741 write_stubs_header("CL", "cl", "CL", "cl.xml", CL_STUBS_HEADER_PATH, clxml.all_commands, 3742 cl_commands, CLEntryPoints.get_packed_enums(), CL_PACKED_TYPES) 3743 3744 # EGL 3745 eglxml = registry_xml.RegistryXML('egl.xml', 'egl_angle_ext.xml') 3746 3747 egl_validation_protos = [] 3748 egl_context_lock_protos = [] 3749 egl_decls = ["extern \"C\" {"] 3750 egl_defs = ["extern \"C\" {"] 3751 libegl_ep_defs = [] 3752 libegl_windows_def_exports = [] 3753 egl_commands = [] 3754 egl_capture_protos = [] 3755 egl_capture_methods = [] 3756 3757 for major_version, minor_version in registry_xml.EGL_VERSIONS: 3758 version = "%d_%d" % (major_version, minor_version) 3759 annotation = "EGL_%s" % version 3760 name_prefix = "EGL_VERSION_" 3761 3762 comment = version.replace("_", ".") 3763 feature_name = "%s%s" % (name_prefix, version) 3764 3765 eglxml.AddCommands(feature_name, version) 3766 3767 egl_version_commands = eglxml.commands[version] 3768 egl_commands += egl_version_commands 3769 3770 # Spec revs may have no new commands. 3771 if not egl_version_commands: 3772 continue 3773 3774 eps = EGLEntryPoints(eglxml, egl_version_commands) 3775 3776 comment = "\n// EGL %d.%d" % (major_version, minor_version) 3777 win_def_comment = "\n ; EGL %d.%d" % (major_version, minor_version) 3778 3779 egl_decls += [comment] + eps.decls 3780 egl_defs += [comment] + eps.defs 3781 libegl_ep_defs += [comment] + eps.export_defs 3782 egl_validation_protos += [comment] + eps.validation_protos 3783 egl_context_lock_protos += [comment] + eps.context_lock_protos 3784 libegl_windows_def_exports += [win_def_comment] + get_exports(eglxml.commands[version]) 3785 egl_capture_protos += eps.capture_protos 3786 egl_capture_methods += eps.capture_methods 3787 3788 egl_decls.append("} // extern \"C\"") 3789 egl_defs.append("} // extern \"C\"") 3790 3791 write_file("egl", "EGL", TEMPLATE_ENTRY_POINT_HEADER, "\n".join(egl_decls), "h", 3792 EGL_HEADER_INCLUDES, "libGLESv2", "egl.xml") 3793 write_file("egl", "EGL", TEMPLATE_ENTRY_POINT_SOURCE, "\n".join(egl_defs), "cpp", 3794 EGL_SOURCE_INCLUDES, "libGLESv2", "egl.xml") 3795 write_stubs_header("EGL", "egl", "EGL", "egl.xml", EGL_STUBS_HEADER_PATH, eglxml.all_commands, 3796 egl_commands, EGLEntryPoints.get_packed_enums(), EGL_PACKED_TYPES) 3797 3798 eglxml.AddExtensionCommands(registry_xml.supported_egl_extensions, ['egl']) 3799 egl_ext_decls = ["extern \"C\" {"] 3800 egl_ext_defs = ["extern \"C\" {"] 3801 egl_ext_commands = [] 3802 3803 for extension_name, ext_cmd_names in sorted(eglxml.ext_data.items()): 3804 3805 # Extensions may have no new commands. 3806 if not ext_cmd_names: 3807 continue 3808 3809 # Detect and filter duplicate extensions. 3810 eps = EGLEntryPoints(eglxml, ext_cmd_names) 3811 3812 comment = "\n// %s" % extension_name 3813 win_def_comment = "\n ; %s" % (extension_name) 3814 3815 egl_ext_commands += ext_cmd_names 3816 3817 egl_ext_decls += [comment] + eps.decls 3818 egl_ext_defs += [comment] + eps.defs 3819 libegl_ep_defs += [comment] + eps.export_defs 3820 egl_validation_protos += [comment] + eps.validation_protos 3821 egl_context_lock_protos += [comment] + eps.context_lock_protos 3822 libegl_windows_def_exports += [win_def_comment] + get_exports(ext_cmd_names) 3823 egl_capture_protos += eps.capture_protos 3824 egl_capture_methods += eps.capture_methods 3825 3826 # Avoid writing out entry points defined by a prior extension. 3827 for dupe in eglxml.ext_dupes[extension_name]: 3828 msg = "// %s is already defined.\n" % strip_api_prefix(dupe) 3829 egl_ext_defs.append(msg) 3830 3831 egl_ext_decls.append("} // extern \"C\"") 3832 egl_ext_defs.append("} // extern \"C\"") 3833 3834 write_file("egl_ext", "EGL Extension", TEMPLATE_ENTRY_POINT_HEADER, "\n".join(egl_ext_decls), 3835 "h", EGL_EXT_HEADER_INCLUDES, "libGLESv2", "egl.xml and egl_angle_ext.xml") 3836 write_file("egl_ext", "EGL Extension", TEMPLATE_ENTRY_POINT_SOURCE, "\n".join(egl_ext_defs), 3837 "cpp", EGL_EXT_SOURCE_INCLUDES, "libGLESv2", "egl.xml and egl_angle_ext.xml") 3838 write_validation_header("EGL", "EGL", egl_validation_protos, "egl.xml and egl_angle_ext.xml", 3839 TEMPLATE_EGL_VALIDATION_HEADER) 3840 write_context_lock_header("EGL", "EGL", egl_context_lock_protos, 3841 "egl.xml and egl_angle_ext.xml", TEMPLATE_EGL_CONTEXT_LOCK_HEADER) 3842 write_stubs_header("EGL", "egl_ext", "EXT extension", "egl.xml and egl_angle_ext.xml", 3843 EGL_EXT_STUBS_HEADER_PATH, eglxml.all_commands, egl_ext_commands, 3844 EGLEntryPoints.get_packed_enums(), EGL_PACKED_TYPES) 3845 3846 write_capture_header(apis.EGL, 'egl', 'EGL', egl_capture_protos, []) 3847 write_capture_source(apis.EGL, 'egl', 'EGL', 'all', egl_capture_methods) 3848 3849 wglxml = registry_xml.RegistryXML('wgl.xml') 3850 3851 name_prefix = "WGL_VERSION_" 3852 version = "1_0" 3853 comment = version.replace("_", ".") 3854 feature_name = "{}{}".format(name_prefix, version) 3855 wglxml.AddCommands(feature_name, version) 3856 wgl_commands = wglxml.commands[version] 3857 3858 3859 # Other versions of these functions are used 3860 wgl_commands.remove("wglUseFontBitmaps") 3861 wgl_commands.remove("wglUseFontOutlines") 3862 3863 # Formatting for outputting to def file 3864 wgl_commands = [cmd if cmd.startswith('wgl') else 'wgl' + cmd for cmd in wgl_commands] 3865 wgl_commands = ['\n ; WGL 1.0'] + [' {}'.format(cmd) for cmd in wgl_commands] 3866 3867 extension_decls.append("} // extern \"C\"") 3868 extension_defs.append("} // extern \"C\"") 3869 3870 write_file("gles_ext", "GLES extension", TEMPLATE_ENTRY_POINT_HEADER, 3871 "\n".join([item for item in extension_decls]), "h", GLES_EXT_HEADER_INCLUDES, 3872 "libGLESv2", "gl.xml and gl_angle_ext.xml") 3873 write_file("gles_ext", "GLES extension", TEMPLATE_ENTRY_POINT_SOURCE, 3874 "\n".join([item for item in extension_defs]), "cpp", GLES_EXT_SOURCE_INCLUDES, 3875 "libGLESv2", "gl.xml and gl_angle_ext.xml") 3876 3877 write_gl_validation_header("ESEXT", "ES extension", ext_validation_protos, 3878 "gl.xml and gl_angle_ext.xml") 3879 write_capture_header(apis.GLES, "gles_ext", "extension", ext_capture_protos, 3880 ext_capture_pointer_funcs) 3881 write_capture_source(apis.GLES, "gles_ext", "ESEXT", "extension", ext_capture_methods) 3882 3883 write_context_api_decls(glesdecls, "gles") 3884 write_context_api_decls(desktop_gl_decls, "gl") 3885 3886 # Entry point enum 3887 unsorted_enums = clxml.GetEnums() + eglxml.GetEnums() + xml.GetEnums() + glxml.GetEnums( 3888 ) + wglxml.GetEnums('wgl') 3889 all_enums = [('Invalid', 'Invalid')] + sorted(list(set(unsorted_enums))) 3890 3891 entry_points_enum_header = TEMPLATE_ENTRY_POINTS_ENUM_HEADER.format( 3892 script_name=os.path.basename(sys.argv[0]), 3893 data_source_name="gl.xml and gl_angle_ext.xml", 3894 lib="GL/GLES", 3895 entry_points_list=",\n".join([" " + enum for (enum, _) in all_enums])) 3896 3897 entry_points_enum_header_path = path_to("common", "entry_points_enum_autogen.h") 3898 with open(entry_points_enum_header_path, "w") as out: 3899 out.write(entry_points_enum_header) 3900 out.close() 3901 3902 entry_points_cases = [ 3903 TEMPLATE_ENTRY_POINTS_NAME_CASE.format(enum=enum, cmd=cmd) for (enum, cmd) in all_enums 3904 ] 3905 entry_points_enum_source = TEMPLATE_ENTRY_POINTS_ENUM_SOURCE.format( 3906 script_name=os.path.basename(sys.argv[0]), 3907 data_source_name="gl.xml and gl_angle_ext.xml", 3908 lib="GL/GLES", 3909 entry_points_name_cases="\n".join(entry_points_cases)) 3910 3911 entry_points_enum_source_path = path_to("common", "entry_points_enum_autogen.cpp") 3912 with open(entry_points_enum_source_path, "w") as out: 3913 out.write(entry_points_enum_source) 3914 out.close() 3915 3916 write_export_files("\n".join([item for item in libgles_ep_defs]), LIBGLESV2_EXPORT_INCLUDES, 3917 "gl.xml and gl_angle_ext.xml", "libGLESv2", "OpenGL ES") 3918 write_export_files("\n".join([item for item in libegl_ep_defs]), 3919 LIBEGL_EXPORT_INCLUDES_AND_PREAMBLE, "egl.xml and egl_angle_ext.xml", 3920 "libEGL", "EGL") 3921 write_export_files("\n".join([item for item in libcl_ep_defs]), LIBCL_EXPORT_INCLUDES, 3922 "cl.xml", "libOpenCL", "CL") 3923 3924 libgles_ep_exports += get_egl_exports() 3925 3926 everything = "Khronos and ANGLE XML files" 3927 3928 for lib in [ 3929 "libGLESv2" + suffix 3930 for suffix in ["", "_no_capture", "_with_capture", "_vulkan_secondaries"] 3931 ]: 3932 write_windows_def_file(everything, lib, lib, "libGLESv2", libgles_ep_exports) 3933 3934 write_windows_def_file(everything, "opengl32_with_wgl", "opengl32", "libGLESv2", 3935 libgl_ep_exports + sorted(wgl_commands)) 3936 write_windows_def_file(everything, "opengl32", "opengl32", "libGLESv2", libgl_ep_exports) 3937 3938 for lib in ["libEGL" + suffix for suffix in ["", "_vulkan_secondaries"]]: 3939 write_windows_def_file("egl.xml and egl_angle_ext.xml", lib, lib, "libEGL", 3940 libegl_windows_def_exports) 3941 3942 all_gles_param_types = sorted(GLEntryPoints.all_param_types) 3943 all_egl_param_types = sorted(EGLEntryPoints.all_param_types) 3944 resource_id_types = get_resource_id_types(GLEntryPoints.all_param_types) 3945 # Get a sorted list of param types without duplicates 3946 all_param_types = sorted(list(set(all_gles_param_types + all_egl_param_types))) 3947 write_capture_helper_header(all_param_types) 3948 write_capture_helper_source(all_param_types) 3949 write_capture_replay_source(xml.all_commands, all_commands_with_suffix, 3950 GLEntryPoints.get_packed_enums(), eglxml.all_commands, 3951 egl_commands, EGLEntryPoints.get_packed_enums(), resource_id_types) 3952 3953 3954if __name__ == '__main__': 3955 sys.exit(main()) 3956