aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2001-07-24 12:07:18 +0000
committerSven Gothel <[email protected]>2001-07-24 12:07:18 +0000
commit3583101e586a6fe3306f84d4d34ee764596e0632 (patch)
treed5c228654f882fa0f0c6214e6d4866ce44181b89
parentc9eae90cb823d918ecc4bf5afa73ce3a0859d578 (diff)
optimized context switchingrel-2-8-0-0-prerelease-3
-rw-r--r--CHANGES.txt27
-rwxr-xr-xCNativeCode/OpenGL_Win32.c26
-rwxr-xr-xCNativeCode/OpenGL_Win32_jawt.c69
-rw-r--r--CNativeCode/OpenGL_X11.c26
-rw-r--r--CNativeCode/OpenGL_X11_jawt.c110
-rw-r--r--CNativeCode/OpenGL_misc.c9
-rw-r--r--demos/MiscDemos/gears.java7
-rwxr-xr-xdocs-src/UpdateHtml2
-rw-r--r--gl4java/GLContext.java.skel237
-rw-r--r--gl4java/GLRunnable.java129
-rw-r--r--gl4java/applet/SimpleGLAnimApplet1.java41
-rw-r--r--gl4java/awt/GLAnimCanvas.java149
-rw-r--r--gl4java/awt/GLCanvas.java180
-rw-r--r--gl4java/drawable/GLDrawable.java55
-rw-r--r--makefile17
-rw-r--r--symbols.mak.linux-java2-xf86-ppc-32bit3
16 files changed, 774 insertions, 313 deletions
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
@@ -66,6 +66,32 @@ Java_gl4java_GLContext_hasJAWTSurfaceChanged( JNIEnv *env, jobject obj,
}
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
@@ -92,6 +92,71 @@ Java_gl4java_GLContext_hasJAWTSurfaceChanged( JNIEnv *env, jobject obj,
}
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
*
@@ -579,6 +568,82 @@ Java_gl4java_GLContext_gljResizeNative( JNIEnv *env, jobject obj,
}
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,
jlong disp,
@@ -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,26 +747,13 @@ 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 <GL/glx.h>
#include <dlfcn.h>
#include "glxtool.h"
+ #include <unistd.h>
#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 <Value> 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
@@ -2187,11 +2195,75 @@ public class GLContext extends Object
/**
*
+ * 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
* AND makes the GL-Context current for this thread.
*
* <p>
*
+ * This functions now optimizes the context-switch !
+ *
+ * The context is changed, only if :
+ * <pre>
+ - 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
+ * </pre>
+ *
+ * <p>
+ *
* You MUST encapsulate your OpenGL call's within:
* <pre>
- 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+" <EarMarked Run>");
+ System.out.println("MakeCurrent: "+thisThread+" <EarMarked Run>");
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
+ * <p>
+ *
+ * This functions now optimizes the context-switch !
+ *
+ * The context is changed, only if :
+ * <pre>
+ - another thread has requested this context -> release it
+ * </pre>
+ *
+ * <p>
+ *
+ * @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 !
+ *
+ * <p>
+ *
+ * This functions now optimizes the context-switch !
+ *
+ * The context is changed, only if one of the following is true:
+ * <pre>
+ - 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
+ * </pre>
+ *
+ * <p>
+ *
+ * @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:
+ * <pre>
+ - you exit this run loop
+ - you suspend your thread -> wait
+ - you kill your thread ..
+ * </pre>
+ *
+ * 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,6 +404,7 @@ 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;
@@ -416,6 +412,20 @@ public class GLAnimCanvas extends GLCanvas
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();
}
/**
@@ -711,15 +630,14 @@ 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
* <p>
* 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.
*
* <p>
@@ -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,49 +743,9 @@ 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();
@@ -851,12 +753,6 @@ public class GLCanvas extends Canvas
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
@@ -31,6 +31,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}.
+ *
+ * <p>
+ * 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.
+ *
+ * <p>
+ * <pre>
+ 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
+ * </pre>
+ *
+ * <p>
+ * 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:
+ * <pre>
+ - glj.gljMakeCurrent()
+ YOUR OpenGL commands here !
+ - glj.gljFree()
+ * </pre>
+ *
+ * @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