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