summaryrefslogtreecommitdiffstats
path: root/src/classes/com/sun/gluegen/opengl/GLEmitter.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/classes/com/sun/gluegen/opengl/GLEmitter.java')
-rw-r--r--src/classes/com/sun/gluegen/opengl/GLEmitter.java518
1 files changed, 25 insertions, 493 deletions
diff --git a/src/classes/com/sun/gluegen/opengl/GLEmitter.java b/src/classes/com/sun/gluegen/opengl/GLEmitter.java
index 4ba1df87b..8e7484a73 100644
--- a/src/classes/com/sun/gluegen/opengl/GLEmitter.java
+++ b/src/classes/com/sun/gluegen/opengl/GLEmitter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * 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
@@ -44,22 +44,15 @@ import java.text.MessageFormat;
import java.util.*;
import com.sun.gluegen.*;
import com.sun.gluegen.cgram.types.*;
+import com.sun.gluegen.procaddress.*;
import com.sun.gluegen.runtime.*;
/**
- * A subclass of JavaEmitter that modifies the normal emission of C and Java
- * code in order to allow a high-performance, cross-platform binding of Java
- * to OpenGL.
+ * A subclass of ProcAddressEmitter with special OpenGL-specific
+ * configuration abilities.
*/
-public class GLEmitter extends JavaEmitter
+public class GLEmitter extends ProcAddressEmitter
{
- public static final String PROCADDRESS_VAR_PREFIX = ProcAddressHelper.PROCADDRESS_VAR_PREFIX;
- protected static final String WRAP_PREFIX = "dispatch_";
- private TypeDictionary typedefDictionary;
- private PrintWriter tableWriter;
- private String tableClassPackage;
- private String tableClassName;
- private int numProcAddressEntries;
// Keeps track of which MethodBindings were created for handling
// Buffer Object variants. Used as a Set rather than a Map.
private Map/*<MethodBinding>*/ bufferObjectMethodBindings = new IdentityHashMap();
@@ -79,36 +72,8 @@ public class GLEmitter extends JavaEmitter
super.beginEmission(controls);
}
- public void beginFunctions(TypeDictionary typedefDictionary,
- TypeDictionary structDictionary,
- Map canonMap) throws Exception
- {
- this.typedefDictionary = typedefDictionary;
-
- if (getGLConfig().emitProcAddressTable())
- {
- beginGLProcAddressTable();
- }
- super.beginFunctions(typedefDictionary, structDictionary, canonMap);
- }
-
- public void endFunctions() throws Exception
- {
- if (getGLConfig().emitProcAddressTable())
- {
- endGLProcAddressTable();
- }
- super.endFunctions();
- }
-
- public void beginStructs(TypeDictionary typedefDictionary,
- TypeDictionary structDictionary,
- Map canonMap) throws Exception {
- super.beginStructs(typedefDictionary, structDictionary, canonMap);
- }
-
protected JavaConfiguration createConfig() {
- return new GLConfiguration();
+ return new GLConfiguration(this);
}
/** In order to implement Buffer Object variants of certain
@@ -166,76 +131,17 @@ public class GLEmitter extends JavaEmitter
return newBindings;
}
- protected List generateMethodBindingEmitters(FunctionSymbol sym) throws Exception
- {
- return generateMethodBindingEmittersImpl(sym);
- }
-
- private List generateMethodBindingEmittersImpl(FunctionSymbol sym) throws Exception
- {
- List defaultEmitters = super.generateMethodBindingEmitters(sym);
-
- // if the superclass didn't generate any bindings for the symbol, let's
- // honor that (for example, the superclass might have caught an Ignore
- // direction that matched the symbol's name).
- if (defaultEmitters.isEmpty())
- {
- return defaultEmitters;
- }
-
- // Don't do anything special if this symbol doesn't require
- // OpenGL-related modifications
+ protected boolean needsModifiedEmitters(FunctionSymbol sym) {
if ((!needsProcAddressWrapper(sym) && !needsBufferObjectVariant(sym)) ||
- getConfig().isUnimplemented(sym.getName()))
- {
- return defaultEmitters;
+ getConfig().isUnimplemented(sym.getName())) {
+ return false;
}
- ArrayList modifiedEmitters = new ArrayList(defaultEmitters.size());
-
- if (needsProcAddressWrapper(sym)) {
- if (getGLConfig().emitProcAddressTable()) {
- // emit an entry in the GL proc address table for this method.
- emitGLProcAddressTableEntryForSymbol(sym);
- }
- }
-
- for (Iterator iter = defaultEmitters.iterator(); iter.hasNext(); )
- {
- FunctionEmitter emitter = (FunctionEmitter) iter.next();
- if (emitter instanceof JavaMethodBindingEmitter)
- {
- generateModifiedEmitters((JavaMethodBindingEmitter) emitter, modifiedEmitters);
- }
- else if (emitter instanceof CMethodBindingEmitter)
- {
- generateModifiedEmitters((CMethodBindingEmitter) emitter, modifiedEmitters);
- }
- else
- {
- throw new RuntimeException("Unexpected emitter type: " +
- emitter.getClass().getName());
- }
- }
-
- return modifiedEmitters;
+ return true;
}
- /**
- * Returns the name of the typedef for a pointer to the GL function
- * represented by the argument. For example, if the argument is the function
- * "glFuncName", the value returned will be "PFNGLFUNCNAMEPROC". This
- * returns a valid string regardless of whether or not the typedef is
- * actually defined.
- */
- static String getGLFunctionPointerTypedefName(FunctionSymbol sym)
- {
- String symName = sym.getName();
- StringBuffer buf = new StringBuffer(symName.length() + 8);
- buf.append("PFN");
- buf.append(symName.toUpperCase());
- buf.append("PROC");
- return buf.toString();
+ public boolean isBufferObjectMethodBinding(MethodBinding binding) {
+ return bufferObjectMethodBindings.containsKey(binding);
}
//----------------------------------------------------------------------
@@ -243,405 +149,31 @@ public class GLEmitter extends JavaEmitter
//
protected void generateModifiedEmitters(JavaMethodBindingEmitter baseJavaEmitter, List emitters) {
- if (getGLConfig().manuallyImplement(baseJavaEmitter.getName())) {
- // User will provide Java-side implementation of this routine;
- // pass through any emitters which will produce signatures for
- // it unmodified
- emitters.add(baseJavaEmitter);
- return;
- }
-
- // See whether we need a proc address entry for this one
- boolean callThroughProcAddress = needsProcAddressWrapper(baseJavaEmitter.getBinding().getCSymbol());
+ List superEmitters = new ArrayList();
+ super.generateModifiedEmitters(baseJavaEmitter, superEmitters);
+
// See whether this is one of the Buffer Object variants
boolean bufferObjectVariant = bufferObjectMethodBindings.containsKey(baseJavaEmitter.getBinding());
- GLJavaMethodBindingEmitter emitter =
- new GLJavaMethodBindingEmitter(baseJavaEmitter,
- callThroughProcAddress,
- getGLConfig().getProcAddressTableExpr(),
- baseJavaEmitter.isForImplementingMethodCall(),
- bufferObjectVariant);
- emitters.add(emitter);
-
- // If this emitter doesn't have a body (i.e., is a public native
- // call), we need to force it to emit a body, and produce another
- // one to act as the entry point
- if (baseJavaEmitter.signatureOnly() &&
- baseJavaEmitter.hasModifier(JavaMethodBindingEmitter.PUBLIC) &&
- baseJavaEmitter.hasModifier(JavaMethodBindingEmitter.NATIVE) &&
- callThroughProcAddress) {
- emitter.setEmitBody(true);
- emitter.removeModifier(JavaMethodBindingEmitter.NATIVE);
- emitter = new GLJavaMethodBindingEmitter(baseJavaEmitter,
- callThroughProcAddress,
- getGLConfig().getProcAddressTableExpr(),
- true,
- bufferObjectVariant);
- emitter.setForImplementingMethodCall(true);
- emitters.add(emitter);
- }
- }
-
- protected void generateModifiedEmitters(CMethodBindingEmitter baseCEmitter, List emitters)
- {
- // See whether we need a proc address entry for this one
- boolean callThroughProcAddress = needsProcAddressWrapper(baseCEmitter.getBinding().getCSymbol());
- // Note that we don't care much about the naming of the C argument
- // variables so to keep things simple we ignore the buffer object
- // property for the binding
-
- // The C-side JNI binding for this particular function will have an
- // extra final argument, which is the address (the OpenGL procedure
- // address) of the function it needs to call
- GLCMethodBindingEmitter res = new GLCMethodBindingEmitter(baseCEmitter, callThroughProcAddress);
- MessageFormat exp = baseCEmitter.getReturnValueCapacityExpression();
- if (exp != null) {
- res.setReturnValueCapacityExpression(exp);
- }
- emitters.add(res);
- }
-
- protected boolean needsProcAddressWrapper(FunctionSymbol sym)
- {
- String symName = sym.getName();
-
- GLConfiguration config = getGLConfig();
-
- // We should only wrap the GL symbol if its function pointer typedef has
- // been defined (most likely in glext.h).
- String funcPointerTypedefName = getGLFunctionPointerTypedefName(sym);
- boolean shouldWrap = typedefDictionary.containsKey(funcPointerTypedefName);
- //System.err.println(funcPointerTypedefName + " defined: " + shouldWrap);
-
- if (config.skipProcAddressGen(symName)) {
- shouldWrap = false;
- }
-
- if (!shouldWrap)
- {
- //System.err.println("WARNING (GL): *not* run-time linking: " + sym +
- // "(" + funcPointerTypedefName + " undefined)");
- }
- else
- {
- FunctionType typedef = typedefDictionary.get(funcPointerTypedefName).asPointer().getTargetType().asFunction();
- FunctionType fun = sym.getType();
- int numarg = typedef.getNumArguments();
- for ( int i =0; i < numarg; i++ )
- {
- if ( fun.getArgumentName(i) == null )
- fun.setArgumentName(i,typedef.getArgumentName(i));
+ if (bufferObjectVariant) {
+ for (Iterator iter = superEmitters.iterator(); iter.hasNext(); ) {
+ JavaMethodBindingEmitter emitter = (JavaMethodBindingEmitter) iter.next();
+ if (emitter instanceof ProcAddressJavaMethodBindingEmitter) {
+ emitters.add(new GLJavaMethodBindingEmitter((ProcAddressJavaMethodBindingEmitter) emitter, bufferObjectVariant));
+ } else {
+ emitters.add(emitter);
+ }
}
+ } else {
+ emitters.addAll(superEmitters);
}
-
- return shouldWrap;
}
protected boolean needsBufferObjectVariant(FunctionSymbol sym) {
return getGLConfig().isBufferObjectFunction(sym.getName());
}
- private void beginGLProcAddressTable() throws Exception
- {
- tableClassPackage = getGLConfig().tableClassPackage();
- tableClassName = getGLConfig().tableClassName();
-
- // Table defaults to going into the impl directory unless otherwise overridden
- String implPackageName = tableClassPackage;
- if (implPackageName == null) {
- implPackageName = getImplPackageName();
- }
- String jImplRoot =
- getJavaOutputDir() + File.separator +
- CodeGenUtils.packageAsPath(implPackageName);
-
- tableWriter = openFile(jImplRoot + File.separator + tableClassName + ".java");
-
- CodeGenUtils.emitAutogeneratedWarning(tableWriter, this);
-
- tableWriter.println("package " + implPackageName + ";");
- tableWriter.println();
- for (Iterator iter = getConfig().imports().iterator(); iter.hasNext(); ) {
- tableWriter.println("import " + ((String) iter.next()) + ";");
- }
- tableWriter.println();
- tableWriter.println("/**");
- tableWriter.println(" * This table is a cache of the native pointers to OpenGL extension");
- tableWriter.println(" * functions, to be used for run-time linking of these extensions. ");
- tableWriter.println(" * These pointers are obtained by the OpenGL context via a ");
- tableWriter.println(" * platform-specific function (e.g., wglGetProcAddress() on Win32,");
- tableWriter.println(" * glXGetProcAddress() on X11, etc). If the member variable ");
- tableWriter.println(" * " + PROCADDRESS_VAR_PREFIX + "glFuncName is non-zero then function");
- tableWriter.println(" * \"glFuncName\" can be called through the associated GLContext; ");
- tableWriter.println(" * if it is 0, then the extension is not available and cannot be called.");
- tableWriter.println(" */");
- tableWriter.println("public class " + tableClassName);
- tableWriter.println("{");
- numProcAddressEntries = 0;
-
- for (Iterator iter = getGLConfig().getForceProcAddressGen().iterator(); iter.hasNext(); ) {
- emitGLProcAddressTableEntryForString((String) iter.next());
- }
- }
-
- private void endGLProcAddressTable() throws Exception
- {
- PrintWriter w = tableWriter;
-
- w.println();
- w.println(" /**");
- w.println(" * This is a convenience method to get (by name) the native function ");
- w.println(" * pointer for a given extension function. It lets you avoid ");
- w.println(" * having to manually compute the " + PROCADDRESS_VAR_PREFIX + "<glFunctionName>");
- w.println(" * member variable name and look it up via reflection; it also");
- w.println(" * will throw an exception if you try to get the address of an");
- w.println(" * unknown GL extension, or one that is statically linked ");
- w.println(" * and therefore does not have a valid GL procedure address. ");
- w.println(" */");
- w.println(" public long getAddressFor(String glFunctionName) {");
- w.println(" String addressFieldName = com.sun.gluegen.opengl.GLEmitter.PROCADDRESS_VAR_PREFIX + glFunctionName;");
- w.println(" try { ");
- w.println(" java.lang.reflect.Field addressField = this.getClass().getField(addressFieldName);");
- w.println(" return addressField.getLong(this);");
- w.println(" } catch (Exception e) {");
- w.println(" // The user is calling a bogus function or one which is not runtime");
- w.println(" // linked (extensions and core post-OpenGL 1.1 functions are runtime linked)");
- w.println(" if (!FunctionAvailabilityCache.isPartOfGLCore(\"1.1\", glFunctionName)) ");
- w.println(" {");
- w.println(" throw new RuntimeException(" );
- w.println(" \"WARNING: Address query failed for \\\"\" + glFunctionName +");
- w.println(" \"\\\"; either it's not runtime linked or it is not a known \" +");
- w.println(" \"OpenGL function\", e);");
- w.println(" }");
- w.println(" } ");
- w.println(" assert(false); // should never get this far");
- w.println(" return 0;");
- w.println(" }");
-
- w.println("} // end of class " + tableClassName);
- w.flush();
- w.close();
- }
-
- protected void emitGLProcAddressTableEntryForSymbol(FunctionSymbol cFunc)
- {
- emitGLProcAddressTableEntryForString(cFunc.getName());
- }
-
- protected void emitGLProcAddressTableEntryForString(String str)
- {
- tableWriter.print(" public long ");
- tableWriter.print(PROCADDRESS_VAR_PREFIX);
- tableWriter.print(str);
- tableWriter.println(";");
- ++numProcAddressEntries;
- }
-
protected GLConfiguration getGLConfig() {
return (GLConfiguration) getConfig();
}
-
- protected class GLConfiguration extends JavaConfiguration
- {
- private boolean emitProcAddressTable = false;
- private String tableClassPackage;
- private String tableClassName = "ProcAddressTable";
- private Set/*<String>*/ skipProcAddressGen = new HashSet();
- private List/*<String>*/ forceProcAddressGen = new ArrayList();
- private String contextVariableName = "context";
- private String getProcAddressTableExpr;
- // 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 BuildStaticGLInfo glInfo;
- // Maps function names to the kind of buffer object it deals with
- private Map/*<String,BufferObjectKind>*/ bufferObjectKinds = new HashMap();
-
- protected void dispatch(String cmd, StringTokenizer tok, File file, String filename, int lineNo) throws IOException {
- if (cmd.equalsIgnoreCase("EmitProcAddressTable"))
- {
- emitProcAddressTable =
- readBoolean("EmitProcAddressTable", tok, filename, lineNo).booleanValue();
- }
- else if (cmd.equalsIgnoreCase("ProcAddressTablePackage"))
- {
- tableClassPackage = readString("ProcAddressTablePackage", tok, filename, lineNo);
- }
- else if (cmd.equalsIgnoreCase("ProcAddressTableClassName"))
- {
- tableClassName = readString("ProcAddressTableClassName", tok, filename, lineNo);
- }
- else if (cmd.equalsIgnoreCase("SkipProcAddressGen"))
- {
- String sym = readString("SkipProcAddressGen", tok, filename, lineNo);
- skipProcAddressGen.add(sym);
- }
- else if (cmd.equalsIgnoreCase("ForceProcAddressGen"))
- {
- String sym = readString("ForceProcAddressGen", tok, filename, lineNo);
- forceProcAddressGen.add(sym);
- }
- else if (cmd.equalsIgnoreCase("ContextVariableName"))
- {
- contextVariableName = readString("ContextVariableName", tok, filename, lineNo);
- }
- else if (cmd.equalsIgnoreCase("GetProcAddressTableExpr"))
- {
- getProcAddressTableExpr = readGetProcAddressTableExpr(tok, filename, lineNo);
- }
- else if (cmd.equalsIgnoreCase("IgnoreExtension"))
- {
- String sym = readString("IgnoreExtension", tok, filename, lineNo);
- ignoredExtensions.add(sym);
- }
- else if (cmd.equalsIgnoreCase("GLHeader"))
- {
- String sym = readString("GLHeader", tok, filename, lineNo);
- glHeaders.add(sym);
- }
- else if (cmd.equalsIgnoreCase("BufferObjectKind"))
- {
- readBufferObjectKind(tok, filename, lineNo);
- }
- else
- {
- super.dispatch(cmd,tok,file,filename,lineNo);
- }
- }
-
- protected String readGetProcAddressTableExpr(StringTokenizer tok, String filename, int lineNo) {
- try {
- String restOfLine = tok.nextToken("\n\r\f");
- return restOfLine.trim();
- } catch (NoSuchElementException e) {
- throw new RuntimeException("Error parsing \"GetProcAddressTableExpr\" command at line " + lineNo +
- " in file \"" + filename + "\"", e);
- }
- }
-
- protected void readBufferObjectKind(StringTokenizer tok, String filename, int lineNo) {
- try {
- String kindString = tok.nextToken();
- BufferObjectKind kind = null;
- String target = tok.nextToken();
- if (kindString.equalsIgnoreCase("UnpackPixel")) {
- kind = BufferObjectKind.UNPACK_PIXEL;
- } else if (kindString.equalsIgnoreCase("PackPixel")) {
- kind = BufferObjectKind.PACK_PIXEL;
- } else if (kindString.equalsIgnoreCase("Array")) {
- kind = BufferObjectKind.ARRAY;
- } else if (kindString.equalsIgnoreCase("Element")) {
- kind = BufferObjectKind.ELEMENT;
- } else {
- throw new RuntimeException("Error parsing \"BufferObjectKind\" command at line " + lineNo +
- " in file \"" + filename + "\": illegal BufferObjectKind \"" +
- kindString + "\", expected one of UnpackPixel, PackPixel, Array, or Element");
- }
-
- bufferObjectKinds.put(target, kind);
- } catch (NoSuchElementException e) {
- throw new RuntimeException("Error parsing \"BufferObjectKind\" command at line " + lineNo +
- " in file \"" + filename + "\"", e);
- }
- }
-
- public boolean emitProcAddressTable() { return emitProcAddressTable; }
- public String tableClassPackage() { return tableClassPackage; }
- public String tableClassName() { return tableClassName; }
- public boolean skipProcAddressGen (String name) { return skipProcAddressGen.contains(name); }
- public List getForceProcAddressGen() { return forceProcAddressGen; }
- public String contextVariableName() { return contextVariableName; }
- public String getProcAddressTableExpr() {
- if (getProcAddressTableExpr == null) {
- getProcAddressTableExpr = contextVariableName + ".get" + tableClassName + "()";
- }
- return getProcAddressTableExpr;
- }
-
- public boolean shouldIgnore(String symbol) {
- // Check ignored extensions based on our knowledge of the static GL info
- if (glInfo != null) {
- String extension = glInfo.getExtension(symbol);
- if (extension != null &&
- ignoredExtensions.contains(extension)) {
- return true;
- }
- }
-
- return super.shouldIgnore(symbol);
- }
-
- /** Overrides javaPrologueForMethod in superclass and
- automatically generates prologue code for functions associated
- with buffer objects. */
- public List/*<String>*/ javaPrologueForMethod(MethodBinding binding,
- boolean forImplementingMethodCall,
- boolean eraseBufferAndArrayTypes) {
- List/*<String>*/ res = super.javaPrologueForMethod(binding,
- forImplementingMethodCall,
- eraseBufferAndArrayTypes);
- BufferObjectKind kind = getBufferObjectKind(binding.getName());
- if (kind != null) {
- // Need to generate appropriate prologue based on both buffer
- // object kind and whether this variant of the MethodBinding
- // is the one accepting a "long" as argument
- if (res == null) {
- res = new ArrayList();
- }
-
- String prologue = "check";
-
- if (kind == BufferObjectKind.UNPACK_PIXEL) {
- prologue = prologue + "UnpackPBO";
- } else if (kind == BufferObjectKind.PACK_PIXEL) {
- prologue = prologue + "PackPBO";
- } else if (kind == BufferObjectKind.ARRAY) {
- prologue = prologue + "ArrayVBO";
- } else if (kind == BufferObjectKind.ELEMENT) {
- prologue = prologue + "ElementVBO";
- } else {
- throw new RuntimeException("Unknown BufferObjectKind " + kind);
- }
-
- if (bufferObjectMethodBindings.containsKey(binding)) {
- prologue = prologue + "Enabled";
- } else {
- prologue = prologue + "Disabled";
- }
-
- prologue = prologue + "();";
-
- res.add(0, prologue);
- }
-
- return res;
- }
-
- /** Returns the kind of buffer object this function deals with, or
- null if none. */
- public BufferObjectKind getBufferObjectKind(String name) {
- return (BufferObjectKind) bufferObjectKinds.get(name);
- }
-
- public boolean isBufferObjectFunction(String name) {
- return (getBufferObjectKind(name) != null);
- }
-
- /** Parses any GL headers specified in the configuration file for
- the purpose of being able to ignore an extension at a time. */
- public void parseGLHeaders(GlueEmitterControls controls) throws IOException {
- if (!glHeaders.isEmpty()) {
- glInfo = new BuildStaticGLInfo();
- for (Iterator iter = glHeaders.iterator(); iter.hasNext(); ) {
- String file = (String) iter.next();
- String fullPath = controls.findHeaderFile(file);
- if (fullPath == null) {
- throw new IOException("Unable to locate header file \"" + file + "\"");
- }
- glInfo.parse(fullPath);
- }
- }
- }
- } // end class GLConfiguration
}