From 3583101e586a6fe3306f84d4d34ee764596e0632 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Tue, 24 Jul 2001 12:07:18 +0000 Subject: optimized context switching --- CHANGES.txt | 27 +++- CNativeCode/OpenGL_Win32.c | 26 ++++ CNativeCode/OpenGL_Win32_jawt.c | 69 +++++++++- CNativeCode/OpenGL_X11.c | 26 ++++ CNativeCode/OpenGL_X11_jawt.c | 110 +++++++++++---- CNativeCode/OpenGL_misc.c | 9 +- demos/MiscDemos/gears.java | 7 +- docs-src/UpdateHtml | 2 +- gl4java/GLContext.java.skel | 237 ++++++++++++++++++++++++++------ gl4java/GLRunnable.java | 129 +++++++++++++++++ gl4java/applet/SimpleGLAnimApplet1.java | 41 ++++-- gl4java/awt/GLAnimCanvas.java | 149 ++++++++++---------- gl4java/awt/GLCanvas.java | 180 +++++------------------- gl4java/drawable/GLDrawable.java | 55 ++++++++ makefile | 17 ++- symbols.mak.linux-java2-xf86-ppc-32bit | 3 + 16 files changed, 774 insertions(+), 313 deletions(-) create mode 100644 gl4java/GLRunnable.java diff --git a/CHANGES.txt b/CHANGES.txt index 00f272f..9ec1252 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,6 +1,6 @@ \begin{verbatim} -Last Changes: 19th June 2001 (Version 2.8.0 - PRE-Release 0 (CVS only) ) +Last Changes: 24th July 2001 (Version 2.8.0 - PRE-Release 1 (CVS only) ) Started: July 1997 (Version 0) ----------------- @@ -8,6 +8,31 @@ TOP = NEW DOWN = OLD ----------------- +24th July 2001 (Version 2.8.0 - PRE-Release 1 (CVS only) ) + o Changed Kenneth's manual context switching optimization + to an automatical optimization of context switching + + - introducing gl4java.GLRunnable + as an interface for an animator gl4java.drawable.GLDrawable, + e.g. gl4java.awt.GLAnimCanvas + + - no more flag setting stuff for optimized context switching + + - gljMakeCurrent/gljFree now handles the context switching. + + They now skip freeing the context, if: + + - the component is a gl4java.GLRunnable + + - the thread is not the AWT rendering thread + + - the freeing is not forced + + Otherwise they behave as usual and do a real lock/unlock .. + + I have also added the JAWT lock/unlock calls, in the case, + gljMakeCurrent/gljFree does not really lock/unlock the GL context. + 19th June 2001 (Version 2.8.0 - PRE-Release 0 (CVS only) ) o Added temporary native file access (secure, no filename passing) to gl4java.utils.Tool diff --git a/CNativeCode/OpenGL_Win32.c b/CNativeCode/OpenGL_Win32.c index 6213fdd..8e888e3 100755 --- a/CNativeCode/OpenGL_Win32.c +++ b/CNativeCode/OpenGL_Win32.c @@ -65,6 +65,32 @@ Java_gl4java_GLContext_hasJAWTSurfaceChanged( JNIEnv *env, jobject obj, return JNI_FALSE; } +JNIEXPORT jboolean JNICALL +Java_gl4java_GLContext_lockJAWT( JNIEnv *env, jobject obj, + jobject canvas, + jlong thisWin, jboolean verbose + ) +{ + (void) env; + (void) obj; + (void) canvas; + (void) thisWin; + (void) verbose; + return JNI_TRUE; +} + +JNIEXPORT jboolean JNICALL +Java_gl4java_GLContext_unlockJAWT( JNIEnv *env, jobject obj, + jlong thisWin, jboolean verbose + ) +{ + (void) env; + (void) obj; + (void) thisWin; + (void) verbose; + return JNI_TRUE; +} + JNIEXPORT jboolean JNICALL Java_gl4java_GLContext_openOpenGLNative( JNIEnv *env, jobject obj, jobject canvas) diff --git a/CNativeCode/OpenGL_Win32_jawt.c b/CNativeCode/OpenGL_Win32_jawt.c index 5eefec3..2f69ad7 100755 --- a/CNativeCode/OpenGL_Win32_jawt.c +++ b/CNativeCode/OpenGL_Win32_jawt.c @@ -91,6 +91,71 @@ Java_gl4java_GLContext_hasJAWTSurfaceChanged( JNIEnv *env, jobject obj, return JNI_FALSE; } +JNIEXPORT jboolean JNICALL +Java_gl4java_GLContext_lockJAWT( JNIEnv *env, jobject obj, + jobject canvas, + jlong thisWin, jboolean verbose + ) +{ + jboolean ret = JNI_TRUE; + JAWTDataHolder * pData = (JAWTDataHolder *) ( (PointerHolder) thisWin ); + + if(pData==0) + { + fprintf(stderr, "GL4Java ERROR: LockAWT NO JAWT Holder exist ! (pData=%p, thisWin=%lX) ...\n", pData, (long)thisWin); + fflush(stderr); + return JNI_FALSE; + } + + if(jawt_open(env, canvas, pData, verbose)==JNI_FALSE || + pData->result==JNI_FALSE + ) + { + fprintf(stderr,"\nGL4Java ERROR: LockAWT could not open JAWT reference!\n"); + fflush(stderr); + ret=JNI_FALSE; + jawt_close_unlock(env, pData, JNI_FALSE); + return ret; + } + + if(jawt_lock(env, pData, JNI_FALSE, verbose)==JNI_FALSE || + pData->result==JNI_FALSE + ) + { + /* this can happen: + if ( (pJData->lock & JAWT_LOCK_SURFACE_CHANGED) != 0 ) + + In this case, we need a new GLXContext ... + + This has to be queried by the java class, + while using the native method hasJAWTSurfaceChanged ! + */ + if(verbose) + { + fprintf(stderr,"\nGL4Java ERROR: LockAWT could not lock JAWT reference!\n"); + fflush(stderr); + } + ret=JNI_FALSE; + jawt_close_unlock(env, pData, JNI_FALSE); + return ret; + } + return ret; +} + +JNIEXPORT jboolean JNICALL +Java_gl4java_GLContext_unlockJAWT( JNIEnv *env, jobject obj, + jlong thisWin, jboolean verbose + ) +{ + jboolean ret = JNI_TRUE; + JAWTDataHolder * pData = (JAWTDataHolder *) ( (PointerHolder) thisWin ); + + jawt_close_unlock(env, pData, verbose); + + return ret; +} + + JNIEXPORT jboolean JNICALL Java_gl4java_GLContext_openOpenGLNative( JNIEnv *env, jobject obj, jobject canvas) @@ -489,7 +554,7 @@ Java_gl4java_GLContext_gljFreeNative( JNIEnv *env, jobject obj, } if(pData!=NULL) - jawt_close_unlock(env, pData, verbose); + jawt_close_unlock(env, pData, JNI_FALSE); return ret; } @@ -642,7 +707,7 @@ Java_gl4java_GLContext_gljDestroyNative( JNIEnv *env, jobject obj, gc = 0; thisWin = 0; - jawt_free_close_unlock(env, &pData, verbose); + jawt_free_close_unlock(env, &pData, JNI_FALSE); pData=0; ret=JNI_TRUE; // force .. diff --git a/CNativeCode/OpenGL_X11.c b/CNativeCode/OpenGL_X11.c index 14510ec..f95ee8a 100644 --- a/CNativeCode/OpenGL_X11.c +++ b/CNativeCode/OpenGL_X11.c @@ -102,6 +102,32 @@ Java_gl4java_GLContext_hasJAWTSurfaceChanged( JNIEnv *env, jobject obj, return JNI_FALSE; } +JNIEXPORT jboolean JNICALL +Java_gl4java_GLContext_lockJAWT( JNIEnv *env, jobject obj, + jobject canvas, + jlong thisWin, jboolean verbose + ) +{ + (void) env; + (void) obj; + (void) canvas; + (void) thisWin; + (void) verbose; + return JNI_TRUE; +} + +JNIEXPORT jboolean JNICALL +Java_gl4java_GLContext_unlockJAWT( JNIEnv *env, jobject obj, + jlong thisWin, jboolean verbose + ) +{ + (void) env; + (void) obj; + (void) thisWin; + (void) verbose; + return JNI_TRUE; +} + /* * OpenGL_GLFrame_openOpenGL * diff --git a/CNativeCode/OpenGL_X11_jawt.c b/CNativeCode/OpenGL_X11_jawt.c index bb91c5c..21231ef 100644 --- a/CNativeCode/OpenGL_X11_jawt.c +++ b/CNativeCode/OpenGL_X11_jawt.c @@ -125,17 +125,6 @@ Java_gl4java_GLContext_useJAWT( JNIEnv *env, jobject obj ) return JNI_TRUE; } -JNIEXPORT jboolean JNICALL -Java_gl4java_GLContext_hasJAWTSurfaceChanged( JNIEnv *env, jobject obj, - jlong thisWin ) -{ - JAWTDataHolder * pData = (JAWTDataHolder *) ( (PointerHolder) thisWin ); - (void)env; - (void)obj; - - return (pData->lock & JAWT_LOCK_SURFACE_CHANGED) != 0 ; -} - /* * OpenGL_GLFrame_openOpenGL * @@ -578,6 +567,82 @@ Java_gl4java_GLContext_gljResizeNative( JNIEnv *env, jobject obj, return; } +JNIEXPORT jboolean JNICALL +Java_gl4java_GLContext_hasJAWTSurfaceChanged( JNIEnv *env, jobject obj, + jlong thisWin ) +{ + JAWTDataHolder * pData = (JAWTDataHolder *) ( (PointerHolder) thisWin ); + (void)env; + (void)obj; + + return (pData->lock & JAWT_LOCK_SURFACE_CHANGED) != 0 ; +} + +JNIEXPORT jboolean JNICALL +Java_gl4java_GLContext_lockJAWT( JNIEnv *env, jobject obj, + jobject canvas, + jlong thisWin, jboolean verbose + ) +{ + jboolean ret = JNI_TRUE; + JAWTDataHolder * pData = (JAWTDataHolder *) ( (PointerHolder) thisWin ); + + if(pData==0) + { + fprintf(stderr, "GL4Java ERROR: LockAWT NO JAWT Holder exist ! (pData=%p, thisWin=%lX) ...\n", pData, (long)thisWin); + fflush(stderr); + return JNI_FALSE; + } + + if(jawt_open(env, canvas, pData, verbose)==JNI_FALSE || + pData->result==JNI_FALSE + ) + { + fprintf(stderr,"\nGL4Java ERROR: LockAWT could not open JAWT reference!\n"); + fflush(stderr); + ret=JNI_FALSE; + jawt_close_unlock(env, pData, JNI_FALSE); + return ret; + } + + if(jawt_lock(env, pData, JNI_FALSE, verbose)==JNI_FALSE || + pData->result==JNI_FALSE + ) + { + /* this can happen: + if ( (pJData->lock & JAWT_LOCK_SURFACE_CHANGED) != 0 ) + + In this case, we need a new GLXContext ... + + This has to be queried by the java class, + while using the native method hasJAWTSurfaceChanged ! + */ + if(verbose) + { + fprintf(stderr,"\nGL4Java ERROR: LockAWT could not lock JAWT reference!\n"); + fflush(stderr); + } + ret=JNI_FALSE; + jawt_close_unlock(env, pData, JNI_FALSE); + return ret; + } + return ret; +} + +JNIEXPORT jboolean JNICALL +Java_gl4java_GLContext_unlockJAWT( JNIEnv *env, jobject obj, + jlong thisWin, jboolean verbose + ) +{ + jboolean ret = JNI_TRUE; + JAWTDataHolder * pData = (JAWTDataHolder *) ( (PointerHolder) thisWin ); + + jawt_close_unlock(env, pData, verbose); + + return ret; +} + + JNIEXPORT jboolean JNICALL Java_gl4java_GLContext_gljMakeCurrentNative( JNIEnv *env, jobject obj, jobject canvas, @@ -592,14 +657,14 @@ Java_gl4java_GLContext_gljMakeCurrentNative( JNIEnv *env, jobject obj, if(pData==0) { - fprintf(stderr, "GL4Java ERROR: gljUse NO JAWT Holder exist ! (pData=%p, thisWin=%lX) ...\n", pData, (long)thisWin); + fprintf(stderr, "GL4Java ERROR: MakeCurrent NO JAWT Holder exist ! (pData=%p, thisWin=%lX) ...\n", pData, (long)thisWin); fflush(stderr); return JNI_FALSE; } if(glContext==0) { - fprintf(stderr, "GL4Java ERROR: gljUse NO actual GC was created ...\n"); + fprintf(stderr, "GL4Java ERROR: MakeCurrent NO actual GC was created ...\n"); fflush(stderr); return JNI_FALSE; } @@ -682,25 +747,12 @@ Java_gl4java_GLContext_gljFreeNative( JNIEnv *env, jobject obj, } } - jawt_close_unlock(env, pData, verbose); + if(pData!=NULL) + jawt_close_unlock(env, pData, JNI_FALSE); return ret; } -JNIEXPORT jboolean JNICALL -Java_gl4java_GLContext_gljIsContextCurrentNative( JNIEnv *env, jobject obj, - jlong glContext - ) -{ - GLXContext ctx = disp__glXGetCurrentContext(); - - if(ctx==(GLXContext)((PointerHolder)glContext)) - return JNI_TRUE; - - return JNI_FALSE; -} - - JNIEXPORT jboolean JNICALL Java_gl4java_GLContext_gljDestroyNative( JNIEnv *env, jobject obj, jobject canvas ) @@ -846,7 +898,7 @@ Java_gl4java_GLContext_gljDestroyNative( JNIEnv *env, jobject obj, } } - jawt_free_close_unlock(env, &pData, verbose); + jawt_free_close_unlock(env, &pData, JNI_FALSE); if(ret==JNI_TRUE) { diff --git a/CNativeCode/OpenGL_misc.c b/CNativeCode/OpenGL_misc.c index fabd968..ff00cce 100644 --- a/CNativeCode/OpenGL_misc.c +++ b/CNativeCode/OpenGL_misc.c @@ -6,6 +6,7 @@ #include #include #include "glxtool.h" + #include #endif #ifdef _WIN32_ @@ -863,17 +864,17 @@ Java_gl4java_GLContext_gljTestGLProc ( } -JNIEXPORT jint JNICALL +JNIEXPORT jlong JNICALL Java_gl4java_GLContext_gljGetCurrentContext( JNIEnv *env, jobject obj ) { #ifdef _WIN32_ - return (jint) disp__wglGetCurrentContext(); + return (jlong) ((PointerHolder)disp__wglGetCurrentContext()); #else #ifdef _MAC_OS9_ - return (jint) aglGetCurrentContext(); + return (jlong) ((PointerHolder)aglGetCurrentContext()); #else - return (jint) disp__glXGetCurrentContext(); + return (jlong) ((PointerHolder)disp__glXGetCurrentContext()); #endif #endif } diff --git a/demos/MiscDemos/gears.java b/demos/MiscDemos/gears.java index b80e3e1..dd4cb13 100644 --- a/demos/MiscDemos/gears.java +++ b/demos/MiscDemos/gears.java @@ -30,8 +30,6 @@ public class gears extends SimpleGLAnimApplet1 public void init(boolean showGL) { super.init(); - GLContext.gljNativeDebug = false; - GLContext.gljClassDebug = false; Dimension d = getSize(); @@ -57,6 +55,7 @@ public class gears extends SimpleGLAnimApplet1 GLContext.gljNativeDebug = true; GLContext.gljClassDebug = true; + GLContext.gljThreadDebug = true; while(args.length>i) { @@ -93,7 +92,7 @@ public class gears extends SimpleGLAnimApplet1 if(perftest) GLContext.gljClassDebug=true; - GLContext.loadNativeLibraries(gljLib, glLib, gluLib); + GLContext.doLoadNativeLibraries(gljLib, glLib, gluLib); if(perftest) GLContext.gljClassDebug=false; @@ -121,6 +120,8 @@ public class gears extends SimpleGLAnimApplet1 { applet.canvas.setUseFpsSleep(false); applet.canvas.setUseRepaint(false); + applet.canvas.setUseYield(false); + System.out.println("useFpsSleep: "+ applet.canvas.getUseFpsSleep()); System.out.println("useRepaint: "+ diff --git a/docs-src/UpdateHtml b/docs-src/UpdateHtml index b8b8bfb..d133843 100755 --- a/docs-src/UpdateHtml +++ b/docs-src/UpdateHtml @@ -16,7 +16,7 @@ if [ \( "$1" = "GL4Java" \) -o \( -z "$1" \) ] ; then $LATEX GL4Java.tex $LATEX GL4Java.tex $DVIPS GL4Java.dvi - $DVIPDF -p a4 -r 600 GL4Java.dvi + $DVIPDF -p a4 -r 600 -z 9 GL4Java.dvi mv GL4Java.pdf ../docs/. $LATEX2HTML -html_version 4.0,table,math,i18n -prefix "glj_" \ -show_section_numbers \ diff --git a/gl4java/GLContext.java.skel b/gl4java/GLContext.java.skel index f5518a1..eac6bc5 100644 --- a/gl4java/GLContext.java.skel +++ b/gl4java/GLContext.java.skel @@ -249,7 +249,7 @@ public class GLContext extends Object * * Each is dezimal ! */ - public final static String version = __SED_CLASS_VERSION__ ; + public final static String version = __SED_CLASS_VERSION__ ; /** * Flag's to enable/disable verbose Information. @@ -393,6 +393,8 @@ public class GLContext extends Object */ protected Component _compHeavy = null; + protected Thread awtThread = null; + /** * Variable to tell is where windows or not (X11) * Usally X11 ;-)) @@ -1143,6 +1145,11 @@ public class GLContext extends Object } else System.out.println("got empty Component"); + awtThread = Thread.currentThread(); + + if(gljThreadDebug) + System.out.println("GLContext: locked awt-Thread: "+awtThread); + if(_comp!=null && _gr!=null) { int i = 0; @@ -1169,6 +1176,7 @@ public class GLContext extends Object System.out.println("GLContext GLContext() failed"); } } + /** * * Constructor @@ -2185,6 +2193,58 @@ public class GLContext extends Object private Thread ctxThread = null; private Thread nextThread = null; + /** + * + * gljIsCurrent checks + * if the current Thread holds the GL context of this + * GLContext instance ! + * + * @return boolean + * + * @see gl4java.GLContext#gljIsRequested + * @see gl4java.GLContext#gljMakeCurrent + * @see gl4java.GLContext#getNativeGLContext + * @see gl4java.GLContext#gljGetCurrentContext + */ + public synchronized final boolean gljIsCurrent() + { + if ( ! isInitialized || !glEnabled ) + return false; + + Thread thisThread = Thread.currentThread(); + + if (ctxThread!=null && ctxThread==thisThread && glContext==gljGetCurrentContext()) + return true; + + return false; + } + + /** + * + * gljIsRequested checks + * if the this GLContext instance's native context + * is requested by another thread ! + * + * @return boolean + * + * @see gl4java.GLContext#gljIsCurrent + * @see gl4java.GLContext#gljMakeCurrent + * @see gl4java.GLContext#getNativeGLContext + * @see gl4java.GLContext#gljGetCurrentContext + */ + public synchronized final boolean gljIsRequested() + { + if ( ! isInitialized || !glEnabled ) + return false; + + Thread thisThread = Thread.currentThread(); + + if (nextThread!=null && nextThread!=thisThread) + return true; + + return false; + } + /** * * gljMakeCurrent checks whether GL4Java is initializes @@ -2192,6 +2252,18 @@ public class GLContext extends Object * *

* + * This functions now optimizes the context-switch ! + * + * The context is changed, only if : + *

+    	- another thread has requested this context -> release it
+	  this gives the other thread a chance to get it ..
+
+	- this thread does not own the current context
+    * 
+ * + *

+ * * You MUST encapsulate your OpenGL call's within: *

     	- gljMakeCurrent()
@@ -2234,8 +2306,12 @@ public class GLContext extends Object
 	      * that the same thread enters this point twice,
 	      * before calling gljFree !
 	      */
