summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2012-08-16 15:58:33 +0200
committerSven Gothel <[email protected]>2012-08-16 15:58:33 +0200
commit43a473b2005d7f59a7f4f5b8bc7ca9ae88b4e894 (patch)
tree9580d25adf52aa9a24165f44ee8d304453ebe428 /src
parent53ba263381c7b0434cfe834e4be1ff67ebebe1fe (diff)
EGLDisplayUtil: Workaround (latest) PVR 540 EGL regression where 3nd EGLDisplay's eglInitialize(..) fails ; Fix EGLDrawableFactory.getEGLSurface()
- EGLDisplayUtil: Workaround (latest) PVR 540 EGL regression where 3nd EGLDisplay's eglInitialize(..) fails In this case and if eglGetDisplay(..) fails w/ a non EGL_DEFAULT_DEVICE, fall back to EGL_DEFAULT_DEVICE - always. This workaround actually simplifies handling both cases. - Fix EGLDrawableFactory.getEGLSurface() Tests whether a given NativeSurface w/ EGLGraphicsDevice and EGLGraphicsConfiguration has a valid EGL Surface. Only if true, reuse the whole NativeSurface, otherwise construct the missing pieces (device, config and use a WrappedSurface for EGL).
Diffstat (limited to 'src')
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLContext.java4
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java114
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java33
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java27
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java15
5 files changed, 127 insertions, 66 deletions
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
index c5d0df645..919f92c02 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
@@ -209,8 +209,8 @@ public abstract class EGLContext extends GLContextImpl {
",\n\tsharing with 0x" + Long.toHexString(shareWithHandle));
}
if (!EGL.eglMakeCurrent(eglDisplay, drawable.getHandle(), drawableRead.getHandle(), contextHandle)) {
- throw new GLException("Error making context 0x" +
- Long.toHexString(contextHandle) + " current: error code " + EGL.eglGetError());
+ throw new GLException("Error making context " +
+ toHexString(contextHandle) + " current: error code " + toHexString(EGL.eglGetError()));
}
setGLFunctionAvailability(true, glProfile.usesNativeGLES2() ? 2 : 1, 0, CTX_PROFILE_ES);
return true;
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
index 432010f49..dbf35d68c 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
@@ -70,6 +70,14 @@ public class EGLDisplayUtil {
return eglDisplay;
}
+ /**
+ * @param eglDisplay
+ * @param major
+ * @param minor
+ * @return true if the eglDisplay is valid and it's reference counter becomes one and {@link EGL#eglInitialize(long, int[], int, int[], int)} was successful, otherwise false
+ *
+ * @see EGL#eglInitialize(long, int[], int, int[], int)}
+ */
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
@@ -80,19 +88,18 @@ public class EGLDisplayUtil {
}
eglDisplayCounter.put(eglDisplay, refCnt);
if(DEBUG) {
- System.err.println("EGL.eglInitialize(0x"+Long.toHexString(eglDisplay)+" ...): #"+refCnt+" = "+res);
+ System.err.println("EGLDisplayUtil.eglInitialize1("+EGLContext.toHexString(eglDisplay)+" ...): #"+refCnt+" = "+res);
}
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
+ * @return true if the eglDisplay is valid and it's reference counter becomes one and {@link EGL#eglInitialize(long, IntBuffer, IntBuffer)} was successful, otherwise false
*
- * @see EGL#eglInitialize(long, int[], int, int[], int)}
+ * @see EGL#eglInitialize(long, IntBuffer, IntBuffer)
*/
public static synchronized boolean eglInitialize(long eglDisplay, IntBuffer major, IntBuffer minor) {
if( EGL.EGL_NO_DISPLAY == eglDisplay) {
@@ -104,15 +111,69 @@ public class EGLDisplayUtil {
res = EGL.eglInitialize(eglDisplay, major, minor);
} else {
res = true;
+ }
+ if(res) { // map if successfully initialized, only
+ eglDisplayCounter.put(eglDisplay, refCnt);
}
- eglDisplayCounter.put(eglDisplay, refCnt);
if(DEBUG) {
- System.err.println("EGL.eglInitialize(0x"+Long.toHexString(eglDisplay)+" ...): #"+refCnt+" = "+res);
+ System.err.println("EGLDisplayUtil.eglInitialize2("+EGLContext.toHexString(eglDisplay)+" ...): #"+refCnt+" = "+res);
}
return res;
}
/**
+ * @param nativeDisplayID
+ * @param eglDisplay array of size 1 holding return value if successful, otherwise {@link EGL#EGL_NO_DISPLAY}.
+ * @param eglErr array of size 1 holding the EGL error value as retrieved by {@link EGL#eglGetError()} if not successful.
+ * @param major
+ * @param minor
+ * @return {@link EGL#EGL_SUCCESS} if successful, otherwise {@link EGL#EGL_BAD_DISPLAY} if {@link #eglGetDisplay(long)} failed
+ * or {@link EGL#EGL_NOT_INITIALIZED} if {@link #eglInitialize(long, IntBuffer, IntBuffer)} failed.
+ *
+ * @see #eglGetDisplay(long)
+ * @see #eglInitialize(long, IntBuffer, IntBuffer)
+ */
+ public static synchronized int eglGetDisplayAndInitialize(long nativeDisplayID, long[] eglDisplay, int[] eglErr, IntBuffer major, IntBuffer minor) {
+ eglDisplay[0] = EGL.EGL_NO_DISPLAY;
+ final long _eglDisplay = EGLDisplayUtil.eglGetDisplay( nativeDisplayID );
+ if ( EGL.EGL_NO_DISPLAY == _eglDisplay ) {
+ eglErr[0] = EGL.eglGetError();
+ return EGL.EGL_BAD_DISPLAY;
+ }
+ if ( !EGLDisplayUtil.eglInitialize( _eglDisplay, major, minor) ) {
+ eglErr[0] = EGL.eglGetError();
+ return EGL.EGL_NOT_INITIALIZED;
+ }
+ eglDisplay[0] = _eglDisplay;
+ return EGL.EGL_SUCCESS;
+ }
+
+ /**
+ * @param nativeDisplayID in/out array of size 1, passing the requested nativeVisualID, may return a different revised nativeVisualID handle
+ * @return the initialized EGL display ID
+ * @throws GLException if not successful
+ */
+ public static synchronized long eglGetDisplayAndInitialize(long[] nativeDisplayID) {
+ final long[] eglDisplay = new long[1];
+ final int[] eglError = new int[1];
+ int eglRes = EGLDisplayUtil.eglGetDisplayAndInitialize(nativeDisplayID[0], eglDisplay, eglError, null, null);
+ if( EGL.EGL_SUCCESS == eglRes ) {
+ return eglDisplay[0];
+ }
+ if( EGL.EGL_DEFAULT_DISPLAY != nativeDisplayID[0] ) { // fallback to DEGAULT_DISPLAY
+ if(DEBUG) {
+ System.err.println("EGLDisplayUtil.eglGetAndInitDisplay failed with native "+EGLContext.toHexString(nativeDisplayID[0])+", error "+EGLContext.toHexString(eglRes)+"/"+EGLContext.toHexString(eglError[0])+" - fallback!");
+ }
+ eglRes = EGLDisplayUtil.eglGetDisplayAndInitialize(EGL.EGL_DEFAULT_DISPLAY, eglDisplay, eglError, null, null);
+ if( EGL.EGL_SUCCESS == eglRes ) {
+ nativeDisplayID[0] = EGL.EGL_DEFAULT_DISPLAY;
+ return eglDisplay[0];
+ }
+ }
+ throw new GLException("Failed to created/initialize EGL display incl. fallback default: native "+EGLContext.toHexString(nativeDisplayID[0])+", error "+EGLContext.toHexString(eglRes)+"/"+EGLContext.toHexString(eglError[0]));
+ }
+
+ /**
* @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
*/
@@ -131,21 +192,15 @@ public class EGLDisplayUtil {
eglDisplayCounter.put(eglDisplay, refCnt);
}
if(DEBUG) {
- System.err.println("EGL.eglTerminate(0x"+Long.toHexString(eglDisplay)+" ...): #"+refCnt+" = "+res);
+ System.err.println("EGLDisplayUtil.eglTerminate("+EGLContext.toHexString(eglDisplay)+" ...): #"+refCnt+" = "+res);
+ // Thread.dumpStack();
}
return res;
}
public static final EGLGraphicsDevice.EGLDisplayLifecycleCallback eglLifecycleCallback = new EGLGraphicsDevice.EGLDisplayLifecycleCallback() {
- public long eglGetAndInitDisplay(long nativeDisplayID) {
- 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 eglDisplay;
+ public long eglGetAndInitDisplay(long[] nativeDisplayID) {
+ return eglGetDisplayAndInitialize(nativeDisplayID);
}
public void eglTerminate(long eglDisplayHandle) {
EGLDisplayUtil.eglTerminate(eglDisplayHandle);
@@ -161,39 +216,26 @@ public class EGLDisplayUtil {
* @see EGLGraphicsDevice#EGLGraphicsDevice(long, long, String, int, com.jogamp.nativewindow.egl.EGLGraphicsDevice.EGLDisplayLifecycleCallback)
*/
public static EGLGraphicsDevice eglCreateEGLGraphicsDevice(long nativeDisplayID, String connection, int unitID) {
- final EGLGraphicsDevice eglDisplay = new EGLGraphicsDevice(nativeDisplayID, 0, connection, unitID, eglLifecycleCallback);
+ final EGLGraphicsDevice eglDisplay = new EGLGraphicsDevice(nativeDisplayID, EGL.EGL_NO_DISPLAY, connection, unitID, eglLifecycleCallback);
eglDisplay.open();
return eglDisplay;
}
/**
* @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
+ * @throws GLException if {@link EGL#eglGetDisplay(long)} or {@link EGL#eglInitialize(long, int[], int, int[], int)} fails incl fallback
*/
- public static EGLGraphicsDevice eglCreateEGLGraphicsDevice(NativeSurface surface, boolean allowFallBackToDefault) {
- long nativeDisplayID;
+ public static EGLGraphicsDevice eglCreateEGLGraphicsDevice(NativeSurface surface) {
+ final 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(), eglLifecycleCallback);
+ final EGLGraphicsDevice eglDevice = new EGLGraphicsDevice(nativeDisplayID, EGL.EGL_NO_DISPLAY, adevice.getConnection(), adevice.getUnitID(), eglLifecycleCallback);
+ eglDevice.open();
+ return eglDevice;
}
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
index 383b61f88..0dba4bb09 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
@@ -114,25 +114,30 @@ public abstract class EGLDrawable extends GLDrawableImpl {
}
}
+ protected static boolean isValidEGLSurface(EGLGraphicsDevice eglDevice, NativeSurface surface) {
+ final long eglDisplayHandle = eglDevice.getHandle();
+ if (EGL.EGL_NO_DISPLAY == eglDisplayHandle) {
+ throw new GLException("Invalid EGL display in EGLGraphicsDevice "+eglDevice);
+ }
+ boolean eglSurfaceValid = 0 != surface.getSurfaceHandle();
+ if(eglSurfaceValid) {
+ int[] tmp = new int[1];
+ eglSurfaceValid = EGL.eglQuerySurface(eglDisplayHandle, surface.getSurfaceHandle(), EGL.EGL_CONFIG_ID, tmp, 0);
+ if(!eglSurfaceValid) {
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": EGLDrawable.isValidEGLSurface eglQuerySuface failed: "+toHexString(EGL.eglGetError())+", "+surface);
+ }
+ }
+ }
+ return eglSurfaceValid;
+ }
+
@Override
protected final void setRealizedImpl() {
final EGLGraphicsConfiguration eglConfig = (EGLGraphicsConfiguration) surface.getGraphicsConfiguration();
final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) eglConfig.getScreen().getDevice();
if (realized) {
- final long eglDisplayHandle = eglDevice.getHandle();
- if (EGL.EGL_NO_DISPLAY == eglDisplayHandle) {
- throw new GLException("Invalid EGL display in EGLGraphicsDevice "+eglDevice);
- }
- int[] tmp = new int[1];
- boolean eglSurfaceValid = 0 != surface.getSurfaceHandle();
- if(eglSurfaceValid) {
- eglSurfaceValid = EGL.eglQuerySurface(eglDisplayHandle, surface.getSurfaceHandle(), EGL.EGL_CONFIG_ID, tmp, 0);
- if(!eglSurfaceValid) {
- if(DEBUG) {
- System.err.println(getThreadName() + ": EGLDrawable.setRealizedImpl eglQuerySuface failed: "+toHexString(EGL.eglGetError())+", "+surface);
- }
- }
- }
+ final boolean eglSurfaceValid = isValidEGLSurface(eglDevice, surface);
if(eglSurfaceValid) {
// surface holds valid EGLSurface
if(DEBUG) {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
index c848e3e5c..f7377a648 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
@@ -282,7 +282,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
if(null != upstreamSurface) {
upstreamSurface.createNotify();
}
- eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(surface, true);
+ eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(surface);
deviceFromUpstreamSurface = true;
}
@@ -471,14 +471,27 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
AbstractGraphicsConfiguration aConfig = surface.getGraphicsConfiguration();
AbstractGraphicsDevice aDevice = aConfig.getScreen().getDevice();
if( aDevice instanceof EGLGraphicsDevice && aConfig instanceof EGLGraphicsConfiguration ) {
- // already in native EGL format
- if(DEBUG) {
- System.err.println(getThreadName() + ": getEGLSurface - already in EGL format - use as-is: "+aConfig);
+ if(EGLDrawable.isValidEGLSurface((EGLGraphicsDevice)aDevice, surface)) {
+ // already in native EGL format
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": getEGLSurface - already valid EGL surface - use as-is: "+aConfig);
+ }
+ return surface;
}
- return surface;
}
// create EGL instance out of platform native types
- final EGLGraphicsDevice eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(surface, true);
+ final EGLGraphicsDevice eglDevice;
+ if( aDevice instanceof EGLGraphicsDevice ) {
+ eglDevice = (EGLGraphicsDevice) aDevice;
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": getEGLSurface - Reusing eglDevice: "+eglDevice);
+ }
+ if(0 == eglDevice.getHandle()) {
+ eglDevice.open();
+ }
+ } else {
+ eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(surface);
+ }
final AbstractGraphicsScreen eglScreen = new DefaultGraphicsScreen(eglDevice, aConfig.getScreen().getIndex());
final GLCapabilitiesImmutable capsRequested = (GLCapabilitiesImmutable) aConfig.getRequestedCapabilities();
final EGLGraphicsConfiguration eglConfig;
@@ -489,7 +502,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
// 'refresh' the native EGLConfig handle
capsChosen.setEGLConfig(EGLGraphicsConfiguration.EGLConfigId2EGLConfig(eglDevice.getHandle(), capsChosen.getEGLConfigID()));
if( 0 == capsChosen.getEGLConfig() ) {
- throw new GLException("Refreshing native EGLConfig handle failed: "+capsChosen+" of "+aConfig);
+ throw new GLException("Refreshing native EGLConfig handle failed with error "+EGLContext.toHexString(EGL.eglGetError())+": "+eglDevice+", "+capsChosen+" of "+aConfig);
}
}
eglConfig = new EGLGraphicsConfiguration(eglScreen, capsChosen, capsRequested, null);
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java b/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java
index 389949e90..40042ec81 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/egl/EGLGraphicsDevice.java
@@ -37,7 +37,7 @@ import javax.media.nativewindow.*;
/** Encapsulates a graphics device on EGL platforms.
*/
public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneable {
- final long nativeDisplayID;
+ final long[] nativeDisplayID = new long[1];
final EGLDisplayLifecycleCallback eglLifecycleCallback;
/**
@@ -51,9 +51,10 @@ public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
/**
* Implementation should issue an <code>EGL.eglGetDisplay(nativeDisplayID)</code>
* inclusive <code>EGL.eglInitialize(eglDisplayHandle, ..)</code> call.
- * @param eglDisplayHandle
+ * @param nativeDisplayID in/out array of size 1, passing the requested nativeVisualID, may return a different revised nativeVisualID handle
+ * @return the initialized EGL display ID, or <code>0</code> if not successful
*/
- public long eglGetAndInitDisplay(long nativeDisplayID);
+ public long eglGetAndInitDisplay(long[] nativeDisplayID);
/**
* Implementation should issue an <code>EGL.eglTerminate(eglDisplayHandle)</code> call.
@@ -68,17 +69,17 @@ public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
*/
public EGLGraphicsDevice(String connection, int unitID) {
super(NativeWindowFactory.TYPE_EGL, connection, unitID);
- this.nativeDisplayID = 0 ; // EGL.EGL_DEFAULT_DISPLAY
+ this.nativeDisplayID[0] = 0 ; // EGL.EGL_DEFAULT_DISPLAY
this.eglLifecycleCallback = null;
}
public EGLGraphicsDevice(long nativeDisplayID, long eglDisplay, String connection, int unitID, EGLDisplayLifecycleCallback eglLifecycleCallback) {
super(NativeWindowFactory.TYPE_EGL, connection, unitID, eglDisplay);
- this.nativeDisplayID = nativeDisplayID;
+ this.nativeDisplayID[0] = nativeDisplayID;
this.eglLifecycleCallback = eglLifecycleCallback;
}
- public long getNativeDisplayID() { return nativeDisplayID; }
+ public long getNativeDisplayID() { return nativeDisplayID[0]; }
@Override
public Object clone() {
@@ -113,7 +114,7 @@ public class EGLGraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
@Override
public String toString() {
- return "EGLGraphicsDevice[type EGL, connection "+getConnection()+", unitID "+getUnitID()+", handle 0x"+Long.toHexString(getHandle())+", nativeDisplayID 0x"+Long.toHexString(nativeDisplayID)+"]";
+ return "EGLGraphicsDevice[type EGL, connection "+getConnection()+", unitID "+getUnitID()+", handle 0x"+Long.toHexString(getHandle())+", nativeDisplayID 0x"+Long.toHexString(nativeDisplayID[0])+", eglLifecycleCallback "+(null != eglLifecycleCallback)+"]";
}
}