]> git.tdb.fi Git - libs/gl.git/blobdiff - scripts/extgen.py
Detect deprecation versions for extensions
[libs/gl.git] / scripts / extgen.py
index c5bc219a392e35db1d823a61df8dc3b927e28c88..e6edd42bf944aad566c811202873282dc730f072 100755 (executable)
@@ -31,7 +31,10 @@ if sys.argv[i].startswith("gl"):
        i += 1
 
 target_ext = sys.argv[i]
+backport_ext = None
+deprecated_version = None
 out_base = None
+ignore_things = []
 if target_ext.endswith(".glext"):
        fn = target_ext
        target_ext = None
@@ -44,8 +47,15 @@ if target_ext.endswith(".glext"):
                elif parts[0]=="core_version":
                        if parts[1]==target_api:
                                core_version = parts[2]
+               elif parts[0]=="deprecated":
+                       if parts[1]==target_api:
+                               deprecated_version = parts[2]
                elif parts[0]=="secondary":
                        secondary.append(parts[1])
+               elif parts[0]=="backport":
+                       backport_ext = parts[1]
+               elif parts[0]=="ignore":
+                       ignore_things.append(parts[1])
        if i+1<len(sys.argv):
                out_base = os.path.splitext(sys.argv[i+1])[0]
 else:
@@ -55,11 +65,13 @@ else:
                core_version = secondary.pop(0)
 
 ext_type = target_ext.split('_')[0]
-backport_ext = None
 
 if core_version:
        core_version = map(int, core_version.split('.'))
 
+if deprecated_version:
+       deprecated_version = map(int, deprecated_version.split('.'))
+
 if not out_base:
        out_base = target_ext.lower()
 
@@ -73,8 +85,10 @@ class Thing:
                self.name = name
                self.kind = kind
                self.version = None
+               self.deprecated_version = None
                self.extension = None
                self.supported_apis = {}
+               self.deprecated = {}
                self.aliases = []
                self.sources = []
 
@@ -95,7 +109,9 @@ class Extension:
        def __init__(self, name):
                self.name = name
                self.supported_apis = []
-               self.ext_type = name[0:name.find('_')]
+               underscore = name.find('_')
+               self.ext_type = name[0:underscore]
+               self.base_name = name[underscore+1:]
 
 extensions = {}
 things = {}
@@ -186,8 +202,11 @@ def parse_feature(feat):
 
                        for t in itertools.chain(commands, enums):
                                name = t.getAttribute("name")
-                               if profile!="core" and name in things:
-                                       del things[name]
+                               if name in things:
+                                       if profile!="core":
+                                               del things[name]
+                                       else:
+                                               things[name].deprecated.setdefault(api, version)
 
 def parse_extension(ext):
        ext_name = ext.getAttribute("name")
@@ -217,6 +236,9 @@ def parse_extension(ext):
                enums = get_nested_elements(req, "enum")
                for t in itertools.chain(commands, enums):
                        name = t.getAttribute("name")
+                       if name in ignore_things:
+                               continue
+
                        thing = things.get(name)
                        if thing:
                                if thing.extension and extension.name!=target_ext:
@@ -315,15 +337,58 @@ enums = filter(is_relevant, enums)
 enums.sort(key=(lambda e: e.value))
 
 # Some final preparations for creating the files
+core_version_candidates = {}
+min_deprecated_version = [999, 0]
+backport_ext_candidates = []
 for t in itertools.chain(funcs, enums):
        if target_api in t.supported_apis and t.supported_apis[target_api]!="ext":
                t.version = t.supported_apis[target_api]
-       if not core_version:
-               core_version = t.version
+               if t.version:
+                       ver_tuple = tuple(t.version)
+                       core_version_candidates[ver_tuple] = core_version_candidates.get(ver_tuple, 0)+1
+
+       if target_api in t.deprecated:
+               t.deprecated_version = t.deprecated[target_api]
+               min_deprecated_version = min(min_deprecated_version, t.deprecated_version)
+       else:
+               min_deprecated_version = None
 
        # Things in backport extensions don't acquire an extension suffix
        if t.extension and not t.name.endswith(ext_type) and target_api in t.supported_apis:
-               backport_ext = t.extension
+               if t.extension not in backport_ext_candidates:
+                       backport_ext_candidates.append(t.extension)
+
+if not core_version and core_version_candidates:
+       core_version_candidates = list((v, k) for k, v in core_version_candidates.items())
+       if len(core_version_candidates)>1:
+               core_version_candidates.sort(reverse=True)
+               if core_version_candidates[1][0]+1>=core_version_candidates[0][0]:
+                       ver0 = core_version_candidates[0][1]
+                       ver1 = core_version_candidates[1][1]
+                       print "Warning: multiple likely core version candidates: %d.%d %d.%d"%(ver0[0], ver0[1], ver1[0], ver1[1])
+       core_version = core_version_candidates[0][1]
+
+if not deprecated_version:
+       deprecated_version = min_deprecated_version
+
+if backport_ext:
+       if backport_ext=="none":
+               backport_ext = None
+       else:
+               backport_ext = extensions[backport_ext]
+
+               if backport_ext not in backport_ext_candidates:
+                       print "Warning: explicitly specified backport extension %s does not look like a backport extension"
+elif backport_ext_candidates:
+       if len(backport_ext_candidates)>1:
+               print "Warning: multiple backport extension candidates: %s"%(" ".join(e.name for e in backport_ext_candidates))
+
+       for e in backport_ext_candidates:
+               if e.base_name==target_ext.base_name:
+                       backport_ext = e
+
+       if not backport_ext and len(backport_ext_candidates)==1:
+               print "Warning: potential backport extension has mismatched name: %s"%backport_ext_candidates[0].name
 
 for f in funcs:
        f.typedef = "FPtr_%s"%f.name
@@ -386,7 +451,7 @@ namespace GL {
 if funcs or enums:
        if funcs:
                for f in funcs:
-                       out.write("typedef %s (*%s)(%s);\n"%(f.return_type, f.typedef, ", ".join(f.params)))
+                       out.write("typedef %s (APIENTRY *%s)(%s);\n"%(f.return_type, f.typedef, ", ".join(f.params)))
                out.write("\n")
 
        if enums:
@@ -430,10 +495,16 @@ out.write("#include \"%s.h\"\n"%target_ext.name.lower())
 if funcs:
        out.write("""
 #ifdef __APPLE__
-#define GET_PROC_ADDRESS(x) ::x
+#define GET_PROC_ADDRESS(x) &::x
 #else
 #define GET_PROC_ADDRESS(x) get_proc_address(#x)
 #endif
+
+#ifdef WIN32
+#define GET_PROC_ADDRESS_1_1(x) &::x
+#else
+#define GET_PROC_ADDRESS_1_1(x) GET_PROC_ADDRESS(x)
+#endif
 """)
 out.write("""
 namespace Msp {
@@ -446,23 +517,43 @@ for f in funcs:
 
 out.write("\nExtension::SupportLevel init_%s()\n{\n"%target_ext.name.lower())
 if core_version:
-       out.write("\tif(is_version_at_least(%d, %d)"%tuple(core_version))
+       out.write("\tif(")
+       if deprecated_version and backport_ext:
+               out.write("(")
+       out.write("is_version_at_least(%d, %d)"%tuple(core_version))
+       if deprecated_version:
+               out.write(" && (get_gl_profile()!=CORE_PROFILE || !is_version_at_least(%d, %d))"%tuple(deprecated_version))
+               if backport_ext:
+                       out.write(")")
        if backport_ext:
                out.write(" || is_supported(\"GL_%s\")"%backport_ext.name)
        out.write(")\n\t{\n")
        for f in funcs:
                if target_api in f.supported_apis:
-                       out.write("\t\t%s = reinterpret_cast<%s>(GET_PROC_ADDRESS(%s));\n"%(f.name, f.typedef, f.name))
+                       gpa_suffix = ""
+                       if f.version is not None and f.version<=[1, 1]:
+                               gpa_suffix = "_1_1"
+                       out.write("\t\t%s = reinterpret_cast<%s>(GET_PROC_ADDRESS%s(%s));\n"%(f.name, f.typedef, gpa_suffix, f.name))
        out.write("\t\treturn Extension::CORE;\n")
        out.write("\t}\n")
 if source_ext and source_ext!=backport_ext:
        out.write("\tif(is_supported(\"GL_%s\"))\n\t{\n"%(source_ext.name))
        for f in funcs:
-               s = f
                if f.sources:
-                       s = f.sources[0]
-               if target_api in s.supported_apis:
-                       out.write("\t\t%s = reinterpret_cast<%s>(GET_PROC_ADDRESS(%s));\n"%(f.name, f.typedef, s.name))
+                       src = None
+                       for s in f.sources:
+                               if s.name.endswith(source_ext.ext_type):
+                                       src = s
+                                       break
+                       if not src:
+                               src = f.sources[0]
+               else:
+                       src = f
+
+               if target_api in src.supported_apis:
+                       if not src.name.endswith(source_ext.ext_type):
+                               print "Warning: %s does not match extension type %s"%(src.name, source_ext.ext_type)
+                       out.write("\t\t%s = reinterpret_cast<%s>(GET_PROC_ADDRESS(%s));\n"%(f.name, f.typedef, src.name))
        out.write("\t\treturn Extension::EXTENSION;\n")
        out.write("\t}\n")
 out.write("\treturn Extension::UNSUPPORTED;\n")