-	     if (ctxThread!=null && ctxThread==thisThread)
-		     gljFree();
+	     if(gljThreadDebug && !dbgPrinted)
+	     {
+	         System.out.println("wait-current: "+thisThread+" for earmarked: "+nextThread);
+	         System.out.println("\tfreeing context force .. ctxThread="+ctxThread);
+	     }
+	     gljFree(true); // force freeing the context
 
 	     try {
 		  // wait till earmarked nextThread has its chance ..
@@ -2262,6 +2338,19 @@ public class GLContext extends Object
 		     System.out.println("\tctxThread="+ctxThread+", next="+nextThread);
 		     dbgPrinted=true;
 	     }
+             if( _comp instanceof GLRunnable )
+	     {
+	     	if ( ((GLRunnable)_comp).ownsThread(ctxThread) )
+		{
+			synchronized (_comp) {
+				((GLRunnable)_comp).freeGLContext();
+				((GLRunnable)_comp).notifyAll();
+			}
+			notifyAll();
+		        if(gljThreadDebug)
+				System.out.println("\tfreeGLContext -> "+ctxThread);
+		}
+	     }
 
 	     try {
 		  // wait for gljFree to release the GLXContext
@@ -2269,16 +2358,27 @@ public class GLContext extends Object
 	     } catch (InterruptedException e) { }
 	}
 
