aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes
diff options
context:
space:
mode:
authorSven Göthel <[email protected]>2024-01-25 09:53:30 +0100
committerSven Göthel <[email protected]>2024-01-25 09:53:30 +0100
commit8fe39d3a524e5e580cf2667988965f1e27fed95b (patch)
treec7630c970b23ad5f6a2a5665cd8838a04b05aa58 /src/jogl/classes
parent78812de21182e32f86a823321b017f7f6cf52ae3 (diff)
Bug 1491: GLMediaPlayerImpl: Use a shared *GraphicsDevice for all compatible shared GLContext, removing resource restrictions
In a use case with hundreds of GLMediaPlayer instances, this causes the application to bail out due to running out of resources. +++ GLMediaPlayer exposes resource restrictions and locking related with the created off-thread shared GLContext due to its newly created NativeWindow *GraphicsDevice instance (on X11). On the X11 platform, the *GraphicsDevice actually uses a native resource (X11 Display handle) and hence creating such device is costly and limited. To operate an off-thread GLContext w/o actual X11 input handling, it is *NOT* required to use a new instance. +++ Further more, the device is using locking. To operate an off-thread GLContext, it is *NOT* required to use locking on it as it does not perform actual X11 input handling etc. All operations are performed on the shared GL context. +++ Solution is to create a shared non-locking device clone compatible with the source. A share counter shall determine that the last one actually gets destructed. The usual ..
Diffstat (limited to 'src/jogl/classes')
-rw-r--r--src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java44
1 files changed, 41 insertions, 3 deletions
diff --git a/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java b/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java
index 4a7e52c4f..2c916dddc 100644
--- a/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java
+++ b/src/jogl/classes/jogamp/opengl/util/av/GLMediaPlayerImpl.java
@@ -38,6 +38,8 @@ import java.util.Iterator;
import java.util.Map;
import com.jogamp.nativewindow.AbstractGraphicsDevice;
+import com.jogamp.nativewindow.DefaultGraphicsDevice;
+import com.jogamp.nativewindow.NativeWindowFactory;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.GL2GL3;
import com.jogamp.opengl.GLContext;
@@ -1457,7 +1459,17 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
final AbstractGraphicsDevice device = dummyDrawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice();
dummyDrawable.setRealized(false);
dummyDrawable = null;
- device.close();
+ synchronized( singleLock ) {
+ if( singleDEBUG ) { System.err.println("ZZZ: device "+singleCount+": "+device.getClass()+", "+device); }
+ if( device == singleDevice && 0 == --singleCount ) {
+ DefaultGraphicsDevice.swapHandleAndOwnership(singleOwner, singleDevice);
+ if( singleDEBUG ) {
+ System.err.println("ZZZ: singleOwner "+singleOwner.getClass()+", "+singleOwner);
+ System.err.println("ZZZ: singleDevice "+singleDevice.getClass()+", "+singleDevice);
+ }
+ device.close();
+ }
+ }
}
}
@@ -1469,8 +1481,29 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
final boolean glCtxCurrent = glCtx.isCurrent();
final GLProfile glp = gl.getGLProfile();
final GLDrawableFactory factory = GLDrawableFactory.getFactory(glp);
- final AbstractGraphicsDevice device = glCtx.getGLDrawable().getNativeSurface().getGraphicsConfiguration().getScreen().getDevice();
- dummyDrawable = factory.createDummyDrawable(device, true, glCtx.getGLDrawable().getChosenGLCapabilities(), null); // own device!
+ boolean createNewDevice = true;
+ AbstractGraphicsDevice device = glCtx.getGLDrawable().getNativeSurface().getGraphicsConfiguration().getScreen().getDevice();
+ synchronized( singleLock ) {
+ if( null == singleOwner || singleOwner.getUniqueID().equals(device.getUniqueID()) ) {
+ if( null == singleOwner ) {
+ singleDevice = (DefaultGraphicsDevice) NativeWindowFactory.createDevice(device.getType(), device.getConnection(), device.getUnitID(), true);
+ singleOwner = new DefaultGraphicsDevice(singleDevice.getType(), singleDevice.getConnection(), singleDevice.getUnitID(), singleDevice.getHandle(), null);
+ DefaultGraphicsDevice.swapHandleAndOwnership(singleOwner, singleDevice);
+ if( singleDEBUG ) {
+ System.err.println("XXX: origDevice "+device.getClass()+", "+device);
+ System.err.println("XXX: singleOwner "+singleOwner.getClass()+", "+singleOwner);
+ System.err.println("XXX: singleDevice "+singleDevice.getClass()+", "+singleDevice);
+ }
+ }
+ createNewDevice = false;
+ device = singleDevice;
+ ++singleCount;
+ if( singleDEBUG ) { System.err.println("XXX: singleDevice "+singleCount+": "+device.getClass()+", "+device); }
+ } else {
+ if( singleDEBUG ) { System.err.println("XXX: createDevice from "+device.getClass()+", "+device); }
+ }
+ }
+ dummyDrawable = factory.createDummyDrawable(device, createNewDevice, glCtx.getGLDrawable().getChosenGLCapabilities(), null);
dummyDrawable.setRealized(true);
sharedGLCtx = dummyDrawable.createContext(glCtx);
hasSharedGLCtx = null != sharedGLCtx;
@@ -1598,6 +1631,11 @@ public abstract class GLMediaPlayerImpl implements GLMediaPlayer {
}
private volatile StreamWorker streamWorker = null;
private StreamException streamErr = null;
+ private static final boolean singleDEBUG = false;
+ private static final Object singleLock = new Object();
+ private static DefaultGraphicsDevice singleDevice = null;
+ private static DefaultGraphicsDevice singleOwner = null;
+ private static int singleCount = 0;
protected final GLMediaPlayer.EventMask addStateEventMask(final GLMediaPlayer.EventMask eventMask, final State newState) {
if( state != newState ) {