1bf215546Sopenharmony_ci#!/usr/bin/env python3 2bf215546Sopenharmony_ci 3bf215546Sopenharmony_ci# (C) Copyright 2016, NVIDIA CORPORATION. 4bf215546Sopenharmony_ci# All Rights Reserved. 5bf215546Sopenharmony_ci# 6bf215546Sopenharmony_ci# Permission is hereby granted, free of charge, to any person obtaining a 7bf215546Sopenharmony_ci# copy of this software and associated documentation files (the "Software"), 8bf215546Sopenharmony_ci# to deal in the Software without restriction, including without limitation 9bf215546Sopenharmony_ci# on the rights to use, copy, modify, merge, publish, distribute, sub 10bf215546Sopenharmony_ci# license, and/or sell copies of the Software, and to permit persons to whom 11bf215546Sopenharmony_ci# the Software is furnished to do so, subject to the following conditions: 12bf215546Sopenharmony_ci# 13bf215546Sopenharmony_ci# The above copyright notice and this permission notice (including the next 14bf215546Sopenharmony_ci# paragraph) shall be included in all copies or substantial portions of the 15bf215546Sopenharmony_ci# Software. 16bf215546Sopenharmony_ci# 17bf215546Sopenharmony_ci# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18bf215546Sopenharmony_ci# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19bf215546Sopenharmony_ci# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 20bf215546Sopenharmony_ci# IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21bf215546Sopenharmony_ci# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22bf215546Sopenharmony_ci# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 23bf215546Sopenharmony_ci# IN THE SOFTWARE. 24bf215546Sopenharmony_ci# 25bf215546Sopenharmony_ci# Authors: 26bf215546Sopenharmony_ci# Kyle Brenneman <kbrenneman@nvidia.com> 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci""" 29bf215546Sopenharmony_ciGenerates dispatch functions for EGL. 30bf215546Sopenharmony_ci 31bf215546Sopenharmony_ciThe list of functions and arguments is read from the Khronos's XML files, with 32bf215546Sopenharmony_ciadditional information defined in the module eglFunctionList. 33bf215546Sopenharmony_ci""" 34bf215546Sopenharmony_ci 35bf215546Sopenharmony_ciimport argparse 36bf215546Sopenharmony_ciimport collections 37bf215546Sopenharmony_ciimport eglFunctionList 38bf215546Sopenharmony_ciimport sys 39bf215546Sopenharmony_ciimport textwrap 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_ciimport os 42bf215546Sopenharmony_ciNEWAPI = os.path.join(os.path.dirname(__file__), "..", "..", "mapi", "new") 43bf215546Sopenharmony_cisys.path.insert(0, NEWAPI) 44bf215546Sopenharmony_ciimport genCommon 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_cidef main(): 47bf215546Sopenharmony_ci parser = argparse.ArgumentParser() 48bf215546Sopenharmony_ci parser.add_argument("target", choices=("header", "source"), 49bf215546Sopenharmony_ci help="Whether to build the source or header file.") 50bf215546Sopenharmony_ci parser.add_argument("xml_files", nargs="+", help="The XML files with the EGL function lists.") 51bf215546Sopenharmony_ci 52bf215546Sopenharmony_ci args = parser.parse_args() 53bf215546Sopenharmony_ci 54bf215546Sopenharmony_ci xmlFunctions = genCommon.getFunctions(args.xml_files) 55bf215546Sopenharmony_ci xmlByName = dict((f.name, f) for f in xmlFunctions) 56bf215546Sopenharmony_ci functions = [] 57bf215546Sopenharmony_ci for (name, eglFunc) in eglFunctionList.EGL_FUNCTIONS: 58bf215546Sopenharmony_ci func = xmlByName[name] 59bf215546Sopenharmony_ci eglFunc = fixupEglFunc(func, eglFunc) 60bf215546Sopenharmony_ci functions.append((func, eglFunc)) 61bf215546Sopenharmony_ci 62bf215546Sopenharmony_ci # Sort the function list by name. 63bf215546Sopenharmony_ci functions = sorted(functions, key=lambda f: f[0].name) 64bf215546Sopenharmony_ci 65bf215546Sopenharmony_ci if args.target == "header": 66bf215546Sopenharmony_ci text = generateHeader(functions) 67bf215546Sopenharmony_ci elif args.target == "source": 68bf215546Sopenharmony_ci text = generateSource(functions) 69bf215546Sopenharmony_ci sys.stdout.write(text) 70bf215546Sopenharmony_ci 71bf215546Sopenharmony_cidef fixupEglFunc(func, eglFunc): 72bf215546Sopenharmony_ci result = dict(eglFunc) 73bf215546Sopenharmony_ci if result.get("prefix") is None: 74bf215546Sopenharmony_ci result["prefix"] = "" 75bf215546Sopenharmony_ci 76bf215546Sopenharmony_ci if result.get("extension") is not None: 77bf215546Sopenharmony_ci text = "defined(" + result["extension"] + ")" 78bf215546Sopenharmony_ci result["extension"] = text 79bf215546Sopenharmony_ci 80bf215546Sopenharmony_ci if result["method"] in ("none", "custom"): 81bf215546Sopenharmony_ci return result 82bf215546Sopenharmony_ci 83bf215546Sopenharmony_ci if result["method"] not in ("display", "device", "current"): 84bf215546Sopenharmony_ci raise ValueError("Invalid dispatch method %r for function %r" % (result["method"], func.name)) 85bf215546Sopenharmony_ci 86bf215546Sopenharmony_ci if func.hasReturn(): 87bf215546Sopenharmony_ci if result.get("retval") is None: 88bf215546Sopenharmony_ci result["retval"] = getDefaultReturnValue(func.rt) 89bf215546Sopenharmony_ci 90bf215546Sopenharmony_ci return result 91bf215546Sopenharmony_ci 92bf215546Sopenharmony_cidef generateHeader(functions): 93bf215546Sopenharmony_ci text = textwrap.dedent(r""" 94bf215546Sopenharmony_ci #ifndef G_EGLDISPATCH_STUBS_H 95bf215546Sopenharmony_ci #define G_EGLDISPATCH_STUBS_H 96bf215546Sopenharmony_ci 97bf215546Sopenharmony_ci #ifdef __cplusplus 98bf215546Sopenharmony_ci extern "C" { 99bf215546Sopenharmony_ci #endif 100bf215546Sopenharmony_ci 101bf215546Sopenharmony_ci #include <EGL/egl.h> 102bf215546Sopenharmony_ci #include <EGL/eglext.h> 103bf215546Sopenharmony_ci #include <EGL/eglmesaext.h> 104bf215546Sopenharmony_ci #include <EGL/eglextchromium.h> 105bf215546Sopenharmony_ci #include "glvnd/libeglabi.h" 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_ci """.lstrip("\n")) 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_ci text += "enum {\n" 110bf215546Sopenharmony_ci for (func, eglFunc) in functions: 111bf215546Sopenharmony_ci text += generateGuardBegin(func, eglFunc) 112bf215546Sopenharmony_ci text += " __EGL_DISPATCH_" + func.name + ",\n" 113bf215546Sopenharmony_ci text += generateGuardEnd(func, eglFunc) 114bf215546Sopenharmony_ci text += " __EGL_DISPATCH_COUNT\n" 115bf215546Sopenharmony_ci text += "};\n" 116bf215546Sopenharmony_ci 117bf215546Sopenharmony_ci for (func, eglFunc) in functions: 118bf215546Sopenharmony_ci if eglFunc["inheader"]: 119bf215546Sopenharmony_ci text += generateGuardBegin(func, eglFunc) 120bf215546Sopenharmony_ci text += "{f.rt} EGLAPIENTRY {ex[prefix]}{f.name}({f.decArgs});\n".format(f=func, ex=eglFunc) 121bf215546Sopenharmony_ci text += generateGuardEnd(func, eglFunc) 122bf215546Sopenharmony_ci 123bf215546Sopenharmony_ci text += textwrap.dedent(r""" 124bf215546Sopenharmony_ci #ifdef __cplusplus 125bf215546Sopenharmony_ci } 126bf215546Sopenharmony_ci #endif 127bf215546Sopenharmony_ci #endif // G_EGLDISPATCH_STUBS_H 128bf215546Sopenharmony_ci """) 129bf215546Sopenharmony_ci return text 130bf215546Sopenharmony_ci 131bf215546Sopenharmony_cidef generateSource(functions): 132bf215546Sopenharmony_ci # First, sort the function list by name. 133bf215546Sopenharmony_ci text = "" 134bf215546Sopenharmony_ci text += '#include "egldispatchstubs.h"\n' 135bf215546Sopenharmony_ci text += '#include "g_egldispatchstubs.h"\n' 136bf215546Sopenharmony_ci text += '#include <stddef.h>\n' 137bf215546Sopenharmony_ci text += "\n" 138bf215546Sopenharmony_ci 139bf215546Sopenharmony_ci for (func, eglFunc) in functions: 140bf215546Sopenharmony_ci if eglFunc["method"] not in ("custom", "none"): 141bf215546Sopenharmony_ci text += generateGuardBegin(func, eglFunc) 142bf215546Sopenharmony_ci text += generateDispatchFunc(func, eglFunc) 143bf215546Sopenharmony_ci text += generateGuardEnd(func, eglFunc) 144bf215546Sopenharmony_ci 145bf215546Sopenharmony_ci text += "\n" 146bf215546Sopenharmony_ci text += "const char * const __EGL_DISPATCH_FUNC_NAMES[__EGL_DISPATCH_COUNT + 1] = {\n" 147bf215546Sopenharmony_ci for (func, eglFunc) in functions: 148bf215546Sopenharmony_ci text += generateGuardBegin(func, eglFunc) 149bf215546Sopenharmony_ci text += ' "' + func.name + '",\n' 150bf215546Sopenharmony_ci text += generateGuardEnd(func, eglFunc) 151bf215546Sopenharmony_ci text += " NULL\n" 152bf215546Sopenharmony_ci text += "};\n" 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_ci text += "const __eglMustCastToProperFunctionPointerType __EGL_DISPATCH_FUNCS[__EGL_DISPATCH_COUNT + 1] = {\n" 155bf215546Sopenharmony_ci for (func, eglFunc) in functions: 156bf215546Sopenharmony_ci text += generateGuardBegin(func, eglFunc) 157bf215546Sopenharmony_ci if eglFunc["method"] != "none": 158bf215546Sopenharmony_ci text += " (__eglMustCastToProperFunctionPointerType) " + eglFunc.get("prefix", "") + func.name + ",\n" 159bf215546Sopenharmony_ci else: 160bf215546Sopenharmony_ci text += " NULL, // " + func.name + "\n" 161bf215546Sopenharmony_ci text += generateGuardEnd(func, eglFunc) 162bf215546Sopenharmony_ci text += " NULL\n" 163bf215546Sopenharmony_ci text += "};\n" 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_ci return text 166bf215546Sopenharmony_ci 167bf215546Sopenharmony_cidef generateGuardBegin(func, eglFunc): 168bf215546Sopenharmony_ci ext = eglFunc.get("extension") 169bf215546Sopenharmony_ci if ext is not None: 170bf215546Sopenharmony_ci return "#if " + ext + "\n" 171bf215546Sopenharmony_ci else: 172bf215546Sopenharmony_ci return "" 173bf215546Sopenharmony_ci 174bf215546Sopenharmony_cidef generateGuardEnd(func, eglFunc): 175bf215546Sopenharmony_ci if eglFunc.get("extension") is not None: 176bf215546Sopenharmony_ci return "#endif\n" 177bf215546Sopenharmony_ci else: 178bf215546Sopenharmony_ci return "" 179bf215546Sopenharmony_ci 180bf215546Sopenharmony_cidef generateDispatchFunc(func, eglFunc): 181bf215546Sopenharmony_ci text = "" 182bf215546Sopenharmony_ci 183bf215546Sopenharmony_ci if eglFunc.get("static"): 184bf215546Sopenharmony_ci text += "static " 185bf215546Sopenharmony_ci elif eglFunc.get("public"): 186bf215546Sopenharmony_ci text += "PUBLIC " 187bf215546Sopenharmony_ci text += textwrap.dedent( 188bf215546Sopenharmony_ci r""" 189bf215546Sopenharmony_ci {f.rt} EGLAPIENTRY {ef[prefix]}{f.name}({f.decArgs}) 190bf215546Sopenharmony_ci {{ 191bf215546Sopenharmony_ci typedef {f.rt} EGLAPIENTRY (* _pfn_{f.name})({f.decArgs}); 192bf215546Sopenharmony_ci """).lstrip("\n").format(f=func, ef=eglFunc) 193bf215546Sopenharmony_ci 194bf215546Sopenharmony_ci if func.hasReturn(): 195bf215546Sopenharmony_ci text += " {f.rt} _ret = {ef[retval]};\n".format(f=func, ef=eglFunc) 196bf215546Sopenharmony_ci 197bf215546Sopenharmony_ci text += " _pfn_{f.name} _ptr_{f.name} = (_pfn_{f.name}) ".format(f=func) 198bf215546Sopenharmony_ci if eglFunc["method"] == "current": 199bf215546Sopenharmony_ci text += "__eglDispatchFetchByCurrent(__EGL_DISPATCH_{f.name});\n".format(f=func) 200bf215546Sopenharmony_ci 201bf215546Sopenharmony_ci elif eglFunc["method"] in ("display", "device"): 202bf215546Sopenharmony_ci if eglFunc["method"] == "display": 203bf215546Sopenharmony_ci lookupFunc = "__eglDispatchFetchByDisplay" 204bf215546Sopenharmony_ci lookupType = "EGLDisplay" 205bf215546Sopenharmony_ci else: 206bf215546Sopenharmony_ci assert eglFunc["method"] == "device" 207bf215546Sopenharmony_ci lookupFunc = "__eglDispatchFetchByDevice" 208bf215546Sopenharmony_ci lookupType = "EGLDeviceEXT" 209bf215546Sopenharmony_ci 210bf215546Sopenharmony_ci lookupArg = None 211bf215546Sopenharmony_ci for arg in func.args: 212bf215546Sopenharmony_ci if arg.type == lookupType: 213bf215546Sopenharmony_ci lookupArg = arg.name 214bf215546Sopenharmony_ci break 215bf215546Sopenharmony_ci if lookupArg is None: 216bf215546Sopenharmony_ci raise ValueError("Can't find %s argument for function %s" % (lookupType, func.name,)) 217bf215546Sopenharmony_ci 218bf215546Sopenharmony_ci text += "{lookupFunc}({lookupArg}, __EGL_DISPATCH_{f.name});\n".format( 219bf215546Sopenharmony_ci f=func, lookupFunc=lookupFunc, lookupArg=lookupArg) 220bf215546Sopenharmony_ci else: 221bf215546Sopenharmony_ci raise ValueError("Unknown dispatch method: %r" % (eglFunc["method"],)) 222bf215546Sopenharmony_ci 223bf215546Sopenharmony_ci text += " if(_ptr_{f.name} != NULL) {{\n".format(f=func) 224bf215546Sopenharmony_ci text += " " 225bf215546Sopenharmony_ci if func.hasReturn(): 226bf215546Sopenharmony_ci text += "_ret = " 227bf215546Sopenharmony_ci text += "_ptr_{f.name}({f.callArgs});\n".format(f=func) 228bf215546Sopenharmony_ci text += " }\n" 229bf215546Sopenharmony_ci 230bf215546Sopenharmony_ci if func.hasReturn(): 231bf215546Sopenharmony_ci text += " return _ret;\n" 232bf215546Sopenharmony_ci text += "}\n" 233bf215546Sopenharmony_ci return text 234bf215546Sopenharmony_ci 235bf215546Sopenharmony_cidef getDefaultReturnValue(typename): 236bf215546Sopenharmony_ci if typename.endswith("*"): 237bf215546Sopenharmony_ci return "NULL" 238bf215546Sopenharmony_ci elif typename == "EGLDisplay": 239bf215546Sopenharmony_ci return "EGL_NO_DISPLAY" 240bf215546Sopenharmony_ci elif typename == "EGLContext": 241bf215546Sopenharmony_ci return "EGL_NO_CONTEXT" 242bf215546Sopenharmony_ci elif typename == "EGLSurface": 243bf215546Sopenharmony_ci return "EGL_NO_SURFACE" 244bf215546Sopenharmony_ci elif typename == "EGLBoolean": 245bf215546Sopenharmony_ci return "EGL_FALSE"; 246bf215546Sopenharmony_ci 247bf215546Sopenharmony_ci return "0" 248bf215546Sopenharmony_ci 249bf215546Sopenharmony_ciif __name__ == "__main__": 250bf215546Sopenharmony_ci main() 251bf215546Sopenharmony_ci 252