aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2010-12-11 06:41:00 +0100
committerSven Gothel <[email protected]>2010-12-11 06:41:00 +0100
commitc8807f6847e34d599b8bc9a476c84785e1925c8a (patch)
treecd1703bf757f864daaf9335a8a387fe88b0b7bc6
parent74fb7ca7ac8484e86ff6c84a5e3ceef79fb4d0d6 (diff)
Generalize SharedResourceRunner and use/impl it for WGL as well (besides X11).
It seems necessary to use off thread shared resources (dummy window, drawable and context) to keep them alive in Java Webstart.
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/SharedResourceRunner.java244
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java243
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java402
3 files changed, 521 insertions, 368 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/SharedResourceRunner.java b/src/jogl/classes/com/jogamp/opengl/impl/SharedResourceRunner.java
new file mode 100644
index 000000000..1ea83f84a
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/SharedResourceRunner.java
@@ -0,0 +1,244 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package com.jogamp.opengl.impl;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+
+public class SharedResourceRunner implements Runnable {
+ protected static final boolean DEBUG = GLDrawableImpl.DEBUG;
+
+ public static interface Resource {
+ AbstractGraphicsDevice getDevice();
+ AbstractGraphicsScreen getScreen();
+ GLDrawableImpl getDrawable();
+ GLContextImpl getContext();
+ }
+
+ public static interface Implementation {
+ Resource createSharedResource(String connection);
+ void releaseSharedResource(Resource shared);
+ void clear();
+
+ Resource mapPut(String connection, Resource resource);
+ Resource mapGet(String connection);
+ Collection/*<Resource>*/ mapValues();
+ }
+
+ Implementation impl = null;
+
+ boolean ready = false;
+ boolean released = false;
+ boolean shouldRelease = false;
+ String initConnection = null;
+ String releaseConnection = null;
+
+ HashSet devicesTried = new HashSet();
+
+ private boolean getDeviceTried(String connection) {
+ synchronized (devicesTried) {
+ return devicesTried.contains(connection);
+ }
+ }
+ private void addDeviceTried(String connection) {
+ synchronized (devicesTried) {
+ devicesTried.add(connection);
+ }
+ }
+ private void removeDeviceTried(String connection) {
+ synchronized (devicesTried) {
+ devicesTried.remove(connection);
+ }
+ }
+
+ public SharedResourceRunner(Implementation impl) {
+ this.impl = impl;
+ }
+
+ public SharedResourceRunner.Resource getOrCreateShared(AbstractGraphicsDevice device) {
+ String connection = device.getConnection();
+ SharedResourceRunner.Resource sr = impl.mapGet(connection);
+
+ if (null == sr && !getDeviceTried(connection)) {
+ addDeviceTried(connection);
+ if (DEBUG) {
+ System.err.println("getOrCreateShared() " + connection + ": trying");
+ }
+ doAndWait(connection, null);
+ sr = impl.mapGet(connection);
+ if (DEBUG) {
+ Throwable t = new Throwable("getOrCreateSharedl() " + connection + ": done");
+ t.printStackTrace();
+ }
+ }
+ return sr;
+ }
+
+ public SharedResourceRunner.Resource releaseShared(AbstractGraphicsDevice device) {
+ String connection = device.getConnection();
+ SharedResourceRunner.Resource sr = impl.mapGet(connection);
+
+ if (null != sr) {
+ removeDeviceTried(connection);
+ if (DEBUG) {
+ System.err.println("releaseShared() " + connection + ": trying");
+ }
+ doAndWait(null, connection);
+ if (DEBUG) {
+ Throwable t = new Throwable("releaseSharedl() " + connection + ": done");
+ t.printStackTrace();
+ }
+ }
+ return sr;
+ }
+
+ private final void doAndWait(String initConnection, String releaseConnection) {
+ // wait until thread becomes ready to init new device,
+ // pass the device and release the sync
+ String threadName = Thread.currentThread().getName();
+ if (DEBUG) {
+ System.err.println(threadName + " doAndWait START init: " + initConnection + ", release: "+releaseConnection);
+ }
+ synchronized (this) {
+ while (!ready) {
+ try {
+ this.wait();
+ } catch (InterruptedException ex) {
+ }
+ }
+ if (DEBUG) {
+ System.err.println(threadName + " initializeAndWait set command init: " + initConnection + ", release: "+releaseConnection);
+ }
+ this.initConnection = initConnection;
+ this.releaseConnection = releaseConnection;
+ this.notifyAll();
+
+ // wait until thread has init/released the device
+ while (!ready || null != this.initConnection || null != this.releaseConnection) {
+ try {
+ this.wait();
+ } catch (InterruptedException ex) {
+ }
+ }
+ if (DEBUG) {
+ System.err.println(threadName + " initializeAndWait END init: " + initConnection + ", release: "+releaseConnection);
+ }
+ }
+ // done
+ }
+
+ public final void releaseAndWait() {
+ synchronized (this) {
+ shouldRelease = true;
+ this.notifyAll();
+
+ while (!released) {
+ try {
+ this.wait();
+ } catch (InterruptedException ex) {
+ }
+ }
+ }
+ }
+
+ public final void run() {
+ String threadName = Thread.currentThread().getName();
+
+ if (DEBUG) {
+ System.err.println(threadName + " STARTED");
+ }
+
+ synchronized (this) {
+ while (!shouldRelease) {
+ try {
+ // wait for stop or init
+ ready = true;
+ if (DEBUG) {
+ System.err.println(threadName + " -> ready");
+ }
+ notifyAll();
+ this.wait();
+ } catch (InterruptedException ex) { }
+ ready = false;
+
+ if (!shouldRelease) {
+ if (DEBUG) {
+ System.err.println(threadName + " woke up for device connection init: " + initConnection +
+ ", release: " + releaseConnection);
+ }
+ if(null != initConnection) {
+ if (DEBUG) {
+ System.err.println(threadName + " create Shared for: " + initConnection);
+ }
+ Resource sr = impl.createSharedResource(initConnection);
+ if (null != sr) {
+ impl.mapPut(initConnection, sr);
+ }
+ }
+ if(null != releaseConnection) {
+ if (DEBUG) {
+ System.err.println(threadName + " release Shared for: " + releaseConnection);
+ }
+ Resource sr = impl.mapPut(releaseConnection, null);
+ if (null != sr) {
+ impl.releaseSharedResource(sr);
+ }
+ }
+ }
+ initConnection = null;
+ releaseConnection = null;
+ }
+
+ if (DEBUG) {
+ System.err.println(threadName + " release START");
+ }
+
+ releaseSharedResources();
+
+ if (DEBUG) {
+ System.err.println(threadName + " release END");
+ }
+
+ released = true;
+ ready = false;
+ notifyAll();
+ }
+ }
+
+ private void releaseSharedResources() {
+ Collection/*<Resource>*/ sharedResources = impl.mapValues();
+ for (Iterator iter = sharedResources.iterator(); iter.hasNext();) {
+ Resource sr = (Resource) iter.next();
+ impl.releaseSharedResource(sr);
+ }
+ impl.clear();
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java
index 84636f539..4d687a00c 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java
@@ -66,9 +66,11 @@ import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.nativewindow.impl.ProxySurface;
import com.jogamp.nativewindow.impl.windows.GDI;
import com.jogamp.opengl.impl.DesktopGLDynamicLookupHelper;
+import com.jogamp.opengl.impl.GLContextImpl;
import com.jogamp.opengl.impl.GLDrawableFactoryImpl;
import com.jogamp.opengl.impl.GLDrawableImpl;
import com.jogamp.opengl.impl.GLDynamicLookupHelper;
+import com.jogamp.opengl.impl.SharedResourceRunner;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.opengl.GLCapabilitiesImmutable;
@@ -108,32 +110,141 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
}
defaultDevice = new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
+
+ // Init shared resources off thread
+ // Will be released via ShutdownHook
+ sharedResourceImpl = new SharedResourceImplementation();
+ sharedResourceRunner = new SharedResourceRunner(sharedResourceImpl);
+ sharedResourceThread = new Thread(sharedResourceRunner, Thread.currentThread().getName()+"-SharedResourceRunner");
+ sharedResourceThread.setDaemon(true); // Allow JVM to exit, even if this one is running
+ sharedResourceThread.start();
}
- static class SharedResource {
+ WindowsGraphicsDevice defaultDevice;
+ SharedResourceImplementation sharedResourceImpl;
+ SharedResourceRunner sharedResourceRunner;
+ Thread sharedResourceThread;
+ HashMap/*<connection, SharedResource>*/ sharedMap = new HashMap();
+
+ static class SharedResource implements SharedResourceRunner.Resource {
private WindowsGraphicsDevice device;
+ private AbstractGraphicsScreen screen;
private WindowsDummyWGLDrawable drawable;
private WindowsWGLContext context;
private boolean canCreateGLPbuffer;
private boolean readDrawableAvailable;
- SharedResource(WindowsGraphicsDevice dev, WindowsDummyWGLDrawable draw, WindowsWGLContext ctx,
+ SharedResource(WindowsGraphicsDevice dev, AbstractGraphicsScreen scrn, WindowsDummyWGLDrawable draw, WindowsWGLContext ctx,
boolean readBufferAvail, boolean canPbuffer) {
device = dev;
+ screen = scrn;
drawable = draw;
context = ctx;
canCreateGLPbuffer = canPbuffer;
readDrawableAvailable = readBufferAvail;
}
- WindowsGraphicsDevice getDevice() { return device; }
- WindowsWGLDrawable getDrawable() { return drawable; }
- WindowsWGLContext getContext() { return context; }
+ public AbstractGraphicsDevice getDevice() { return device; }
+ public AbstractGraphicsScreen getScreen() { return screen; }
+ public GLDrawableImpl getDrawable() { return drawable; }
+ public GLContextImpl getContext() { return context; }
+
boolean canCreateGLPbuffer() { return canCreateGLPbuffer; }
boolean isReadDrawableAvailable() { return readDrawableAvailable; }
+ }
+
+ class SharedResourceImplementation implements SharedResourceRunner.Implementation {
+ public void clear() {
+ synchronized(sharedMap) {
+ sharedMap.clear();
+ }
+ }
+ public SharedResourceRunner.Resource mapPut(String connection, SharedResourceRunner.Resource resource) {
+ synchronized(sharedMap) {
+ return (SharedResourceRunner.Resource) sharedMap.put(connection, resource);
+ }
+ }
+ public SharedResourceRunner.Resource mapGet(String connection) {
+ synchronized(sharedMap) {
+ return (SharedResourceRunner.Resource) sharedMap.get(connection);
+ }
+ }
+ public Collection/*<Resource>*/ mapValues() {
+ synchronized(sharedMap) {
+ return sharedMap.values();
+ }
+ }
+
+ public SharedResourceRunner.Resource createSharedResource(String connection) {
+ WindowsGraphicsDevice sharedDevice = new WindowsGraphicsDevice(connection, AbstractGraphicsDevice.DEFAULT_UNIT);
+ sharedDevice.lock();
+ try {
+ AbstractGraphicsScreen absScreen = new DefaultGraphicsScreen(sharedDevice, 0);
+ if (null == absScreen) {
+ throw new GLException("Couldn't create shared screen for device: "+sharedDevice+", idx 0");
+ }
+ GLProfile glp = GLProfile.getDefault(sharedDevice);
+ if (null == glp) {
+ throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice);
+ }
+ WindowsDummyWGLDrawable sharedDrawable = WindowsDummyWGLDrawable.create(WindowsWGLDrawableFactory.this, glp, absScreen);
+ if (null == sharedDrawable) {
+ throw new GLException("Couldn't create shared drawable for screen: "+absScreen+", "+glp);
+ }
+ WindowsWGLContext sharedContext = (WindowsWGLContext) sharedDrawable.createContext(null);
+ if (null == sharedContext) {
+ throw new GLException("Couldn't create shared context for drawable: "+sharedDrawable);
+ }
+ sharedContext.setSynchronized(true);
+ sharedContext.makeCurrent();
+ boolean canCreateGLPbuffer = sharedContext.getGL().isExtensionAvailable(GL_ARB_pbuffer);
+ boolean readDrawableAvailable = sharedContext.isExtensionAvailable(WGL_ARB_make_current_read) &&
+ sharedContext.isFunctionAvailable(wglMakeContextCurrent);
+ sharedContext.release();
+ if (DEBUG) {
+ System.err.println("!!! SharedDevice: " + sharedDevice);
+ System.err.println("!!! SharedScreen: " + absScreen);
+ System.err.println("!!! SharedContext: " + sharedContext);
+ System.err.println("!!! pbuffer avail: " + canCreateGLPbuffer);
+ System.err.println("!!! readDrawable: " + readDrawableAvailable);
+ }
+ return new SharedResource(sharedDevice, absScreen, sharedDrawable, sharedContext, readDrawableAvailable, canCreateGLPbuffer);
+ } catch (Throwable t) {
+ throw new GLException("WindowsWGLDrawableFactory - Could not initialize shared resources for "+connection, t);
+ } finally {
+ sharedDevice.unlock();
+ }
+ }
+
+ public void releaseSharedResource(SharedResourceRunner.Resource shared) {
+ SharedResource sr = (SharedResource) shared;
+ if (DEBUG) {
+ System.err.println("!!! Shutdown Shared:");
+ System.err.println("!!! Device : " + sr.device);
+ System.err.println("!!! Screen : " + sr.screen);
+ System.err.println("!!! Drawable: " + sr.drawable);
+ System.err.println("!!! CTX : " + sr.context);
+ }
+
+ if (null != sr.context) {
+ // may cause JVM SIGSEGV: sharedContext.destroy();
+ sr.context = null;
+ }
+
+ if (null != sr.drawable) {
+ // may cause JVM SIGSEGV: sharedDrawable.destroy();
+ sr.drawable = null;
+ }
+
+ if (null != sr.screen) {
+ sr.screen = null;
+ }
+ if (null != sr.device) {
+ sr.device.close();
+ sr.device = null;
+ }
+ }
}
- HashMap/*<connection, SharedResource>*/ sharedMap = new HashMap();
- WindowsGraphicsDevice defaultDevice;
public final AbstractGraphicsDevice getDefaultDevice() {
return defaultDevice;
@@ -146,62 +257,12 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
return false;
}
- HashSet devicesTried = new HashSet();
- private final boolean getDeviceTried(String connection) {
- synchronized(devicesTried) {
- return devicesTried.contains(connection);
- }
- }
- private final void addDeviceTried(String connection) {
- synchronized(devicesTried) {
- devicesTried.add(connection);
- }
- }
-
final static String GL_ARB_pbuffer = "GL_ARB_pbuffer";
final static String WGL_ARB_make_current_read = "WGL_ARB_make_current_read";
final static String wglMakeContextCurrent = "wglMakeContextCurrent";
- private SharedResource getOrCreateShared(AbstractGraphicsDevice device) {
- String connection = device.getConnection();
- SharedResource sr;
- synchronized(sharedMap) {
- sr = (SharedResource) sharedMap.get(connection);
- }
- if(null==sr && !getDeviceTried(connection)) {
- addDeviceTried(connection);
- NativeWindowFactory.getDefaultToolkitLock().lock(); // OK
- try {
- WindowsGraphicsDevice sharedDevice = new WindowsGraphicsDevice(connection, AbstractGraphicsDevice.DEFAULT_UNIT);
- GLProfile glp = GLProfile.getDefault(/*sharedDevice*/); // can't fetch device profile, which shared resource we create here
- AbstractGraphicsScreen absScreen = new DefaultGraphicsScreen(sharedDevice, 0);
- WindowsDummyWGLDrawable sharedDrawable = WindowsDummyWGLDrawable.create(this, glp, absScreen);
- WindowsWGLContext ctx = (WindowsWGLContext) sharedDrawable.createContext(null);
- ctx.setSynchronized(true);
- ctx.makeCurrent();
- boolean canCreateGLPbuffer = ctx.getGL().isExtensionAvailable(GL_ARB_pbuffer);
- boolean readDrawableAvailable = ctx.isExtensionAvailable(WGL_ARB_make_current_read) &&
- ctx.isFunctionAvailable(wglMakeContextCurrent);
- if (DEBUG) {
- System.err.println("!!! SharedContext: "+ctx+", pbuffer supported "+canCreateGLPbuffer+
- ", readDrawable supported "+readDrawableAvailable);
- }
- ctx.release();
- sr = new SharedResource(sharedDevice, sharedDrawable, ctx, readDrawableAvailable, canCreateGLPbuffer);
- synchronized(sharedMap) {
- sharedMap.put(connection, sr);
- }
- } catch (Throwable t) {
- throw new GLException("WindowsWGLDrawableFactory - Could not initialize shared resources", t);
- } finally {
- NativeWindowFactory.getDefaultToolkitLock().unlock(); // OK
- }
- }
- return sr;
- }
-
protected final GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device) {
- SharedResource sr = getOrCreateShared(device);
+ SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device);
if(null!=sr) {
return sr.getContext();
}
@@ -209,7 +270,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
}
protected AbstractGraphicsDevice getOrCreateSharedDeviceImpl(AbstractGraphicsDevice device) {
- SharedResource sr = getOrCreateShared(device);
+ SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device);
if(null!=sr) {
return sr.getDevice();
}
@@ -217,43 +278,15 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
}
protected WindowsWGLDrawable getSharedDrawable(AbstractGraphicsDevice device) {
- SharedResource sr = getOrCreateShared(device);
+ SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device);
if(null!=sr) {
- return sr.getDrawable();
+ return (WindowsWGLDrawable) sr.getDrawable();
}
return null;
}
protected final void shutdownInstance() {
- if (DEBUG) {
- Exception e = new Exception("Debug");
- e.printStackTrace();
- }
- Collection/*<SharedResource>*/ sharedResources = sharedMap.values();
- for(Iterator iter=sharedResources.iterator(); iter.hasNext(); ) {
- SharedResource sr = (SharedResource) iter.next();
-
- if (DEBUG) {
- System.err.println("!!! Shutdown Shared:");
- System.err.println("!!! Drawable: "+sr.drawable);
- System.err.println("!!! CTX : "+sr.context);
- }
-
- if (null != sr.context) {
- // may cause JVM SIGSEGV: sharedContext.destroy();
- sr.context = null;
- }
-
- if (null != sr.drawable) {
- // may cause JVM SIGSEGV: sharedDrawable.destroy();
- sr.drawable = null;
- }
-
- }
- sharedMap.clear();
- if (DEBUG) {
- System.err.println("!!! Shutdown Shared Finished");
- }
+ sharedResourceRunner.releaseAndWait();
}
protected final GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) {
@@ -276,7 +309,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
// PBuffer GLDrawable Creation
final AbstractGraphicsDevice device = config.getScreen().getDevice();
- final SharedResource sr = getOrCreateShared(device);
+ final SharedResource sr = (SharedResource) sharedResourceRunner.getOrCreateShared(device);
if(null==sr) {
throw new IllegalArgumentException("No shared resource for "+device);
}
@@ -287,19 +320,17 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
if (lastContext != null) {
lastContext.release();
}
- synchronized(sr.context) {
- sr.context.makeCurrent();
- try {
- GLDrawableImpl pbufferDrawable = new WindowsPbufferWGLDrawable(WindowsWGLDrawableFactory.this, target,
- sr.drawable,
- sr.context);
- returnList.add(pbufferDrawable);
- } finally {
- sr.context.release();
- if (lastContext != null) {
- lastContext.makeCurrent();
- }
- }
+ sr.context.makeCurrent();
+ try {
+ GLDrawableImpl pbufferDrawable = new WindowsPbufferWGLDrawable(WindowsWGLDrawableFactory.this, target,
+ sr.drawable,
+ sr.context);
+ returnList.add(pbufferDrawable);
+ } finally {
+ sr.context.release();
+ if (lastContext != null) {
+ lastContext.makeCurrent();
+ }
}
}
};
@@ -312,7 +343,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
* and -1 if undefined yet, ie no shared device exist at this point.
*/
public final int isReadDrawableAvailable(AbstractGraphicsDevice device) {
- SharedResource sr = getOrCreateShared((null!=device)?device:defaultDevice);
+ SharedResource sr = (SharedResource) sharedResourceRunner.getOrCreateShared((null!=device)?device:defaultDevice);
if(null!=sr) {
return sr.isReadDrawableAvailable() ? 1 : 0 ;
}
@@ -320,7 +351,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
}
public final boolean canCreateGLPbuffer(AbstractGraphicsDevice device) {
- SharedResource sr = getOrCreateShared((null!=device)?device:defaultDevice);
+ SharedResource sr = (SharedResource) sharedResourceRunner.getOrCreateShared((null!=device)?device:defaultDevice);
if(null!=sr) {
return sr.canCreateGLPbuffer();
}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java
index 7303e6e50..38294bf4f 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java
@@ -49,8 +49,6 @@ import com.jogamp.nativewindow.impl.ProxySurface;
import com.jogamp.nativewindow.impl.x11.*;
import java.util.Collection;
import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
@@ -90,205 +88,22 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
defaultDevice = new X11GraphicsDevice(X11Util.getNullDisplayName(), AbstractGraphicsDevice.DEFAULT_UNIT);
- // Init shared resources via own thread
+ // Init shared resources off thread
// Will be released via ShutdownHook
- sharedResourcesRunner = new SharedResourcesRunner();
- sharedResourcesThread = new Thread(sharedResourcesRunner, Thread.currentThread().getName()+"-SharedResourcesRunner");
- sharedResourcesThread.setDaemon(true); // Allow JVM to exit, even if this one is running
- sharedResourcesThread.start();
+ sharedResourceImpl = new SharedResourceImplementation();
+ sharedResourceRunner = new SharedResourceRunner(sharedResourceImpl);
+ sharedResourceThread = new Thread(sharedResourceRunner, Thread.currentThread().getName()+"-SharedResourceRunner");
+ sharedResourceThread.setDaemon(true); // Allow JVM to exit, even if this one is running
+ sharedResourceThread.start();
}
- class SharedResourcesRunner implements Runnable {
- boolean ready = false;
- boolean released = false;
- boolean shouldRelease = false;
- String initConnection = null;
- SharedResource result = null;
-
- public final void initializeAndWait(String connection) {
- // wait until thread becomes ready to init new device,
- // pass the device and release the sync
- String threadName = Thread.currentThread().getName();
- if (DEBUG) {
- System.err.println(threadName+ " initializeAndWait START: "+connection);
- }
- synchronized (this) {
- while (!ready) {
- try {
- this.wait();
- } catch (InterruptedException ex) { }
- }
- if (DEBUG) {
- System.err.println(threadName+ " initializeAndWait set command: "+connection);
- }
- initConnection = connection;
- this.notifyAll();
-
- // wait until thread has initialized the device
- while (!ready || null != initConnection) {
- try {
- this.wait();
- } catch (InterruptedException ex) { }
- }
- if (DEBUG) {
- System.err.println(threadName+ " initializeAndWait done: "+connection);
- }
- }
- // done
- }
-
- public final void releaseAndWait() {
- synchronized (this) {
- shouldRelease = true;
- this.notifyAll();
-
- while (!released) {
- try {
- this.wait();
- } catch (InterruptedException ex) {
- }
- }
- }
- }
-
- public final void run() {
- String threadName = Thread.currentThread().getName();
-
- synchronized (this) {
- if (DEBUG) {
- System.err.println(threadName+ " STARTED -> ready");
- }
-
- while (!shouldRelease) {
- try {
- // wait for stop or init
- ready = true;
- this.wait();
- } catch (InterruptedException ex) { }
- ready = false;
-
- if(!shouldRelease && null!=initConnection) {
- if (DEBUG) {
- System.err.println(threadName+ " create Shared for: "+initConnection);
- }
- SharedResource sr = createSharedResource(initConnection);
- if(null!=sr) {
- synchronized(sharedMap) {
- sharedMap.put(initConnection, sr);
- }
- }
- if (DEBUG) {
- String msg = "Info: (" + threadName + ") initializedSharedResource for device connection: "+initConnection+" -> ready";
- System.err.println(msg);
- Throwable t = new Throwable(msg);
- t.printStackTrace();
- }
- }
- initConnection = null;
- notifyAll();
- }
-
- if (DEBUG) {
- System.err.println(threadName+ " release START");
- }
-
- releaseSharedResources();
-
- if (DEBUG) {
- System.err.println(threadName+ " release END");
- }
-
- released = true;
- ready = false;
- notifyAll();
- }
- }
-
- private final SharedResource createSharedResource(String connection) {
- X11GraphicsDevice sharedDevice = new X11GraphicsDevice(X11Util.createDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT);
- sharedDevice.setCloseDisplay(true);
- sharedDevice.lock();
- try {
- String glXVendorName = GLXUtil.getVendorName(sharedDevice.getHandle());
- X11GraphicsScreen sharedScreen = new X11GraphicsScreen(sharedDevice, 0);
- X11DummyGLXDrawable sharedDrawable = X11DummyGLXDrawable.create(sharedScreen, X11GLXDrawableFactory.this,
- GLProfile.getDefault(sharedDevice));
- if (null == sharedScreen || null == sharedDrawable) {
- throw new GLException("Couldn't init shared screen(" + sharedScreen + ")/drawable(" + sharedDrawable + ")");
- }
- X11GLXContext sharedContext;
- VersionNumber glXVersion;
- try {
- X11GLXContext ctx = (X11GLXContext) sharedDrawable.createContext(null);
- ctx.setSynchronized(true);
- ctx.makeCurrent();
- {
- int[] major = new int[1];
- int[] minor = new int[1];
- GLXUtil.getGLXVersion(sharedDevice.getHandle(), major, minor);
- glXVersion = new VersionNumber(major[0], minor[0], 0);
- }
- ctx.release();
- sharedContext = ctx;
- } catch (Throwable t) {
- throw new GLException("X11GLXDrawableFactory - Could not initialize shared resources", t);
- }
- if (null == sharedContext) {
- throw new GLException("X11GLXDrawableFactory - Shared Context is null");
- }
- if (DEBUG) {
- System.err.println("!!! SharedDevice: "+sharedDevice);
- System.err.println("!!! SharedScreen: "+sharedScreen);
- System.err.println("!!! SharedContext: "+sharedContext);
- System.err.println("!!! GLX Vendor: "+glXVendorName);
- System.err.println("!!! GLX Version: "+glXVersion +
- " >= 1.3: " + ( glXVersion.compareTo(versionOneThree) >= 0 ) );
- }
- return new SharedResource(sharedDevice, sharedScreen, sharedDrawable, sharedContext, glXVersion, glXVendorName);
- } finally {
- sharedDevice.unlock();
- }
- }
-
- private final void releaseSharedResources() {
- Collection/*<SharedResource>*/ sharedResources = sharedMap.values();
- for(Iterator iter=sharedResources.iterator(); iter.hasNext(); ) {
- SharedResource sr = (SharedResource) iter.next();
-
- if (DEBUG) {
- System.err.println("!!! Shutdown Shared:");
- System.err.println("!!! Device : "+sr.device);
- System.err.println("!!! Screen : "+sr.screen);
- System.err.println("!!! Drawable: "+sr.drawable);
- System.err.println("!!! CTX : "+sr.context);
- }
-
- if (null != sr.context) {
- // may cause JVM SIGSEGV: sharedContext.destroy();
- sr.context = null;
- }
-
- if (null != sr.drawable) {
- // may cause JVM SIGSEGV: sharedDrawable.destroy();
- sr.drawable = null;
- }
-
- if (null != sr.screen) {
- sr.screen = null;
- }
-
- if (null != sr.device) {
- sr.device.close();
- sr.device=null;
- }
- }
- sharedMap.clear();
- }
- }
- Thread sharedResourcesThread = null;
- SharedResourcesRunner sharedResourcesRunner=null;
+ X11GraphicsDevice defaultDevice;
+ SharedResourceImplementation sharedResourceImpl;
+ SharedResourceRunner sharedResourceRunner;
+ Thread sharedResourceThread;
+ HashMap/*<connection, SharedResource>*/ sharedMap = new HashMap();
- static class SharedResource {
+ static class SharedResource implements SharedResourceRunner.Resource {
X11GraphicsDevice device;
X11GraphicsScreen screen;
X11DummyGLXDrawable drawable;
@@ -298,7 +113,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
boolean isGLXVendorNVIDIA;
VersionNumber glXVersion;
- SharedResource(X11GraphicsDevice dev, X11GraphicsScreen scrn,
+ SharedResource(X11GraphicsDevice dev, X11GraphicsScreen scrn,
X11DummyGLXDrawable draw, X11GLXContext ctx,
VersionNumber glXVer, String glXVendor) {
device = dev;
@@ -310,16 +125,117 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
isGLXVendorATI = GLXUtil.isVendorATI(glXVendorName);
isGLXVendorNVIDIA = GLXUtil.isVendorNVIDIA(glXVendorName);
}
- X11GraphicsDevice getDevice() { return device; }
- X11GraphicsScreen getScreen() { return screen; }
- X11GLXContext getContext() { return context; }
+ public AbstractGraphicsDevice getDevice() { return device; }
+ public AbstractGraphicsScreen getScreen() { return screen; }
+ public GLDrawableImpl getDrawable() { return drawable; }
+ public GLContextImpl getContext() { return context; }
+
String getGLXVendorName() { return glXVendorName; }
boolean isGLXVendorATI() { return isGLXVendorATI; }
boolean isGLXVendorNVIDIA() { return isGLXVendorNVIDIA; }
VersionNumber getGLXVersion() { return glXVersion; }
}
- HashMap/*<connection, SharedResource>*/ sharedMap = new HashMap();
- X11GraphicsDevice defaultDevice;
+
+ class SharedResourceImplementation implements SharedResourceRunner.Implementation {
+ public void clear() {
+ synchronized(sharedMap) {
+ sharedMap.clear();
+ }
+ }
+ public SharedResourceRunner.Resource mapPut(String connection, SharedResourceRunner.Resource resource) {
+ synchronized(sharedMap) {
+ return (SharedResourceRunner.Resource) sharedMap.put(connection, resource);
+ }
+ }
+ public SharedResourceRunner.Resource mapGet(String connection) {
+ synchronized(sharedMap) {
+ return (SharedResourceRunner.Resource) sharedMap.get(connection);
+ }
+ }
+ public Collection/*<Resource>*/ mapValues() {
+ synchronized(sharedMap) {
+ return sharedMap.values();
+ }
+ }
+
+ public SharedResourceRunner.Resource createSharedResource(String connection) {
+ X11GraphicsDevice sharedDevice = new X11GraphicsDevice(X11Util.createDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT);
+ sharedDevice.setCloseDisplay(true);
+ sharedDevice.lock();
+ try {
+ String glXVendorName = GLXUtil.getVendorName(sharedDevice.getHandle());
+ X11GraphicsScreen sharedScreen = new X11GraphicsScreen(sharedDevice, 0);
+ if (null == sharedScreen) {
+ throw new GLException("Couldn't create shared screen for device: "+sharedDevice+", idx 0");
+ }
+ GLProfile glp = GLProfile.getDefault(sharedDevice);
+ if (null == glp) {
+ throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice);
+ }
+ X11DummyGLXDrawable sharedDrawable = X11DummyGLXDrawable.create(sharedScreen, X11GLXDrawableFactory.this, glp);
+ if (null == sharedDrawable) {
+ throw new GLException("Couldn't create shared drawable for screen: "+sharedScreen+", "+glp);
+ }
+ X11GLXContext sharedContext = (X11GLXContext) sharedDrawable.createContext(null);
+ if (null == sharedContext) {
+ throw new GLException("Couldn't create shared context for drawable: "+sharedDrawable);
+ }
+ sharedContext.setSynchronized(true);
+ sharedContext.makeCurrent();
+ VersionNumber glXVersion;
+ {
+ int[] major = new int[1];
+ int[] minor = new int[1];
+ GLXUtil.getGLXVersion(sharedDevice.getHandle(), major, minor);
+ glXVersion = new VersionNumber(major[0], minor[0], 0);
+ }
+ sharedContext.release();
+ if (DEBUG) {
+ System.err.println("!!! SharedDevice: " + sharedDevice);
+ System.err.println("!!! SharedScreen: " + sharedScreen);
+ System.err.println("!!! SharedContext: " + sharedContext);
+ System.err.println("!!! GLX Vendor: " + glXVendorName);
+ System.err.println("!!! GLX Version: " + glXVersion
+ + " >= 1.3: " + (glXVersion.compareTo(versionOneThree) >= 0));
+ }
+ return new SharedResource(sharedDevice, sharedScreen, sharedDrawable, sharedContext, glXVersion, glXVendorName);
+ } catch (Throwable t) {
+ throw new GLException("WindowsWGLDrawableFactory - Could not initialize shared resources for "+connection, t);
+ } finally {
+ sharedDevice.unlock();
+ }
+ }
+
+ public void releaseSharedResource(SharedResourceRunner.Resource shared) {
+ SharedResource sr = (SharedResource) shared;
+ if (DEBUG) {
+ System.err.println("!!! Shutdown Shared:");
+ System.err.println("!!! Device : " + sr.device);
+ System.err.println("!!! Screen : " + sr.screen);
+ System.err.println("!!! Drawable: " + sr.drawable);
+ System.err.println("!!! CTX : " + sr.context);
+ }
+
+ if (null != sr.context) {
+ // may cause JVM SIGSEGV: sharedContext.destroy();
+ sr.context = null;
+ }
+
+ if (null != sr.drawable) {
+ // may cause JVM SIGSEGV: sharedDrawable.destroy();
+ sr.drawable = null;
+ }
+
+ if (null != sr.screen) {
+ sr.screen = null;
+ }
+
+ if (null != sr.device) {
+ sr.device.close();
+ sr.device = null;
+ }
+ }
+ }
public final AbstractGraphicsDevice getDefaultDevice() {
return defaultDevice;
@@ -332,44 +248,8 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
return false;
}
- HashSet devicesTried = new HashSet();
- private final boolean getDeviceTried(String connection) {
- synchronized(devicesTried) {
- return devicesTried.contains(connection);
- }
- }
- private final void addDeviceTried(String connection) {
- synchronized(devicesTried) {
- devicesTried.add(connection);
- }
- }
-
- private SharedResource getOrCreateShared(AbstractGraphicsDevice device) {
- String connection = device.getConnection();
- SharedResource sr;
- synchronized(sharedMap) {
- sr = (SharedResource) sharedMap.get(connection);
- }
-
- if(null==sr && !getDeviceTried(connection)) {
- addDeviceTried(connection);
- if (DEBUG) {
- System.err.println("getOrCreateShared() "+connection+": trying");
- }
- sharedResourcesRunner.initializeAndWait(connection);
- synchronized(sharedMap) {
- sr = (SharedResource) sharedMap.get(connection);
- }
- if(DEBUG) {
- Throwable t = new Throwable("getOrCreateSharedl() "+connection+": done");
- t.printStackTrace();
- }
- }
- return sr;
- }
-
protected final GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device) {
- SharedResource sr = getOrCreateShared(device);
+ SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device);
if(null!=sr) {
return sr.getContext();
}
@@ -377,7 +257,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
}
protected AbstractGraphicsDevice getOrCreateSharedDeviceImpl(AbstractGraphicsDevice device) {
- SharedResource sr = getOrCreateShared(device);
+ SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device);
if(null!=sr) {
return sr.getDevice();
}
@@ -385,7 +265,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
}
protected final long getOrCreateSharedDpy(AbstractGraphicsDevice device) {
- SharedResource sr = getOrCreateShared(device);
+ SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device);
if(null!=sr) {
return sr.getDevice().getHandle();
}
@@ -393,39 +273,39 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
}
protected final VersionNumber getGLXVersion(AbstractGraphicsDevice device) {
- SharedResource sr = getOrCreateShared(device);
+ SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device);
if(null!=sr) {
- return sr.getGLXVersion();
+ return ((SharedResource)sr).getGLXVersion();
}
return null;
}
protected final String getGLXVendorName(AbstractGraphicsDevice device) {
- SharedResource sr = getOrCreateShared(device);
+ SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device);
if(null!=sr) {
- return sr.getGLXVendorName();
+ return ((SharedResource)sr).getGLXVendorName();
}
return GLXUtil.getVendorName(device.getHandle());
}
protected final boolean isGLXVendorATI(AbstractGraphicsDevice device) {
- SharedResource sr = getOrCreateShared(device);
+ SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device);
if(null!=sr) {
- return sr.isGLXVendorATI();
+ return ((SharedResource)sr).isGLXVendorATI();
}
return GLXUtil.isVendorATI(device.getHandle());
}
protected final boolean isGLXVendorNVIDIA(AbstractGraphicsDevice device) {
- SharedResource sr = getOrCreateShared(device);
+ SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device);
if(null!=sr) {
- return sr.isGLXVendorNVIDIA();
+ return ((SharedResource)sr).isGLXVendorNVIDIA();
}
return GLXUtil.isVendorNVIDIA(device.getHandle());
}
protected final void shutdownInstance() {
- sharedResourcesRunner.releaseAndWait();
+ sharedResourceRunner.releaseAndWait();
// Don't really close pending Display connections,
// since this may trigger a JVM exception
@@ -459,15 +339,13 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
* The dummy context shall also use the same Display,
* since switching Display in this regard is another ATI bug.
*/
- SharedResource sr = getOrCreateShared(device);
+ SharedResource sr = (SharedResource) sharedResourceRunner.getOrCreateShared(device);
if( null!=sr && sr.isGLXVendorATI() && null == GLContext.getCurrent() ) {
- synchronized(sr.context) {
- sr.context.makeCurrent();
- try {
- pbufferDrawable = new X11PbufferGLXDrawable(this, target);
- } finally {
- sr.context.release();
- }
+ sr.getContext().makeCurrent();
+ try {
+ pbufferDrawable = new X11PbufferGLXDrawable(this, target);
+ } finally {
+ sr.getContext().release();
}
} else {
pbufferDrawable = new X11PbufferGLXDrawable(this, target);
@@ -482,7 +360,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
public final boolean canCreateGLPbuffer(AbstractGraphicsDevice device) {
if(null == device) {
- SharedResource sr = getOrCreateShared(defaultDevice);
+ SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(defaultDevice);
if(null!=sr) {
device = sr.getDevice();
}
@@ -495,9 +373,9 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
GLCapabilitiesChooser chooser,
int width, int height) {
X11GraphicsScreen screen = null;
- SharedResource sr = getOrCreateShared(device);
+ SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device);
if(null!=sr) {
- screen = sr.getScreen();
+ screen = (X11GraphicsScreen) sr.getScreen();
}
if(null==screen) {
return null;