+	boolean result = false;
+
+	/* is this thread allready owning the context ? */
+        if ( ctxThread==thisThread )
+	{
+		result = lockJAWT(_comp, windowHandle, gljThreadDebug);
+		if(gljThreadDebug)
+		     System.out.println("MakeCurrent: "+thisThread+" no CTX change, allready own, lockJAWT: "+result);
+		return result;
+	}
+
 	ctxThread = thisThread ; // blocking asap ..
 
         if(gljThreadDebug)
 	{
 		if(nextThread==thisThread)
 		{
-		     System.out.println(thisThread+" ");
+		     System.out.println("MakeCurrent: "+thisThread+" ");
 		     System.out.println("\tctxThread="+ctxThread+", next:=NULL");
 	        } else {
-		     System.out.println(thisThread);
+		     System.out.println("MakeCurrent: "+thisThread);
 		     System.out.println("\tctxThread="+ctxThread+", next="+nextThread);
 		}
 	}
@@ -2289,8 +2389,8 @@ public class GLContext extends Object
         if(nextThread==thisThread)
 	     nextThread = null;
 
-        boolean result =  gljMakeCurrentNative( _comp, displayHandle, 
-	                                        windowHandle, glContext);
+        result =  gljMakeCurrentNative( _comp, displayHandle, 
+	                                windowHandle, glContext);
 
 	/**
 	 * If glXMakeCurrent failed, nobody holds this GLXContext ..
@@ -2346,17 +2446,24 @@ public class GLContext extends Object
     *
     * @deprecated The argument freeContextFirst is obsolete !
     */ 
