diff options
Diffstat (limited to 'src/classes/com/sun/gluegen/opengl')
4 files changed, 241 insertions, 781 deletions
diff --git a/src/classes/com/sun/gluegen/opengl/GLCMethodBindingEmitter.java b/src/classes/com/sun/gluegen/opengl/GLCMethodBindingEmitter.java deleted file mode 100755 index 43053410e..000000000 --- a/src/classes/com/sun/gluegen/opengl/GLCMethodBindingEmitter.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (c) 2003 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. - * - * Sun gratefully acknowledges that this software was originally authored - * and developed by Kenneth Bradley Russell and Christopher John Kline. - */ - -package com.sun.gluegen.opengl; - -import java.io.*; -import java.util.*; -import com.sun.gluegen.*; -import com.sun.gluegen.cgram.types.*; - -public class GLCMethodBindingEmitter extends CMethodBindingEmitter { - private static final CommentEmitter defaultCommentEmitter = - new CGLPAWrapperCommentEmitter(); - - private boolean callThroughProcAddress; - private String glFuncPtrTypedefValue; - private static String procAddressJavaTypeName = - JavaType.createForClass(Long.TYPE).jniTypeName(); - - public GLCMethodBindingEmitter(CMethodBindingEmitter methodToWrap, - final boolean callThroughProcAddress) { - super( - new MethodBinding(methodToWrap.getBinding()) { - public String getName() { - if (callThroughProcAddress) { - return GLEmitter.WRAP_PREFIX + super.getName(); - } else { - return super.getName(); - } - } - - public String getRenamedMethodName() { - if (callThroughProcAddress) { - return GLEmitter.WRAP_PREFIX + super.getRenamedMethodName(); - } else { - return super.getRenamedMethodName(); - } - } - }, - methodToWrap.getDefaultOutput(), - methodToWrap.getDefaultMachineDescription(), - methodToWrap.getJavaPackageName(), - methodToWrap.getJavaClassName(), - methodToWrap.getIsOverloadedBinding(), - methodToWrap.getIsJavaMethodStatic(), - true, - methodToWrap.forIndirectBufferAndArrayImplementation() - ); - - if (methodToWrap.getReturnValueCapacityExpression() != null) { - setReturnValueCapacityExpression(methodToWrap.getReturnValueCapacityExpression()); - } - if (methodToWrap.getReturnValueLengthExpression() != null) { - setReturnValueLengthExpression(methodToWrap.getReturnValueLengthExpression()); - } - setTemporaryCVariableDeclarations(methodToWrap.getTemporaryCVariableDeclarations()); - setTemporaryCVariableAssignments (methodToWrap.getTemporaryCVariableAssignments ()); - - setCommentEmitter(defaultCommentEmitter); - this.callThroughProcAddress = callThroughProcAddress; - } - - protected int emitArguments(PrintWriter writer) { - int numEmitted = super.emitArguments(writer); - if (callThroughProcAddress) { - if (numEmitted > 0) - { - writer.print(", "); - } - //writer.print("long glProcAddress"); - writer.print(procAddressJavaTypeName); - writer.print(" glProcAddress"); - ++numEmitted; - } - - return numEmitted; - } - - protected void emitBodyVariableDeclarations(PrintWriter writer) { - if (callThroughProcAddress) { - // create variable for the function pointer with the right type, and set - // it to the value of the passed-in glProcAddress - FunctionSymbol cSym = getBinding().getCSymbol(); - String funcPointerTypedefName = - GLEmitter.getGLFunctionPointerTypedefName(cSym); - - writer.print(" "); - writer.print(funcPointerTypedefName); - writer.print(" ptr_"); - writer.print(cSym.getName()); - writer.println(";"); - } - - super.emitBodyVariableDeclarations(writer); - } - - protected void emitBodyVariablePreCallSetup(PrintWriter writer, - boolean emittingPrimitiveArrayCritical) { - super.emitBodyVariablePreCallSetup(writer, emittingPrimitiveArrayCritical); - - if (callThroughProcAddress) { - if (!emittingPrimitiveArrayCritical) { - // set the function pointer to the value of the passed-in glProcAddress - FunctionSymbol cSym = getBinding().getCSymbol(); - String funcPointerTypedefName = - GLEmitter.getGLFunctionPointerTypedefName(cSym); - - String ptrVarName = "ptr_" + cSym.getName(); - - writer.print(" "); - writer.print(ptrVarName); - writer.print(" = ("); - writer.print(funcPointerTypedefName); - writer.println(") (intptr_t) glProcAddress;"); - - writer.println(" assert(" + ptrVarName + " != NULL);"); - } - } - } - - protected void emitBodyCallCFunction(PrintWriter writer) { - if (!callThroughProcAddress) { - super.emitBodyCallCFunction(writer); - } else { - // Make the call to the actual C function - writer.print(" "); - - // WARNING: this code assumes that the return type has already been - // typedef-resolved. - Type cReturnType = binding.getCReturnType(); - - if (!cReturnType.isVoid()) { - writer.print("_res = "); - } - MethodBinding binding = getBinding(); - if (binding.hasContainingType()) { - // Cannot call GL func through function pointer - throw new IllegalStateException( - "Cannot call GL func through function pointer: " + binding); - } - - // call throught the run-time function pointer - writer.print("(* ptr_"); - writer.print(binding.getCSymbol().getName()); - writer.print(") "); - writer.print("("); - emitBodyPassCArguments(writer); - writer.println(");"); - } - } - - protected String jniMangle(MethodBinding binding) { - StringBuffer buf = new StringBuffer(super.jniMangle(binding)); - if (callThroughProcAddress) { - jniMangle(Long.TYPE, buf, false); // to account for the additional _addr_ parameter - } - return buf.toString(); - } - - /** This class emits the comment for the wrapper method */ - private static class CGLPAWrapperCommentEmitter extends CMethodBindingEmitter.DefaultCommentEmitter { - protected void emitBeginning(FunctionEmitter methodEmitter, PrintWriter writer) { - writer.print(" -- FIXME: IMPLEMENT COMMENT FOR CGLPAWrapperCommentEmitter -- "); - } - } -} // end class GLCMethodBindingEmitter diff --git a/src/classes/com/sun/gluegen/opengl/GLConfiguration.java b/src/classes/com/sun/gluegen/opengl/GLConfiguration.java new file mode 100755 index 000000000..a44f3fe9f --- /dev/null +++ b/src/classes/com/sun/gluegen/opengl/GLConfiguration.java @@ -0,0 +1,198 @@ +/* + * 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. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package com.sun.gluegen.opengl; + +import java.io.*; +import java.util.*; + +import com.sun.gluegen.*; +import com.sun.gluegen.procaddress.*; + +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 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; + + public GLConfiguration(GLEmitter emitter) { + super(); + this.emitter = emitter; + try { + setProcAddressNameExpr("PFN $UPPERCASE({0}) PROC"); + } catch (NoSuchElementException e) { + throw new RuntimeException("Error configuring ProcAddressNameExpr", e); + } + } + + protected void dispatch(String cmd, StringTokenizer tok, File file, String filename, int lineNo) throws IOException { + 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 void readBufferObjectKind(StringTokenizer tok, String filename, int lineNo) { + try { + String kindString = tok.nextToken(); + GLEmitter.BufferObjectKind kind = null; + String target = tok.nextToken(); + if (kindString.equalsIgnoreCase("UnpackPixel")) { + kind = GLEmitter.BufferObjectKind.UNPACK_PIXEL; + } else if (kindString.equalsIgnoreCase("PackPixel")) { + kind = GLEmitter.BufferObjectKind.PACK_PIXEL; + } else if (kindString.equalsIgnoreCase("Array")) { + kind = GLEmitter.BufferObjectKind.ARRAY; + } else if (kindString.equalsIgnoreCase("Element")) { + kind = GLEmitter.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); + } + } + + /** 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); + GLEmitter.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 == GLEmitter.BufferObjectKind.UNPACK_PIXEL) { + prologue = prologue + "UnpackPBO"; + } else if (kind == GLEmitter.BufferObjectKind.PACK_PIXEL) { + prologue = prologue + "PackPBO"; + } else if (kind == GLEmitter.BufferObjectKind.ARRAY) { + prologue = prologue + "ArrayVBO"; + } else if (kind == GLEmitter.BufferObjectKind.ELEMENT) { + prologue = prologue + "ElementVBO"; + } else { + throw new RuntimeException("Unknown BufferObjectKind " + kind); + } + + if (emitter.isBufferObjectMethodBinding(binding)) { + prologue = prologue + "Enabled"; + } else { + prologue = prologue + "Disabled"; + } + + prologue = prologue + "();"; + + res.add(0, prologue); + } + + return res; + } + + 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); + } + + /** Returns the kind of buffer object this function deals with, or + null if none. */ + public GLEmitter.BufferObjectKind getBufferObjectKind(String name) { + return (GLEmitter.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); + } + } + } +} 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 } diff --git a/src/classes/com/sun/gluegen/opengl/GLJavaMethodBindingEmitter.java b/src/classes/com/sun/gluegen/opengl/GLJavaMethodBindingEmitter.java index 1e72cd633..ce7f3110e 100755 --- a/src/classes/com/sun/gluegen/opengl/GLJavaMethodBindingEmitter.java +++ b/src/classes/com/sun/gluegen/opengl/GLJavaMethodBindingEmitter.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 @@ -43,44 +43,33 @@ import java.io.*; import java.util.*; import com.sun.gluegen.*; import com.sun.gluegen.cgram.types.*; +import com.sun.gluegen.procaddress.*; -public class GLJavaMethodBindingEmitter extends JavaMethodBindingEmitter { - private final CommentEmitter commentEmitterForWrappedMethod = - new WrappedMethodCommentEmitter(); +/** A specialization of the proc address emitter which knows how to + change argument names to take into account Vertex Buffer Object / + Pixel Buffer Object variants. */ - private boolean callThroughProcAddress; - private boolean changeNameAndArguments; - private String getProcAddressTableExpr; +public class GLJavaMethodBindingEmitter extends ProcAddressJavaMethodBindingEmitter { private boolean bufferObjectVariant; public GLJavaMethodBindingEmitter(JavaMethodBindingEmitter methodToWrap, boolean callThroughProcAddress, String getProcAddressTableExpr, boolean changeNameAndArguments, - boolean bufferObjectVariant) { - super(methodToWrap); - this.callThroughProcAddress = callThroughProcAddress; - this.getProcAddressTableExpr = getProcAddressTableExpr; - this.changeNameAndArguments = changeNameAndArguments; + boolean bufferObjectVariant, + GLEmitter emitter) { + super(methodToWrap, + callThroughProcAddress, + getProcAddressTableExpr, + changeNameAndArguments, + emitter); this.bufferObjectVariant = bufferObjectVariant; - if (callThroughProcAddress) { - setCommentEmitter(new WrappedMethodCommentEmitter()); - } - - if (methodToWrap.getBinding().hasContainingType()) - { - throw new IllegalArgumentException( - "Cannot create OpenGL proc. address wrapper; method has containing type: \"" + - methodToWrap.getBinding() + "\""); - } } - public String getName() { - String res = super.getName(); - if (changeNameAndArguments) { - return GLEmitter.WRAP_PREFIX + res; - } - return res; + public GLJavaMethodBindingEmitter(ProcAddressJavaMethodBindingEmitter methodToWrap, + boolean bufferObjectVariant) { + super(methodToWrap); + this.bufferObjectVariant = bufferObjectVariant; } protected String getArgumentName(int i) { @@ -103,61 +92,4 @@ public class GLJavaMethodBindingEmitter extends JavaMethodBindingEmitter { return name; } - - protected int emitArguments(PrintWriter writer) { - int numEmitted = super.emitArguments(writer); - if (callThroughProcAddress) { - if (changeNameAndArguments) { - if (numEmitted > 0) { - writer.print(", "); - } - - writer.print("long glProcAddress"); - ++numEmitted; - } - } - - return numEmitted; - } - - protected String getImplMethodName(boolean direct) { - String name = super.getImplMethodName(direct); - if (callThroughProcAddress) { - return GLEmitter.WRAP_PREFIX + name; - } - return name; - } - - protected void emitPreCallSetup(MethodBinding binding, PrintWriter writer) { - super.emitPreCallSetup(binding, writer); - - if (callThroughProcAddress) { - String procAddressVariable = - GLEmitter.PROCADDRESS_VAR_PREFIX + binding.getName(); - writer.println(" final long __addr_ = " + getProcAddressTableExpr + "." + procAddressVariable + ";"); - writer.println(" if (__addr_ == 0) {"); - writer.println(" throw new GLException(\"Method \\\"" + binding.getName() + "\\\" not available\");"); - writer.println(" }"); - } - } - - protected int emitCallArguments(MethodBinding binding, PrintWriter writer, boolean indirect) { - int numEmitted = super.emitCallArguments(binding, writer, indirect); - if (callThroughProcAddress) { - if (numEmitted > 0) { - writer.print(", "); - } - writer.print("__addr_"); - ++numEmitted; - } - - return numEmitted; - } - - /** This class emits the comment for the wrapper method */ - private class WrappedMethodCommentEmitter extends JavaMethodBindingEmitter.DefaultCommentEmitter { - protected void emitBeginning(FunctionEmitter methodEmitter, PrintWriter writer) { - writer.print("Encapsulates function pointer for OpenGL function <br>: "); - } - } -} // end class GLJavaMethodBindingEmitter +} |