From 72a84b422327c6abb688339419d3552ec0e5c70c Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Mon, 9 Jul 2012 17:07:02 +0200 Subject: EGLGraphicsDevice adds desctruction callback and nativeDisplayID; EGLDisplayUtil adds creation of EGLGraphicsDevice. Due to EGL's location in JOGL, supporting destruction of an EGLGraphicsDevice is solved (hack) temporary by passing an eglTerminate callback to it's ctor. Using EGLGraphicsDevice's close() method to also issue eglTerminate() simplifies the code. In future we shall move EGL to nativewindow! --- .../classes/jogamp/opengl/egl/EGLDisplayUtil.java | 95 ++++++++++++++++++---- .../classes/jogamp/opengl/egl/EGLDrawable.java | 74 ++++++++--------- .../jogamp/opengl/egl/EGLDrawableFactory.java | 23 ++---- .../egl/EGLGraphicsConfigurationFactory.java | 34 ++++---- .../jogamp/nativewindow/egl/EGLGraphicsDevice.java | 43 +++++++++- .../jogamp/nativewindow/x11/X11GraphicsDevice.java | 1 - .../media/nativewindow/AbstractGraphicsDevice.java | 4 + .../jogamp/newt/driver/android/AndroidDisplay.java | 16 +--- .../jogamp/newt/driver/broadcom/egl/Display.java | 4 +- .../classes/jogamp/newt/driver/kd/KDDisplay.java | 15 +--- 10 files changed, 182 insertions(+), 127 deletions(-) (limited to 'src') diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java index e09400c09..7f10d3bd9 100644 --- a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java +++ b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java @@ -30,12 +30,15 @@ package jogamp.opengl.egl; import java.nio.IntBuffer; +import javax.media.nativewindow.AbstractGraphicsDevice; import javax.media.nativewindow.NativeSurface; import javax.media.nativewindow.NativeWindowFactory; +import javax.media.opengl.GLException; import jogamp.opengl.Debug; import com.jogamp.common.util.LongIntHashMap; +import com.jogamp.nativewindow.egl.EGLGraphicsDevice; /** * This implementation provides recursive calls to @@ -67,23 +70,6 @@ public class EGLDisplayUtil { return eglDisplay; } - public static long eglGetDisplay(NativeSurface surface, boolean allowFallBackToDefault) { - final long nDisplay; - if( NativeWindowFactory.TYPE_WINDOWS.equals(NativeWindowFactory.getNativeWindowType(false)) ) { - nDisplay = surface.getSurfaceHandle(); // don't even ask .. - } else { - nDisplay = surface.getDisplayHandle(); // 0 == EGL.EGL_DEFAULT_DISPLAY - } - long eglDisplay = EGLDisplayUtil.eglGetDisplay(nDisplay); - if (eglDisplay == EGL.EGL_NO_DISPLAY && nDisplay != EGL.EGL_DEFAULT_DISPLAY && allowFallBackToDefault) { - if(DEBUG) { - System.err.println("EGLDisplayUtil.eglGetDisplay(): Fall back to EGL_DEFAULT_DISPLAY"); - } - eglDisplay = EGLDisplayUtil.eglGetDisplay(EGL.EGL_DEFAULT_DISPLAY); - } - return eglDisplay; - } - public static synchronized boolean eglInitialize(long eglDisplay, int[] major, int major_offset, int[] minor, int minor_offset) { final boolean res; final int refCnt = eglDisplayCounter.get(eglDisplay) + 1; // 0 + 1 = 1 -> 1st init @@ -99,7 +85,19 @@ public class EGLDisplayUtil { return res; } + /** + * + * @param eglDisplay + * @param major + * @param minor + * @return true if the eglDisplay is valid and it's reference counter becomes one and {@link EGL#eglTerminate(long)} was successful, otherwise false + * + * @see EGL#eglInitialize(long, int[], int, int[], int)} + */ public static synchronized boolean eglInitialize(long eglDisplay, IntBuffer major, IntBuffer minor) { + if( EGL.EGL_NO_DISPLAY == eglDisplay) { + return false; + } final boolean res; final int refCnt = eglDisplayCounter.get(eglDisplay) + 1; // 0 + 1 = 1 -> 1st init if(1==refCnt) { // only initialize once @@ -114,7 +112,14 @@ public class EGLDisplayUtil { return res; } + /** + * @param eglDisplay the EGL display handle + * @return true if the eglDisplay is valid and it's reference counter becomes zero and {@link EGL#eglTerminate(long)} was successful, otherwise false + */ public static synchronized boolean eglTerminate(long eglDisplay) { + if( EGL.EGL_NO_DISPLAY == eglDisplay) { + return false; + } final boolean res; final int refCnt = eglDisplayCounter.get(eglDisplay) - 1; // 1 - 1 = 0 -> final terminate if(0==refCnt) { // no terminate if still in use or already terminated @@ -130,4 +135,60 @@ public class EGLDisplayUtil { } return res; } + + public static final EGLGraphicsDevice.EGLTerminateCallback eglTerminateCallback = new EGLGraphicsDevice.EGLTerminateCallback() { + public void eglTerminate(long eglDisplayHandle) { + EGLDisplayUtil.eglTerminate(eglDisplayHandle); + } + }; + + /** + * @param nativeDisplayID + * @param connection + * @param unitID + * @return an initialized EGLGraphicsDevice + * @throws GLException if {@link EGL#eglGetDisplay(long)} or {@link EGL#eglInitialize(long, int[], int, int[], int)} fails + * @see EGLGraphicsDevice#EGLGraphicsDevice(long, long, String, int, com.jogamp.nativewindow.egl.EGLGraphicsDevice.EGLTerminateCallback) + */ + public static EGLGraphicsDevice eglCreateEGLGraphicsDevice(long nativeDisplayID, String connection, int unitID) { + long eglDisplay = EGLDisplayUtil.eglGetDisplay(nativeDisplayID); + if (eglDisplay == EGL.EGL_NO_DISPLAY) { + throw new GLException("Failed to created EGL display: 0x"+Long.toHexString(nativeDisplayID)+", error 0x"+Integer.toHexString(EGL.eglGetError())); + } + if (!EGLDisplayUtil.eglInitialize(eglDisplay, null, null)) { + throw new GLException("eglInitialize failed"+", error 0x"+Integer.toHexString(EGL.eglGetError())); + } + return new EGLGraphicsDevice(nativeDisplayID, eglDisplay, connection, unitID, eglTerminateCallback); + } + + /** + * @param surface + * @param allowFallBackToDefault + * @return an initialized EGLGraphicsDevice + * @throws GLException if {@link EGL#eglGetDisplay(long)} or {@link EGL#eglInitialize(long, int[], int, int[], int)} fails + */ + public static EGLGraphicsDevice eglCreateEGLGraphicsDevice(NativeSurface surface, boolean allowFallBackToDefault) { + long nativeDisplayID; + if( NativeWindowFactory.TYPE_WINDOWS.equals(NativeWindowFactory.getNativeWindowType(false)) ) { + nativeDisplayID = surface.getSurfaceHandle(); // don't even ask .. + } else { + nativeDisplayID = surface.getDisplayHandle(); // 0 == EGL.EGL_DEFAULT_DISPLAY + } + long eglDisplay = EGLDisplayUtil.eglGetDisplay(nativeDisplayID); + if (eglDisplay == EGL.EGL_NO_DISPLAY && nativeDisplayID != EGL.EGL_DEFAULT_DISPLAY && allowFallBackToDefault) { + if(DEBUG) { + System.err.println("EGLDisplayUtil.eglGetDisplay(): Fall back to EGL_DEFAULT_DISPLAY"); + } + nativeDisplayID = EGL.EGL_DEFAULT_DISPLAY; + eglDisplay = EGLDisplayUtil.eglGetDisplay(nativeDisplayID); + } + if (eglDisplay == EGL.EGL_NO_DISPLAY) { + throw new GLException("Failed to created EGL display: "+surface+", error 0x"+Integer.toHexString(EGL.eglGetError())); + } + if (!EGLDisplayUtil.eglInitialize(eglDisplay, null, null)) { + throw new GLException("eglInitialize failed"+", error 0x"+Integer.toHexString(EGL.eglGetError())); + } + final AbstractGraphicsDevice adevice = surface.getGraphicsConfiguration().getScreen().getDevice(); + return new EGLGraphicsDevice(nativeDisplayID, eglDisplay, adevice.getConnection(), adevice.getUnitID(), eglTerminateCallback); + } } diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java index 491f22119..d777c4f04 100644 --- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java +++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java @@ -46,34 +46,34 @@ import javax.media.opengl.*; import com.jogamp.nativewindow.egl.*; public abstract class EGLDrawable extends GLDrawableImpl { - protected boolean ownEGLDisplay = false; // for destruction - protected boolean ownEGLSurface = false; // for destruction + private boolean ownEGLDisplay = false; // for destruction + private boolean ownEGLSurface = false; // for destruction private EGLGraphicsConfiguration eglConfig; - protected long eglDisplay; - protected long eglSurface; + private EGLGraphicsDevice eglDevice; + private long eglSurface; protected EGLDrawable(EGLDrawableFactory factory, NativeSurface component) throws GLException { super(factory, component, false); eglSurface=EGL.EGL_NO_SURFACE; - eglDisplay=0; + eglDevice=null; } - public long getDisplay() { - return eglDisplay; + public final long getDisplay() { + return null != eglDevice ? eglDevice.getHandle() : 0; } @Override - public long getHandle() { + public final long getHandle() { return eglSurface; } - public EGLGraphicsConfiguration getGraphicsConfiguration() { + public final EGLGraphicsConfiguration getGraphicsConfiguration() { return eglConfig; } @Override - public GLCapabilitiesImmutable getChosenGLCapabilities() { + public final GLCapabilitiesImmutable getChosenGLCapabilities() { return (null==eglConfig)?super.getChosenGLCapabilities():(GLCapabilitiesImmutable)eglConfig.getChosenCapabilities(); } @@ -82,17 +82,17 @@ public abstract class EGLDrawable extends GLDrawableImpl { protected abstract long createSurface(long eglDpy, long eglNativeCfg, long surfaceHandle); - private void recreateSurface() { + private final void recreateSurface() { // create a new EGLSurface .. if(EGL.EGL_NO_SURFACE!=eglSurface) { - EGL.eglDestroySurface(eglDisplay, eglSurface); + EGL.eglDestroySurface(eglDevice.getHandle(), eglSurface); } if(DEBUG) { - System.err.println(getThreadName() + ": createSurface using eglDisplay "+toHexString(eglDisplay)+", "+eglConfig); + System.err.println(getThreadName() + ": createSurface using "+eglDevice+", "+eglConfig); } - eglSurface = createSurface(eglDisplay, eglConfig.getNativeConfig(), surface.getSurfaceHandle()); + eglSurface = createSurface(eglDevice.getHandle(), eglConfig.getNativeConfig(), surface.getSurfaceHandle()); int eglError0 = EGL.EGL_SUCCESS; if (EGL.EGL_NO_SURFACE == eglSurface) { eglError0 = EGL.eglGetError(); @@ -105,7 +105,7 @@ public abstract class EGLDrawable extends GLDrawableImpl { if(DEBUG) { System.err.println(getThreadName() + ": Info: Creation of window surface w/ surface handle failed: "+eglConfig+", error "+toHexString(eglError0)+", retry w/ windowHandle"); } - eglSurface = createSurface(eglDisplay, eglConfig.getNativeConfig(), nw.getWindowHandle()); + eglSurface = createSurface(eglDevice.getHandle(), eglConfig.getNativeConfig(), nw.getWindowHandle()); if (EGL.EGL_NO_SURFACE == eglSurface) { eglError0 = EGL.eglGetError(); } @@ -130,7 +130,7 @@ public abstract class EGLDrawable extends GLDrawableImpl { } @Override - protected void setRealizedImpl() { + protected final void setRealizedImpl() { if (realized) { AbstractGraphicsConfiguration aConfig = surface.getGraphicsConfiguration(); AbstractGraphicsDevice aDevice = aConfig.getScreen().getDevice(); @@ -139,9 +139,10 @@ public abstract class EGLDrawable extends GLDrawableImpl { System.err.println(getThreadName() + ": EGLDrawable.setRealized(true): using existing EGL config - START"); } // just fetch the data .. trust but verify .. - eglDisplay = aDevice.getHandle(); - if (eglDisplay == EGL.EGL_NO_DISPLAY) { - throw new GLException("Invalid EGL display in EGLGraphicsDevice from "+aDevice); + ownEGLDisplay = false; + eglDevice = (EGLGraphicsDevice) aDevice; + if (eglDevice.getHandle() == EGL.EGL_NO_DISPLAY) { + throw new GLException("Invalid EGL display in EGLGraphicsDevice "+eglDevice); } if(aConfig instanceof EGLGraphicsConfiguration) { eglConfig = (EGLGraphicsConfiguration) aConfig; // done .. @@ -151,12 +152,13 @@ public abstract class EGLDrawable extends GLDrawableImpl { int[] tmp = new int[1]; if ( 0 != surface.getSurfaceHandle() && - EGL.eglQuerySurface(eglDisplay, surface.getSurfaceHandle(), EGL.EGL_CONFIG_ID, tmp, 0) ) { + EGL.eglQuerySurface(eglDevice.getHandle(), surface.getSurfaceHandle(), EGL.EGL_CONFIG_ID, tmp, 0) ) { // surface holds static EGLSurface eglSurface = surface.getSurfaceHandle(); if(DEBUG) { System.err.println(getThreadName() + ": setSurface re-using component's EGLSurface: handle "+toHexString(eglSurface)); } + ownEGLSurface=false; } else { // EGLSurface is ours - subsequent updateHandle() will issue recreateSurface(); ownEGLSurface=true; @@ -173,35 +175,28 @@ public abstract class EGLDrawable extends GLDrawableImpl { // EGLSurface is ours .. ownEGLSurface=true; - eglDisplay = EGLDisplayUtil.eglGetDisplay(surface, true); - if (eglDisplay == EGL.EGL_NO_DISPLAY) { - throw new GLException("Failed to created EGL display: "+surface+", "+aDevice+", error "+toHexString(EGL.eglGetError())); - } - if (!EGLDisplayUtil.eglInitialize(eglDisplay, null, null)) { - throw new GLException("eglInitialize failed"+", error "+Integer.toHexString(EGL.eglGetError())); - } - EGLGraphicsDevice e = new EGLGraphicsDevice(eglDisplay, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT); - AbstractGraphicsScreen s = new DefaultGraphicsScreen(e, aConfig.getScreen().getIndex()); + eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(surface, true); + AbstractGraphicsScreen eglScreen = new DefaultGraphicsScreen(eglDevice, aConfig.getScreen().getIndex()); final GLCapabilitiesImmutable capsRequested = (GLCapabilitiesImmutable) aConfig.getRequestedCapabilities(); if(aConfig instanceof EGLGraphicsConfiguration) { final EGLGLCapabilities capsChosen = (EGLGLCapabilities) aConfig.getChosenCapabilities(); if(0 == capsChosen.getEGLConfig()) { // 'refresh' the native EGLConfig handle - capsChosen.setEGLConfig(EGLGraphicsConfiguration.EGLConfigId2EGLConfig(eglDisplay, capsChosen.getEGLConfigID())); + capsChosen.setEGLConfig(EGLGraphicsConfiguration.EGLConfigId2EGLConfig(eglDevice.getHandle(), capsChosen.getEGLConfigID())); if(0 == capsChosen.getEGLConfig()) { throw new GLException("Refreshing native EGLConfig handle failed: "+capsChosen+" of "+aConfig); } } - eglConfig = new EGLGraphicsConfiguration(s, capsChosen, capsRequested, null); + eglConfig = new EGLGraphicsConfiguration(eglScreen, capsChosen, capsRequested, null); if(DEBUG) { System.err.println(getThreadName() + ": Reusing chosenCaps: "+eglConfig); } } else { eglConfig = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic( - capsRequested, capsRequested, null, s, aConfig.getVisualID(VIDType.NATIVE), false); + capsRequested, capsRequested, null, eglScreen, aConfig.getVisualID(VIDType.NATIVE), false); if (null == eglConfig) { - throw new GLException("Couldn't create EGLGraphicsConfiguration from "+s); + throw new GLException("Couldn't create EGLGraphicsConfiguration from "+eglScreen); } else if(DEBUG) { System.err.println(getThreadName() + ": Chosen eglConfig: "+eglConfig); } @@ -213,25 +208,23 @@ public abstract class EGLDrawable extends GLDrawableImpl { } } else if (ownEGLSurface && eglSurface != EGL.EGL_NO_SURFACE) { if(DEBUG) { - System.err.println(getThreadName() + ": EGLDrawable.setRealized(false): ownDisplay "+ownEGLDisplay+", ownSurface "+ownEGLSurface+", eglDisplay: "+toHexString(eglDisplay)+", eglSurface: "+toHexString(eglSurface)); + System.err.println(getThreadName() + ": EGLDrawable.setRealized(false): ownDisplay "+ownEGLDisplay+", ownSurface "+ownEGLSurface+", "+eglDevice+", eglSurface: "+toHexString(eglSurface)); } // Destroy the window surface - if (!EGL.eglDestroySurface(eglDisplay, eglSurface)) { + if (!EGL.eglDestroySurface(eglDevice.getHandle(), eglSurface)) { throw new GLException("Error destroying window surface (eglDestroySurface)"); } eglSurface = EGL.EGL_NO_SURFACE; - if (ownEGLDisplay && EGL.EGL_NO_DISPLAY!=eglDisplay) { - EGLDisplayUtil.eglTerminate(eglDisplay); - } - eglDisplay=EGL.EGL_NO_DISPLAY; eglConfig=null; + eglDevice.close(); + eglDevice=null; } } @Override protected final void swapBuffersImpl() { // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers() - if(!EGL.eglSwapBuffers(eglDisplay, eglSurface)) { + if(!EGL.eglSwapBuffers(eglDevice.getHandle(), eglSurface)) { throw new GLException("Error swapping buffers, eglError "+toHexString(EGL.eglGetError())+", "+this); } } @@ -270,6 +263,7 @@ public abstract class EGLDrawable extends GLDrawableImpl { public String toString() { return getClass().getName()+"[realized "+isRealized()+ ",\n\tfactory "+getFactory()+ + ",\n\tdevice "+eglDevice+ ",\n\tsurface "+getNativeSurface()+ ",\n\teglSurface "+toHexString(eglSurface)+ ",\n\teglConfig "+eglConfig+ diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java index e4f6f0ef8..f4fa1f13f 100644 --- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java +++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java @@ -184,10 +184,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { if(DEBUG) { System.err.println("EGLDrawableFactory.destroy("+shutdownType+"): "+sr.device.toString()); } - final long eglDisplay = sr.device.getHandle(); - if(EGL.EGL_NO_DISPLAY != eglDisplay) { - EGLDisplayUtil.eglTerminate(eglDisplay); - } + sr.device.close(); } sharedMap.clear(); sharedMap = null; @@ -282,22 +279,14 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { if(null == eglES1DynamicLookupHelper && null == eglES2DynamicLookupHelper) { return null; } - String connection = adevice.getConnection(); + final String connection = adevice.getConnection(); SharedResource sr; synchronized(sharedMap) { sr = sharedMap.get(connection); } if(null==sr) { - long eglDisplay = EGLDisplayUtil.eglGetDisplay(EGL.EGL_DEFAULT_DISPLAY); - if (eglDisplay == EGL.EGL_NO_DISPLAY) { - throw new GLException("Failed to created EGL default display: error 0x"+Integer.toHexString(EGL.eglGetError())); - } else if(DEBUG) { - System.err.println("EGLDrawableFactory.createShared: eglDisplay(EGL_DEFAULT_DISPLAY): 0x"+Long.toHexString(eglDisplay)); - } - if (!EGLDisplayUtil.eglInitialize(eglDisplay, null, null)) { - throw new GLException("eglInitialize failed"+", error 0x"+Integer.toHexString(EGL.eglGetError())); - } - final EGLGraphicsDevice sharedDevice = new EGLGraphicsDevice(eglDisplay, connection, adevice.getUnitID()); + final EGLGraphicsDevice sharedDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, connection, adevice.getUnitID()); + // final boolean madeCurrentES1 = isEGLContextAvailable(sharedDevice, GLProfile.GLES1); // final boolean madeCurrentES2 = isEGLContextAvailable(sharedDevice, GLProfile.GLES2); final boolean madeCurrentES1 = true; // FIXME @@ -401,7 +390,9 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl { } @Override - protected NativeSurface createOffscreenSurfaceImpl(AbstractGraphicsDevice device, GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, int width, int height) { + protected NativeSurface createOffscreenSurfaceImpl(AbstractGraphicsDevice deviceReq, GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, int width, int height) { + final EGLGraphicsDevice eglDeviceReq = (EGLGraphicsDevice) deviceReq; + final EGLGraphicsDevice device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(eglDeviceReq.getNativeDisplayID(), deviceReq.getConnection(), deviceReq.getUnitID()); WrappedSurface ns = new WrappedSurface(EGLGraphicsConfigurationFactory.createOffscreenGraphicsConfiguration(device, capsChosen, capsRequested, chooser)); ns.surfaceSizeChanged(width, height); return ns; diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java index 5ab2632c6..809e2b688 100644 --- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java @@ -223,23 +223,17 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact throw new GLException("Null AbstractGraphicsDevice"); } - final long eglDisplay; + final EGLGraphicsDevice eglDevice; final boolean ownEGLDisplay; - if( !(absDevice instanceof EGLGraphicsDevice) ) { - eglDisplay = EGLDisplayUtil.eglGetDisplay(absDevice.getHandle()); - if (eglDisplay == EGL.EGL_NO_DISPLAY) { - throw new GLException("Could not get EGL display from: "+absDevice); - } - if (!EGLDisplayUtil.eglInitialize(eglDisplay, null, null)) { - throw new GLException("eglInitialize failed eglDisplay 0x"+Long.toHexString(eglDisplay)+", "+absDevice+", error 0x"+Integer.toHexString(EGL.eglGetError())); - } - ownEGLDisplay = true; - } else { - eglDisplay = absDevice.getHandle(); - if (eglDisplay == EGL.EGL_NO_DISPLAY) { - throw new GLException("Invalid EGL display: "+absDevice); + if( absDevice instanceof EGLGraphicsDevice ) { + eglDevice = (EGLGraphicsDevice) absDevice; + if (eglDevice.getHandle() == EGL.EGL_NO_DISPLAY) { + throw new GLException("Invalid EGL display: "+eglDevice); } ownEGLDisplay = false; + } else { + eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(absDevice.getHandle(), absDevice.getConnection(), absDevice.getUnitID()); + ownEGLDisplay = true; } EGLDrawableFactory factory = (EGLDrawableFactory) GLDrawableFactory.getEGLFactory(); @@ -248,7 +242,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact GLProfile glp = capsChosen.getGLProfile(); GLCapabilities fixedCaps; - EGLGraphicsConfiguration res = eglChooseConfig(eglDisplay, capsChosen, capsReq, chooser, absScreen, nativeVisualID, forceTransparentFlag); + EGLGraphicsConfiguration res = eglChooseConfig(eglDevice.getHandle(), capsChosen, capsReq, chooser, absScreen, nativeVisualID, forceTransparentFlag); if(null==res) { if(DEBUG) { System.err.println("eglChooseConfig failed with given capabilities "+capsChosen); @@ -267,7 +261,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact if(DEBUG) { System.err.println("trying fixed caps (1): "+fixedCaps); } - res = eglChooseConfig(eglDisplay, fixedCaps, capsReq, chooser, absScreen, nativeVisualID, false); + res = eglChooseConfig(eglDevice.getHandle(), fixedCaps, capsReq, chooser, absScreen, nativeVisualID, false); } if(null==res) { // @@ -280,7 +274,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact if(DEBUG) { System.err.println("trying fixed caps (2): "+fixedCaps); } - res = eglChooseConfig(eglDisplay, fixedCaps, capsReq, chooser, absScreen, nativeVisualID, false); + res = eglChooseConfig(eglDevice.getHandle(), fixedCaps, capsReq, chooser, absScreen, nativeVisualID, false); } if(null==res) { // @@ -295,14 +289,14 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact if(DEBUG) { System.err.println("trying fixed caps (3): "+fixedCaps); } - res = eglChooseConfig(eglDisplay, fixedCaps, capsReq, chooser, absScreen, nativeVisualID, false); + res = eglChooseConfig(eglDevice.getHandle(), fixedCaps, capsReq, chooser, absScreen, nativeVisualID, false); } if(null==res) { throw new GLException("Graphics configuration failed [direct caps, eglGetConfig/chooser and fixed-caps(1-3)]"); } if(ownEGLDisplay) { - ((EGLGLCapabilities) res.getChosenCapabilities()).setEGLConfig(0); // eglDisplay: EOL - EGLDisplayUtil.eglTerminate(eglDisplay); + ((EGLGLCapabilities) res.getChosenCapabilities()).setEGLConfig(0); // eglDisplay: EOL + eglDevice.close(); } return res; } diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java b/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java index 4ee336176..d161f2f34 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java @@ -36,25 +36,60 @@ import javax.media.nativewindow.*; /** Encapsulates a graphics device on EGL platforms. */ - public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneable { - boolean closeDisplay = false; + final long nativeDisplayID; + final EGLTerminateCallback eglTerminateCallback; + /** + * Hack to allow inject a EGL termination call. + *

+ * FIXME: This shall be removed when relocated EGL to the nativewindow package, + * since then it can be utilized directly. + *

+ */ + public interface EGLTerminateCallback { + /** + * Implementation should issue an EGL.eglTerminate(eglDisplayHandle) call. + * @param eglDisplayHandle + */ + void eglTerminate(long eglDisplayHandle); + } + /** * Note that this is not an open connection, ie no native display handle exist. * This constructor exist to setup a default device connection/unit.
*/ public EGLGraphicsDevice(String connection, int unitID) { super(NativeWindowFactory.TYPE_EGL, connection, unitID); + this.nativeDisplayID = 0; + this.eglTerminateCallback = null; } - /** Constructs a new EGLGraphicsDevice corresponding to the given EGL display handle. */ - public EGLGraphicsDevice(long eglDisplay, String connection, int unitID) { + public EGLGraphicsDevice(long nativeDisplayID, long eglDisplay, String connection, int unitID, EGLTerminateCallback eglTerminateCallback) { super(NativeWindowFactory.TYPE_EGL, connection, unitID, eglDisplay); + this.nativeDisplayID = nativeDisplayID; + this.eglTerminateCallback = eglTerminateCallback; } + public long getNativeDisplayID() { return nativeDisplayID; } + public Object clone() { return super.clone(); } + + public boolean close() { + if(null != eglTerminateCallback) { + if(DEBUG) { + System.err.println(Thread.currentThread().getName() + " - eglTerminate: "+this); + } + eglTerminateCallback.eglTerminate(handle); + } + return super.close(); + } + + @Override + public String toString() { + return "EGLGraphicsDevice[type EGL, connection "+getConnection()+", unitID "+getUnitID()+", handle 0x"+Long.toHexString(getHandle())+", nativeDisplayID 0x"+Long.toHexString(nativeDisplayID)+"]"; + } } diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java index 308756b54..a02332413 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/x11/X11GraphicsDevice.java @@ -46,7 +46,6 @@ import javax.media.nativewindow.ToolkitLock; */ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneable { - public static final boolean DEBUG = Debug.debug("GraphicsDevice"); final boolean closeDisplay; /** Constructs a new X11GraphicsDevice corresponding to the given connection and default diff --git a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java index 1dd01a274..4979f1949 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java +++ b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java @@ -40,11 +40,15 @@ package javax.media.nativewindow; +import jogamp.nativewindow.Debug; + /** A interface describing a graphics device in a toolkit-independent manner. */ public interface AbstractGraphicsDevice extends Cloneable { + public static final boolean DEBUG = Debug.debug("GraphicsDevice"); + /** Dummy connection value for a default connection where no native support for multiple devices is available */ public static String DEFAULT_CONNECTION = "decon"; diff --git a/src/newt/classes/jogamp/newt/driver/android/AndroidDisplay.java b/src/newt/classes/jogamp/newt/driver/android/AndroidDisplay.java index 3f360f20f..0a43c9b8f 100644 --- a/src/newt/classes/jogamp/newt/driver/android/AndroidDisplay.java +++ b/src/newt/classes/jogamp/newt/driver/android/AndroidDisplay.java @@ -32,9 +32,6 @@ import jogamp.newt.*; import jogamp.opengl.egl.*; import javax.media.nativewindow.*; -import javax.media.opengl.GLException; - -import com.jogamp.nativewindow.egl.*; public class AndroidDisplay extends jogamp.newt.DisplayImpl { static { @@ -55,20 +52,11 @@ public class AndroidDisplay extends jogamp.newt.DisplayImpl { protected void createNativeImpl() { // EGL Device - final long eglDisplay = EGLDisplayUtil.eglGetDisplay(EGL.EGL_DEFAULT_DISPLAY); - if (eglDisplay == EGL.EGL_NO_DISPLAY) { - throw new GLException("Failed to created EGL default display: error 0x"+Integer.toHexString(EGL.eglGetError())); - } - if (!EGLDisplayUtil.eglInitialize(eglDisplay, null, null)) { - throw new GLException("eglInitialize failed eglDisplay 0x"+Long.toHexString(eglDisplay)+", error 0x"+Integer.toHexString(EGL.eglGetError())); - } - aDevice = new EGLGraphicsDevice(eglDisplay, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT); + aDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT); } protected void closeNativeImpl() { - if (aDevice.getHandle() != EGL.EGL_NO_DISPLAY) { - EGLDisplayUtil.eglTerminate(aDevice.getHandle()); - } + aDevice.close(); } protected void dispatchMessagesNative() { diff --git a/src/newt/classes/jogamp/newt/driver/broadcom/egl/Display.java b/src/newt/classes/jogamp/newt/driver/broadcom/egl/Display.java index f90c62ff4..e3f50b7e0 100644 --- a/src/newt/classes/jogamp/newt/driver/broadcom/egl/Display.java +++ b/src/newt/classes/jogamp/newt/driver/broadcom/egl/Display.java @@ -61,11 +61,11 @@ public class Display extends jogamp.newt.DisplayImpl { } protected void createNativeImpl() { - long handle = CreateDisplay(Screen.fixedWidth, Screen.fixedHeight); + final long handle = CreateDisplay(Screen.fixedWidth, Screen.fixedHeight); if (handle == EGL.EGL_NO_DISPLAY) { throw new NativeWindowException("BC EGL CreateDisplay failed"); } - aDevice = new EGLGraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT); + aDevice = new EGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, handle, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT, null); } protected void closeNativeImpl() { diff --git a/src/newt/classes/jogamp/newt/driver/kd/KDDisplay.java b/src/newt/classes/jogamp/newt/driver/kd/KDDisplay.java index 73bbe0b5b..07b031841 100644 --- a/src/newt/classes/jogamp/newt/driver/kd/KDDisplay.java +++ b/src/newt/classes/jogamp/newt/driver/kd/KDDisplay.java @@ -42,8 +42,6 @@ import jogamp.newt.NEWTJNILibLoader; import jogamp.opengl.egl.EGL; import jogamp.opengl.egl.EGLDisplayUtil; -import com.jogamp.nativewindow.egl.EGLGraphicsDevice; - public class KDDisplay extends DisplayImpl { static { @@ -64,20 +62,11 @@ public class KDDisplay extends DisplayImpl { protected void createNativeImpl() { // FIXME: map name to EGL_*_DISPLAY - long handle = EGLDisplayUtil.eglGetDisplay(EGL.EGL_DEFAULT_DISPLAY); - if (handle == EGL.EGL_NO_DISPLAY) { - throw new NativeWindowException("eglGetDisplay failed"); - } - if (!EGLDisplayUtil.eglInitialize(handle, null, null)) { - throw new NativeWindowException("eglInitialize failed"); - } - aDevice = new EGLGraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT); + aDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT); } protected void closeNativeImpl() { - if (aDevice.getHandle() != EGL.EGL_NO_DISPLAY) { - EGLDisplayUtil.eglTerminate(aDevice.getHandle()); - } + aDevice.close(); } protected void dispatchMessagesNative() { -- cgit v1.2.3