diff options
author | Kenneth Russel <[email protected]> | 2001-11-11 21:30:13 +0000 |
---|---|---|
committer | Kenneth Russel <[email protected]> | 2001-11-11 21:30:13 +0000 |
commit | f610ac01f50165b2ea6bc4a81d02abf2e222d876 (patch) | |
tree | 2b54144d82803e6665a371b6eeeae6812a16e3ac /gl4java | |
parent | 3b0e7fd364c6d61b97f4f2daf405b30e662fddc7 (diff) |
Support for NVidia AllocateMemoryNV extension and fixed problem with extensions not being loaded
Diffstat (limited to 'gl4java')
-rw-r--r-- | gl4java/GLContext.java.skel | 44 | ||||
-rw-r--r-- | gl4java/GLFunc14.java | 75 | ||||
-rw-r--r-- | gl4java/GLFunc14JauJNI.java | 90 | ||||
-rw-r--r-- | gl4java/utils/DirectBufferCleanup.java | 110 |
4 files changed, 266 insertions, 53 deletions
diff --git a/gl4java/GLContext.java.skel b/gl4java/GLContext.java.skel index 0bf5461..50aa7c3 100644 --- a/gl4java/GLContext.java.skel +++ b/gl4java/GLContext.java.skel @@ -2449,6 +2449,14 @@ public class GLContext extends Object notifyAll(); // notify gljFree after action is done .. + // Workaround for problem on Windows where extensions do not + // become visible until the first time an OpenGL context is + // made current (at least with NVidia's drivers). + if (firstContextMakeCurrent) { + firstContextMakeCurrent = false; + gljFetchGLFunctions0(null, null, false, true); + } + return result; } @@ -2730,15 +2738,43 @@ public class GLContext extends Object */ public final static native boolean gljFetchOSGLFunctions ( String gllibname, String glulibname, boolean force ); - public final static native boolean gljFetchGLFunctions - ( String gllibname, String glulibname, boolean force ); + public final static boolean gljFetchGLFunctions(String gllibname, + String glulibname, + boolean force) { + return gljFetchGLFunctions0(gllibname, glulibname, force, false); + } + + // This routine is used internally only. On Windows it appears + // that extensions only become visible once an OpenGL context is + // made current for the first time (at least with NVidia's + // drivers). To avoid making drastic changes to the code + // structure, we reload all of the OpenGL functions the first time + // a context is made current. (This could be made more efficient + // by only loading extensions' routines at this time.) + private volatile static boolean firstContextMakeCurrent = true; + private final static native boolean gljFetchGLFunctions0(String gllibname, + String glulibname, + boolean force, + boolean reload); /** * This functions checks the existence of * the GL functions ! */ - public final static native boolean gljTestGLProc - ( String name, boolean verbose ); + public final static boolean gljTestGLProc ( String name, boolean verbose ) { + // Special case any routines which are exposed in a different fashion + if (name.equals("glAllocateMemoryNV")) { + int os = getNativeOSType(); + if (os == OsWindoof) { + name = "wglAllocateMemoryNV"; + } else if (os == OsX11) { + name = "glXAllocateMemoryNV"; + } // else will fail anyway; fall through + } + return gljTestGLProc0(name, verbose); + } + + private static final native boolean gljTestGLProc0(String name, boolean verbose); /** * This functions reads the pixel from the GL frame diff --git a/gl4java/GLFunc14.java b/gl4java/GLFunc14.java index 59555ba..0cf527d 100644 --- a/gl4java/GLFunc14.java +++ b/gl4java/GLFunc14.java @@ -4,35 +4,52 @@ */ -/**
- * @(#) GLFunc14.java
- */
-
-
-package gl4java;
-
-import java.nio.*;
-
-/**
- * The base interface for OpenGL native function mapping
- *
- * @version 2.00, 21. April 1999
- * @author Sven Goethel
- */
-public interface GLFunc14
- extends GLFunc
-{
-
-
-public String glGetString ( int name ) ;
-
-public String getNativeVendor ( ) ;
-public String getNativeVersion ( ) ;
-
-public String getClassVendor ( ) ;
-public String getClassVersion ( ) ;
-
-public static final String[] GL_PROC_NAMES = {
+/** + * @(#) GLFunc14.java + */ + + +package gl4java; + +import java.nio.*; + +/** + * The base interface for OpenGL native function mapping + * + * @version 2.00, 21. April 1999 + * @author Sven Goethel + */ +public interface GLFunc14 + extends GLFunc +{ + + //---------------------------------------------------------------------- + // Special-case routines requiring hand coding + // + + /** Access to the underlying wglAllocateMemoryNV or + glXAllocateMemoryNV routine, if present. Presence of this + routine can be queried by calling GLContext.gljTestGLProc with + the argument "glAllocateMemoryNV". */ + public ByteBuffer glAllocateMemoryNV(int size, + float readFreq, + float writeFreq, + float priority); + + //---------------------------------------------------------------------- + // All other routines below are autogenerated + // + + +public String glGetString ( int name ) ; + +public String getNativeVendor ( ) ; +public String getNativeVersion ( ) ; + +public String getClassVendor ( ) ; +public String getClassVersion ( ) ; + +public static final String[] GL_PROC_NAMES = { /** * C2J Parser Version 3.0 * Jausoft - Sven Goethel Software Development diff --git a/gl4java/GLFunc14JauJNI.java b/gl4java/GLFunc14JauJNI.java index 12a0e12..62b48ac 100644 --- a/gl4java/GLFunc14JauJNI.java +++ b/gl4java/GLFunc14JauJNI.java @@ -4,26 +4,76 @@ */ -/**
- * @(#) GLFunc14JauJNI.java
- */
-
-
-package gl4java;
-
-import java.nio.*;
-
-/**
- * The default implementation class for OpenGL native function mapping
- *
- * @version 2.00, 21. April 1999
- * @author Sven Goethel
- */
-public class GLFunc14JauJNI
- implements GLFunc14
-{
-
-
+/** + * @(#) GLFunc14JauJNI.java + */ + + +package gl4java; + +import java.nio.*; +import gl4java.utils.DirectBufferCleanup; + +/** + * The default implementation class for OpenGL native function mapping + * + * @version 2.00, 21. April 1999 + * @author Sven Goethel + */ +public class GLFunc14JauJNI + implements GLFunc14 +{ + + //---------------------------------------------------------------------- + // Special-case routines requiring hand coding + // + + /** Access to the underlying wglAllocateMemoryNV or + glXAllocateMemoryNV routine, if present. Presence of this + routine can be queried by calling GLContext.gljTestGLProc with + the argument "glAllocateMemoryNV". */ + public ByteBuffer glAllocateMemoryNV(int size, + float readFreq, + float writeFreq, + float priority) { + long address = glAllocateMemoryNV0(size, readFreq, writeFreq, priority); + if (address == 0) { + throw new OutOfMemoryError(); + } + ByteBuffer buf = newDirectByteBuffer(address, size); + registerForCleanup(this, buf); + return buf; + } + + /** This delegates to either wglAllocateMemoryNV or + glXAllocateMemoryNV in the native code, depending on the window + system */ + private native long glAllocateMemoryNV0(int size, float readFreq, float writeFreq, float priority); + + /** This delegates to either wglFreeMemoryNV or glXFreeMemoryNV in + the native code, depending on the window system */ + private native void glFreeMemoryNV0(long addr); + + /** Allocate a direct byte buffer pointing at an arbitrary memory + address -- must be hidden for security reasons */ + private native ByteBuffer newDirectByteBuffer(long addr, int capacity); + + private static volatile DirectBufferCleanup cleanup; + private static synchronized void registerForCleanup(final GLFunc14JauJNI gl, Buffer buf) { + if (cleanup == null) { + cleanup = new DirectBufferCleanup(new DirectBufferCleanup.Callback() { + public void cleanup(long addr) { + gl.glFreeMemoryNV0(addr); + } + }); + } + cleanup.register(buf); + } + + //---------------------------------------------------------------------- + // All other routines below are autogenerated + // + public final native String glGetString ( int name ) ; diff --git a/gl4java/utils/DirectBufferCleanup.java b/gl4java/utils/DirectBufferCleanup.java new file mode 100644 index 0000000..378cd76 --- /dev/null +++ b/gl4java/utils/DirectBufferCleanup.java @@ -0,0 +1,110 @@ +package gl4java.utils; + +import java.lang.ref.PhantomReference; +import java.lang.ref.Reference; +import java.lang.ref.ReferenceQueue; +import java.nio.*; +import java.util.HashMap; +import java.util.Map; + +/** Provides a cleanup mechanism for direct buffers instantiated via + the JNI entry point <code>NewDirectByteBuffer</code>. A direct + buffer can be <i>registered</i> with a DirectBufferCleanup. When + that buffer is reclaimed by the garbage collector, the callback + associated with that DirectBufferCleanup is called on the address + the direct buffer was associated with. */ + +public class DirectBufferCleanup { + + // Put DirectBufferCleanup.c into its own library if extracting just + // this mechanism + // static { + // System.loadLibrary("DirectBufferCleanup"); + // } + + public static interface Callback { + public void cleanup(long addr); + } + + public DirectBufferCleanup(Callback cb) { + this.cb = cb; + refToAddrMap = new HashMap(); + queue = new ReferenceQueue(); + start(); + } + + /** The DirectBufferCleanup contains an internal thread which is + started automatically upon construction. This method starts the + thread again if it is manually stopped via the {@link #stop} + method. */ + public synchronized void start() { + if (t == null) { + t = new Thread(new Runnable() { + public void run() { + while (!done) { + try { + Reference r = queue.remove(); + Long addr = (Long) refToAddrMap.remove(r); + cb.cleanup(addr.longValue()); + r.clear(); + } catch (InterruptedException e) { + } + } + t = null; + } + }); + done = false; + t.start(); + } + } + + /** Stops the internal thread of this DirectBufferCleanup. Should + not typically be necessary. */ + public synchronized void stop() { + done = true; + while (t != null) { + try { + wait(); + } catch (InterruptedException e) { + } + } + } + + /** Registers the given buffer (which must be a direct buffer) for + later cleanup when it is reclaimed by the garbage collector. + + @throw IllegalArgumentException if the passed buffer is not + direct. + */ + + public void register(Buffer buf) throws IllegalArgumentException { + try { + long addr = getDirectBufferAddress(buf); + if (addr == 0) throw new IllegalArgumentException(); + refToAddrMap.put(new PhantomReference(buf, queue), + new Long(addr)); + } catch (ClassCastException e) { + throw new IllegalArgumentException(); + } + } + + //---------------------------------------------------------------------- + // Internals only below this point + // + + private Callback cb; + + // Maps PhantomReferences to addresses + private Map refToAddrMap; + + // Reference queue which gets notified + private ReferenceQueue queue; + + // Thread watching reference queue + private volatile Thread t; + + // Native method providing direct buffer address via JNI + private static native long getDirectBufferAddress(Buffer buf); + + private volatile boolean done = false; +} |