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