"Fossies" - the Fresh Open Source Software Archive

Member "mesa-20.1.8/src/egl/generate/gen_egl_dispatch.py" (16 Sep 2020, 8207 Bytes) of package /linux/misc/mesa-20.1.8.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "gen_egl_dispatch.py" see the Fossies "Dox" file reference documentation.

    1 #!/usr/bin/env python
    2 
    3 # (C) Copyright 2016, NVIDIA CORPORATION.
    4 # All Rights Reserved.
    5 #
    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:
   12 #
   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
   15 # Software.
   16 #
   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
   23 # IN THE SOFTWARE.
   24 #
   25 # Authors:
   26 #    Kyle Brenneman <kbrenneman@nvidia.com>
   27 
   28 """
   29 Generates dispatch functions for EGL.
   30 
   31 The list of functions and arguments is read from the Khronos's XML files, with
   32 additional information defined in the module eglFunctionList.
   33 """
   34 
   35 import argparse
   36 import collections
   37 import eglFunctionList
   38 import sys
   39 import textwrap
   40 
   41 import os
   42 NEWAPI = os.path.join(os.path.dirname(__file__), "..", "..", "mapi", "new")
   43 sys.path.insert(0, NEWAPI)
   44 import genCommon
   45 
   46 def main():
   47     parser = argparse.ArgumentParser()
   48     parser.add_argument("target", choices=("header", "source"),
   49             help="Whether to build the source or header file.")
   50     parser.add_argument("xml_files", nargs="+", help="The XML files with the EGL function lists.")
   51 
   52     args = parser.parse_args()
   53 
   54     xmlFunctions = genCommon.getFunctions(args.xml_files)
   55     xmlByName = dict((f.name, f) for f in xmlFunctions)
   56     functions = []
   57     for (name, eglFunc) in eglFunctionList.EGL_FUNCTIONS:
   58         func = xmlByName[name]
   59         eglFunc = fixupEglFunc(func, eglFunc)
   60         functions.append((func, eglFunc))
   61 
   62     # Sort the function list by name.
   63     functions = sorted(functions, key=lambda f: f[0].name)
   64 
   65     if args.target == "header":
   66         text = generateHeader(functions)
   67     elif args.target == "source":
   68         text = generateSource(functions)
   69     sys.stdout.write(text)
   70 
   71 def fixupEglFunc(func, eglFunc):
   72     result = dict(eglFunc)
   73     if result.get("prefix") is None:
   74         result["prefix"] = ""
   75 
   76     if result.get("extension") is not None:
   77         text = "defined(" + result["extension"] + ")"
   78         result["extension"] = text
   79 
   80     if result["method"] in ("none", "custom"):
   81         return result
   82 
   83     if result["method"] not in ("display", "device", "current"):
   84         raise ValueError("Invalid dispatch method %r for function %r" % (result["method"], func.name))
   85 
   86     if func.hasReturn():
   87         if result.get("retval") is None:
   88             result["retval"] = getDefaultReturnValue(func.rt)
   89 
   90     return result
   91 
   92 def generateHeader(functions):
   93     text = textwrap.dedent(r"""
   94     #ifndef G_EGLDISPATCH_STUBS_H
   95     #define G_EGLDISPATCH_STUBS_H
   96 
   97     #ifdef __cplusplus
   98     extern "C" {
   99     #endif
  100 
  101     #include <EGL/egl.h>
  102     #include <EGL/eglext.h>
  103     #include <EGL/eglmesaext.h>
  104     #include <EGL/eglextchromium.h>
  105     #include "glvnd/libeglabi.h"
  106 
  107     """.lstrip("\n"))
  108 
  109     text += "enum {\n"
  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"
  115     text += "};\n"
  116 
  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)
  122 
  123     text += textwrap.dedent(r"""
  124     #ifdef __cplusplus
  125     }
  126     #endif
  127     #endif // G_EGLDISPATCH_STUBS_H
  128     """)
  129     return text
  130 
  131 def generateSource(functions):
  132     # First, sort the function list by name.
  133     text = ""
  134     text += '#include "egldispatchstubs.h"\n'
  135     text += '#include "g_egldispatchstubs.h"\n'
  136     text += '#include <stddef.h>\n'
  137     text += "\n"
  138 
  139     for (func, eglFunc) in functions:
  140         if eglFunc["method"] not in ("custom", "none"):
  141             text += generateGuardBegin(func, eglFunc)
  142             text += generateDispatchFunc(func, eglFunc)
  143             text += generateGuardEnd(func, eglFunc)
  144 
  145     text += "\n"
  146     text += "const char * const __EGL_DISPATCH_FUNC_NAMES[__EGL_DISPATCH_COUNT + 1] = {\n"
  147     for (func, eglFunc) in functions:
  148         text += generateGuardBegin(func, eglFunc)
  149         text += '    "' + func.name + '",\n'
  150         text += generateGuardEnd(func, eglFunc)
  151     text += "    NULL\n"
  152     text += "};\n"
  153 
  154     text += "const __eglMustCastToProperFunctionPointerType __EGL_DISPATCH_FUNCS[__EGL_DISPATCH_COUNT + 1] = {\n"
  155     for (func, eglFunc) in functions:
  156         text += generateGuardBegin(func, eglFunc)
  157         if eglFunc["method"] != "none":
  158             text += "    (__eglMustCastToProperFunctionPointerType) " + eglFunc.get("prefix", "") + func.name + ",\n"
  159         else:
  160             text += "    NULL, // " + func.name + "\n"
  161         text += generateGuardEnd(func, eglFunc)
  162     text += "    NULL\n"
  163     text += "};\n"
  164 
  165     return text
  166 
  167 def generateGuardBegin(func, eglFunc):
  168     ext = eglFunc.get("extension")
  169     if ext is not None:
  170         return "#if " + ext + "\n"
  171     else:
  172         return ""
  173 
  174 def generateGuardEnd(func, eglFunc):
  175     if eglFunc.get("extension") is not None:
  176         return "#endif\n"
  177     else:
  178         return ""
  179 
  180 def generateDispatchFunc(func, eglFunc):
  181     text = ""
  182 
  183     if eglFunc.get("static"):
  184         text += "static "
  185     elif eglFunc.get("public"):
  186         text += "PUBLIC "
  187     text += textwrap.dedent(
  188     r"""
  189     {f.rt} EGLAPIENTRY {ef[prefix]}{f.name}({f.decArgs})
  190     {{
  191         typedef {f.rt} EGLAPIENTRY (* _pfn_{f.name})({f.decArgs});
  192     """).lstrip("\n").format(f=func, ef=eglFunc)
  193 
  194     if func.hasReturn():
  195         text += "    {f.rt} _ret = {ef[retval]};\n".format(f=func, ef=eglFunc)
  196 
  197     text += "    _pfn_{f.name} _ptr_{f.name} = (_pfn_{f.name}) ".format(f=func)
  198     if eglFunc["method"] == "current":
  199         text += "__eglDispatchFetchByCurrent(__EGL_DISPATCH_{f.name});\n".format(f=func)
  200 
  201     elif eglFunc["method"] in ("display", "device"):
  202         if eglFunc["method"] == "display":
  203             lookupFunc = "__eglDispatchFetchByDisplay"
  204             lookupType = "EGLDisplay"
  205         else:
  206             assert eglFunc["method"] == "device"
  207             lookupFunc = "__eglDispatchFetchByDevice"
  208             lookupType = "EGLDeviceEXT"
  209 
  210         lookupArg = None
  211         for arg in func.args:
  212             if arg.type == lookupType:
  213                 lookupArg = arg.name
  214                 break
  215         if lookupArg is None:
  216             raise ValueError("Can't find %s argument for function %s" % (lookupType, func.name,))
  217 
  218         text += "{lookupFunc}({lookupArg}, __EGL_DISPATCH_{f.name});\n".format(
  219                 f=func, lookupFunc=lookupFunc, lookupArg=lookupArg)
  220     else:
  221         raise ValueError("Unknown dispatch method: %r" % (eglFunc["method"],))
  222 
  223     text += "    if(_ptr_{f.name} != NULL) {{\n".format(f=func)
  224     text += "        "
  225     if func.hasReturn():
  226         text += "_ret = "
  227     text += "_ptr_{f.name}({f.callArgs});\n".format(f=func)
  228     text += "    }\n"
  229 
  230     if func.hasReturn():
  231         text += "    return _ret;\n"
  232     text += "}\n"
  233     return text
  234 
  235 def getDefaultReturnValue(typename):
  236     if typename.endswith("*"):
  237         return "NULL"
  238     elif typename == "EGLDisplay":
  239         return "EGL_NO_DISPLAY"
  240     elif typename == "EGLContext":
  241         return "EGL_NO_CONTEXT"
  242     elif typename == "EGLSurface":
  243         return "EGL_NO_SURFACE"
  244     elif typename == "EGLBoolean":
  245         return "EGL_FALSE";
  246 
  247     return "0"
  248 
  249 if __name__ == "__main__":
  250     main()
  251