diff options
author | Kenneth Russel <[email protected]> | 2009-05-20 21:45:40 +0000 |
---|---|---|
committer | Kenneth Russel <[email protected]> | 2009-05-20 21:45:40 +0000 |
commit | 06fd97a1343718c6949b0408108f4c3124420299 (patch) | |
tree | e42f35a8945effeadbac2510be96dbdb0afd847c /src/java/com/sun/gluegen | |
parent | 1351343c7065f0ebbb9a3597c90a740498b2e7eb (diff) |
Recently code (UnifiedName, GLUnifiedName) was added to GlueGen to
automatically detect duplicate constant and function definitions
between vendor and ARB extensions and the OpenGL core, and to remove
the suffixes of ARB extensions. This code has helped automate the
process of discovering extensions that were promoted into the OpenGL
core.
While this code has saved some manual effort, it has also caused
several problems:
1. It causes obsolete ARB extensions to be incorrectly moved into the
core OpenGL namespace. GL_ARB_texture_rectangle, GL_ARB_vertex_blend,
and GL_ARB_matrix_palette are examples of extensions that should not
have their ARB suffixes removed because they are dead-end extensions.
Definitions which are explicitly specified that they will change, such
as those in the EGL_KHR_sync extension, were also incorrectly moved
into the core namespace.
2. It has caused certain OpenGL ES-specific definitions to
accidentally be promoted into the core OpenGL namespace: for example,
the constants associated with the GL_OES_point_size_array extension,
which were incorrectly placed into the GL2ES1 interface.
3. It causes namespace collisions between certain ARB extensions that
are only accessible via their ARB entry points and core OpenGL
routines: specifically GL_ARB_vertex_program and GL_ARB_fragment
program. Based on tests on NVIDIA's drivers, when a developer wants to
use the earlier ARB_vertex_program and ARB_fragment_program semantics
rather than GLSL, it is mandatory to use the ARB entry points rather
than the core OpenGL entry points.
4. It is not easy to configure the behavior of this automatic merging,
nor easy to see how it would be extended to be configurable.
5. It does not address the problem of detecting which extensions are
common between desktop OpenGL and OpenGL ES. A different algorithm
would be needed to solve that problem.
6. It has a high degree of functional overlap to the IgnoreExtension
directive which has previously been used to ignore ARB extensions that
were promoted into the OpenGL core. There were already IgnoreExtension
directives in place for all of the OpenGL extensions subsumed in
OpenGL 1.1 through 1.3.
7. It has been the cause of several bugs and unexpected interactions
with the Ignore and ForceProcAddressGen directives.
After careful consideration, it appears that the problems with this
code outweigh the benefits and it has been removed. The run-time code
which attempts to find extension variants of core entry points has
been retained, however.
To reduce the amount of subsequent manual work, the following
additions have been made:
1. A generic SymbolFilter mechanism has been added to GlueGen, which
can be used to pre-process the entire set of constant and function
definitions at any time during glue code generation (although it is
recommended to do so at the beginning of processing, i.e., in
GlueEmitter.beginEmission()).
2. The RenameJavaMethod directive has been generalized to
RenameJavaSymbol, and can now work on constant definitions.
3. A ConstantDefinition class has been added.
4. A RenameExtensionIntoCore directive has been added to the GLEmitter
which will rename all constant definitions and entry points associated
with a particular OpenGL extension into the core namespace, i.e.,
stripping off any ARB or similar suffixes.
5. An AutoUnifyExtensions directive has been added which is disabled
by default but which will automatically ignore any OpenGL extension
which has been completely subsumed into the OpenGL core and, if not,
print out the first declaration in that extension which caused it to
fail to be ignored.
The extensions common between OpenGL ES and desktop OpenGL have now
largely been moved into the core namespace using the
RenameExtensionIntoCore directive. A couple of these extensions had
slight differences between desktop OpenGL and OpenGL ES; the common
declarations were renamed manually.
IgnoreExtension directives have been added for those ARB extensions
promoted into the OpenGL core up to OpenGL 2.1. A few extensions which
were either silently promoted into the core specification
(GL_EXT_paletted_texture) or are obsolete (GL_EXT_multisample,
GL_EXT_point_parameters) were also ignored. The GlueGen runtime code
which looks up extension versions of core APIs via GLExtensionNames
makes this possible without breaking compatibility on older machines
that do not support OpenGL 2.1 directly.
With these changes, the same effect as the automatic extension
unification mechanism has been achieved, with much more explainable
and controllable results. Before-and-after versions of all of the
public interfaces (GL, GL2ES1, GL2ES2, GLES1, GLES2, and GL2) have
been compared by hand to ensure that the results are as expected and
desired.
Bugs in BuildStaticGLInfo were fixed which were preventing the
extension associations in the OpenGL ES headers from being discovered.
getExtensions() was added to be able to enumerate the discovered
extensions. Most .cfg files were changed to parse both the desktop
OpenGL and the OpenGL ES headers using the GLHeaders directive so that
the extension associations are known for both sets of APIs.
git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/../svn-server-sync/gluegen/branches/JOGL_2_SANDBOX@134 a78bb65f-1512-4460-ba86-f6dc96a7bf27
Diffstat (limited to 'src/java/com/sun/gluegen')
-rw-r--r-- | src/java/com/sun/gluegen/ConstantDefinition.java | 91 | ||||
-rw-r--r-- | src/java/com/sun/gluegen/GlueEmitterControls.java | 8 | ||||
-rw-r--r-- | src/java/com/sun/gluegen/GlueGen.java | 84 | ||||
-rw-r--r-- | src/java/com/sun/gluegen/JavaConfiguration.java | 46 | ||||
-rw-r--r-- | src/java/com/sun/gluegen/JavaEmitter.java | 54 | ||||
-rw-r--r-- | src/java/com/sun/gluegen/JavaMethodBindingEmitter.java | 9 | ||||
-rw-r--r-- | src/java/com/sun/gluegen/SymbolFilter.java | 64 | ||||
-rw-r--r-- | src/java/com/sun/gluegen/UnifiedName.java | 216 | ||||
-rw-r--r-- | src/java/com/sun/gluegen/opengl/BuildStaticGLInfo.java | 11 | ||||
-rwxr-xr-x | src/java/com/sun/gluegen/opengl/GLConfiguration.java | 36 | ||||
-rw-r--r-- | src/java/com/sun/gluegen/opengl/GLEmitter.java | 453 | ||||
-rw-r--r-- | src/java/com/sun/gluegen/opengl/GLUnifiedName.java | 115 | ||||
-rw-r--r-- | src/java/com/sun/gluegen/pcpp/PCPP.java | 7 | ||||
-rwxr-xr-x | src/java/com/sun/gluegen/procaddress/ProcAddressEmitter.java | 4 | ||||
-rw-r--r-- | src/java/com/sun/gluegen/runtime/opengl/GLExtensionNames.java | 9 |
15 files changed, 487 insertions, 720 deletions
diff --git a/src/java/com/sun/gluegen/ConstantDefinition.java b/src/java/com/sun/gluegen/ConstantDefinition.java new file mode 100644 index 0000000..e06903b --- /dev/null +++ b/src/java/com/sun/gluegen/ConstantDefinition.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ + +package com.sun.gluegen; + +import java.util.*; + +/** Represents the definition of a constant which was provided either + via a #define statement or through an enum definition. */ +public class ConstantDefinition { + private String name; + private String value; + private String enumName; + private Set/*<String>*/ aliases; + + public ConstantDefinition(String name, + String value, + String enumName) { + this.name = name; + this.value = value; + this.enumName = enumName; + } + + public boolean equals(ConstantDefinition other) { + return (equals(name, other.name) && + equals(value, other.value) && + equals(enumName, other.enumName)); + } + + private boolean equals(String s1, String s2) { + if (s1 == null || s2 == null) { + if (s1 == null && s2 == null) { + return true; + } + return false; + } + + return s1.equals(s2); + } + + public int hashCode() { + return name.hashCode(); + } + + public String getName() { return name; } + public String getValue() { return value; } + /** Returns null if this definition was not part of an + enumeration, or if the enum was anonymous. */ + public String getEnumName() { return enumName; } + + public Set/*<String>*/ getAliases() { + return aliases; + } + + public void addAlias(String alias) { + if (aliases == null) { + aliases = new LinkedHashSet/*<String>*/(); + } + aliases.add(alias); + } +} diff --git a/src/java/com/sun/gluegen/GlueEmitterControls.java b/src/java/com/sun/gluegen/GlueEmitterControls.java index 46ff9fd..659a4ee 100644 --- a/src/java/com/sun/gluegen/GlueEmitterControls.java +++ b/src/java/com/sun/gluegen/GlueEmitterControls.java @@ -50,4 +50,12 @@ public interface GlueEmitterControls { /** Finds the full path name of the specified header file based on the include directories specified on the command line. */ public String findHeaderFile(String headerFileName); + + /** Runs the given filter on the #defines, enum definitions and + function symbols that this controller has parsed. It is valid to + call this method as soon as {@link GlueEmitter#beginEmission} + has been called on the GlueEmitter, and it is recommended to + call it from that method call. Calling it during glue code + emission may cause problems. */ + public void runSymbolFilter(SymbolFilter filter); } diff --git a/src/java/com/sun/gluegen/GlueGen.java b/src/java/com/sun/gluegen/GlueGen.java index 1a7c690..5d61fdb 100644 --- a/src/java/com/sun/gluegen/GlueGen.java +++ b/src/java/com/sun/gluegen/GlueGen.java @@ -54,6 +54,10 @@ public class GlueGen implements GlueEmitterControls { private java.util.List forcedStructNames = new ArrayList(); private PCPP preprocessor; + // State for SymbolFilters + private java.util.List/*<ConstantDefinition>*/ constants; + private java.util.List/*<FunctionSymbol>*/ functions; + public void forceStructEmission(String typedefName) { forcedStructNames.add(typedefName); } @@ -62,6 +66,18 @@ public class GlueGen implements GlueEmitterControls { return preprocessor.findFile(headerFileName); } + public void runSymbolFilter(SymbolFilter filter) { + filter.filterSymbols(constants, functions); + java.util.List/*<ConstantDefinition>*/ newConstants = filter.getConstants(); + java.util.List/*<FunctionSymbol>*/ newFunctions = filter.getFunctions(); + if (newConstants != null) { + constants = newConstants; + } + if (newFunctions != null) { + functions = newFunctions; + } + } + public void run(String[] args) { try { Reader reader = null; @@ -198,43 +214,65 @@ public class GlueGen implements GlueEmitterControls { MachineDescription md64 = new MachineDescription64Bit(); emit.setMachineDescription(md32, md64); - // begin emission of glue code - emit.beginEmission(this); - - emit.beginDefines(); - Set emittedDefines = new HashSet(100); - // emit java equivalent of enum { ... } statements + // Repackage the enum and #define statements from the parser into a common format + // so that SymbolFilters can operate upon both identically + constants = new ArrayList/*<ConstantDefinition>*/(); for (Iterator iter = headerParser.getEnums().iterator(); iter.hasNext(); ) { EnumType enumeration = (EnumType)iter.next(); + String enumName = enumeration.getName(); + if (enumName.equals("<anonymous>")) { + enumName = null; + } // iterate over all values in the enumeration for (int i = 0; i < enumeration.getNumEnumerates(); ++i) { String enumElementName = enumeration.getEnumName(i); - if (emittedDefines.contains(enumElementName) == false) { - emittedDefines.add(enumElementName); - String comment = null; - if (! enumeration.getName().equals("<anonymous>")) { - comment = "Defined as part of enum type \"" + - enumeration.getName() + "\""; - } - emit.emitDefine( - enumElementName, - String.valueOf(enumeration.getEnumValue(i)), - comment); - } + String value = String.valueOf(enumeration.getEnumValue(i)); + constants.add(new ConstantDefinition(enumElementName, value, enumName)); } } - // emit java equivalent of #define statements for (Iterator iter = lexer.getDefines().iterator(); iter.hasNext(); ) { Define def = (Define) iter.next(); - if (emittedDefines.contains(def.getName()) == false) { + constants.add(new ConstantDefinition(def.getName(), def.getValue(), null)); + } + + functions = headerParser.getParsedFunctions(); + + // begin emission of glue code + emit.beginEmission(this); + + emit.beginDefines(); + Set emittedDefines = new HashSet(100); + // emit java equivalent of enum { ... } statements + for (Iterator iter = constants.iterator(); iter.hasNext(); ) { + ConstantDefinition def = (ConstantDefinition) iter.next(); + if (!emittedDefines.contains(def.getName())) { emittedDefines.add(def.getName()); - emit.emitDefine(def.getName(), def.getValue(), null); + String comment = null; + Set/*<String>*/ aliases = def.getAliases(); + if (aliases != null) { + comment = "Alias for: <code>"; + for (Iterator i2 = aliases.iterator(); i2.hasNext(); ) { + String alias = (String) i2.next(); + comment += " " + alias; + } + comment += "</code>"; + } + if (def.getEnumName() != null) { + String enumName = "Defined as part of enum type \"" + + def.getEnumName() + "\""; + if (comment == null) { + comment = enumName; + } else { + comment += "<br>\n" + enumName; + } + } + emit.emitDefine(def.getName(), + def.getValue(), + comment); } } emit.endDefines(); - java.util.List functions = headerParser.getParsedFunctions(); - // Iterate through the functions finding structs that are referenced in // the function signatures; these will be remembered for later emission ReferencedStructs referencedStructs = new ReferencedStructs(); diff --git a/src/java/com/sun/gluegen/JavaConfiguration.java b/src/java/com/sun/gluegen/JavaConfiguration.java index 91cb814..5693150 100644 --- a/src/java/com/sun/gluegen/JavaConfiguration.java +++ b/src/java/com/sun/gluegen/JavaConfiguration.java @@ -142,12 +142,9 @@ public class JavaConfiguration { private Map/*<String,List<String>>*/ implementedInterfaces = new HashMap(); private Map/*<String,String>*/ parentClass = new HashMap(); private Map/*<String,String>*/ javaTypeRenames = new HashMap(); - private Map/*<String,String>*/ javaMethodRenames = new HashMap(); + private Map/*<String,String>*/ javaSymbolRenames = new HashMap(); private Map/*<String,List<String>>*/ javaPrologues = new HashMap(); private Map/*<String,List<String>>*/ javaEpilogues = new HashMap(); - protected Map/*<String, UnifiedName>*/ uniqNameMap = new HashMap(); - public Map/*<String, UnifiedName>*/ getUniqNameMap() { return uniqNameMap; } - /** Reads the configuration file. @param filename path to file that should be read @@ -632,16 +629,9 @@ public class JavaConfiguration { } if (extendedIntfSymbolsOnly) { - String uniSymbol; - UnifiedName uniName = (UnifiedName) getUniqNameMap().get(symbol); - if(null!=uniName) { - uniSymbol=uniName.getUni(); - } else { - uniSymbol=symbol; - } - if(!extendedIntfSymbols.contains(uniSymbol)) { + if(!extendedIntfSymbols.contains(symbol)) { if(DEBUG_IGNORES) { - System.err.println("Ignore Impl !extended: "+uniSymbol+": "+uniName); + System.err.println("Ignore Impl !extended: " + symbol); } return true; } @@ -742,12 +732,18 @@ public class JavaConfiguration { return javaTypeName; } - /** Returns a replacement name for this function which should be - used as the Java name for the bound method. It still calls the - originally-named C function under the hood. Returns null if this - function has not been explicitly renamed. */ - public String getJavaMethodRename(String functionName) { - return (String) javaMethodRenames.get(functionName); + /** Returns a replacement name for this function or definition which + should be used as the Java name for the bound method or + constant. If a function, it still calls the originally-named C + function under the hood. Returns null if this symbol has not + been explicitly renamed. */ + public String getJavaSymbolRename(String symbolName) { + return (String) javaSymbolRenames.get(symbolName); + } + + /** Programmatically adds a rename directive for the given symbol. */ + public void addJavaSymbolRename(String origName, String newName) { + javaSymbolRenames.put(origName, newName); } /** Returns true if the emission style is AllStatic. */ @@ -928,8 +924,10 @@ public class JavaConfiguration { readParentClass(tok, filename, lineNo); } else if (cmd.equalsIgnoreCase("RenameJavaType")) { readRenameJavaType(tok, filename, lineNo); - } else if (cmd.equalsIgnoreCase("RenameJavaMethod")) { - readRenameJavaMethod(tok, filename, lineNo); + } else if (cmd.equalsIgnoreCase("RenameJavaSymbol") || + // Backward compatibility + cmd.equalsIgnoreCase("RenameJavaMethod")) { + readRenameJavaSymbol(tok, filename, lineNo); } else if (cmd.equalsIgnoreCase("RuntimeExceptionType")) { runtimeExceptionType = readString("RuntimeExceptionType", tok, filename, lineNo); } else if (cmd.equalsIgnoreCase("UnsupportedExceptionType")) { @@ -1404,13 +1402,13 @@ public class JavaConfiguration { } } - protected void readRenameJavaMethod(StringTokenizer tok, String filename, int lineNo) { + protected void readRenameJavaSymbol(StringTokenizer tok, String filename, int lineNo) { try { String fromName = tok.nextToken(); String toName = tok.nextToken(); - javaMethodRenames.put(fromName, toName); + javaSymbolRenames.put(fromName, toName); } catch (NoSuchElementException e) { - throw new RuntimeException("Error parsing \"RenameJavaMethod\" command at line " + lineNo + + throw new RuntimeException("Error parsing \"RenameJavaSymbol\" command at line " + lineNo + " in file \"" + filename + "\": missing expected parameter", e); } } diff --git a/src/java/com/sun/gluegen/JavaEmitter.java b/src/java/com/sun/gluegen/JavaEmitter.java index 2588158..ffd273f 100644 --- a/src/java/com/sun/gluegen/JavaEmitter.java +++ b/src/java/com/sun/gluegen/JavaEmitter.java @@ -103,6 +103,40 @@ public class JavaEmitter implements GlueEmitter { machDesc64 = md64; } + class ConstantRenamer implements SymbolFilter { + private List/*<ConstantDefinition>*/ constants; + + public void filterSymbols(List/*<ConstantDefinition>*/ constants, + List/*<FunctionSymbol>*/ functions) { + this.constants = constants; + doWork(); + } + + public List/*<ConstantDefinition>*/ getConstants() { + return constants; + } + + public List/*<FunctionSymbol>*/ getFunctions() { + return null; + } + + private void doWork() { + List/*<ConstantDefinition>*/ newConstants = new ArrayList/*<ConstantDefinition>*/(); + JavaConfiguration cfg = getConfig(); + for (Iterator iter = constants.iterator(); iter.hasNext(); ) { + ConstantDefinition def = (ConstantDefinition) iter.next(); + String rename = cfg.getJavaSymbolRename(def.getName()); + if (rename != null) { + ConstantDefinition newDef = new ConstantDefinition(rename, def.getValue(), def.getEnumName()); + newDef.addAlias(def.getName()); + def = newDef; + } + newConstants.add(def); + } + constants = newConstants; + } + } + public void beginEmission(GlueEmitterControls controls) throws IOException { try @@ -121,6 +155,9 @@ public class JavaEmitter implements GlueEmitter { for (Iterator iter = cfg.forcedStructs().iterator(); iter.hasNext(); ) { controls.forceStructEmission((String) iter.next()); } + + // Handle renaming of constants + controls.runSymbolFilter(new ConstantRenamer()); } public void endEmission() @@ -322,7 +359,7 @@ public class JavaEmitter implements GlueEmitter { } } - validateFunctionsToBind(funcsToBindSet); + // validateFunctionsToBind(funcsToBindSet); ArrayList funcsToBind = new ArrayList(funcsToBindSet.size()); funcsToBind.addAll(funcsToBindSet); @@ -628,19 +665,6 @@ public class JavaEmitter implements GlueEmitter { } } - protected void validateFunctionsToBind(Set/*FunctionSymbol*/ funcsSet) { - for (Iterator iter = funcsSet.iterator(); iter.hasNext(); ) { - FunctionSymbol fsOrig = (FunctionSymbol) iter.next(); - String name = fsOrig.getName(); - UnifiedName uniName = UnifiedName.getOrPut(cfg.getUniqNameMap(), name); - String renamedName = cfg.getJavaMethodRename(fsOrig.getName()); - if(null!=renamedName) { - uniName.setUni(renamedName); - uniName.remapAllNames(cfg.getUniqNameMap()); - } - } - } - /** * Generate all appropriate Java bindings for the specified C function * symbols. @@ -1619,7 +1643,7 @@ public class JavaEmitter implements GlueEmitter { MethodBinding binding = new MethodBinding(sym, containingType, containingCType); - binding.setRenamedMethodName(cfg.getJavaMethodRename(sym.getName())); + binding.setRenamedMethodName(cfg.getJavaSymbolRename(sym.getName())); if (cfg.returnsString(binding.getName())) { PointerType prt = sym.getReturnType().asPointer(); diff --git a/src/java/com/sun/gluegen/JavaMethodBindingEmitter.java b/src/java/com/sun/gluegen/JavaMethodBindingEmitter.java index 5e6f1cb..d6d7977 100644 --- a/src/java/com/sun/gluegen/JavaMethodBindingEmitter.java +++ b/src/java/com/sun/gluegen/JavaMethodBindingEmitter.java @@ -814,15 +814,6 @@ public class JavaMethodBindingEmitter extends FunctionEmitter writer.print("Entry point to C language function: "); } protected void emitBindingCSignature(MethodBinding binding, PrintWriter writer) { - UnifiedName uniName = (UnifiedName) cfg.getUniqNameMap().get(binding.getCSymbol().getName()); - if(null!=uniName) { - writer.print("- Alias for: <br> <code> "); - writer.print(binding.getCSymbol().getType().toString(uniName.getOrigStringList(", "), tagNativeBinding)); - writer.print(" </code> "); - return ; // done - } - writer.print(": <br> "); - writer.print("<code> "); writer.print(binding.getCSymbol().toString(tagNativeBinding)); writer.print(" </code> "); diff --git a/src/java/com/sun/gluegen/SymbolFilter.java b/src/java/com/sun/gluegen/SymbolFilter.java new file mode 100644 index 0000000..1cc31aa --- /dev/null +++ b/src/java/com/sun/gluegen/SymbolFilter.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ + +package com.sun.gluegen; + +import java.util.List; + +/** Provides a mechanism by which the GlueEmitter can look at all of + the #defines, enum values and function symbols and perform certain + filtering and processing which requires all of them to be visible + simultaneously. */ + +public interface SymbolFilter { + /** + * Filters the given constant and function symbols. The caller + * will query the SymbolFilter for its resulting constant and + * function symbol lists after this routine returns. + * + * @param defines a list of {@link com.sun.gluegen.cgram.Define Define} objects + * @param functions a list of {@link com.sun.gluegen.cgram.types.FunctionSymbol FunctionSymbol} objects + */ + public void filterSymbols(List/*<ConstantDefinition>*/ constants, + List/*<FunctionSymbol>*/ functions); + + /** Returns the filtered list of constants. This method may return + a new list, the original list, or null, in which case the + original list will be used. */ + public List/*<ConstantDefinition>*/ getConstants(); + + /** Returns the filtered list of function symbols. This method may + return a new list, the original list, or null, in which case + the original list will be used. */ + public List/*<FunctionSymbol>*/ getFunctions(); +} diff --git a/src/java/com/sun/gluegen/UnifiedName.java b/src/java/com/sun/gluegen/UnifiedName.java deleted file mode 100644 index ec1cdb3..0000000 --- a/src/java/com/sun/gluegen/UnifiedName.java +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (c) 2003-2005 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that this software is not designed or intended for use - * in the design, construction, operation or maintenance of any nuclear - * facility. - * - */ - -package com.sun.gluegen; - -import java.util.*; - -public class UnifiedName implements Cloneable { - - public UnifiedName(String name) { - nameUni=name; - nameList=new ArrayList(); - nameSet=new HashSet(); - add(name); - } - - protected UnifiedName(UnifiedName un) { - nameUni=un.nameUni; - nameList=new ArrayList(un.nameList); - nameSet=new HashSet(un.nameSet); - } - - public void reset() { - resetUni(); - resetOriginal(); - } - - public void resetUni() { - nameSet.remove(nameUni); - nameUni=(String)nameList.get(0); - } - - public void resetOriginal() { - nameList.clear(); - nameSet.clear(); - add(nameUni); - } - - public void setUni(String name) { - if(!nameUni.equals(name)) { - nameUni=name; - add(name); - } - } - - /** - * unique in case this name reflects only one - * original entry (no extension unification) - */ - public boolean isUnique() { - return nameSet.size()==1; - } - - public void add(String name) { - if (nameSet.add(name)) { - nameList.add(name); - } - } - public void addAll(Collection col) { - for (Iterator iter = col.iterator(); iter.hasNext(); ) { - Object obj = iter.next(); - if( obj instanceof String ) { - add((String)obj); - } else { - throw new ClassCastException("not a String: "+obj); - } - } - - } - - public boolean contains(UnifiedName un) { - boolean res = contains(un.nameUni); - for (Iterator iter = un.nameList.iterator(); !res && iter.hasNext(); ) { - res = contains((String)iter.next()); - } - return res; - } - - public boolean contains(String name) { - return nameSet.contains(name); - } - - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if(obj instanceof UnifiedName) { - UnifiedName un = (UnifiedName)obj; - return nameUni.equals(un.nameUni) && nameSet.equals(un.nameSet); - } - return false; - } - - public Object clone() { - return new UnifiedName(this); - } - - public int hashCode() { - return nameSet.hashCode(); - } - - public String getUni() { return nameUni; } - public List getNameList() { return nameList; } - public Set getNameSet() { return nameSet; } - - public int size() { return nameList.size(); } - public String get(int i) { return (String)nameList.get(i); } - - public void remapAllNames(Map map) { - List allNames = new ArrayList(); - // 1st pass: collect all other x-mappings to this one - for (Iterator iter = nameList.iterator(); iter.hasNext(); ) { - UnifiedName un = (UnifiedName) map.get((String)iter.next()); - if(null!=un && this!=un) { - allNames.addAll(un.getNameList()); - } - } - addAll(allNames); - - // 2nd pass: map all containing names - for (Iterator iter = nameList.iterator(); iter.hasNext(); ) { - map.put((String)iter.next(), this); - } - } - - public static UnifiedName getOrPut(Map map, String name) { - UnifiedName un = (UnifiedName)map.get(name); - if(null==un) { - un = new UnifiedName(name); - un.remapAllNames(map); - } - return un; - } - - public String getCommentString() { - return getCommentString(true, " "); - } - public String getCommentString(boolean encloseCommentStartEnd, String seperator) { - if(nameList.size()==1 && ((String)nameList.get(0)).equals(nameUni)) { - return new String(); - } - String res = new String(); - if(encloseCommentStartEnd) { - res = res.concat(" /** "); - } - res = res.concat("Alias for: <code>"); - res = res.concat(getOrigStringList(seperator)); - res = res.concat("</code> "); - if(encloseCommentStartEnd) { - res = res.concat("*/"); - } - return res; - } - public String getOrigStringList(String seperator) { - String res = new String(); - for (Iterator iter = nameList.iterator(); iter.hasNext(); ) { - res = res.concat((String)iter.next()); - if(iter.hasNext()) { - res = res.concat(seperator); - } - } - return res; - } - - public String toString() { - if(nameList.size()==1 && ((String)nameList.get(0)).equals(nameUni)) { - return nameUni; - } - String res = nameUni + " /* " ; - for (Iterator iter = nameList.iterator(); iter.hasNext(); ) { - res = res.concat((String)iter.next()+", "); - } - res = res.concat(" */"); - return res; - } - - protected String nameUni; - protected List nameList; - protected HashSet nameSet; - -} - diff --git a/src/java/com/sun/gluegen/opengl/BuildStaticGLInfo.java b/src/java/com/sun/gluegen/opengl/BuildStaticGLInfo.java index 13660b9..4226f46 100644 --- a/src/java/com/sun/gluegen/opengl/BuildStaticGLInfo.java +++ b/src/java/com/sun/gluegen/opengl/BuildStaticGLInfo.java @@ -92,7 +92,7 @@ public class BuildStaticGLInfo { // Handles function pointer protected static Pattern funcPattern = - Pattern.compile("^(EGLAPI|GLAPI|extern)?(\\s*)(\\w+)(\\*)?(\\s+)(EGLAPIENTRY|GLAPIENTRY|APIENTRY|WINAPI)?(\\s*)([ew]?gl\\w+)\\s?(\\(.*)"); + Pattern.compile("^(GLAPI|GL_API|GL_APICALL|EGLAPI|extern)?(\\s*)(\\w+)(\\*)?(\\s+)(GLAPIENTRY|GL_APIENTRY|APIENTRY|EGLAPIENTRY|WINAPI)?(\\s*)([ew]?gl\\w+)\\s?(\\(.*)"); protected static Pattern associationPattern = Pattern.compile("\\#ifndef ([EW]?GL[X]?_[A-Za-z0-9_]+)"); protected static Pattern definePattern = @@ -188,12 +188,13 @@ public class BuildStaticGLInfo // Handles #ifndef GL_... #define GL_... !identifier.equals(activeAssociation)) { addAssociation(identifier, activeAssociation); + // System.err.println(" ADDING ASSOCIATION: " + identifier + " " + activeAssociation); } } else if ((m = associationPattern.matcher(line)).matches()) { // found a new #ifndef GL_XXX block activeAssociation = m.group(1); - //System.err.println("FOUND NEW ASSOCIATION BLOCK: " + activeAssociation); + // System.err.println("FOUND NEW ASSOCIATION BLOCK: " + activeAssociation); } } reader.close(); @@ -217,10 +218,14 @@ public class BuildStaticGLInfo return (String) declarationToExtensionMap.get(identifier); } - public Set getDeclarations(String extension) { + public Set/*<String>*/ getDeclarations(String extension) { return (Set) extensionToDeclarationMap.get(extension); } + public Set/*<String>*/ getExtensions() { + return extensionToDeclarationMap.keySet(); + } + public void emitJavaCode(PrintWriter output, String packageName) { output.println("package " + packageName + ";"); output.println(); diff --git a/src/java/com/sun/gluegen/opengl/GLConfiguration.java b/src/java/com/sun/gluegen/opengl/GLConfiguration.java index 3d61b60..3013848 100755 --- a/src/java/com/sun/gluegen/opengl/GLConfiguration.java +++ b/src/java/com/sun/gluegen/opengl/GLConfiguration.java @@ -50,11 +50,16 @@ public class GLConfiguration extends ProcAddressConfiguration { // The following data members support ignoring an entire extension at a time private List/*<String>*/ glHeaders = new ArrayList(); private Set/*<String>*/ ignoredExtensions = new HashSet(); + private Set/*<String>*/ extensionsRenamedIntoCore = new HashSet(); private BuildStaticGLInfo glInfo; // Maps function names to the kind of buffer object it deals with private Map/*<String,GLEmitter.BufferObjectKind>*/ bufferObjectKinds = new HashMap(); private GLEmitter emitter; private Set/*String*/ dropUniqVendorExtensions = new HashSet(); + // This directive is off by default but can help automatically + // indicate which extensions have been folded into the core OpenGL + // namespace, and if not, then why not + private boolean autoUnifyExtensions; public GLConfiguration(GLEmitter emitter) { super(); @@ -72,6 +77,15 @@ public class GLConfiguration extends ProcAddressConfiguration { String sym = readString("IgnoreExtension", tok, filename, lineNo); ignoredExtensions.add(sym); } + else if (cmd.equalsIgnoreCase("RenameExtensionIntoCore")) + { + String sym = readString("RenameExtensionIntoCore", tok, filename, lineNo); + extensionsRenamedIntoCore.add(sym); + } + else if (cmd.equalsIgnoreCase("AutoUnifyExtensions")) + { + autoUnifyExtensions = readBoolean("AutoUnifyExtensions", tok, filename, lineNo).booleanValue(); + } else if (cmd.equalsIgnoreCase("GLHeader")) { String sym = readString("GLHeader", tok, filename, lineNo); @@ -228,6 +242,13 @@ public class GLConfiguration extends ProcAddressConfiguration { return shouldIgnoreExtension(symbol, checkEXT) || super.shouldIgnoreInImpl(symbol); } + /** Should we automatically ignore extensions that have already been + fully subsumed into the OpenGL core namespace, and if they have + not been, indicate which definition is not already in the core? */ + public boolean getAutoUnifyExtensions() { + return autoUnifyExtensions; + } + /** shall the non unified (uniq) vendor extensions be dropped ? */ public boolean getDropUniqVendorExtensions(String extName) { return dropUniqVendorExtensions.contains(extName); @@ -258,4 +279,19 @@ public class GLConfiguration extends ProcAddressConfiguration { } } } + + /** Returns the information about the association between #defines, + function symbols and the OpenGL extensions they are defined + in. */ + public BuildStaticGLInfo getGLInfo() { + return glInfo; + } + + /** Returns the OpenGL extensions that should have all of their + constant definitions and functions renamed into the core + namespace; for example, glGenFramebuffersEXT to + glGenFramebuffers and GL_FRAMEBUFFER_EXT to GL_FRAMEBUFFER. */ + public Set/*<String>*/ getExtensionsRenamedIntoCore() { + return extensionsRenamedIntoCore; + } } diff --git a/src/java/com/sun/gluegen/opengl/GLEmitter.java b/src/java/com/sun/gluegen/opengl/GLEmitter.java index ab92e9d..d49f9f1 100644 --- a/src/java/com/sun/gluegen/opengl/GLEmitter.java +++ b/src/java/com/sun/gluegen/opengl/GLEmitter.java @@ -70,226 +70,165 @@ public class GLEmitter extends ProcAddressEmitter public void beginEmission(GlueEmitterControls controls) throws IOException { getGLConfig().parseGLHeaders(controls); + renameExtensionsIntoCore(); + if (getGLConfig().getAutoUnifyExtensions()) { + unifyExtensions(controls); + } super.beginEmission(controls); } - class DefineEntry implements Cloneable { - public DefineEntry(String namestr, String valuestr, String optionalComment) { - this.name=new GLUnifiedName(namestr); - this.value=getJavaValue(namestr, valuestr); - this.type=getJavaType(namestr, this.value); - this.radix=getJavaRadix(namestr, valuestr); - this.optionalComment=optionalComment; - } - - protected DefineEntry(GLUnifiedName name, String type, Object value, int radix, String optionalComment) { - this.name=name; - this.value=value; - this.type=type; - this.radix=radix; - this.optionalComment=optionalComment; - } - - public Object clone() { - return new DefineEntry((GLUnifiedName)name.clone(), type, value, radix, optionalComment); - } - - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if(null==obj || !(obj instanceof DefineEntry)) return false; - DefineEntry de = (DefineEntry) obj; - return name.getUni().equals(de.name.getUni()) && - type.equals(de.type) && - value.equals(de.value); - } - - public String toString() { - String res = " public static final " + type + " " + name + " = "; - if(16!=radix) { - res = res + value; - } else { - res = res.concat("0x"); - if(value instanceof Integer) { - res = res.concat( Integer.toString( ((Integer)value).intValue(), radix ).toUpperCase() ); - } else if(value instanceof Long) { - res = res.concat( Long.toString( ((Long)value).longValue(), radix ).toUpperCase() ); - } else { - res = res + value; - } - } - - return res.concat(";"); - } - - public String getOptCommentString() { - if (optionalComment != null && optionalComment.length() > 0) { - return " /** " + optionalComment + " */"; + protected void renameExtensionsIntoCore() { + // This method handles renaming of entire extensions into the + // OpenGL core namespace. For example, it is used to move certain + // OpenGL ES (OES) extensions into the core namespace which are + // already in the core namespace in desktop OpenGL. It builds upon + // renaming mechanisms that are built elsewhere. + + GLConfiguration config = getGLConfig(); + BuildStaticGLInfo glInfo = config.getGLInfo(); + for (Iterator iter = config.getExtensionsRenamedIntoCore().iterator(); + iter.hasNext(); ) { + String extension = (String) iter.next(); + Set/*<String>*/ declarations = glInfo.getDeclarations(extension); + if (declarations != null) { + for (Iterator i2 = declarations.iterator(); i2.hasNext(); ) { + String decl = (String) i2.next(); + boolean isGLFunction = GLExtensionNames.isGLFunction(decl); + boolean isGLEnumeration = false; + if (!isGLFunction) { + isGLEnumeration = GLExtensionNames.isGLEnumeration(decl); + } + if (isGLFunction || isGLEnumeration) { + String renamed = GLExtensionNames.normalize(decl, isGLFunction); + config.addJavaSymbolRename(decl, renamed); + } } - return new String(); + } } + } - public void add(String name) { - this.name.add(name); - } - public boolean isExtensionVEN() { - return name.isExtensionVEN(); - } - public void normalizeVEN() { - name.normalizeVEN(); - } - public boolean shouldIgnoreInInterface(GLConfiguration cfg) { - return GLEmitter.this.shouldIgnoreInInterface(name, cfg); - } + class ExtensionUnifier implements SymbolFilter { + private List/*<ConstantDefinition>*/ constants; + private List/*<FunctionSymbol>*/ functions; - protected GLUnifiedName name; - protected Object value; - protected String type; - protected int radix; - protected String optionalComment; - } + public void filterSymbols(List/*<ConstantDefinition>*/ constants, + List/*<FunctionSymbol>*/ functions) { + this.constants = constants; + this.functions = functions; + doWork(); + } - protected boolean shouldIgnoreInInterface(GLUnifiedName name, GLConfiguration cfg) { - boolean res = cfg.shouldIgnoreInInterface(name.getUni(), name.isUnique()); - if(JavaConfiguration.DEBUG_IGNORES) { - if(res) { - System.err.println("Ignore Intf Uni: "+name); - } - } /* - for (Iterator iter = name.getNameList().iterator(); !res && iter.hasNext(); ) { - String s = (String)iter.next(); - res = cfg.shouldIgnoreInInterface(s, false); - if(JavaConfiguration.DEBUG_IGNORES) { - if(res) { - System.err.println("Ignore Intf Ext: "+name+", "+s); - } - } - } */ - return res; - } + public List/*<ConstantDefinition>*/ getConstants() { + return constants; + } + + public List/*<FunctionSymbol>*/ getFunctions() { + return functions; + } - protected boolean shouldIgnoreInImpl(GLUnifiedName name, GLConfiguration cfg) { - boolean res = cfg.shouldIgnoreInImpl(name.getUni(), name.isUnique()); - if(JavaConfiguration.DEBUG_IGNORES) { - if(res) { - System.err.println("Ignore Impl Uni: "+name); + private void doWork() { + BuildStaticGLInfo glInfo = getGLConfig().getGLInfo(); + if (glInfo == null) { + return; } - } - /* - if(!cfg.extendedIntfSymbolsOnly()) { - for (Iterator iter = name.getNameList().iterator(); !res && iter.hasNext(); ) { - String s = (String)iter.next(); - res = cfg.shouldIgnoreInImpl(s, false); - if(JavaConfiguration.DEBUG_IGNORES) { - if(res) { - System.err.println("Ignore Impl Ext: "+name+", "+s); + // Try to retain a "good" ordering for these symbols + Map/*<String, ConstantDefinition>*/ constantMap = new LinkedHashMap(); + Map/*<String, FunctionSymbol>*/ functionMap = new LinkedHashMap(); + for (Iterator iter = constants.iterator(); iter.hasNext(); ) { + ConstantDefinition def = (ConstantDefinition) iter.next(); + constantMap.put(def.getName(), def); + } + for (Iterator iter = functions.iterator(); iter.hasNext(); ) { + FunctionSymbol sym = (FunctionSymbol) iter.next(); + functionMap.put(sym.getName(), sym); + } + // Go through all of the declared extensions. + // For each extension, look at its #define and function symbols. + // If we find all of the extension's symbols in the core API under + // non-ARB (or whatever is the suffix) names, then remove this extension + // from the public API. If it turns out that we are running on hardware + // that doesn't support the core version of these APIs, the runtime + // will take care of looking up the extension version of these entry + // points. + Set/*<String>*/ extensionNames = glInfo.getExtensions(); + for (Iterator iter1 = extensionNames.iterator(); iter1.hasNext(); ) { + String extension = (String) iter1.next(); + Set/*<String>*/ declarations = glInfo.getDeclarations(extension); + boolean isExtension = true; + boolean shouldUnify = true; + String cause = null; + for (Iterator iter2 = declarations.iterator(); iter2.hasNext(); ) { + String decl = (String) iter2.next(); + boolean isFunc = !decl.startsWith("GL_"); + if (!GLExtensionNames.isExtension(decl, isFunc)) { + isExtension = false; + break; } - } - } - } */ - return res; - } - - protected LinkedHashMap/*<String name, DefineEntry entry>*/ defineMap = new LinkedHashMap(); - - public void beginDefines() throws Exception - { - super.beginDefines(); - } - - /** - * Pass-1 Unify ARB extensions with the same value - */ - public void emitDefine(String name, String value, String optionalComment) throws Exception { - if (cfg.allStatic() || cfg.emitInterface()) { - // unify ARB and map names - DefineEntry deNew = new DefineEntry(name, value, optionalComment); - DefineEntry deExist = (DefineEntry) defineMap.get(deNew.name.getUni()); - if(deExist!=null) { - // non ARB counterpart exist .. - if(deNew.equals(deExist)) { - if(deNew.getOptCommentString().length()>deExist.getOptCommentString().length()) { - deExist.optionalComment=deNew.optionalComment; - } - deExist.add(name); - return; // done .. - } - deNew.name.resetUni(); - System.err.println("WARNING: Normalized ARB entry with different value exists (keep ARB orig):"+ - "\n\tDef: "+deExist+ - "\n\tNew: "+deNew); + // See whether we're emitting glue code for this + // entry point or definition at all + if (isFunc) { + if (!functionMap.containsKey(decl)) { + isExtension = false; + break; + } + } else { + if (!constantMap.containsKey(decl)) { + isExtension = false; + break; + } + } + cause = decl; + String unifiedName = GLExtensionNames.normalize(decl, isFunc); + // NOTE that we look up the unified name in the + // BuildStaticGLInfo's notion of the APIs -- since + // we might not be emitting glue code for the + // headers that actually contain the core entry + // point. Think of the case where we are parsing the + // GLES2 gl2.h, which contains certain desktop + // OpenGL extensions that have been moved into the + // core, but later generating the implementing glue + // code (not the interface) for the desktop gl.h / + // glext.h. + shouldUnify = (glInfo.getExtension(unifiedName) != null); + // if (isFunc) { + // shouldUnify = functionMap.containsKey(unifiedName); + // } else { + // shouldUnify = constantMap.containsKey(unifiedName); + // } + if (!shouldUnify) { + break; + } + } + if (isExtension) { + if (shouldUnify) { + for (Iterator iter2 = declarations.iterator(); iter2.hasNext(); ) { + String decl = (String) iter2.next(); + boolean isFunc = !decl.startsWith("GL_"); + if (isFunc) { + functionMap.remove(decl); + } else { + constantMap.remove(decl); + } + } + System.err.println("INFO: unified extension " + extension + " into core API"); + } else { + System.err.println("INFO: didn't unify extension " + extension + " into core API because of " + cause); + } + } + } + constants = new ArrayList(); + for (Iterator iter = constantMap.keySet().iterator(); iter.hasNext(); ) { + constants.add(constantMap.get(iter.next())); + } + functions = new ArrayList(); + for (Iterator iter = functionMap.keySet().iterator(); iter.hasNext(); ) { + functions.add(functionMap.get(iter.next())); + } } - defineMap.put(deNew.name.getUni(), deNew); - } } - /** - * Pass-2 Unify vendor extensions, - * if exist as an ARB extension with the same value. - * Pass-3 Emit all .. - */ - public void endDefines() throws Exception - { - if (cfg.allStatic() || cfg.emitInterface()) { - Iterator/*<DefineEntry>*/ deIter = null; - - // unify VEN - deIter = defineMap.values().iterator(); - while( deIter.hasNext() ) { - DefineEntry de = (DefineEntry) deIter.next(); - if(de.isExtensionVEN()) { - String extSuffix = GLExtensionNames.getExtensionSuffix(de.name.getUni(), false); - DefineEntry deUni = (DefineEntry) de.clone(); - deUni.normalizeVEN(); - DefineEntry deExist = (DefineEntry) defineMap.get(deUni.name.getUni()); - if(null!=deExist) { - if(deUni.equals(deExist)) { - if(deUni.getOptCommentString().length()>deExist.getOptCommentString().length()) { - deExist.optionalComment=deUni.optionalComment; - } - deIter.remove(); - deExist.add(de.name.getUni()); - } else { - if( ((GLConfiguration)cfg).getDropUniqVendorExtensions(extSuffix) ) { - deIter.remove(); // remove non unified (uniq) vendor extension - System.err.println("INFO: Drop uniq VEN entry: "+de.name.getUni()); - } else { - System.err.println("INFO: Normalized VEN entry with different value exists (keep VEN orig):"+ - "\n\tDef: "+deExist+ - "\n\tNew: "+de); - } - } - } else if( ((GLConfiguration)cfg).getDropUniqVendorExtensions(extSuffix) ) { - deIter.remove(); // remove non unified (uniq) vendor extension - System.err.println("INFO: Drop uniq VEN entry: "+de.name.getUni()); - } - } - } - - // add mapping and emit .. - deIter = defineMap.values().iterator(); - while( deIter.hasNext() ) { - DefineEntry de = (DefineEntry) deIter.next(); - if (de.shouldIgnoreInInterface((GLConfiguration)cfg)) { - continue; - } - String comment = de.getOptCommentString(); - if (comment.length() != 0) { - javaWriter().println(comment); - } else { - comment = de.name.getCommentString(); - if (comment.length() != 0) { - de.name.resetOriginal(); // just shorten the comment space - javaWriter().println(comment); - } - } - javaWriter().println(de.toString()); - } - } - defineMap.clear(); - - super.endDefines(); + private void unifyExtensions(GlueEmitterControls controls) { + controls.runSymbolFilter(new ExtensionUnifier()); } protected JavaConfiguration createConfig() { @@ -368,108 +307,6 @@ public class GLEmitter extends ProcAddressEmitter // Internals only below this point // - protected void validateFunctionsToBind(Set/*FunctionSymbol*/ funcsSet) { - - String localCallingConvention = ((GLConfiguration)cfg).getLocalProcAddressCallingConvention4All(); - if(null==localCallingConvention) { - localCallingConvention="GL_APIENTRY"; - } - ArrayList newUniFuncs = new ArrayList(); - - // 1st Pass: map function names and process ARB extensions - for (Iterator iter = funcsSet.iterator(); iter.hasNext(); ) { - FunctionSymbol fsOrig = (FunctionSymbol) iter.next(); - String fname = fsOrig.getName(); - GLUnifiedName uniName; - { - uniName = (GLUnifiedName) GLUnifiedName.getOrPut(cfg.getUniqNameMap(), fname); - String renamedName = cfg.getJavaMethodRename(fname); - if(null!=renamedName) { - fname = renamedName; - uniName.setUni(fname); - uniName.remapAllNames(cfg.getUniqNameMap()); - } - } - - if(GLExtensionNames.isExtensionARB(fname, true)) { - if(!((GLConfiguration)cfg).skipProcAddressGen(fname)) { - // Do not process ignored functions with this logic - // because if we do then we will not be able to later - // tell that the function should be ignored - if (!((GLConfiguration)cfg).shouldIgnoreInImpl(fname)) { - FunctionSymbol fsUni = new FunctionSymbol(uniName.getUni(), fsOrig.getType()); - if(!funcsSet.contains(fsUni)) { - newUniFuncs.add(fsUni); // add new uni name - System.err.println("INFO: New ARB Normalized Function:"+ - "\n\tARB: "+fsOrig+ - "\n\tUNI: "+fsUni); - } else { - System.err.println("INFO: Dub ARB Normalized Function:"+ - "\n\tARB: "+fsOrig+ - "\n\tDUB: "+fsUni); - } - - iter.remove(); // remove ARB function - // make the function being dynamical fetched, due to it's dynamic naming scheme - ((GLConfiguration)cfg).addForceProcAddressGen(uniName.getUni()); - // Make sure we produce the right calling convention for - // the typedefed function pointers on Windows - ((GLConfiguration)cfg).addLocalProcAddressCallingConvention(uniName.getUni(), localCallingConvention); - } - } - } - if(JavaConfiguration.DEBUG_IGNORES) { - System.err.println("1st Pass: "+uniName); - } - } - funcsSet.addAll(newUniFuncs); - - // 2nd Pass: Unify VEN extensions - for (Iterator iter = funcsSet.iterator(); iter.hasNext(); ) { - FunctionSymbol fsOrig = (FunctionSymbol) iter.next(); - String fname = fsOrig.getName(); - GLUnifiedName uniName = (GLUnifiedName)cfg.getUniqNameMap().get(fname); - if(null==uniName) { - throw new RuntimeException("no mapping found for: "+fname); - } - - if(GLExtensionNames.isExtensionVEN(fname, true)) { - uniName.normalizeVEN(); - uniName.remapAllNames(cfg.getUniqNameMap()); - String extSuffix = GLExtensionNames.getExtensionSuffix(fname, true); - FunctionSymbol fsUni = new FunctionSymbol(uniName.getUni(), fsOrig.getType()); - if(funcsSet.contains(fsUni)) { - iter.remove(); // remove VEN function (already incl. as ARB) - System.err.println("INFO: Dub VEN Function:"+ - "\n\tVEN: "+fsOrig+ - "\n\tDUB: "+fsUni); - } else if( ((GLConfiguration)cfg).getDropUniqVendorExtensions(extSuffix) ) { - iter.remove(); // remove non unified (uniq) vendor extension - System.err.println("INFO: Drop uniq VEN Function: "+fsOrig.getName()); - } - } - if(JavaConfiguration.DEBUG_IGNORES) { - System.err.println("2nd Pass: "+uniName); - } - } - - // 3rd Pass: Remove all ignored functions - for (Iterator iter = funcsSet.iterator(); iter.hasNext(); ) { - FunctionSymbol fsOrig = (FunctionSymbol) iter.next(); - GLUnifiedName uniName = (GLUnifiedName)cfg.getUniqNameMap().get(fsOrig.getName()); - if(null==uniName) { - throw new RuntimeException("no mapping found for: "+fsOrig.getName()); - } - if (cfg.shouldIgnoreInImpl(fsOrig.getName())) { - if(JavaConfiguration.DEBUG_IGNORES) { - System.err.println("INFO: Ignored: Remove Function:"+ uniName); - } - iter.remove(); // remove ignored function - } - } - } - - protected void generateModifiedEmitters(JavaMethodBindingEmitter baseJavaEmitter, List emitters) { List superEmitters = new ArrayList(); super.generateModifiedEmitters(baseJavaEmitter, superEmitters); diff --git a/src/java/com/sun/gluegen/opengl/GLUnifiedName.java b/src/java/com/sun/gluegen/opengl/GLUnifiedName.java deleted file mode 100644 index 64ca302..0000000 --- a/src/java/com/sun/gluegen/opengl/GLUnifiedName.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2003-2005 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that this software is not designed or intended for use - * in the design, construction, operation or maintenance of any nuclear - * facility. - * - */ - -package com.sun.gluegen.opengl; - -import java.util.*; -import com.sun.gluegen.UnifiedName; -import com.sun.gluegen.runtime.opengl.GLExtensionNames; - -public class GLUnifiedName extends UnifiedName implements Cloneable { - - public GLUnifiedName(String name) { - super(name); - isGLFunc = GLExtensionNames.isGLFunction(name); - isGLEnum = GLExtensionNames.isGLEnumeration(name); - if(isGLFunc || isGLEnum) { - setUni(GLExtensionNames.normalizeARB(name, isGLFunc)); - } - } - - protected GLUnifiedName(GLUnifiedName un) { - super(un); - this.isGLFunc=un.isGLFunc; - this.isGLEnum=un.isGLEnum; - } - - public boolean isExtensionARB() { - boolean res = false; - if(isGLFunc||isGLEnum) { - res = GLExtensionNames.isExtensionARB(nameUni, isGLFunc); - for (Iterator iter = nameList.iterator(); !res && iter.hasNext(); ) { - res = GLExtensionNames.isExtensionARB((String)iter.next(), isGLFunc); - } - } - return res; - } - - public void normalizeVEN() { - if(isGLFunc||isGLEnum) { - setUni(GLExtensionNames.normalizeVEN(nameUni, isGLFunc)); - } - } - - public boolean isExtensionVEN() { - boolean res = false; - if(isGLFunc||isGLEnum) { - res = GLExtensionNames.isExtensionVEN(nameUni, isGLFunc); - for (Iterator iter = nameList.iterator(); !res && iter.hasNext(); ) { - res = GLExtensionNames.isExtensionVEN((String)iter.next(), isGLFunc); - } - } - return res; - } - - public boolean isExtension() { - boolean res = false; - if(isGLFunc||isGLEnum) { - res = GLExtensionNames.isExtension(nameUni, isGLFunc); - for (Iterator iter = nameList.iterator(); !res && iter.hasNext(); ) { - res = GLExtensionNames.isExtension((String)iter.next(), isGLFunc); - } - } - return res; - } - - public static UnifiedName getOrPut(Map map, String name) { - GLUnifiedName un = (GLUnifiedName)map.get(name); - if(null==un) { - un = new GLUnifiedName(name); - un.remapAllNames(map); - } - return un; - } - - public Object clone() { - return new GLUnifiedName(this); - } - - protected boolean isGLFunc, isGLEnum; -} - diff --git a/src/java/com/sun/gluegen/pcpp/PCPP.java b/src/java/com/sun/gluegen/pcpp/PCPP.java index af33635..4523032 100644 --- a/src/java/com/sun/gluegen/pcpp/PCPP.java +++ b/src/java/com/sun/gluegen/pcpp/PCPP.java @@ -415,8 +415,9 @@ public class PCPP { int sz = values.size(); if (sz == 0) { // definition to nothing, like "#define FOO" - String oldDef = (String) defineMap.put(name, ""); - if (oldDef != null) { + String value = ""; + String oldDef = (String) defineMap.put(name, value); + if (oldDef != null && !oldDef.equals(value)) { System.err.println("WARNING: \"" + name + "\" redefined from \"" + oldDef + "\" to \"\""); } @@ -431,7 +432,7 @@ public class PCPP { // Value is numeric constant like "#define FOO 5". // Put it in the #define map String oldDef = (String)defineMap.put(name, value); - if (oldDef != null) { + if (oldDef != null && !oldDef.equals(value)) { System.err.println("WARNING: \"" + name + "\" redefined from \"" + oldDef + "\" to \"" + value + "\""); } diff --git a/src/java/com/sun/gluegen/procaddress/ProcAddressEmitter.java b/src/java/com/sun/gluegen/procaddress/ProcAddressEmitter.java index 6fb1ad8..8f849ac 100755 --- a/src/java/com/sun/gluegen/procaddress/ProcAddressEmitter.java +++ b/src/java/com/sun/gluegen/procaddress/ProcAddressEmitter.java @@ -181,10 +181,6 @@ public class ProcAddressEmitter extends JavaEmitter // Internals only below this point // - protected void validateFunctionsToBind(Set/*FunctionSymbol*/ funcsSet) { - super.validateFunctionsToBind(funcsSet); - } - protected void generateModifiedEmitters(JavaMethodBindingEmitter baseJavaEmitter, List emitters) { if (getConfig().manuallyImplement(baseJavaEmitter.getName())) { // User will provide Java-side implementation of this routine; diff --git a/src/java/com/sun/gluegen/runtime/opengl/GLExtensionNames.java b/src/java/com/sun/gluegen/runtime/opengl/GLExtensionNames.java index 5182e9d..3c6f600 100644 --- a/src/java/com/sun/gluegen/runtime/opengl/GLExtensionNames.java +++ b/src/java/com/sun/gluegen/runtime/opengl/GLExtensionNames.java @@ -144,6 +144,15 @@ public class GLExtensionNames { public static final boolean isExtensionVEN(String str, boolean isGLFunc) { return isExtension(extensionsVEN, str, isGLFunc); } + public static final String normalize(String str, boolean isGLFunc) { + if (isExtensionARB(str, isGLFunc)) { + return normalizeARB(str, isGLFunc); + } + if (isExtensionVEN(str, isGLFunc)) { + return normalizeVEN(str, isGLFunc); + } + return str; + } public static final boolean isExtension(String str, boolean isGLFunc) { return isExtension(extensionsARB, str, isGLFunc) || isExtension(extensionsVEN, str, isGLFunc); |