summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2013-04-04 05:34:57 +0200
committerSven Gothel <[email protected]>2013-04-04 05:34:57 +0200
commit68526d3f9432ea9c80e444146fc99b4ae1352d50 (patch)
tree79c72ef4b84332ffe05252ebb556bf86e46688b2
parent15e20956fc6a700c12b54342b6e1320a150ce039 (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.
-rw-r--r--src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m24
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java97
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java50
-rw-r--r--src/nativewindow/native/macosx/OSXmisc.m44
4 files changed, 95 insertions, 120 deletions
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
index 35c9b6a7f..6738364a7 100644
--- a/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
+++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
@@ -67,29 +67,29 @@ extern GLboolean glIsVertexArray (GLuint array);
- (id)initWithFormat:(NSOpenGLPixelFormat *)format shareContext:(NSOpenGLContext *)share
{
- DBG_PRINT("MyNSOpenGLContext.initWithFormat.0: format %p, share %p\n", format, share);
+ DBG_PRINT("MyNSOpenGLContext::initWithFormat.0: format %p, share %p\n", format, share);
MyNSOpenGLContext * o = [super initWithFormat:format shareContext:share];
- DBG_PRINT("MyNSOpenGLContext.initWithFormat.X: new %p\n", o);
+ DBG_PRINT("MyNSOpenGLContext::initWithFormat.X: new %p\n", o);
return o;
}
- (void)setView:(NSView *)view
{
- DBG_PRINT("MyNSOpenGLContext.setView: this.0 %p, view %p\n", self, view);
+ DBG_PRINT("MyNSOpenGLContext::setView: this.0 %p, view %p\n", self, view);
// NSLog(@"MyNSOpenGLContext::setView: %@",[NSThread callStackSymbols]);
if(NULL != view) {
[super setView:view];
} else {
[self clearDrawable];
}
- DBG_PRINT("MyNSOpenGLContext.setView.X\n");
+ DBG_PRINT("MyNSOpenGLContext::setView.X\n");
}
- (void)update
{
- DBG_PRINT("MyNSOpenGLContext.update: this.0 %p, view %p\n", self, [self view]);
+ DBG_PRINT("MyNSOpenGLContext::update: this.0 %p, view %p\n", self, [self view]);
[super update];
- DBG_PRINT("MyNSOpenGLContext.update.X\n");
+ DBG_PRINT("MyNSOpenGLContext::update.X\n");
}
#ifdef DBG_LIFECYCLE
@@ -132,20 +132,20 @@ extern GLboolean glIsVertexArray (GLuint array);
// NSLog(@"MyNSOpenGLContext::dealloc: %@",[NSThread callStackSymbols]);
[self clearDrawable];
- DBG_PRINT("MyNSOpenGLContext.dealloc.1 %d\n", CGLRETAINCOUNT(cglCtx));
+ DBG_PRINT("MyNSOpenGLContext::dealloc.1 %d\n", CGLRETAINCOUNT(cglCtx));
if( NULL != cglCtx ) {
CGLRetainContext( cglCtx );
- DBG_PRINT("MyNSOpenGLContext.dealloc.2 %d\n", CGLRETAINCOUNT(cglCtx));
+ DBG_PRINT("MyNSOpenGLContext::dealloc.2 %d\n", CGLRETAINCOUNT(cglCtx));
}
[super dealloc];
- DBG_PRINT("MyNSOpenGLContext.dealloc.3 %d\n", CGLRETAINCOUNT(cglCtx));
+ DBG_PRINT("MyNSOpenGLContext::dealloc.3 %d\n", CGLRETAINCOUNT(cglCtx));
if( NULL != cglCtx ) {
CGLReleaseContext( cglCtx );
- DBG_PRINT("MyNSOpenGLContext.dealloc.4 %d\n", CGLRETAINCOUNT(cglCtx));
+ DBG_PRINT("MyNSOpenGLContext::dealloc.4 %d\n", CGLRETAINCOUNT(cglCtx));
CGLDestroyContext( cglCtx );
- DBG_PRINT("MyNSOpenGLContext.dealloc.5 %d\n", CGLRETAINCOUNT(cglCtx));
+ DBG_PRINT("MyNSOpenGLContext::dealloc.5 %d\n", CGLRETAINCOUNT(cglCtx));
}
- DBG_PRINT("MyNSOpenGLContext.dealloc.X\n");
+ DBG_PRINT("MyNSOpenGLContext::dealloc.X\n");
}
@end
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;
}