summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2013-03-14 10:48:44 +0100
committerSven Gothel <[email protected]>2013-03-14 10:48:44 +0100
commit896e8b021b39e9415040a57a1d540d7d24b02db1 (patch)
treec031248b4a464602aaa150b4d088235b9db065f0
parent58f6f4e5665ae2c72ec6bbd86ad5a36bef00de07 (diff)
OSX/CALayer: Revise CALayer 'RunOnMainThread' utilization, avoiding deadlocks
RunOnMainThread(waitUntilDone:=true,..) can deadlock the main-thread if called from AWT-EDT, since the main-thread may call back to AWT-EDT while injecting a new main-thread task. This patch revises all RunOnMainThread CALayer usage, resulting in only one required left: - OSXUtil.AddCASublayer() w/ waitUntilDone:=false Hence the CALayer code has no more potential to deadlock main-thread/AWT-EDT. OSXUtil.AddCASublayer() must be performed on main-thread, otherwise the CALayer attachment will fail - no visible rendering result. +++ Note: A good trigger to test this deadlock is to magnify/zoom the OSX desktop (click background + ctrl-mouse_wheel) before running some unit tests. TestGLCanvasAWTActionDeadlock01AWT and TestAddRemove02GLWindowNewtCanvasAWT also have the potential to trigger the mentioned deadlock.
-rw-r--r--make/config/jogl/cgl-macosx-CustomJavaCode.java23
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java30
-rw-r--r--src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m36
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java4
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java38
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java37
-rw-r--r--src/nativewindow/native/macosx/OSXmisc.m16
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2AWT.java41
8 files changed, 102 insertions, 123 deletions
diff --git a/make/config/jogl/cgl-macosx-CustomJavaCode.java b/make/config/jogl/cgl-macosx-CustomJavaCode.java
index d32e0ae8f..ab1d44b64 100644
--- a/make/config/jogl/cgl-macosx-CustomJavaCode.java
+++ b/make/config/jogl/cgl-macosx-CustomJavaCode.java
@@ -1,9 +1,9 @@
/**
- * Creates the NSOpenGLLayer for FBO/PBuffer w/ optional GL3 shader program on Main-Thread
+ * Creates the NSOpenGLLayer for FBO/PBuffer w/ optional GL3 shader program
* <p>
- * It is mandatory that the shared context handle <code>ctx</code>
- * is not locked while calling this method.
+ * The NSOpenGLLayer will immediatly create a OpenGL context sharing the given ctx,
+ * which will be used to render the texture offthread.
* </p>
* <p>
* The NSOpenGLLayer starts in enabled mode,
@@ -12,10 +12,7 @@
*/
public static long createNSOpenGLLayer(final long ctx, final int gl3ShaderProgramName, final long fmt, final long p,
final int texID, final boolean opaque, final int texWidth, final int texHeight) {
- return OSXUtil.RunOnMainThread(true, new Function<Long, Object>() {
- public Long eval(Object... args) {
- return Long.valueOf( createNSOpenGLLayerImpl(ctx, gl3ShaderProgramName, fmt, p, texID, opaque, texWidth, texHeight) );
- } } ).longValue();
+ return createNSOpenGLLayerImpl(ctx, gl3ShaderProgramName, fmt, p, texID, opaque, texWidth, texHeight);
}
/**
@@ -26,19 +23,13 @@ public static long createNSOpenGLLayer(final long ctx, final int gl3ShaderProgra
* </p>
*/
public static void setNSOpenGLLayerEnabled(final long nsOpenGLLayer, final boolean enable) {
- OSXUtil.RunOnMainThread(true, new Runnable() {
- public void run() {
- setNSOpenGLLayerEnabledImpl(nsOpenGLLayer, enable);
- } } );
+ setNSOpenGLLayerEnabledImpl(nsOpenGLLayer, enable);
}
/**
- * Releases the NSOpenGLLayer on Main-Thread
+ * Releases the NSOpenGLLayer
*/
public static void releaseNSOpenGLLayer(final long nsOpenGLLayer) {
- OSXUtil.RunOnMainThread(true, new Runnable() {
- public void run() {
- releaseNSOpenGLLayerImpl(nsOpenGLLayer);
- } } );
+ releaseNSOpenGLLayerImpl(nsOpenGLLayer);
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
index a03850043..9e6085030 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
@@ -676,30 +676,24 @@ public abstract class MacOSXCGLContext extends GLContextImpl
}
/**
- * Perform NSOpenGLLayer creation and attaching on main-thread,
- * hence release the lock on our context - which will be used to
- * create a shared context within NSOpenGLLayer.
+ * NSOpenGLLayer creation is performed on the current thread,
+ * which immediately creates it's own GL ctx sharing this ctx
+ * not causing any locking issues.
+ *
+ * Subsequent attaching is performed on main-thread w/o blocking.
+ *
+ * This is a lock free operation.
*/
final long cglCtx = CGL.getCGLContext(ctx);
if(0 == cglCtx) {
throw new InternalError("Null CGLContext for: "+this);
}
- final boolean ctxUnlocked = CGL.kCGLNoError == CGL.CGLUnlockContext(cglCtx);
- try {
- nsOpenGLLayer = CGL.createNSOpenGLLayer(ctx, gl3ShaderProgramName, pixelFormat, pbufferHandle, texID, chosenCaps.isBackgroundOpaque(), lastWidth, lastHeight);
- if (DEBUG) {
- System.err.println("NS create nsOpenGLLayer "+toHexString(nsOpenGLLayer)+" w/ pbuffer "+toHexString(pbufferHandle)+", texID "+texID+", texSize "+lastWidth+"x"+lastHeight+", "+drawable);
- }
- backingLayerHost.attachSurfaceLayer(nsOpenGLLayer);
- setSwapInterval(1); // enabled per default in layered surface
- } finally {
- if( ctxUnlocked ) {
- if( CGL.kCGLNoError != CGL.CGLLockContext(cglCtx) ) {
- throw new InternalError("Could not re-lock CGLContext for: "+this);
- }
- }
+ nsOpenGLLayer = CGL.createNSOpenGLLayer(ctx, gl3ShaderProgramName, pixelFormat, pbufferHandle, texID, chosenCaps.isBackgroundOpaque(), lastWidth, lastHeight);
+ if (DEBUG) {
+ System.err.println("NS create nsOpenGLLayer "+toHexString(nsOpenGLLayer)+" w/ pbuffer "+toHexString(pbufferHandle)+", texID "+texID+", texSize "+lastWidth+"x"+lastHeight+", "+drawable);
}
- backingLayerHost.layoutSurfaceLayer();
+ backingLayerHost.attachSurfaceLayer(nsOpenGLLayer);
+ setSwapInterval(1); // enabled per default in layered surface
} else {
lastWidth = drawable.getWidth();
lastHeight = drawable.getHeight();
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
index abc9d7958..f93f15241 100644
--- a/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
+++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
@@ -131,11 +131,10 @@ extern GLboolean glIsVertexArray (GLuint array);
{
@private
GLfloat gl_texCoords[8];
- NSOpenGLContext* myCtx;
+ NSOpenGLContext* glContext;
Bool isGLEnabled;
@protected
- NSOpenGLContext* parentCtx;
GLuint gl3ShaderProgramName;
GLuint vboBufVert;
GLuint vboBufTexCoord;
@@ -247,7 +246,7 @@ static const GLfloat gl_verts[] = {
@implementation MyNSOpenGLLayer
-- (id) setupWithContext: (NSOpenGLContext*) _parentCtx
+- (id) setupWithContext: (NSOpenGLContext*) parentCtx
gl3ShaderProgramName: (GLuint) _gl3ShaderProgramName
pixelFormat: (NSOpenGLPixelFormat*) _parentPixelFmt
pbuffer: (NSOpenGLPixelBuffer*) p
@@ -262,20 +261,19 @@ static const GLfloat gl_verts[] = {
pthread_mutex_init(&renderLock, &renderLockAttr); // recursive
pthread_cond_init(&renderSignal, NULL); // no attribute
- myCtx = NULL;
{
int i;
for(i=0; i<8; i++) {
gl_texCoords[i] = 0.0f;
}
}
- parentCtx = _parentCtx;
+ parentPixelFmt = [_parentPixelFmt retain]; // until destruction
+ glContext = [[MyNSOpenGLContext alloc] initWithFormat:parentPixelFmt shareContext:parentCtx];
gl3ShaderProgramName = _gl3ShaderProgramName;
vboBufVert = 0;
vboBufTexCoord = 0;
vertAttrLoc = 0;
texCoordAttrLoc = 0;
- parentPixelFmt = [_parentPixelFmt retain]; // until destruction
swapInterval = 1; // defaults to on (as w/ new GL profiles)
swapIntervalCounter = 0;
timespec_now(&lastWaitTime);
@@ -338,12 +336,12 @@ static const GLfloat gl_verts[] = {
#ifdef VERBOSE_ON
CGRect lRect = [self bounds];
if(NULL != pbuffer) {
- DBG_PRINT("MyNSOpenGLLayer::init (pbuffer) %p, ctx %p, pfmt %p, pbuffer %p, opaque %d, pbuffer %dx%d -> tex %dx%d, bounds: %lf/%lf %lfx%lf, displayLink %p (refcnt %d)\n",
- self, parentCtx, parentPixelFmt, pbuffer, opaque, [pbuffer pixelsWide], [pbuffer pixelsHigh], texWidth, texHeight,
+ DBG_PRINT("MyNSOpenGLLayer::init (pbuffer) %p, pctx %p, pfmt %p, pbuffer %p, ctx %p, opaque %d, pbuffer %dx%d -> tex %dx%d, bounds: %lf/%lf %lfx%lf, displayLink %p (refcnt %d)\n",
+ self, parentCtx, parentPixelFmt, pbuffer, glContext, opaque, [pbuffer pixelsWide], [pbuffer pixelsHigh], texWidth, texHeight,
lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height, displayLink, (int)[self retainCount]);
} else {
- DBG_PRINT("MyNSOpenGLLayer::init (texture) %p, ctx %p, pfmt %p, opaque %d, tex[id %d, %dx%d], bounds: %lf/%lf %lfx%lf, displayLink %p (refcnt %d)\n",
- self, parentCtx, parentPixelFmt, opaque, (int)textureID, texWidth, texHeight,
+ DBG_PRINT("MyNSOpenGLLayer::init (texture) %p, pctx %p, pfmt %p, ctx %p, opaque %d, tex[id %d, %dx%d], bounds: %lf/%lf %lfx%lf, displayLink %p (refcnt %d)\n",
+ self, parentCtx, parentPixelFmt, glContext, opaque, (int)textureID, texWidth, texHeight,
lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height, displayLink, (int)[self retainCount]);
}
#endif
@@ -493,11 +491,10 @@ static const GLfloat gl_verts[] = {
pthread_mutex_lock(&renderLock);
[self deallocPBuffer];
// [[self openGLContext] release];
- if( NULL != myCtx ) {
- [myCtx release];
- myCtx = NULL;
+ if( NULL != glContext ) {
+ [glContext release];
+ glContext = NULL;
}
- parentCtx = NULL;
if( NULL != parentPixelFmt ) {
[parentPixelFmt release];
parentPixelFmt = NULL;
@@ -632,22 +629,19 @@ static const GLfloat gl_verts[] = {
- (NSOpenGLContext *)openGLContextForPixelFormat:(NSOpenGLPixelFormat *)pixelFormat
{
- DBG_PRINT("MyNSOpenGLLayer::openGLContextForPixelFormat.0: %p (refcnt %d) - pfmt %p, parent %p, DisplayLink %p\n",
- self, (int)[self retainCount], pixelFormat, parentCtx, displayLink);
- // NSLog(@"MyNSOpenGLLayer::openGLContextForPixelFormat: %@",[NSThread callStackSymbols]);
- myCtx = [[MyNSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:parentCtx];
+ DBG_PRINT("MyNSOpenGLLayer::openGLContextForPixelFormat.0: %p (refcnt %d) - pfmt %p, ctx %p, DisplayLink %p\n",
+ self, (int)[self retainCount], pixelFormat, glContext, displayLink);
#ifndef HAS_CADisplayLink
if(NULL != displayLink) {
CVReturn cvres;
DBG_PRINT("MyNSOpenGLLayer::openGLContextForPixelFormat.1: setup DisplayLink %p\n", displayLink);
- cvres = CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, [myCtx CGLContextObj], [pixelFormat CGLPixelFormatObj]);
+ cvres = CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, [glContext CGLContextObj], [pixelFormat CGLPixelFormatObj]);
if(kCVReturnSuccess != cvres) {
DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext failed: %d\n", self, cvres);
}
}
#endif
- DBG_PRINT("MyNSOpenGLLayer::openGLContextForPixelFormat.X: new-ctx %p\n", myCtx);
- return myCtx;
+ return glContext;
}
- (BOOL)canDrawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat
diff --git a/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java b/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java
index 4885d5a4c..df3f04f7f 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java
@@ -36,10 +36,6 @@ public interface OffscreenLayerSurface {
* <p>
* Implementation may realize all required resources at this point.
* </p>
- * <p>
- * It is mandatory that any related resources, e.g. a shared context,
- * are not locked while calling this method.
- * </p>
*
* @see #isOffscreenLayerSurfaceEnabled()
* @throws NativeWindowException if {@link #isOffscreenLayerSurfaceEnabled()} == false
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
index 3ec54ca78..c8f758165 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
@@ -51,7 +51,6 @@ import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.MutableSurface;
import javax.media.nativewindow.util.Point;
-import com.jogamp.common.util.Function;
import com.jogamp.nativewindow.awt.JAWTWindow;
import jogamp.nativewindow.jawt.JAWT;
@@ -90,8 +89,11 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
JAWT_DrawingSurfaceInfo dsi = null;
try {
dsi = ds.GetDrawingSurfaceInfo();
- if(! UnsetJAWTRootSurfaceLayer(dsi.getBuffer(), rootSurfaceLayerHandle)) {
+ try {
+ UnsetJAWTRootSurfaceLayer(dsi.getBuffer(), rootSurfaceLayerHandle);
+ } catch (Exception e) {
System.err.println("Error clearing JAWT rootSurfaceLayerHandle "+toHexString(rootSurfaceLayerHandle));
+ e.printStackTrace();
}
} finally {
if ( null != dsi ) {
@@ -245,8 +247,12 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
rootSurfaceLayerHandle = OSXUtil.CreateCALayer(bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight());
if(0 == rootSurfaceLayerHandle) {
errMsg = "Could not create root CALayer";
- } else if(!SetJAWTRootSurfaceLayer(dsi.getBuffer(), rootSurfaceLayerHandle)) {
- errMsg = "Could not set JAWT rootSurfaceLayerHandle "+toHexString(rootSurfaceLayerHandle);
+ } else {
+ try {
+ SetJAWTRootSurfaceLayer(dsi.getBuffer(), rootSurfaceLayerHandle);
+ } catch(Exception e) {
+ errMsg = "Could not set JAWT rootSurfaceLayerHandle "+toHexString(rootSurfaceLayerHandle)+", cause: "+e.getMessage();
+ }
}
}
}
@@ -307,22 +313,22 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
}
protected Point getLocationOnScreenNativeImpl(final int x0, final int y0) { return null; }
- private static boolean SetJAWTRootSurfaceLayer(final Buffer jawtDrawingSurfaceInfoBuffer, final long caLayer) {
- return OSXUtil.RunOnMainThread(true, new Function<Boolean, Object>() {
- public Boolean eval(Object... args) {
- return Boolean.valueOf( SetJAWTRootSurfaceLayer0(jawtDrawingSurfaceInfoBuffer, caLayer) );
- } } ).booleanValue();
+ /**
+ * Set the given root CALayer in the JAWT surface
+ */
+ private static void SetJAWTRootSurfaceLayer(final Buffer jawtDrawingSurfaceInfoBuffer, final long caLayer) {
+ SetJAWTRootSurfaceLayer0(jawtDrawingSurfaceInfoBuffer, caLayer);
}
- private static boolean UnsetJAWTRootSurfaceLayer(final Buffer jawtDrawingSurfaceInfoBuffer, final long caLayer) {
- return OSXUtil.RunOnMainThread(true, new Function<Boolean, Object>() {
- public Boolean eval(Object... args) {
- return Boolean.valueOf( UnsetJAWTRootSurfaceLayer0(jawtDrawingSurfaceInfoBuffer, caLayer) );
- } } ).booleanValue();
+ /**
+ * Unset the given root CALayer in the JAWT surface
+ */
+ private static void UnsetJAWTRootSurfaceLayer(final Buffer jawtDrawingSurfaceInfoBuffer, final long caLayer) {
+ UnsetJAWTRootSurfaceLayer0(jawtDrawingSurfaceInfoBuffer, caLayer);
}
- private static native boolean SetJAWTRootSurfaceLayer0(Buffer jawtDrawingSurfaceInfoBuffer, long caLayer);
- private static native boolean UnsetJAWTRootSurfaceLayer0(Buffer jawtDrawingSurfaceInfoBuffer, long caLayer);
+ private static native void SetJAWTRootSurfaceLayer0(Buffer jawtDrawingSurfaceInfoBuffer, long caLayer);
+ private static native void UnsetJAWTRootSurfaceLayer0(Buffer jawtDrawingSurfaceInfoBuffer, long caLayer);
// Variables for lockSurface/unlockSurface
private JAWT_DrawingSurface ds;
diff --git a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
index aa44e2d64..59b42c249 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
@@ -137,26 +137,23 @@ public class OSXUtil implements ToolkitProperties {
}
/**
- * Create a CALayer suitable to act as a root CALayer on the main-thread.
+ * Create a CALayer suitable to act as a root CALayer.
* @see #DestroyCALayer(long)
* @see #AddCASublayer(long, long)
*/
public static long CreateCALayer(final int x, final int y, final int width, final int height) {
- return OSXUtil.RunOnMainThread(true, new Function<Long, Object>() {
- public Long eval(Object... args) {
- return Long.valueOf( CreateCALayer0(x, y, width, height) );
- } } ).longValue();
+ return CreateCALayer0(x, y, width, height);
}
/**
- * Attach a sub CALayer to the root CALayer on the main-thread w/ blocking.
+ * Attach a sub CALayer to the root CALayer on the main-thread w/o blocking.
* <p>
* Method will trigger a <code>display</code>
* call to the CALayer hierarchy to enforce resource creation if required, e.g. an NSOpenGLContext.
* </p>
* <p>
- * It is mandatory that any related resources, e.g. a shared NSOpenGLContext,
- * are not locked while calling this method.
+ * Hence it is important that related resources are not locked <i>if</i>
+ * they will be used for creation.
* </p>
* @see #CreateCALayer(int, int, int, int)
* @see #RemoveCASublayer(long, long)
@@ -165,7 +162,7 @@ public class OSXUtil implements ToolkitProperties {
if(0==rootCALayer || 0==subCALayer) {
throw new IllegalArgumentException("rootCALayer 0x"+Long.toHexString(rootCALayer)+", subCALayer 0x"+Long.toHexString(subCALayer));
}
- RunOnMainThread(true, new Runnable() {
+ RunOnMainThread(false, new Runnable() {
public void run() {
AddCASublayer0(rootCALayer, subCALayer);
}
@@ -173,7 +170,7 @@ public class OSXUtil implements ToolkitProperties {
}
/**
- * Fix root and sub CALayer position to 0/0 and size on the main-thread w/o blocking.
+ * Fix root and sub CALayer position to 0/0 and size
* <p>
* If the sub CALayer implements the Objective-C NativeWindow protocol NWDedicatedSize (e.g. JOGL's MyNSOpenGLLayer),
* the dedicated size is passed to the layer, which propagates it appropriately.
@@ -192,38 +189,28 @@ public class OSXUtil implements ToolkitProperties {
if( 0==rootCALayer && 0==subCALayer ) {
return;
}
- RunOnMainThread(false, new Runnable() {
- public void run() {
- FixCALayerLayout0(rootCALayer, subCALayer, width, height);
- }
- });
+ FixCALayerLayout0(rootCALayer, subCALayer, width, height);
}
/**
- * Detach a sub CALayer from the root CALayer on the main-thread w/ blocking.
+ * Detach a sub CALayer from the root CALayer
*/
public static void RemoveCASublayer(final long rootCALayer, final long subCALayer) {
if(0==rootCALayer || 0==subCALayer) {
throw new IllegalArgumentException("rootCALayer 0x"+Long.toHexString(rootCALayer)+", subCALayer 0x"+Long.toHexString(subCALayer));
}
- RunOnMainThread(true, new Runnable() {
- public void run() {
- RemoveCASublayer0(rootCALayer, subCALayer);
- } } );
+ RemoveCASublayer0(rootCALayer, subCALayer);
}
/**
- * Destroy a CALayer on the main-thread w/ blocking.
+ * Destroy a CALayer
* @see #CreateCALayer(int, int, int, int)
*/
public static void DestroyCALayer(final long caLayer) {
if(0==caLayer) {
throw new IllegalArgumentException("caLayer 0x"+Long.toHexString(caLayer));
}
- RunOnMainThread(true, new Runnable() {
- public void run() {
- DestroyCALayer0(caLayer);
- } } );
+ DestroyCALayer0(caLayer);
}
/**
diff --git a/src/nativewindow/native/macosx/OSXmisc.m b/src/nativewindow/native/macosx/OSXmisc.m
index c74d6cc58..14a9781f7 100644
--- a/src/nativewindow/native/macosx/OSXmisc.m
+++ b/src/nativewindow/native/macosx/OSXmisc.m
@@ -584,16 +584,16 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_DestroyCALayer0
/*
* Class: Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow
* Method: SetJAWTRootSurfaceLayer0
- * Signature: (JJ)Z
+ * Signature: (JJ)V
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_SetJAWTRootSurfaceLayer0
+JNIEXPORT void JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_SetJAWTRootSurfaceLayer0
(JNIEnv *env, jclass unused, jobject jawtDrawingSurfaceInfoBuffer, jlong caLayer)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
JAWT_DrawingSurfaceInfo* dsi = (JAWT_DrawingSurfaceInfo*) (*env)->GetDirectBufferAddress(env, jawtDrawingSurfaceInfoBuffer);
if (NULL == dsi) {
NativewindowCommon_throwNewRuntimeException(env, "Argument \"jawtDrawingSurfaceInfoBuffer\" was not a direct buffer");
- return JNI_FALSE;
+ return;
}
MyCALayer* layer = (MyCALayer*) (intptr_t) caLayer;
id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)dsi->platformInfo;
@@ -601,35 +601,33 @@ JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow
surfaceLayers.layer = [layer retain]; // Pairs w/ Unset
[pool release];
DBG_PRINT("CALayer::SetJAWTRootSurfaceLayer.X: root %p (refcnt %d)\n", layer, (int)[layer retainCount]);
- return JNI_TRUE;
}
/*
* Class: Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow
* Method: UnsetJAWTRootSurfaceLayer0
- * Signature: (JJ)Z
+ * Signature: (JJ)V
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_UnsetJAWTRootSurfaceLayer0
+JNIEXPORT void JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_UnsetJAWTRootSurfaceLayer0
(JNIEnv *env, jclass unused, jobject jawtDrawingSurfaceInfoBuffer, jlong caLayer)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
JAWT_DrawingSurfaceInfo* dsi = (JAWT_DrawingSurfaceInfo*) (*env)->GetDirectBufferAddress(env, jawtDrawingSurfaceInfoBuffer);
if (NULL == dsi) {
NativewindowCommon_throwNewRuntimeException(env, "Argument \"jawtDrawingSurfaceInfoBuffer\" was not a direct buffer");
- return JNI_FALSE;
+ return;
}
MyCALayer* layer = (MyCALayer*) (intptr_t) caLayer;
id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)dsi->platformInfo;
if(layer != surfaceLayers.layer) {
NativewindowCommon_throwNewRuntimeException(env, "Attached layer %p doesn't match given layer %p\n", surfaceLayers.layer, layer);
- return JNI_FALSE;
+ return;
}
DBG_PRINT("CALayer::UnsetJAWTRootSurfaceLayer.0: root %p (refcnt %d) -> nil\n", layer, (int)[layer retainCount]);
[layer release]; // Pairs w/ Set
surfaceLayers.layer = NULL;
[pool release];
DBG_PRINT("CALayer::UnsetJAWTRootSurfaceLayer.X: root %p (refcnt %d) -> nil\n", layer, (int)[layer retainCount]);
- return JNI_TRUE;
}
@interface MainRunnable : NSObject
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2AWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2AWT.java
index d59b81ff1..64151362b 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/awt/TestGearsES2AWT.java
@@ -77,6 +77,7 @@ public class TestGearsES2AWT extends UITestCase {
static boolean shutdownSystemExit = false;
static int swapInterval = 1;
static boolean exclusiveContext = false;
+ static boolean useAnimator = true;
static Thread awtEDT;
static Dimension rwsize = null;
@@ -167,8 +168,8 @@ public class TestGearsES2AWT extends UITestCase {
glCanvas.addGLEventListener(new GearsES2(swapInterval));
- Animator animator = new Animator(glCanvas);
- if( exclusiveContext ) {
+ final Animator animator = useAnimator ? new Animator(glCanvas) : null;
+ if( useAnimator && exclusiveContext ) {
animator.setExclusiveContext(awtEDT);
}
QuitAdapter quitAdapter = new QuitAdapter();
@@ -184,11 +185,13 @@ public class TestGearsES2AWT extends UITestCase {
Assert.assertEquals(true, AWTRobotUtil.waitForVisible(frame, true));
Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glCanvas, true));
- animator.start();
- Assert.assertTrue(animator.isStarted());
- Assert.assertTrue(animator.isAnimating());
- Assert.assertEquals(exclusiveContext ? awtEDT : null, glCanvas.getExclusiveContextThread());
- animator.setUpdateFPSFrames(60, System.err);
+ if( useAnimator ) {
+ animator.start();
+ Assert.assertTrue(animator.isStarted());
+ Assert.assertTrue(animator.isAnimating());
+ Assert.assertEquals(exclusiveContext ? awtEDT : null, glCanvas.getExclusiveContextThread());
+ animator.setUpdateFPSFrames(60, System.err);
+ }
System.err.println("canvas pos/siz: "+glCanvas.getX()+"/"+glCanvas.getY()+" "+glCanvas.getWidth()+"x"+glCanvas.getHeight());
@@ -198,19 +201,25 @@ public class TestGearsES2AWT extends UITestCase {
System.err.println("window resize pos/siz: "+glCanvas.getX()+"/"+glCanvas.getY()+" "+glCanvas.getWidth()+"x"+glCanvas.getHeight());
}
- while(!quitAdapter.shouldQuit() /* && animator.isAnimating() */ && animator.getTotalFPSDuration()<duration) {
+ final long t0 = System.currentTimeMillis();
+ long t1 = t0;
+ while(!quitAdapter.shouldQuit() && t1 - t0 < duration) {
Thread.sleep(100);
+ t1 = System.currentTimeMillis();
}
Assert.assertNotNull(frame);
Assert.assertNotNull(glCanvas);
- Assert.assertNotNull(animator);
+
+ if( useAnimator ) {
+ Assert.assertNotNull(animator);
+ Assert.assertEquals(exclusiveContext ? awtEDT : null, glCanvas.getExclusiveContextThread());
+ animator.stop();
+ Assert.assertFalse(animator.isAnimating());
+ Assert.assertFalse(animator.isStarted());
+ Assert.assertEquals(null, glCanvas.getExclusiveContextThread());
+ }
- Assert.assertEquals(exclusiveContext ? awtEDT : null, glCanvas.getExclusiveContextThread());
- animator.stop();
- Assert.assertFalse(animator.isAnimating());
- Assert.assertFalse(animator.isStarted());
- Assert.assertEquals(null, glCanvas.getExclusiveContextThread());
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
frame.setVisible(false);
@@ -288,6 +297,8 @@ public class TestGearsES2AWT extends UITestCase {
swapInterval = MiscUtils.atoi(args[i], swapInterval);
} else if(args[i].equals("-exclctx")) {
exclusiveContext = true;
+ } else if(args[i].equals("-noanim")) {
+ useAnimator = false;
} else if(args[i].equals("-layeredFBO")) {
shallUseOffscreenFBOLayer = true;
} else if(args[i].equals("-layeredPBuffer")) {
@@ -319,6 +330,8 @@ public class TestGearsES2AWT extends UITestCase {
System.err.println("forceGL3 "+forceGL3);
System.err.println("swapInterval "+swapInterval);
System.err.println("exclusiveContext "+exclusiveContext);
+ System.err.println("useAnimator "+useAnimator);
+
System.err.println("shallUseOffscreenFBOLayer "+shallUseOffscreenFBOLayer);
System.err.println("shallUseOffscreenPBufferLayer "+shallUseOffscreenPBufferLayer);