aboutsummaryrefslogtreecommitdiffstats
path: root/gl4java
diff options
context:
space:
mode:
Diffstat (limited to 'gl4java')
-rw-r--r--gl4java/GLContext.java.skel44
-rw-r--r--gl4java/GLFunc14.java75
-rw-r--r--gl4java/GLFunc14JauJNI.java90
-rw-r--r--gl4java/utils/DirectBufferCleanup.java110
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;
+}