|
Packit Service |
38f978 |
#!/usr/bin/env python3
|
|
Packit |
5af8b3 |
|
|
Packit |
5af8b3 |
"""
|
|
Packit |
5af8b3 |
Generates dispatch functions for EGL.
|
|
Packit |
5af8b3 |
|
|
Packit |
5af8b3 |
The list of functions and arguments is read from the Khronos's XML files, with
|
|
Packit |
5af8b3 |
additional information defined in the module eglFunctionList.
|
|
Packit |
5af8b3 |
"""
|
|
Packit |
5af8b3 |
|
|
Packit Service |
29ce97 |
import argparse
|
|
Packit |
5af8b3 |
import collections
|
|
Packit Service |
29ce97 |
import sys
|
|
Packit Service |
29ce97 |
import textwrap
|
|
Packit |
5af8b3 |
|
|
Packit Service |
29ce97 |
import eglFunctionList
|
|
Packit |
5af8b3 |
import genCommon
|
|
Packit |
5af8b3 |
|
|
Packit |
5af8b3 |
def main():
|
|
Packit Service |
29ce97 |
parser = argparse.ArgumentParser()
|
|
Packit Service |
29ce97 |
parser.add_argument("target", choices=("header", "source"),
|
|
Packit Service |
29ce97 |
help="Whether to build the source or header file.")
|
|
Packit Service |
29ce97 |
parser.add_argument("xml_files", nargs="+",
|
|
Packit Service |
29ce97 |
help="The XML files with the EGL function lists.")
|
|
Packit |
5af8b3 |
|
|
Packit Service |
29ce97 |
args = parser.parse_args()
|
|
Packit |
5af8b3 |
|
|
Packit Service |
29ce97 |
xmlFunctions = genCommon.getFunctions(args.xml_files)
|
|
Packit |
5af8b3 |
xmlByName = dict((f.name, f) for f in xmlFunctions)
|
|
Packit |
5af8b3 |
functions = []
|
|
Packit |
5af8b3 |
for (name, eglFunc) in eglFunctionList.EGL_FUNCTIONS:
|
|
Packit |
5af8b3 |
func = xmlByName[name]
|
|
Packit |
5af8b3 |
eglFunc = fixupEglFunc(func, eglFunc)
|
|
Packit |
5af8b3 |
functions.append((func, eglFunc))
|
|
Packit |
5af8b3 |
|
|
Packit |
5af8b3 |
# Sort the function list by name.
|
|
Packit |
5af8b3 |
functions = sorted(functions, key=lambda f: f[0].name)
|
|
Packit |
5af8b3 |
|
|
Packit Service |
29ce97 |
if args.target == "header":
|
|
Packit |
5af8b3 |
text = generateHeader(functions)
|
|
Packit Service |
29ce97 |
elif args.target == "source":
|
|
Packit |
5af8b3 |
text = generateSource(functions)
|
|
Packit |
5af8b3 |
sys.stdout.write(text)
|
|
Packit |
5af8b3 |
|
|
Packit |
5af8b3 |
def fixupEglFunc(func, eglFunc):
|
|
Packit |
5af8b3 |
result = dict(eglFunc)
|
|
Packit Service |
29ce97 |
if result.get("prefix") is None:
|
|
Packit |
5af8b3 |
result["prefix"] = ""
|
|
Packit |
5af8b3 |
|
|
Packit Service |
29ce97 |
if result.get("extension") is not None:
|
|
Packit |
5af8b3 |
text = "defined(" + result["extension"] + ")"
|
|
Packit |
5af8b3 |
result["extension"] = text
|
|
Packit |
5af8b3 |
|
|
Packit Service |
29ce97 |
if result["method"] in ("none", "custom"):
|
|
Packit |
5af8b3 |
return result
|
|
Packit |
5af8b3 |
|
|
Packit Service |
29ce97 |
if result["method"] not in ("display", "device", "current"):
|
|
Packit |
5af8b3 |
raise ValueError("Invalid dispatch method %r for function %r" % (result["method"], func.name))
|
|
Packit |
5af8b3 |
|
|
Packit Service |
29ce97 |
if func.hasReturn():
|
|
Packit Service |
29ce97 |
if result.get("retval") is None:
|
|
Packit |
5af8b3 |
result["retval"] = getDefaultReturnValue(func.rt)
|
|
Packit |
5af8b3 |
|
|
Packit |
5af8b3 |
return result
|
|
Packit |
5af8b3 |
|
|
Packit |
5af8b3 |
def generateHeader(functions):
|
|
Packit Service |
29ce97 |
text = textwrap.dedent(r"""
|
|
Packit Service |
29ce97 |
#ifndef G_EGLDISPATCH_STUBS_H
|
|
Packit Service |
29ce97 |
#define G_EGLDISPATCH_STUBS_H
|
|
Packit |
5af8b3 |
|
|
Packit Service |
29ce97 |
#ifdef __cplusplus
|
|
Packit Service |
29ce97 |
extern "C" {
|
|
Packit Service |
29ce97 |
#endif
|
|
Packit |
5af8b3 |
|
|
Packit Service |
29ce97 |
#include <EGL/egl.h>
|
|
Packit Service |
29ce97 |
#include <EGL/eglext.h>
|
|
Packit Service |
29ce97 |
#include "glvnd/libeglabi.h"
|
|
Packit |
5af8b3 |
|
|
Packit Service |
29ce97 |
""".lstrip("\n"))
|
|
Packit |
5af8b3 |
|
|
Packit |
5af8b3 |
text += "enum {\n"
|
|
Packit |
5af8b3 |
for (func, eglFunc) in functions:
|
|
Packit |
5af8b3 |
text += generateGuardBegin(func, eglFunc)
|
|
Packit |
5af8b3 |
text += " __EGL_DISPATCH_" + func.name + ",\n"
|
|
Packit |
5af8b3 |
text += generateGuardEnd(func, eglFunc)
|
|
Packit |
5af8b3 |
text += " __EGL_DISPATCH_COUNT\n"
|
|
Packit |
5af8b3 |
text += "};\n"
|
|
Packit |
5af8b3 |
|
|
Packit |
5af8b3 |
for (func, eglFunc) in functions:
|
|
Packit Service |
29ce97 |
if eglFunc["inheader"]:
|
|
Packit |
5af8b3 |
text += generateGuardBegin(func, eglFunc)
|
|
Packit |
5af8b3 |
text += "{f.rt} EGLAPIENTRY {ex[prefix]}{f.name}({f.decArgs});\n".format(f=func, ex=eglFunc)
|
|
Packit |
5af8b3 |
text += generateGuardEnd(func, eglFunc)
|
|
Packit |
5af8b3 |
|
|
Packit Service |
29ce97 |
text += textwrap.dedent(r"""
|
|
Packit Service |
29ce97 |
#ifdef __cplusplus
|
|
Packit Service |
29ce97 |
}
|
|
Packit Service |
29ce97 |
#endif
|
|
Packit Service |
29ce97 |
#endif // G_EGLDISPATCH_STUBS_H
|
|
Packit Service |
29ce97 |
""")
|
|
Packit |
5af8b3 |
return text
|
|
Packit |
5af8b3 |
|
|
Packit |
5af8b3 |
def generateSource(functions):
|
|
Packit |
5af8b3 |
# First, sort the function list by name.
|
|
Packit |
5af8b3 |
text = ""
|
|
Packit |
5af8b3 |
text += '#include "egldispatchstubs.h"\n'
|
|
Packit |
5af8b3 |
text += '#include "g_egldispatchstubs.h"\n'
|
|
Packit Service |
29ce97 |
text += '#include <stddef.h>\n'
|
|
Packit |
5af8b3 |
text += "\n"
|
|
Packit |
5af8b3 |
|
|
Packit |
5af8b3 |
for (func, eglFunc) in functions:
|
|
Packit Service |
29ce97 |
if eglFunc["method"] not in ("custom", "none"):
|
|
Packit |
5af8b3 |
text += generateGuardBegin(func, eglFunc)
|
|
Packit |
5af8b3 |
text += generateDispatchFunc(func, eglFunc)
|
|
Packit |
5af8b3 |
text += generateGuardEnd(func, eglFunc)
|
|
Packit |
5af8b3 |
|
|
Packit |
5af8b3 |
text += "\n"
|
|
Packit |
5af8b3 |
text += "const char * const __EGL_DISPATCH_FUNC_NAMES[__EGL_DISPATCH_COUNT + 1] = {\n"
|
|
Packit |
5af8b3 |
for (func, eglFunc) in functions:
|
|
Packit |
5af8b3 |
text += generateGuardBegin(func, eglFunc)
|
|
Packit |
5af8b3 |
text += ' "' + func.name + '",\n'
|
|
Packit |
5af8b3 |
text += generateGuardEnd(func, eglFunc)
|
|
Packit |
5af8b3 |
text += " NULL\n"
|
|
Packit |
5af8b3 |
text += "};\n"
|
|
Packit |
5af8b3 |
|
|
Packit |
5af8b3 |
text += "const __eglMustCastToProperFunctionPointerType __EGL_DISPATCH_FUNCS[__EGL_DISPATCH_COUNT + 1] = {\n"
|
|
Packit |
5af8b3 |
for (func, eglFunc) in functions:
|
|
Packit |
5af8b3 |
text += generateGuardBegin(func, eglFunc)
|
|
Packit Service |
29ce97 |
if eglFunc["method"] != "none":
|
|
Packit |
5af8b3 |
text += " (__eglMustCastToProperFunctionPointerType) " + eglFunc.get("prefix", "") + func.name + ",\n"
|
|
Packit |
5af8b3 |
else:
|
|
Packit |
5af8b3 |
text += " NULL, // " + func.name + "\n"
|
|
Packit |
5af8b3 |
text += generateGuardEnd(func, eglFunc)
|
|
Packit |
5af8b3 |
text += " NULL\n"
|
|
Packit |
5af8b3 |
text += "};\n"
|
|
Packit |
5af8b3 |
|
|
Packit |
5af8b3 |
return text
|
|
Packit |
5af8b3 |
|
|
Packit |
5af8b3 |
def generateGuardBegin(func, eglFunc):
|
|
Packit |
5af8b3 |
ext = eglFunc.get("extension")
|
|
Packit Service |
29ce97 |
if ext is not None:
|
|
Packit |
5af8b3 |
return "#if " + ext + "\n"
|
|
Packit |
5af8b3 |
else:
|
|
Packit |
5af8b3 |
return ""
|
|
Packit |
5af8b3 |
|
|
Packit |
5af8b3 |
def generateGuardEnd(func, eglFunc):
|
|
Packit Service |
29ce97 |
if eglFunc.get("extension") is not None:
|
|
Packit |
5af8b3 |
return "#endif\n"
|
|
Packit |
5af8b3 |
else:
|
|
Packit |
5af8b3 |
return ""
|
|
Packit |
5af8b3 |
|
|
Packit |
5af8b3 |
def generateDispatchFunc(func, eglFunc):
|
|
Packit |
5af8b3 |
text = ""
|
|
Packit |
5af8b3 |
|
|
Packit Service |
29ce97 |
if eglFunc.get("static"):
|
|
Packit |
5af8b3 |
text += "static "
|
|
Packit Service |
29ce97 |
elif eglFunc.get("public"):
|
|
Packit |
5af8b3 |
text += "PUBLIC "
|
|
Packit Service |
29ce97 |
text += textwrap.dedent(
|
|
Packit Service |
29ce97 |
r"""
|
|
Packit Service |
29ce97 |
{f.rt} EGLAPIENTRY {ef[prefix]}{f.name}({f.decArgs})
|
|
Packit Service |
29ce97 |
{{
|
|
Packit Service |
29ce97 |
typedef {f.rt} EGLAPIENTRY (* _pfn_{f.name})({f.decArgs});
|
|
Packit Service |
29ce97 |
""").lstrip("\n").format(f=func, ef=eglFunc)
|
|
Packit Service |
29ce97 |
|
|
Packit Service |
29ce97 |
if func.hasReturn():
|
|
Packit |
5af8b3 |
text += " {f.rt} _ret = {ef[retval]};\n".format(f=func, ef=eglFunc)
|
|
Packit |
5af8b3 |
|
|
Packit |
5af8b3 |
text += " _pfn_{f.name} _ptr_{f.name} = (_pfn_{f.name}) ".format(f=func)
|
|
Packit Service |
29ce97 |
if eglFunc["method"] == "current":
|
|
Packit |
5af8b3 |
text += "__eglDispatchFetchByCurrent(__EGL_DISPATCH_{f.name});\n".format(f=func)
|
|
Packit |
5af8b3 |
|
|
Packit Service |
29ce97 |
elif eglFunc["method"] in ("display", "device"):
|
|
Packit Service |
29ce97 |
if eglFunc["method"] == "display":
|
|
Packit |
5af8b3 |
lookupFunc = "__eglDispatchFetchByDisplay"
|
|
Packit |
5af8b3 |
lookupType = "EGLDisplay"
|
|
Packit |
5af8b3 |
else:
|
|
Packit Service |
29ce97 |
assert eglFunc["method"] == "device"
|
|
Packit |
5af8b3 |
lookupFunc = "__eglDispatchFetchByDevice"
|
|
Packit |
5af8b3 |
lookupType = "EGLDeviceEXT"
|
|
Packit |
5af8b3 |
|
|
Packit |
5af8b3 |
lookupArg = None
|
|
Packit |
5af8b3 |
for arg in func.args:
|
|
Packit Service |
29ce97 |
if arg.type == lookupType:
|
|
Packit |
5af8b3 |
lookupArg = arg.name
|
|
Packit |
5af8b3 |
break
|
|
Packit Service |
29ce97 |
if lookupArg is None:
|
|
Packit |
5af8b3 |
raise ValueError("Can't find %s argument for function %s" % (lookupType, func.name,))
|
|
Packit |
5af8b3 |
|
|
Packit |
5af8b3 |
text += "{lookupFunc}({lookupArg}, __EGL_DISPATCH_{f.name});\n".format(
|
|
Packit |
5af8b3 |
f=func, lookupFunc=lookupFunc, lookupArg=lookupArg)
|
|
Packit |
5af8b3 |
else:
|
|
Packit |
5af8b3 |
raise ValueError("Unknown dispatch method: %r" % (eglFunc["method"],))
|
|
Packit |
5af8b3 |
|
|
Packit |
5af8b3 |
text += " if(_ptr_{f.name} != NULL) {{\n".format(f=func)
|
|
Packit |
5af8b3 |
text += " "
|
|
Packit Service |
29ce97 |
if func.hasReturn():
|
|
Packit |
5af8b3 |
text += "_ret = "
|
|
Packit |
5af8b3 |
text += "_ptr_{f.name}({f.callArgs});\n".format(f=func)
|
|
Packit |
5af8b3 |
text += " }\n"
|
|
Packit |
5af8b3 |
|
|
Packit Service |
29ce97 |
if func.hasReturn():
|
|
Packit |
5af8b3 |
text += " return _ret;\n"
|
|
Packit |
5af8b3 |
text += "}\n"
|
|
Packit |
5af8b3 |
return text
|
|
Packit |
5af8b3 |
|
|
Packit |
5af8b3 |
def getDefaultReturnValue(typename):
|
|
Packit Service |
29ce97 |
if typename.endswith("*"):
|
|
Packit |
5af8b3 |
return "NULL"
|
|
Packit Service |
29ce97 |
elif typename == "EGLDisplay":
|
|
Packit |
5af8b3 |
return "EGL_NO_DISPLAY"
|
|
Packit Service |
29ce97 |
elif typename == "EGLContext":
|
|
Packit |
5af8b3 |
return "EGL_NO_CONTEXT"
|
|
Packit Service |
29ce97 |
elif typename == "EGLSurface":
|
|
Packit |
5af8b3 |
return "EGL_NO_SURFACE"
|
|
Packit Service |
29ce97 |
elif typename == "EGLBoolean":
|
|
Packit |
5af8b3 |
return "EGL_FALSE";
|
|
Packit |
5af8b3 |
|
|
Packit |
5af8b3 |
return "0"
|
|
Packit |
5af8b3 |
|
|
Packit Service |
29ce97 |
if __name__ == "__main__":
|
|
Packit |
5af8b3 |
main()
|
|
Packit |
5af8b3 |
|