-    public synchronized final boolean gljMakeCurrent(boolean freeContextFirst)
+    public final boolean gljMakeCurrent(boolean freeContextFirst)
     {
         return gljMakeCurrent();
     }
 
+    /**
+     * if using JAWT, this function handles the JAWT lock also
+     */
     private final static native boolean gljMakeCurrentNative(
     						Component canvas,
     						long disp, 
     					        long thisWin,
 					        long glContext);
 
+    private final static native boolean lockJAWT(
+    						Component canvas,
+    					        long thisWin, boolean verbose);
+
    /**
     *
     * gljGetCurrentContext fetches the current native
@@ -2364,7 +2471,7 @@ public class GLContext extends Object
     *
     * @return 		int
     */ 
-    public final static native int gljGetCurrentContext();
+    public final static native long gljGetCurrentContext();
 
     /**
      *
@@ -2421,64 +2528,106 @@ public class GLContext extends Object
      *
      * This MUST be called at last in your display function !
      *
-     * @return 		void
+     * 

+ * + * This functions now optimizes the context-switch ! + * + * The context is changed, only if : + *

+    	- another thread has requested this context -> release it
+     * 
+ * + *

+ * + * @return boolean * + * @see gl4java.GLContext#gljFree + * @see gl4java.GLContext#gljIsCurrent + * @see gl4java.GLContext#gljIsRequested * @see gl4java.GLContext#gljMakeCurrent * @see gl4java.GLContext#gljSwap * @see gl4java.awt.GLCanvas#display * @see gl4java.awt.GLCanvas#sDisplay */ - public synchronized final boolean gljFree() + public final boolean gljFree() + { + return gljFree(false); + } + + /** + * + * gljFree free´s the GL Context + * + * This MUST be called at last in your display function ! + * + *

+ * + * This functions now optimizes the context-switch ! + * + * The context is changed, only if one of the following is true: + *

+    	- another thread has requested this context
+	- the force flag is true
+	- this thread is the AWT thread
+	- the component of this context does _not_ implement GLRunnable
+     * 
+ * + *

+ * + * @return boolean + * + * @see gl4java.GLContext#gljIsCurrent + * @see gl4java.GLContext#gljIsRequested + * @see gl4java.GLContext#gljMakeCurrent + * @see gl4java.GLContext#gljSwap + * @see gl4java.GLRunnable#run + */ + public synchronized final boolean gljFree(boolean force) { if ( ! isInitialized ) return false; + boolean result = true; Thread thisThread = Thread.currentThread(); - boolean dbgPrinted = false; - /** - * I do skip a lock for the gljFree semantics, - * because: - * - to minimize a deadlock - * - believing that gljFree is semantically the last call ;-) - * - see above -> redundant - while (ctxThread!=null && ctxThread!=thisThread) - { - if(gljThreadDebug && !dbgPrinted) - { - System.out.println("* wait: "+thisThread); - System.out.println("\tctxThread="+ctxThread+", next="+nextThread); - dbgPrinted=true; - } - - try { - // wait for gljMakeCurrent to lock the GLXContext - wait(); - } catch (InterruptedException e) { } - } + if( thisThread == awtThread || (_comp instanceof GLRunnable) == false) + force=true; - if(gljThreadDebug) - { - System.out.println("*: "+thisThread); - System.out.println("\tctxThread="+ctxThread+", next="+nextThread); - } + /** + * only free the context, if another thread does + * request this context ... + * or the force-flag is true */ - - - boolean result = - gljFreeNative ( _comp, displayHandle, + if ( force==true || + ( nextThread!=null && nextThread!=thisThread && ctxThread==thisThread ) + ) + { + result = gljFreeNative ( _comp, displayHandle, windowHandle, glContext); - ctxThread = null ; - notifyAll(); + ctxThread = null ; + notifyAll(); + if(gljThreadDebug) + System.out.println("gljFree: "+thisThread+" gljFreeNative result: "+result); + } else { + result = unlockJAWT(windowHandle, false); + notifyAll(); + if(gljThreadDebug) + System.out.println("gljFree: "+thisThread+" no CTX change, no requests, unlockJAWT: "+result); + } return result; } - private final static native boolean gljFreeNative( Component canvas, + /** + * if using JAWT, this function handles the JAWT unlock also + */ + private final static native boolean gljFreeNative( Component canvas, long disp, long thisWin, long glContext ); + private final static native boolean unlockJAWT(long thisWin, boolean verbose); + /** * swap method are for double buffering */ diff --git a/gl4java/GLRunnable.java b/gl4java/GLRunnable.java new file mode 100644 index 0000000..ca66af5 --- /dev/null +++ b/gl4java/GLRunnable.java @@ -0,0 +1,129 @@ +/** + * @(#) GLRunnable.java + */ +package gl4java; + +import java.lang.*; + +/** + * This is the interface for a threaded renderer (animator thread). + * + * If an animation class, e.g. {@link gl4java.awt.GLAnimCanvas}, + * implements {@link gl4java.drawable.GLDrawable} and this interface, + * you will benefit from the new context handling {@link gl4java.GLContext#gljFree}. + * + * @see gl4java.GLContext + * @see gl4java.drawable.GLDrawable + * @see gl4java.awt.GLAnimCanvas + */ +public interface GLRunnable extends Runnable +{ + /** + * This creates and start one singleton unique thread ! + */ + public void start(); + + /** + * This stops and destroys (deferred) our singleton unique thread ! + */ + public void stop(); + + /** + * Identifies this object with the given thread .. + * If this object owns this thread, it must return true ! + */ + public boolean ownsThread(Thread thread); + + /** + * The running loop for animations + * which initiates the call of display + * + * Be sure to force freeing the GL context + * with {@link gl4java.GLContext#gljFree}(true), if: + *

+	 	- you exit this run loop
+		- you suspend your thread -> wait
+		- you kill your thread ..
+	 *  
+ * + * Also be sure, to implement this Runnable as Java2 does recomends ! + * Look at the example implementation {@link gl4java.awt.GLAnimCanvas#run} ! + * + * @see gl4java.awt.GLAnimCanvas#run + * @see #setSuspended + */ + public void run(); + + /** + * Here we can (re)start or suspend animation ... + * + * If the thread should be (re)started and is not alive -> killed, + * or never be started, it will be started ! + * + * @param suspend if true the thread will be suspended, + * if false, the thread will be (re)started + * + * @see #isAlive + * @see #start + */ + public void setSuspended(boolean suspend); + + /** + * Here we can (re)start or suspend animation ... + * + * If the thread should be (re)started and is not alive -> killed, + * or never be started, it will be started ! + * + * @param suspend if true the thread will be suspended, + * if false, the thread will be (re)started + * + * @param reInit if true the ReInit will be called additionally, + * where the user can set additional initialisations + * + * @see #ReInit + * @see #isAlive + * @see #start + * @see #run + */ + public void setSuspended(boolean suspend, boolean reInit); + + /** + * is the thread alive, means is started and not died ? + * + * @see #run + * @see #setSuspended + * @see #start + * @see #stop + */ + public boolean isAlive(); + + /** + * is the thread suspended, means is started but waiting, + * or not alive (ok :-| - but it is practical) + * + * @see #run + * @see #setSuspended + * @see #start + * @see #stop + */ + public boolean isSuspended(); + + /** + * ReInit should be overwritten by you, + * to enter your re-initialisation within setSuspended(false) + * + * @see #setSuspended + */ + public void ReInit(); + + /** + * Forces this thread to release it's GLContext ! + * + * To ensure this, this thread enables itself, + * and calls gljFree(true) to force the release ! + * + * @see #setSuspended + * @see #run + */ + public void freeGLContext(); +} diff --git a/gl4java/applet/SimpleGLAnimApplet1.java b/gl4java/applet/SimpleGLAnimApplet1.java index 84ef869..08b85d5 100644 --- a/gl4java/applet/SimpleGLAnimApplet1.java +++ b/gl4java/applet/SimpleGLAnimApplet1.java @@ -26,6 +26,7 @@ public class SimpleGLAnimApplet1 extends Applet public TextField textFps = null; public Checkbox checkUseRepaint = null; public Checkbox checkUseFpsSleep = null; + public Checkbox checkUseYield = null; public Button buttonReStart = null; @@ -38,17 +39,11 @@ public class SimpleGLAnimApplet1 extends Applet setLayout(new BorderLayout()); Panel pan = new Panel(); - pan.setLayout(new GridLayout(2,3)); + pan.setLayout(new GridLayout(2,4)); buttonInfo = new Button("GL4Java"); pan.add(buttonInfo); - checkUseRepaint = new Checkbox("repaint", true); - pan.add(checkUseRepaint); - - checkUseFpsSleep = new Checkbox("fps-sleep", true); - pan.add(checkUseFpsSleep); - buttonReStart = new Button("start/stop"); pan.add(buttonReStart); @@ -58,20 +53,37 @@ public class SimpleGLAnimApplet1 extends Applet textFps=new TextField("0000000000"); pan.add(textFps); + checkUseRepaint = new Checkbox("repaint", true); + pan.add(checkUseRepaint); + + checkUseFpsSleep = new Checkbox("fps-sleep", true); + pan.add(checkUseFpsSleep); + + checkUseYield = new Checkbox("yield", true); + pan.add(checkUseYield); + add("South",pan); } + public void setCheckButtons() + { + checkUseFpsSleep.setState(canvas.getUseFpsSleep()); + checkUseRepaint.setState(canvas.getUseRepaint()); + checkUseYield.setState(canvas.getUseYield()); + } + public void start() { if(GLContext.gljClassDebug) System.out.println("SGLApplet start .."); - checkUseFpsSleep.setState(canvas.getUseFpsSleep()); - checkUseRepaint.setState(canvas.getUseRepaint()); + setCheckButtons(); + buttonInfo.addMouseListener(this); checkUseRepaint.addItemListener(this); checkUseFpsSleep.addItemListener(this); + checkUseYield.addItemListener(this); buttonReStart.addMouseListener(this); buttonFps.addMouseListener(this); canvas.addMouseListener(this); @@ -90,6 +102,7 @@ public class SimpleGLAnimApplet1 extends Applet buttonInfo.removeMouseListener(this); checkUseRepaint.removeItemListener(this); checkUseFpsSleep.removeItemListener(this); + checkUseYield.removeItemListener(this); buttonReStart.removeMouseListener(this); buttonFps.removeMouseListener(this); canvas.removeMouseListener(this); @@ -237,6 +250,16 @@ public class SimpleGLAnimApplet1 extends Applet checkUseFpsSleep.getState()); } } + if( comp.equals(checkUseYield ) ) + { + if(canvas!=null) + { + canvas.setUseYield(checkUseYield.getState()); + System.out.println("canvas uses Yield "+ + checkUseYield.getState()); + } + } + setCheckButtons(); } public void actionPerformed(ActionEvent event) diff --git a/gl4java/awt/GLAnimCanvas.java b/gl4java/awt/GLAnimCanvas.java index b16206c..9268db8 100644 --- a/gl4java/awt/GLAnimCanvas.java +++ b/gl4java/awt/GLAnimCanvas.java @@ -131,7 +131,7 @@ import java.lang.Math; * */ public class GLAnimCanvas extends GLCanvas - implements Runnable + implements GLRunnable { /** * To support frames per scounds, @@ -173,7 +173,7 @@ public class GLAnimCanvas extends GLCanvas protected boolean threadSuspended = false; static { - if(GLContext.loadNativeLibraries(null, null, null)==false) + if(GLContext.doLoadNativeLibraries(null, null, null)==false) System.out.println("GLAnimCanvas could not load def. native libs."); } @@ -286,14 +286,12 @@ public class GLAnimCanvas extends GLCanvas { } - protected boolean useRepaint = true; + protected boolean useRepaint = false; protected boolean useFpsSleep = true; protected boolean useYield = true; - protected boolean useSDisplay = true; - /** * The normal behavior is to use 'repaint' * within the AWT-Event Thread to render. @@ -310,7 +308,7 @@ public class GLAnimCanvas extends GLCanvas * @see gl4java.awt.GLCanvas#sDisplay * @see gl4java.awt.GLAnimCanvas#setUseFpsSleep */ - public void setUseRepaint(boolean b) + public synchronized void setUseRepaint(boolean b) { useRepaint = b; } @@ -327,7 +325,7 @@ public class GLAnimCanvas extends GLCanvas * @see gl4java.awt.GLCanvas#sDisplay * @see gl4java.awt.GLAnimCanvas#setUseRepaint */ - public void setUseFpsSleep(boolean b) + public synchronized void setUseFpsSleep(boolean b) { useFpsSleep = b; } @@ -338,13 +336,6 @@ public class GLAnimCanvas extends GLCanvas useYield = b; } - /** The default behavior, if not using repaints, is to call - sDisplay() in the thread's main loop; set this to false to - call display() directly. */ - public void setUseSDisplay(boolean val) { - useSDisplay = val; - } - public boolean getUseRepaint() { return useRepaint; @@ -360,15 +351,19 @@ public class GLAnimCanvas extends GLCanvas return useYield; } - public boolean getUseSDisplay() - { - return useSDisplay; - } + /** + * Identifies this object with the given thread .. + * If this object owns this thread, it must return true ! + */ + public boolean ownsThread(Thread thread) + { + return killme!=null && killme==thread ; + } - /** - * HERE WE DO HAVE OUR RUNNING THREAD ! - * WE NEED STUFF LIKE THAT FOR ANIMATION ;-) - */ + /** + * HERE WE DO HAVE OUR RUNNING THREAD ! + * WE NEED STUFF LIKE THAT FOR ANIMATION ;-) + */ public void start() { if(killme == null) @@ -409,12 +404,27 @@ public class GLAnimCanvas extends GLCanvas protected boolean shallWeRender = true; protected boolean isRunning = false; + protected boolean forceGLFree = false; private long _fDelay = 0; private long _fDelay_Frames = 10; private boolean _fDelaySync=true; private boolean _fDelayRun=false; + /** + * Forcec this thread to release it's GLContext ! + * + * To ensure this, this thread enables itself, + * and calls gljFree(true) to force the release ! + * + * @see gl4java.awt.GLAnimCanvas#run + * @see gl4java.GLContext#gljMakeCurrent + */ + public void freeGLContext() + { + forceGLFree=true; + } + /** * The running loop for animations * which initiates the call of display @@ -428,10 +438,7 @@ public class GLAnimCanvas extends GLCanvas isRunning = true; - boolean firstRender = true; - int numInitRetries = 1; - int numMakeCurrentRetries = 1; synchronized (this) { globalThreadNumber++; @@ -441,56 +448,54 @@ public class GLAnimCanvas extends GLCanvas { if(cvsIsInit()) { - if (firstRender) { - if (!getAutoMakeContextCurrent()) { - synchronized (this) { - if (!glj.gljMakeCurrent()) { - System.err.println("Error making context current (" + - numMakeCurrentRetries + ")..."); - ++numMakeCurrentRetries; - try { - Thread.currentThread().sleep(100); - } catch (Exception e) { - } - continue; - } - } - System.err.println("Context made current in AnimCanvas's thread"); - } - firstRender = false; - } - - /* DRAW THE TINGS .. */ - if (shallWeRender) - { - if(useRepaint) - repaint(); - else { - if (useSDisplay) { - sDisplay(); - } else { - display(); - } - } - } else { - synchronized (this) { - threadSuspended=true; - } - } - - if(fps_isCounting) - fps_frames++; + // if another thread want's to do use do .. + if(forceGLFree) + { + glj.gljFree(true); + forceGLFree=false; + if(GLContext.gljThreadDebug) + System.out.println("GLAnimCanvas: forceGLFree(1) - gljFree"); + } + else if (shallWeRender) + { + /* DRAW THE TINGS .. */ + if(useRepaint) + repaint(); + else + sDisplay(); + + if(fps_isCounting) + fps_frames++; + + } else { + synchronized (this) { + glj.gljFree(true); + threadSuspended=true; + } + } } else { - System.err.println("Waiting for canvas to initialize (" + - numInitRetries + ")..."); - ++numInitRetries; + if(GLContext.gljThreadDebug) + { + System.err.println("Waiting for canvas to initialize (" + + numInitRetries + ")..."); + } + ++numInitRetries; try { Thread.currentThread().sleep(100); } catch (Exception e) { } } + // if another thread want's to do use do .. + if(forceGLFree) + { + glj.gljFree(true); + forceGLFree=false; + if(GLContext.gljThreadDebug) + System.out.println("GLAnimCanvas: forceGLFree(2) - gljFree"); + } + try { if(useFpsSleep) { @@ -516,6 +521,7 @@ public class GLAnimCanvas extends GLCanvas } if (threadSuspended) { + glj.gljFree(true); stopFpsCounter(); synchronized (this) { while (threadSuspended) @@ -526,10 +532,8 @@ public class GLAnimCanvas extends GLCanvas {} } - if (getAutoMakeContextCurrent()) { - if(glj!=null) - glj.gljFree(); // just to be sure .. - } + if(glj!=null) + glj.gljFree(true); // just to be sure .. force freeing the context synchronized (this) { globalThreadNumber--; @@ -550,7 +554,7 @@ public class GLAnimCanvas extends GLCanvas * @see gl4java.awt.GLAnimCanvas#isAlive * @see gl4java.awt.GLAnimCanvas#start */ - public void setSuspended(boolean suspend) + public synchronized void setSuspended(boolean suspend) { setSuspended(suspend, false); } @@ -567,6 +571,7 @@ public class GLAnimCanvas extends GLCanvas * @param reInit if true the ReInit will be called additionally, * where the user can set additional initialisations * + * @see gl4java.awt.GLAnimCanvas#ReInit * @see gl4java.awt.GLAnimCanvas#isAlive * @see gl4java.awt.GLAnimCanvas#start * @see gl4java.awt.GLAnimCanvas#run diff --git a/gl4java/awt/GLCanvas.java b/gl4java/awt/GLCanvas.java index a7ade2a..041fabb 100644 --- a/gl4java/awt/GLCanvas.java +++ b/gl4java/awt/GLCanvas.java @@ -173,24 +173,6 @@ public class GLCanvas extends Canvas // The list of GLEventListeners private GLEventListenerList listeners = new GLEventListenerList(); - // Indicates whether init() has been called yet. - private volatile boolean initCalled = false; - - // Indicates whether the canvas will permit any calls to init() or - // display() from within the paint() method; defaults to true for - // backward compatibility. - private boolean enableAWTThreadRendering = true; - - // Indicates whether display() automatically makes the canvas's - // GLContext current and frees it each call; defaults to true for - // backward compatibility. On higher-end graphics cards it is - // important to minimize the number of "make current" calls even - // across frames; a GLAnimCanvas running in its own thread, and - // with AWT thread rendering disabled, will only make its - // associated context current once, at the beginning of its - // rendering loop. - private boolean autoMakeContextCurrent = true; - static { if(GLContext.doLoadNativeLibraries(null, null, null)==false) System.out.println("GLCanvas could not load def. native libs."); @@ -403,61 +385,6 @@ public class GLCanvas extends Canvas public final Window getTopLevelWindow() { return topLevelWindow; } - /** Enables/disables calls to init() and display() from within the - AWT thread. If this is enabled (the default, for backward - compatibility with earlier releases), the first call to - paint() from within the AWT thread (typically prompted by a - repaint()) will cause the canvas to be initialized, and - subsequent calls to paint() will cause display() to be called. - If AWT thread rendering is disabled, the AWT thread will not - cause init() or display() to be called if repaint() is called, - and the first call to display() will cause the canvas to be - initialized. This function is present both to work around bugs - in certain vendors' drivers which do not function properly in - multithreaded settings, and to allow improved performance of - GLAnimCanvas. */ - public void setAWTThreadRenderingEnabled(boolean val) { - enableAWTThreadRendering = val; - } - - /** Indicates whether AWT thread rendering is enabled; see {@link - #setAWTThreadRenderingEnabled}. */ - public boolean getAWTThreadRenderingEnabled() { - return enableAWTThreadRendering; - } - - /** Indicates whether the canvas automatically makes its - underlying GLContext current and frees it during each call to - display(); defaults to true for backward compatibility. On - higher-end graphics cards it is important to minimize the - number of "make current" calls even across frames; a - GLAnimCanvas running in its own thread and with AWT thread - rendering disabled will only make its associated context - current once, at the beginning of its rendering loop. */ - public void setAutoMakeContextCurrent(boolean val) { - autoMakeContextCurrent = val; - } - - /** Indicates whether the canvas automatically makes its - underlying GLContext current and frees it during each call to - display(); see {@link #setAutoMakeContextCurrent}. */ - public boolean getAutoMakeContextCurrent() { - return autoMakeContextCurrent; - } - - /** Convenience routine which Enables or disables optimized - context handling by calling {@link - #setAWTThreadRenderingEnabled} and {@link - #setAutoMakeContextCurrent} with the given boolean. */ - public void setOptimizeContextHandling(boolean yesOrNo) { - setAWTThreadRenderingEnabled(yesOrNo); - setAutoMakeContextCurrent(yesOrNo); - } - - public boolean getOptimizeContextHandling() { - return getAWTThreadRenderingEnabled() || getAutoMakeContextCurrent(); - } - /** * this function overrides the Canvas paint method ! * @@ -482,7 +409,7 @@ public class GLCanvas extends Canvas * @see gl4java.awt.GLCanvas#preInit * @see gl4java.awt.GLCanvas#init */ - public synchronized final void paint( Graphics g ) + public final void paint( Graphics g ) { if(glj == null || ( !glj.gljIsInit() && isGLEnabled() ) ) { @@ -521,10 +448,7 @@ public class GLCanvas extends Canvas (float)col.getGreen()/255.0f, (float)col.getBlue()/255.0f, 0.0f); - if (getAWTThreadRenderingEnabled()) { - init(); - initCalled = true; - } + init(); // fetch the top-level window , // to add us as the windowListener @@ -560,14 +484,9 @@ public class GLCanvas extends Canvas /* force a reshape, to be sure .. */ mustResize = true; - - // Free up the OpenGL context for another thread to use - glj.gljFree(); } - if (getAWTThreadRenderingEnabled()) { - sDisplay(); - } + sDisplay(); } /** @@ -710,16 +629,15 @@ public class GLCanvas extends Canvas protected long _f_dur = 0; + /** + * Return the uses milli secounds of the last frame + */ + public long getLastFrameMillis() + { return _f_dur; } + /** * * This is the thread save rendering-method called by paint. - * The actual thread will be set to highes priority befor calling - * 'display'. After 'display' the priority will be reset ! - * - * 'gljFree' will be NOT called after 'display'. - * - * We tested the above to use multi-threading and - * for the demonstration 'glDemos' it works ;-)) ! * * BE SURE, if you want to call 'display' by yourself * (e.g. in the run method for animation) @@ -730,11 +648,35 @@ public class GLCanvas extends Canvas * @see gl4java.awt.GLCanvas#paint * @see gl4java.awt.GLCanvas#display */ - public synchronized final void sDisplay() + public final void sDisplay() { + boolean ok = true; + + if(!cvsIsInit()) + { + return; + } + + if( mustResize ) + { + if( glj.gljMakeCurrent() == true ) + { + size = getSize(); + glj.gljResize( size.width, size.height ) ; + reshape(size.width, size.height); + mustResize = false; + invalidate(); + repaint(100); + glj.gljFree(true); /* force freeing the context here .. */ + } + } + long _s = System.currentTimeMillis(); - display(); + if(ok) + { + display(); + } _f_dur = System.currentTimeMillis()-_s; } @@ -747,7 +689,7 @@ public class GLCanvas extends Canvas *

* The default implementation of display() sends * preDisplay, display and postDisplay events to - * all {@link gl4java.GLEventListener}s associated with this + * all {@link gl4java.drawable.GLEventListener}s associated with this * GLCanvas in the above order. * *

@@ -761,8 +703,8 @@ public class GLCanvas extends Canvas { for_all(gl4java.GLEventListener) SEND display - gljFree() gljSwap() + gljFree() for_all(gl4java.GLEventListener) SEND postDisplay @@ -801,61 +743,15 @@ public class GLCanvas extends Canvas */ public void display() { - if(!cvsIsInit()) - { - return; - } - - if( mustResize ) - { - if (getAutoMakeContextCurrent()) { - if( glj.gljMakeCurrent() == true ) - { - size = getSize(); - glj.gljResize( size.width, size.height ) ; - reshape(size.width, size.height); - mustResize = false; - invalidate(); - repaint(100); - glj.gljFree(); - } - } else { - size = getSize(); - glj.gljResize( size.width, size.height ) ; - if (getAWTThreadRenderingEnabled()) { - reshape(size.width, size.height); - } - mustResize = false; - if (getAWTThreadRenderingEnabled()) { - invalidate(); - repaint(100); - } - } - } - - if (!getAWTThreadRenderingEnabled()) { - if (!initCalled) { - init(); - initCalled = true; - } - } - listeners.sendPreDisplayEvent(this); - if (getAutoMakeContextCurrent()) { - if (glj.gljMakeCurrent()) { + if (glj.gljMakeCurrent()) { listeners.sendDisplayEvent(this); glj.gljSwap(); glj.gljCheckGL(); glj.gljFree(); - listeners.sendPostDisplayEvent(this); - } - } else { - listeners.sendDisplayEvent(this); - glj.gljSwap(); - glj.gljCheckGL(); listeners.sendPostDisplayEvent(this); } } diff --git a/gl4java/drawable/GLDrawable.java b/gl4java/drawable/GLDrawable.java index a0818c0..55c1311 100644 --- a/gl4java/drawable/GLDrawable.java +++ b/gl4java/drawable/GLDrawable.java @@ -30,6 +30,61 @@ public interface GLDrawable */ public GLContext getGLContext(); + /** + * + * This is the rendering-method called by + * e.g.: {@link gl4java.awt.GLCanvas#display} or by + * {@link gl4java.GLThread#run}. + * + *

+ * The default implementation of display() sends + * preDisplay, display and postDisplay events to + * all {@link gl4java.drawable.GLEventListener}s associated with this + * GLDrawable in the above order. + * + *

+ *

+        reset timer for frame duration
+
+     	for_all(gl4java.drawable.GLEventListener)
+		SEND preDisplay
+
+	if( gljMakeCurrent() )
+	{
+		for_all(gl4java.drawable.GLEventListener)
+			SEND display
+		gljSwap()
+		gljFree()
+
+		for_all(gl4java.drawable.GLEventListener)
+			SEND postDisplay
+	}
+
+        stop timer for frame duration
+     * 
+ * + *

+ * If you use the subclassing model (as opposed to the + * GLEventListener model), your subclass will redefine this to + * perform its OpenGL drawing. In this case you MUST encapsulate + * your OpenGL calls within: + *

+    	- glj.gljMakeCurrent()
+		YOUR OpenGL commands here !
+    	- glj.gljFree()
+     * 
+ * + * @return void + * + * @see gl4java.GLContext#gljMakeCurrent + * @see gl4java.GLContext#gljFree + * @see gl4java.GLContext#gljSwap + * @see gl4java.drawable.GLEventListener#preDisplay + * @see gl4java.drawable.GLEventListener#display + * @see gl4java.drawable.GLEventListener#postDisplay + */ + public void display(); + /** * the components listener's should be implemented also ! * since JDK 1.1 diff --git a/makefile b/makefile index 2697622..89ca6c2 100644 --- a/makefile +++ b/makefile @@ -224,6 +224,7 @@ FILES.java = $(PACKAGEDIR)/GL4JavaInitException.java \ $(PACKAGEDIR)/jau/awt/WinHandleAccess.java \ $(PACKAGEDIR)/GL4JavaReflections.java \ $(PACKAGEDIR)/GLCapabilities.java \ + $(PACKAGEDIR)/GLRunnable.java \ $(PACKAGEDIR)/GLEnum.java \ $(PACKAGEDIR)/GLUEnum.java \ $(PACKAGEDIR)/GLFunc.java \ @@ -433,6 +434,9 @@ FILES.gen = $(FILE.gen1.h) \ # SPECIFY ALL TARGETS -- MAIN TARGETS ###################################################################### +classes : $(FILES.class) $(FILES_x11.class) \ + $(DEST_CLASSES_DIR)/gl4java.jar + x11 : cleanup gljni \ $(FILES.class) $(FILES_x11.class) \ $(DEST_CLASSES_DIR)/gl4java.jar \ @@ -719,7 +723,9 @@ cleannative: cd demos/natives/x11 ; make clean # clean out the *.o files and machine generated files from javah -clean: cleannative cleanupw32 cleanhtmldoc +clean: cleannative cleanupw32 cleanhtmldoc cleantemp + +cleantemp: rm -f $(CHEADERDIR)/* errors gl4java/*~ CNativeCode/*~ \ $(FILE.gen1.h) $(FILE.gen2.h) \ $(FILE.gen3.h) $(FILE.gen4.h) $(FILE.gen5.h) @@ -853,9 +859,9 @@ java2binpkg: pbinpkg zip -9r $(THISDIR)/binpkg/gl4java$(LIBMAJOR).$(LIBMINOR).$(LIBBUGFIX).$(RELEASE)-glutfonts-classes.zip \ gl4java/utils/glut/fonts - rm -f binpkg/gl4java$(LIBMAJOR).$(LIBMINOR).$(LIBBUGFIX).$(RELEASE)-glf-fonts.zip + rm -f binpkg/gl4java$(LIBMAJOR).$(LIBMINOR).$(LIBBUGFIX).$(RELEASE)-glffonts.zip cd $(DEST_CLASSES_DIR) ; \ - zip -9r $(THISDIR)/binpkg/gl4java$(LIBMAJOR).$(LIBMINOR).$(LIBBUGFIX).$(RELEASE)-glf-fonts.zip \ + zip -9r $(THISDIR)/binpkg/gl4java$(LIBMAJOR).$(LIBMINOR).$(LIBBUGFIX).$(RELEASE)-glffonts.zip \ gl4java/utils/glf/fonts rm -f binpkg/gl4java$(LIBMAJOR).$(LIBMINOR).$(LIBBUGFIX).$(RELEASE)-INSTALLER.zip @@ -903,9 +909,8 @@ javacalldemos: cd demos/RonsDemos ; javac *.java cd demos/SwingDemos ; javac *.java -archivclean: pbinpkg +archivclean: pbinpkg cleannative cleanupw32 cleantemp if [ ! -e archive ] ; then mkdir archive ; fi - make clean archivdemos: rm -f archive/GL4Java$(LIBMAJOR).$(LIBMINOR).$(LIBBUGFIX).$(RELEASE)-demosV$(DEMORELEASE).zip @@ -937,7 +942,7 @@ archivdoc: rm -f archive/GL4Java$(LIBMAJOR).$(LIBMINOR).$(LIBBUGFIX).$(RELEASE)-doc.zip cd ..; \ zip -9r GL4Java/archive/GL4Java$(LIBMAJOR).$(LIBMINOR).$(LIBBUGFIX).$(RELEASE)-doc.zip \ - GL4Java/docs GL4Java/*.txt + GL4Java/docs GL4Java/doxygens GL4Java/*.txt archiv: archivdemos archivsrc archivdoc diff --git a/symbols.mak.linux-java2-xf86-ppc-32bit b/symbols.mak.linux-java2-xf86-ppc-32bit index 0056fd3..c786980 100644 --- a/symbols.mak.linux-java2-xf86-ppc-32bit +++ b/symbols.mak.linux-java2-xf86-ppc-32bit @@ -15,6 +15,9 @@ UNIXTYPE = Linux-glibc2-xf86-ppc JDK_HOME = $(shell dirname $$(which java))/.. JAVASHAREINC = $(JDK_HOME)/include JAVAOSINC = $(JDK_HOME)/include/linux +JAVAOSLIB = $(JDK_HOME)/jre/lib/ppc + +JAR_DESTS = /usr/local/lib/jdk1.3.0-FCS-blackdown/jre/lib/ext CC = gcc MKLIB = mklibs/mkslib.linux -- cgit v1.2.3