diff options
author | Sven Gothel <[email protected]> | 2013-04-04 05:34:57 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-04-04 05:34:57 +0200 |
commit | 68526d3f9432ea9c80e444146fc99b4ae1352d50 (patch) | |
tree | 79c72ef4b84332ffe05252ebb556bf86e46688b2 /src/nativewindow | |
parent | 15e20956fc6a700c12b54342b6e1320a150ce039 (diff) |
OSX/CALayer Threading Part4: Stream all JAWT Root CALayer Operations on OSX Main-Thread
Previous code created, set and unset the root CALayer on the current thread,
which lead to a very delayed destruction of the root CALayer w/.
With Java7 this lead to a possible resource starvation in certain situations,
since Java7 uses an CAOpenGLLayer.
Similar w/ f354fb204d8973453c538dda78a2c82c87be61dc,
creation, set and unset is operated on main-thread.
Diffstat (limited to 'src/nativewindow')
3 files changed, 83 insertions, 108 deletions
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java index 9f76392a9..080504a5c 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java @@ -85,46 +85,28 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface { if(0 != windowHandle) { OSXUtil.DestroyNSWindow(windowHandle); } - if(0 != rootSurfaceLayer) { - final JAWT jawt = getJAWT(); - if( null != jawt ) { - final JAWT_DrawingSurface ds = jawt.GetDrawingSurface(component); - if (ds != null) { - if ( 0 == ( ds.Lock() & JAWTFactory.JAWT_LOCK_ERROR ) ) { - JAWT_DrawingSurfaceInfo dsi = null; - try { - dsi = ds.GetDrawingSurfaceInfo(); - try { - UnsetJAWTRootSurfaceLayer0(dsi.getBuffer(), rootSurfaceLayer); - } catch (Exception e) { - System.err.println("Error clearing JAWT rootSurfaceLayerHandle "+toHexString(rootSurfaceLayer)); - e.printStackTrace(); - } - } finally { - if ( null != dsi ) { - ds.FreeDrawingSurfaceInfo(dsi); - } - ds.Unlock(); - } + OSXUtil.RunOnMainThread(false, new Runnable() { + public void run() { + if( 0 != rootSurfaceLayer ) { + if( 0 != jawtSurfaceLayersHandle) { + UnsetJAWTRootSurfaceLayer0(jawtSurfaceLayersHandle, rootSurfaceLayer); } - jawt.FreeDrawingSurface(ds); - } - } - - OSXUtil.RunOnMainThread(false, new Runnable() { - public void run() { - OSXUtil.DestroyCALayer(rootSurfaceLayer, false); + OSXUtil.DestroyCALayer(rootSurfaceLayer); rootSurfaceLayer = 0; } - }); - } + jawtSurfaceLayersHandle = 0; + } + }); } windowHandle=0; } @Override protected void attachSurfaceLayerImpl(final long layerHandle) { - OSXUtil.AddCASublayer(rootSurfaceLayer, layerHandle, getWidth(), getHeight()); + OSXUtil.RunOnMainThread(false, new Runnable() { + public void run() { + OSXUtil.AddCASublayer(rootSurfaceLayer, layerHandle, getWidth(), getHeight()); + } } ); } @Override @@ -139,11 +121,8 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface { protected void detachSurfaceLayerImpl(final long layerHandle, final Runnable detachNotify) { OSXUtil.RunOnMainThread(false, new Runnable() { public void run() { - final long l = MacOSXJAWTWindow.this.getAttachedSurfaceLayer(); - if( 0 != l ) { - detachNotify.run(); - OSXUtil.RemoveCASublayer(rootSurfaceLayer, layerHandle, false); - } + detachNotify.run(); + OSXUtil.RemoveCASublayer(rootSurfaceLayer, layerHandle); } } ); } @@ -256,24 +235,32 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface { } } if(null == errMsg) { - if(0 == rootSurfaceLayer) { - rootSurfaceLayer = OSXUtil.CreateCALayer(bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight()); - if(0 == rootSurfaceLayer) { - errMsg = "Could not create root CALayer"; - } else { - try { - SetJAWTRootSurfaceLayer0(dsi.getBuffer(), rootSurfaceLayer); - } catch(Exception e) { - errMsg = "Could not set JAWT rootSurfaceLayerHandle "+toHexString(rootSurfaceLayer)+", cause: "+e.getMessage(); + jawtSurfaceLayersHandle = GetJAWTSurfaceLayersHandle0(dsi.getBuffer()); + OSXUtil.RunOnMainThread(false, new Runnable() { + public void run() { + String errMsg = null; + if(0 == rootSurfaceLayer && 0 != jawtSurfaceLayersHandle) { + rootSurfaceLayer = OSXUtil.CreateCALayer(bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight()); + if(0 == rootSurfaceLayer) { + errMsg = "Could not create root CALayer"; + } else { + try { + SetJAWTRootSurfaceLayer0(jawtSurfaceLayersHandle, rootSurfaceLayer); + } catch(Exception e) { + errMsg = "Could not set JAWT rootSurfaceLayerHandle "+toHexString(rootSurfaceLayer)+", cause: "+e.getMessage(); + } + } + if(null != errMsg) { + if(0 != rootSurfaceLayer) { + OSXUtil.DestroyCALayer(rootSurfaceLayer); + rootSurfaceLayer = 0; + } + throw new NativeWindowException(errMsg+": "+MacOSXJAWTWindow.this); + } } - } - } + } } ); } if(null != errMsg) { - if(0 != rootSurfaceLayer) { - OSXUtil.DestroyCALayer(rootSurfaceLayer, true); - rootSurfaceLayer = 0; - } if(0 != windowHandle) { OSXUtil.DestroyNSWindow(windowHandle); windowHandle = 0; @@ -326,20 +313,24 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface { } protected Point getLocationOnScreenNativeImpl(final int x0, final int y0) { return null; } + + private static native long GetJAWTSurfaceLayersHandle0(Buffer jawtDrawingSurfaceInfoBuffer); + /** * Set the given root CALayer in the JAWT surface */ - private static native void SetJAWTRootSurfaceLayer0(Buffer jawtDrawingSurfaceInfoBuffer, long caLayer); + private static native void SetJAWTRootSurfaceLayer0(long jawtSurfaceLayersHandle, long caLayer); /** * Unset the given root CALayer in the JAWT surface, passing the NIO DrawingSurfaceInfo buffer */ - private static native void UnsetJAWTRootSurfaceLayer0(Buffer jawtDrawingSurfaceInfoBuffer, long caLayer); + private static native void UnsetJAWTRootSurfaceLayer0(long jawtSurfaceLayersHandle, long caLayer); // Variables for lockSurface/unlockSurface private JAWT_DrawingSurface ds; private boolean dsLocked; private JAWT_DrawingSurfaceInfo dsi; + private long jawtSurfaceLayersHandle; private JAWT_MacOSXDrawingSurfaceInfo macosxdsi; diff --git a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java index 4b102be00..1a90c095d 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java +++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java @@ -138,7 +138,7 @@ public class OSXUtil implements ToolkitProperties { /** * Create a CALayer suitable to act as a root CALayer. - * @see #DestroyCALayer(long, boolean) + * @see #DestroyCALayer(long) * @see #AddCASublayer(long, long) */ public static long CreateCALayer(final int x, final int y, final int width, final int height) { @@ -150,7 +150,7 @@ public class OSXUtil implements ToolkitProperties { } /** - * Attach a sub CALayer to the root CALayer on the main-thread w/o blocking. + * Attach a sub CALayer to the root CALayer * <p> * Method will trigger a <code>display</code> * call to the CALayer hierarchy to enforce resource creation if required, e.g. an NSOpenGLContext. @@ -166,14 +166,10 @@ public class OSXUtil implements ToolkitProperties { if(0==rootCALayer || 0==subCALayer) { throw new IllegalArgumentException("rootCALayer 0x"+Long.toHexString(rootCALayer)+", subCALayer 0x"+Long.toHexString(subCALayer)); } - RunOnMainThread(false, new Runnable() { - public void run() { - if(DEBUG) { - System.err.println("OSXUtil.AttachCALayer: 0x"+Long.toHexString(subCALayer)+" - "+Thread.currentThread().getName()); - } - AddCASublayer0(rootCALayer, subCALayer, width, height); - } - }); + if(DEBUG) { + System.err.println("OSXUtil.AttachCALayer: 0x"+Long.toHexString(subCALayer)+" - "+Thread.currentThread().getName()); + } + AddCASublayer0(rootCALayer, subCALayer, width, height); } /** @@ -201,47 +197,29 @@ public class OSXUtil implements ToolkitProperties { /** * Detach a sub CALayer from the root CALayer. - * @param onMainThread if <code>true</code> method will be performed on the main-thread w/o blocking. */ - public static void RemoveCASublayer(final long rootCALayer, final long subCALayer, boolean onMainThread) { + 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)); } - final Runnable action = new Runnable() { - public void run() { - if(DEBUG) { - System.err.println("OSXUtil.DetachCALayer: 0x"+Long.toHexString(subCALayer)+" - "+Thread.currentThread().getName()); - } - RemoveCASublayer0(rootCALayer, subCALayer); - } }; - if( onMainThread ) { - RunOnMainThread(false, action); - } else { - action.run(); + if(DEBUG) { + System.err.println("OSXUtil.DetachCALayer: 0x"+Long.toHexString(subCALayer)+" - "+Thread.currentThread().getName()); } + RemoveCASublayer0(rootCALayer, subCALayer); } /** * Destroy a CALayer. - * @param onMainThread if <code>true</code> method will be performed on the main-thread w/o blocking. * @see #CreateCALayer(int, int, int, int) */ - public static void DestroyCALayer(final long caLayer, boolean onMainThread) { + public static void DestroyCALayer(final long caLayer) { if(0==caLayer) { throw new IllegalArgumentException("caLayer 0x"+Long.toHexString(caLayer)); } - final Runnable action = new Runnable() { - public void run() { - if(DEBUG) { - System.err.println("OSXUtil.DestroyCALayer: 0x"+Long.toHexString(caLayer)+" - "+Thread.currentThread().getName()); - } - DestroyCALayer0(caLayer); - } }; - if( onMainThread ) { - RunOnMainThread(false, action); - } else { - action.run(); + if(DEBUG) { + System.err.println("OSXUtil.DestroyCALayer: 0x"+Long.toHexString(caLayer)+" - "+Thread.currentThread().getName()); } + DestroyCALayer0(caLayer); } /** diff --git a/src/nativewindow/native/macosx/OSXmisc.m b/src/nativewindow/native/macosx/OSXmisc.m index d6a63702b..688ef79b8 100644 --- a/src/nativewindow/native/macosx/OSXmisc.m +++ b/src/nativewindow/native/macosx/OSXmisc.m @@ -348,10 +348,9 @@ JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetNSWindow0 - (id)init { - DBG_PRINT("MyCALayer.0\n"); + DBG_PRINT("MyCALayer::init.0\n"); MyCALayer * o = [super init]; - DBG_PRINT("MyNSOpenGLContext.init.X: new %p\n", o); - DBG_PRINT("MyCALayer.0\n"); + DBG_PRINT("MyCALayer::init.X: new %p\n", o); return o; } @@ -595,25 +594,37 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_DestroyCALayer0 /* * Class: Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow + * Method: GetJAWTSurfaceLayersHandle0 + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_GetJAWTSurfaceLayersHandle0 + (JNIEnv *env, jclass unused, jobject jawtDrawingSurfaceInfoBuffer) +{ + JAWT_DrawingSurfaceInfo* dsi = (JAWT_DrawingSurfaceInfo*) (*env)->GetDirectBufferAddress(env, jawtDrawingSurfaceInfoBuffer); + if (NULL == dsi) { + NativewindowCommon_throwNewRuntimeException(env, "Argument \"jawtDrawingSurfaceInfoBuffer\" was not a direct buffer"); + return 0; + } + id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)dsi->platformInfo; + return (jlong) ((intptr_t) surfaceLayers); +} + +/* + * Class: Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow * Method: SetJAWTRootSurfaceLayer0 * Signature: (JJ)V */ JNIEXPORT void JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_SetJAWTRootSurfaceLayer0 - (JNIEnv *env, jclass unused, jobject jawtDrawingSurfaceInfoBuffer, jlong caLayer) + (JNIEnv *env, jclass unused, jlong jawtSurfaceLayersHandle, jlong caLayer) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; [CATransaction begin]; [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions]; - JAWT_DrawingSurfaceInfo* dsi = (JAWT_DrawingSurfaceInfo*) (*env)->GetDirectBufferAddress(env, jawtDrawingSurfaceInfoBuffer); - if (NULL == dsi) { - NativewindowCommon_throwNewRuntimeException(env, "Argument \"jawtDrawingSurfaceInfoBuffer\" was not a direct buffer"); - return; - } + id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)(intptr_t)jawtSurfaceLayersHandle; MyCALayer* layer = (MyCALayer*) (intptr_t) caLayer; - id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)dsi->platformInfo; - DBG_PRINT("CALayer::SetJAWTRootSurfaceLayer.0: pre %p -> root %p (refcnt %d)\n", surfaceLayers.layer, layer, (int)[layer retainCount]); + DBG_PRINT("CALayer::SetJAWTRootSurfaceLayer.0: pre %p -> root %p (refcnt %d)\n", [surfaceLayers layer], layer, (int)[layer retainCount]); [surfaceLayers setLayer: [layer retain]]; // Pairs w/ Unset [CATransaction commit]; @@ -628,21 +639,16 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_Set * Signature: (JJ)V */ JNIEXPORT void JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_UnsetJAWTRootSurfaceLayer0 - (JNIEnv *env, jclass unused, jobject jawtDrawingSurfaceInfoBuffer, jlong caLayer) + (JNIEnv *env, jclass unused, jlong jawtSurfaceLayersHandle, jlong caLayer) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; [CATransaction begin]; [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions]; - JAWT_DrawingSurfaceInfo* dsi = (JAWT_DrawingSurfaceInfo*) (*env)->GetDirectBufferAddress(env, jawtDrawingSurfaceInfoBuffer); - if (NULL == dsi) { - NativewindowCommon_throwNewRuntimeException(env, "Argument \"jawtDrawingSurfaceInfoBuffer\" was not a direct buffer"); - return; - } + id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)(intptr_t)jawtSurfaceLayersHandle; MyCALayer* layer = (MyCALayer*) (intptr_t) caLayer; - id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)dsi->platformInfo; - if(layer != surfaceLayers.layer) { + if(layer != [surfaceLayers layer]) { NativewindowCommon_throwNewRuntimeException(env, "Attached layer %p doesn't match given layer %p\n", surfaceLayers.layer, layer); return; } |