diff options
Diffstat (limited to 'src/nativewindow')
3 files changed, 53 insertions, 9 deletions
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java index eba26c7d3..d3e339586 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/swt/SWTAccessor.java @@ -480,7 +480,7 @@ public class SWTAccessor { * <li>Mac OSX * <ul> * <!--li>AWT EDT: In case AWT is available, the AWT EDT is the OSX UI main thread</li--> - * <li><i>Main Thread</i>: Run on OSX UI main thread.</li> + * <li><i>Main Thread</i>: Run on OSX UI main thread. 'wait' is implemented on Java site via lock/wait on {@link RunnableTask} to not freeze OSX main thread.</li> * </ul></li> * <li>Linux, Windows, .. * <ul> diff --git a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java index a195f137e..f06f97064 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java +++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java @@ -32,6 +32,8 @@ import javax.media.nativewindow.NativeWindowFactory; import javax.media.nativewindow.util.Insets; import javax.media.nativewindow.util.Point; +import com.jogamp.common.util.RunnableTask; + import jogamp.nativewindow.Debug; import jogamp.nativewindow.NWJNILibLoader; import jogamp.nativewindow.ToolkitProperties; @@ -154,11 +156,42 @@ public class OSXUtil implements ToolkitProperties { DestroyCALayer0(caLayer); } + /** + * Run on OSX UI main thread. + * <p> + * 'waitUntilDone' is implemented on Java site via lock/wait on {@link RunnableTask} to not freeze OSX main thread. + * </p> + * + * @param waitUntilDone + * @param runnable + */ public static void RunOnMainThread(boolean waitUntilDone, Runnable runnable) { - if(IsMainThread0()) { + if( IsMainThread0() ) { runnable.run(); // don't leave the JVM } else { - RunOnMainThread0(waitUntilDone, runnable); + if( waitUntilDone ) { + // Utilize Java side lock/wait and simply pass the Runnable async to OSX main thread, + // otherwise we may freeze the OSX main thread. + Throwable throwable = null; + final Object sync = new Object(); + final RunnableTask rt = new RunnableTask( runnable, sync, true ); + synchronized(sync) { + RunOnMainThread0(rt); + try { + sync.wait(); + } catch (InterruptedException ie) { + throwable = ie; + } + if(null==throwable) { + throwable = rt.getThrowable(); + } + if(null!=throwable) { + throw new RuntimeException(throwable); + } + } + } else { + RunOnMainThread0(runnable); + } } } @@ -205,7 +238,7 @@ public class OSXUtil implements ToolkitProperties { private static native void AddCASublayer0(long rootCALayer, long subCALayer); private static native void RemoveCASublayer0(long rootCALayer, long subCALayer); private static native void DestroyCALayer0(long caLayer); - private static native void RunOnMainThread0(boolean waitUntilDone, Runnable runnable); + private static native void RunOnMainThread0(Runnable runnable); private static native boolean IsMainThread0(); private static native int GetScreenRefreshRate0(int scrn_idx); } diff --git a/src/nativewindow/native/macosx/OSXmisc.m b/src/nativewindow/native/macosx/OSXmisc.m index 1cf41fc9d..72bb2338c 100644 --- a/src/nativewindow/native/macosx/OSXmisc.m +++ b/src/nativewindow/native/macosx/OSXmisc.m @@ -519,13 +519,18 @@ JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow { int shallBeDetached = 0; JNIEnv* env = NativewindowCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached); + DBG_PRINT("MainRunnable.0 env: %d\n", (int)(NULL!=env)); if(NULL!=env) { + DBG_PRINT("MainRunnable.1.0\n"); (*env)->CallVoidMethod(env, runnableObj, runnableRunID); + DBG_PRINT("MainRunnable.1.1\n"); if (shallBeDetached) { + DBG_PRINT("MainRunnable.1.2\n"); (*jvmHandle)->DetachCurrentThread(jvmHandle); } } + DBG_PRINT("MainRunnable.X\n"); } @end @@ -537,14 +542,16 @@ JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow * Signature: (ZLjava/lang/Runnable;)V */ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_RunOnMainThread0 - (JNIEnv *env, jclass unused, jboolean jwait, jobject runnable) + (JNIEnv *env, jclass unused, jobject runnable) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + DBG_PRINT( "RunOnMainThread0: isMainThread %d, NSApp %d, NSApp-isRunning %d\n", + (int)([NSThread isMainThread]), (int)(NULL!=NSApp), (int)([NSApp isRunning])); + if ( NO == [NSThread isMainThread] ) { jobject runnableGlob = (*env)->NewGlobalRef(env, runnable); - BOOL wait = (JNI_TRUE == jwait) ? YES : NO; JavaVM *jvmHandle = NULL; int jvmVersion = 0; @@ -554,14 +561,18 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_RunOnMainThread0 jvmVersion = (*env)->GetVersion(env); } + DBG_PRINT( "RunOnMainThread0.1.0\n"); MainRunnable * mr = [[MainRunnable alloc] initWithRunnable: runnableGlob jvmHandle: jvmHandle jvmVersion: jvmVersion]; - [mr performSelectorOnMainThread:@selector(jRun) withObject:nil waitUntilDone:wait]; + [mr performSelectorOnMainThread:@selector(jRun) withObject:nil waitUntilDone:NO]; [mr release]; + DBG_PRINT( "RunOnMainThread0.1.1\n"); (*env)->DeleteGlobalRef(env, runnableGlob); } else { + DBG_PRINT( "RunOnMainThread0.2\n"); (*env)->CallVoidMethod(env, runnable, runnableRunID); } + DBG_PRINT( "RunOnMainThread0.X\n"); [pool release]; } @@ -620,7 +631,7 @@ JNIEXPORT jint JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetScreenRefreshR DBG_PRINT("GetScreenRefreshRate.0: screen %p\n", (void *)screen); if(NULL != screen) { CGDirectDisplayID display = NewtScreen_getCGDirectDisplayIDByNSScreen(screen); - DBG_PRINT("GetScreenRefreshRate.1: display %p\n", (void *)display); + DBG_PRINT("GetScreenRefreshRate.1: display %p\n", (void *)(intptr_t)display); if(0 != display) { CFDictionaryRef mode = CGDisplayCurrentMode(display); DBG_PRINT("GetScreenRefreshRate.2: mode %p\n", (void *)mode); @@ -633,7 +644,7 @@ JNIEXPORT jint JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetScreenRefreshR if(0 == res) { res = 60; // default .. (experienced on OSX 10.6.8) } - DBG_PRINT(stderr, "GetScreenRefreshRate.X: %d\n", res); + DBG_PRINT(stderr, "GetScreenRefreshRate.X: %d\n", (int)res); // [pool release]; JNF_COCOA_EXIT(env); return res; |