eeb3f3f9a5a2051b958598c1c699455075b424df
3 # (C) Copyright 2016, NVIDIA CORPORATION.
6 # Permission is hereby granted, free of charge, to any person obtaining a
7 # copy of this software and associated documentation files (the "Software"),
8 # to deal in the Software without restriction, including without limitation
9 # on the rights to use, copy, modify, merge, publish, distribute, sub
10 # license, and/or sell copies of the Software, and to permit persons to whom
11 # the Software is furnished to do so, subject to the following conditions:
13 # The above copyright notice and this permission notice (including the next
14 # paragraph) shall be included in all copies or substantial portions of the
17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 # FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
20 # IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
26 # Kyle Brenneman <kbrenneman@nvidia.com>
29 Generates dispatch functions for EGL.
31 The list of functions and arguments is read from the Khronos's XML files, with
32 additional information defined in the module eglFunctionList.
44 parser
= argparse
.ArgumentParser()
45 parser
.add_argument("target", choices
=("header", "source"),
46 help="Whether to build the source or header file.")
47 parser
.add_argument("func_list_file", help="The function list .py file.")
48 parser
.add_argument("xml_files", nargs
="+", help="The XML files with the EGL function lists.")
50 args
= parser
.parse_args()
52 # The function list is a Python module, but it's specified on the command
54 eglFunctionList
= imp
.load_source("eglFunctionList", args
.func_list_file
)
56 xmlFunctions
= genCommon
.getFunctions(args
.xml_files
)
57 xmlByName
= dict((f
.name
, f
) for f
in xmlFunctions
)
59 for (name
, eglFunc
) in eglFunctionList
.EGL_FUNCTIONS
:
60 func
= xmlByName
[name
]
61 eglFunc
= fixupEglFunc(func
, eglFunc
)
62 functions
.append((func
, eglFunc
))
64 # Sort the function list by name.
65 functions
= sorted(functions
, key
=lambda f
: f
[0].name
)
67 if args
.target
== "header":
68 text
= generateHeader(functions
)
69 elif args
.target
== "source":
70 text
= generateSource(functions
)
71 sys
.stdout
.write(text
)
73 def fixupEglFunc(func
, eglFunc
):
74 result
= dict(eglFunc
)
75 if result
.get("prefix") is None:
78 if result
.get("extension") is not None:
79 text
= "defined(" + result
["extension"] + ")"
80 result
["extension"] = text
82 if result
["method"] in ("none", "custom"):
85 if result
["method"] not in ("display", "device", "current"):
86 raise ValueError("Invalid dispatch method %r for function %r" % (result
["method"], func
.name
))
89 if result
.get("retval") is None:
90 result
["retval"] = getDefaultReturnValue(func
.rt
)
94 def generateHeader(functions
):
95 text
= textwrap
.dedent(r
"""
96 #ifndef G_EGLDISPATCH_STUBS_H
97 #define G_EGLDISPATCH_STUBS_H
104 #include <EGL/eglext.h>
105 #include "glvnd/libeglabi.h"
110 for (func
, eglFunc
) in functions
:
111 text
+= generateGuardBegin(func
, eglFunc
)
112 text
+= " __EGL_DISPATCH_" + func
.name
+ ",\n"
113 text
+= generateGuardEnd(func
, eglFunc
)
114 text
+= " __EGL_DISPATCH_COUNT\n"
117 for (func
, eglFunc
) in functions
:
118 if eglFunc
["inheader"]:
119 text
+= generateGuardBegin(func
, eglFunc
)
120 text
+= "{f.rt} EGLAPIENTRY {ex[prefix]}{f.name}({f.decArgs});\n".format(f
=func
, ex
=eglFunc
)
121 text
+= generateGuardEnd(func
, eglFunc
)
123 text
+= textwrap
.dedent(r
"""
127 #endif // G_EGLDISPATCH_STUBS_H
131 def generateSource(functions
):
132 # First, sort the function list by name.
134 text
+= '#include "egldispatchstubs.h"\n'
135 text
+= '#include "g_egldispatchstubs.h"\n'
138 for (func
, eglFunc
) in functions
:
139 if eglFunc
["method"] not in ("custom", "none"):
140 text
+= generateGuardBegin(func
, eglFunc
)
141 text
+= generateDispatchFunc(func
, eglFunc
)
142 text
+= generateGuardEnd(func
, eglFunc
)
145 text
+= "const char * const __EGL_DISPATCH_FUNC_NAMES[__EGL_DISPATCH_COUNT + 1] = {\n"
146 for (func
, eglFunc
) in functions
:
147 text
+= generateGuardBegin(func
, eglFunc
)
148 text
+= ' "' + func
.name
+ '",\n'
149 text
+= generateGuardEnd(func
, eglFunc
)
153 text
+= "const __eglMustCastToProperFunctionPointerType __EGL_DISPATCH_FUNCS[__EGL_DISPATCH_COUNT + 1] = {\n"
154 for (func
, eglFunc
) in functions
:
155 text
+= generateGuardBegin(func
, eglFunc
)
156 if eglFunc
["method"] != "none":
157 text
+= " (__eglMustCastToProperFunctionPointerType) " + eglFunc
.get("prefix", "") + func
.name
+ ",\n"
159 text
+= " NULL, // " + func
.name
+ "\n"
160 text
+= generateGuardEnd(func
, eglFunc
)
166 def generateGuardBegin(func
, eglFunc
):
167 ext
= eglFunc
.get("extension")
169 return "#if " + ext
+ "\n"
173 def generateGuardEnd(func
, eglFunc
):
174 if eglFunc
.get("extension") is not None:
179 def generateDispatchFunc(func
, eglFunc
):
182 if eglFunc
.get("static"):
184 elif eglFunc
.get("public"):
186 text
+= textwrap
.dedent(
188 {f.rt} EGLAPIENTRY {ef[prefix]}{f.name}({f.decArgs})
190 typedef {f.rt} EGLAPIENTRY (* _pfn_{f.name})({f.decArgs});
191 """).lstrip("\n").format(f
=func
, ef
=eglFunc
)
194 text
+= " {f.rt} _ret = {ef[retval]};\n".format(f
=func
, ef
=eglFunc
)
196 text
+= " _pfn_{f.name} _ptr_{f.name} = (_pfn_{f.name}) ".format(f
=func
)
197 if eglFunc
["method"] == "current":
198 text
+= "__eglDispatchFetchByCurrent(__EGL_DISPATCH_{f.name});\n".format(f
=func
)
200 elif eglFunc
["method"] in ("display", "device"):
201 if eglFunc
["method"] == "display":
202 lookupFunc
= "__eglDispatchFetchByDisplay"
203 lookupType
= "EGLDisplay"
205 assert eglFunc
["method"] == "device"
206 lookupFunc
= "__eglDispatchFetchByDevice"
207 lookupType
= "EGLDeviceEXT"
210 for arg
in func
.args
:
211 if arg
.type == lookupType
:
214 if lookupArg
is None:
215 raise ValueError("Can't find %s argument for function %s" % (lookupType
, func
.name
,))
217 text
+= "{lookupFunc}({lookupArg}, __EGL_DISPATCH_{f.name});\n".format(
218 f
=func
, lookupFunc
=lookupFunc
, lookupArg
=lookupArg
)
220 raise ValueError("Unknown dispatch method: %r" % (eglFunc
["method"],))
222 text
+= " if(_ptr_{f.name} != NULL) {{\n".format(f
=func
)
226 text
+= "_ptr_{f.name}({f.callArgs});\n".format(f
=func
)
230 text
+= " return _ret;\n"
234 def getDefaultReturnValue(typename
):
235 if typename
.endswith("*"):
237 elif typename
== "EGLDisplay":
238 return "EGL_NO_DISPLAY"
239 elif typename
== "EGLContext":
240 return "EGL_NO_CONTEXT"
241 elif typename
== "EGLSurface":
242 return "EGL_NO_SURFACE"
243 elif typename
== "EGLBoolean":
248 if __name__
== "__main__":