best_ext = e
best_count = count
- if best_count*2>=total_count:
+ if total_count and best_count*2>=total_count:
print "Warning: Inconsistent backport extension %s"%best_ext.name
def collect_extensions(thing, api, exts):
print "Looking for %d things in %d extensions"%(len(things), len(things_by_ext))
extensions = []
+ keep_exts = 0
+ base_version = None
+ recheck_base_version = True
missing = set(things)
- while missing and things_by_ext:
+ while 1:
+ if recheck_base_version:
+ max_version = Version(1, 0)
+ for t in missing:
+ supp = t.api_support.get(host_api.name)
+ if supp and supp.core_version and max_version:
+ max_version = max(max_version, supp.core_version)
+ else:
+ max_version = None
+
+ if max_version:
+ if not base_version or max_version<base_version:
+ base_version = max_version
+ keep_exts = len(extensions)
+ elif not base_version:
+ keep_exts = len(extensions)
+
+ recheck_base_version = False
+
+ if not missing or not things_by_ext:
+ break
+
largest_ext = None
largest_count = 0
for e, t in things_by_ext.iteritems():
extensions.append(largest_ext)
for t in things_by_ext[largest_ext]:
missing.remove(t)
- if not missing:
- break
+
+ supp = t.api_support.get(host_api.name)
+ if supp and supp.core_version==base_version:
+ recheck_base_version = True
del things_by_ext[largest_ext]
for e in things_by_ext.keys():
else:
del things_by_ext[e]
- if missing:
+ if not missing:
+ return None, extensions
+ elif base_version:
+ if debug:
+ print "Found remaining things in version %s"%base_version
+ if keep_exts<len(extensions):
+ print "Discarding %d extensions that do not improve base version"%(len(extensions)-keep_exts)
+ del extensions[keep_exts:]
+ return base_version, extensions
+ else:
if debug:
print "%d things still missing:"%len(missing)
for t in missing:
print " "+t.name
- return None
-
- return extensions
+ return None, None
class SourceGenerator:
self.enums.sort(key=(lambda e: e.value))
self.core_version = detect_core_version(host_api, things, debug)
self.deprecated_version = detect_deprecated_version(host_api, things, debug)
- self.backport_ext = detect_backport_extension(host_api, things);
- self.source_exts = detect_source_extension(host_api, things, debug)
+ self.backport_ext = detect_backport_extension(host_api, things)
+ b, e = detect_source_extension(host_api, things, debug)
+ self.base_version = b
+ self.source_exts = e
if not self.core_version and not self.backport_ext and not self.source_exts:
print "Warning: Not supportable on host API"
if self.backport_ext:
print "Backport %s"%self.backport_ext.name
if self.source_exts:
- print "Sources %s"%", ".join(e.name for e in self.source_exts)
+ names = [e.name for e in self.source_exts]
+ if self.base_version:
+ names.insert(0, "Version %s"%self.base_version)
+ print "Sources %s"%", ".join(names)
def write_header_intro(self, out):
out.write("#ifndef MSP_GL_%s_\n"%self.ext_name.upper())
out.write(", %r"%self.deprecated_version)
out.write("))\n\t{\n")
for f in self.funcs:
- supp = f.api_support[self.host_api.name]
- gpa_suffix = ""
- if supp.core_version is not None and supp.core_version<=Version(1, 1):
- gpa_suffix = "_1_1"
- out.write("\t\t%s = reinterpret_cast<%s>(GET_PROC_ADDRESS%s(%s));\n"%(f.name, self.func_typedefs[f.name], gpa_suffix, f.name))
+ supp = f.api_support.get(self.host_api.name)
+ if supp:
+ gpa_suffix = ""
+ if supp.core_version is not None and supp.core_version<=Version(1, 1):
+ gpa_suffix = "_1_1"
+ out.write("\t\t%s = reinterpret_cast<%s>(GET_PROC_ADDRESS%s(%s));\n"%(f.name, self.func_typedefs[f.name], gpa_suffix, f.name))
out.write("\t\treturn Extension::CORE;\n")
out.write("\t}\n")
out.write("#endif\n")
if self.source_exts:
out.write("#if !defined(__APPLE__) || defined(GL_%s)\n"%self.ext_name)
- out.write("\tif(%s)\n\t{\n"%" && ".join("is_supported(\"GL_%s\")"%s.name for s in self.source_exts))
+ out.write("\tif(")
+ if self.base_version:
+ out.write("is_supported(%r) && "%self.base_version)
+ out.write("%s)\n\t{\n"%" && ".join("is_supported(\"GL_%s\")"%s.name for s in self.source_exts))
for f in self.funcs:
- supp = f.api_support[self.host_api.name]
- if supp.sources:
- src = None
- for e in self.source_exts:
+ supp = f.api_support.get(self.host_api.name)
+ src = None
+ for e in self.source_exts:
+ if f.name in e.things:
+ src = f
+ elif supp:
for s in supp.sources:
if s.name in e.things:
src = s
break
- if src:
- break
- else:
- src = f
+ if src:
+ break
+ if not src and supp and supp.core_version and self.base_version>=supp.core_version:
+ sec = f
if src:
out.write("\t\t%s = reinterpret_cast<%s>(GET_PROC_ADDRESS(%s));\n"%(f.name, self.func_typedefs[f.name], src.name))
self.core_version = None
self.deprecated_version = None
self.backport_ext = None
+ self.source_exts = []
self.ignore_things = []
self.optional_things = []
def parse(self, fn):
for line in open(fn):
line = line.strip()
- if line.startswith("#"):
+ if not line or line.startswith("#"):
continue
parts = line.split()
self.deprecated_version = Version(*map(int, parts[1].split('.')))
elif keyword=="backport":
self.backport_ext = parts[1]
+ elif keyword=="source":
+ self.source_exts.append(parts[1])
elif keyword=="ignore":
self.ignore_things.append(parts[1])
elif keyword=="optional":
generator.backport_ext = None
else:
generator.backport_ext = get_extension(xml_parser.apis, ext_parser.backport_ext)
+ if ext_parser.source_exts:
+ generator.base_version = None
+ if len(ext_parser.source_exts)==1 and ext_parser.source_exts[0]=="none":
+ generator.source_exts = []
+ else:
+ generator.source_exts = map((lambda e: get_extension(xml_parser.apis, e)), ext_parser.source_exts)
if debug:
generator.dump_info()
generator.write_header(out_base+".h")