aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/jogamp/opengl/egl
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2014-02-23 14:51:06 +0100
committerSven Gothel <[email protected]>2014-02-23 14:51:06 +0100
commit3352601e0860584509adf2b76f993d03893ded4b (patch)
tree974fccc8c0eb2f5ad9d4ffd741dfc35869ed67b5 /src/jogl/classes/jogamp/opengl/egl
parentf51933f0ebe9ae030c26c066e59a728ce08b8559 (diff)
parentc67de337a8aaf52e36104c3f13e273aa19d21f1f (diff)
Merge branch 'master' into stash_glyphcache
Conflicts: make/scripts/tests.sh src/jogl/classes/com/jogamp/graph/curve/OutlineShape.java src/jogl/classes/com/jogamp/graph/curve/Region.java src/jogl/classes/com/jogamp/graph/curve/opengl/GLRegion.java src/jogl/classes/com/jogamp/graph/curve/opengl/RegionRenderer.java src/jogl/classes/com/jogamp/graph/curve/opengl/Renderer.java src/jogl/classes/com/jogamp/graph/curve/opengl/TextRenderer.java src/jogl/classes/com/jogamp/graph/font/Font.java src/jogl/classes/com/jogamp/opengl/math/VectorUtil.java src/jogl/classes/jogamp/graph/curve/text/GlyphShape.java src/jogl/classes/jogamp/graph/curve/text/GlyphString.java src/jogl/classes/jogamp/graph/font/typecast/TypecastFont.java src/jogl/classes/jogamp/graph/font/typecast/TypecastGlyph.java src/jogl/classes/jogamp/graph/font/typecast/TypecastRenderer.java
Diffstat (limited to 'src/jogl/classes/jogamp/opengl/egl')
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/DesktopES2DynamicLibraryBundleInfo.java47
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLContext.java254
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java337
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java262
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java833
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java60
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java55
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLES1DynamicLibraryBundleInfo.java33
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java59
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java50
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java59
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java459
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java287
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLOnscreenContext.java59
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java22
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLPbufferContext.java62
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java53
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java217
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLWrappedSurface.java34
19 files changed, 2092 insertions, 1150 deletions
diff --git a/src/jogl/classes/jogamp/opengl/egl/DesktopES2DynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/egl/DesktopES2DynamicLibraryBundleInfo.java
index cddd142e9..7b85c3e75 100644
--- a/src/jogl/classes/jogamp/opengl/egl/DesktopES2DynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/egl/DesktopES2DynamicLibraryBundleInfo.java
@@ -3,14 +3,14 @@
*
* 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
@@ -20,12 +20,12 @@
* 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 jogamp.opengl.egl;
import java.util.*;
@@ -36,8 +36,8 @@ import jogamp.opengl.*;
* Implementation of the DynamicLookupHelper for Desktop ES2 (AMD, ..)
* where EGL and ES2 functions reside within the desktop OpenGL library.
*/
-public class DesktopES2DynamicLibraryBundleInfo extends GLDynamicLibraryBundleInfo {
- static List<String> glueLibNames;
+public final class DesktopES2DynamicLibraryBundleInfo extends GLDynamicLibraryBundleInfo {
+ static final List<String> glueLibNames;
static {
glueLibNames = new ArrayList<String>();
glueLibNames.add("jogl_mobile");
@@ -47,35 +47,29 @@ public class DesktopES2DynamicLibraryBundleInfo extends GLDynamicLibraryBundleIn
super();
}
- /**
- * Might be a desktop GL library, and might need to allow symbol access to subsequent libs.
- *
- * This respects old DRI requirements:<br>
- * <pre>
- * http://dri.sourceforge.net/doc/DRIuserguide.html
- * </pre>
- */
- public boolean shallLinkGlobal() { return true; }
-
+ @Override
public final List<String> getToolGetProcAddressFuncNameList() {
List<String> res = new ArrayList<String>();
res.add("eglGetProcAddress");
return res;
}
+ @Override
public final long toolGetProcAddress(long toolGetProcAddressHandle, String funcName) {
return EGL.eglGetProcAddress(toolGetProcAddressHandle, funcName);
}
+ @Override
public final boolean useToolGetProcAdressFirst(String funcName) {
return true;
}
-
- public List<List<String>> getToolLibNames() {
+
+ @Override
+ public final List<List<String>> getToolLibNames() {
final List<List<String>> libsList = new ArrayList<List<String>>();
final List<String> libsGL = new ArrayList<String>();
-
- // Be aware that on DRI systems, eg ATI fglrx, etc,
+
+ // Be aware that on DRI systems, eg ATI fglrx, etc,
// you have to set LIBGL_DRIVERS_PATH env variable.
// Eg on Ubuntu 64bit systems this is:
// export LIBGL_DRIVERS_PATH=/usr/lib/fglrx/dri:/usr/lib32/fglrx/dri
@@ -92,15 +86,16 @@ public class DesktopES2DynamicLibraryBundleInfo extends GLDynamicLibraryBundleIn
// OSX (guess ES2 on OSX will never happen)
libsGL.add("/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib");
-
+
// last but not least .. the generic one
libsGL.add("GL");
-
+
libsList.add(libsGL);
return libsList;
- }
-
+ }
+
+ @Override
public final List<String> getGlueLibNames() {
return glueLibNames;
- }
+ }
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
index f5f9f62c4..f89ded4f6 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
@@ -1,22 +1,22 @@
/*
* Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
* Copyright (c) 2011 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:
- *
+ *
* - Redistribution of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
- *
+ *
* - Redistribution 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.
- *
+ *
* Neither the name of Sun Microsystems, Inc. or the names of
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
- *
+ *
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
@@ -29,7 +29,7 @@
* DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
* ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
* SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
- *
+ *
* Sun gratefully acknowledges that this software was originally authored
* and developed by Kenneth Bradley Russell and Christopher John Kline.
*/
@@ -42,7 +42,9 @@ import java.util.Map;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
@@ -50,11 +52,12 @@ import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableImpl;
import com.jogamp.common.nio.Buffers;
-import com.jogamp.common.os.Platform;
import com.jogamp.gluegen.runtime.ProcAddressTable;
import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
+import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
+import com.jogamp.opengl.GLRendererQuirks;
-public abstract class EGLContext extends GLContextImpl {
+public class EGLContext extends GLContextImpl {
private boolean eglQueryStringInitialized;
private boolean eglQueryStringAvailable;
private EGLExt _eglExt;
@@ -68,14 +71,15 @@ public abstract class EGLContext extends GLContextImpl {
}
@Override
- protected void resetStates() {
+ protected void resetStates(boolean isInit) {
eglQueryStringInitialized = false;
eglQueryStringAvailable = false;
eglExtProcAddressTable = null;
// no inner state _eglExt = null;
- super.resetStates();
+ super.resetStates(isInit);
}
-
+
+ @Override
public Object getPlatformGLExtensions() {
return getEGLExt();
}
@@ -87,6 +91,7 @@ public abstract class EGLContext extends GLContextImpl {
return _eglExt;
}
+ @Override
public final ProcAddressTable getPlatformExtProcAddressTable() {
return eglExtProcAddressTable;
}
@@ -95,75 +100,80 @@ public abstract class EGLContext extends GLContextImpl {
return eglExtProcAddressTable;
}
+ @Override
protected Map<String, String> getFunctionNameMap() { return null; }
+ @Override
protected Map<String, String> getExtensionNameMap() { return null; }
+ @Override
public final boolean isGLReadDrawableAvailable() {
return true;
}
+ @Override
protected void makeCurrentImpl() throws GLException {
- if(EGL.EGL_NO_DISPLAY==((EGLDrawable)drawable).getDisplay() ) {
- throw new GLException("drawable not properly initialized, NO DISPLAY: "+drawable);
- }
if (EGL.eglGetCurrentContext() != contextHandle) {
- if (!EGL.eglMakeCurrent(((EGLDrawable)drawable).getDisplay(),
- drawable.getHandle(),
- drawableRead.getHandle(),
- contextHandle)) {
- throw new GLException("Error making context 0x" +
- Long.toHexString(contextHandle) + " current: error code 0x" + Integer.toHexString(EGL.eglGetError()));
+ final long dpy = drawable.getNativeSurface().getDisplayHandle();
+ if (!EGL.eglMakeCurrent(dpy, drawable.getHandle(), drawableRead.getHandle(), contextHandle)) {
+ throw new GLException("Error making context " + toHexString(contextHandle) +
+ " current on Thread " + getThreadName() +
+ " with display " + toHexString(dpy) +
+ ", drawableWrite " + toHexString(drawable.getHandle()) +
+ ", drawableRead "+ toHexString(drawableRead.getHandle()) +
+ " - Error code " + toHexString(EGL.eglGetError()) + ", " + this);
}
}
}
+ @Override
protected void releaseImpl() throws GLException {
- if (!EGL.eglMakeCurrent(((EGLDrawable)drawable).getDisplay(),
- EGL.EGL_NO_SURFACE,
- EGL.EGL_NO_SURFACE,
- EGL.EGL_NO_CONTEXT)) {
- throw new GLException("Error freeing OpenGL context 0x" +
- Long.toHexString(contextHandle) + ": error code 0x" + Integer.toHexString(EGL.eglGetError()));
+ if (!EGL.eglMakeCurrent(drawable.getNativeSurface().getDisplayHandle(), EGL.EGL_NO_SURFACE, EGL.EGL_NO_SURFACE, EGL.EGL_NO_CONTEXT)) {
+ throw new GLException("Error freeing OpenGL context " + toHexString(contextHandle) +
+ ": error code " + toHexString(EGL.eglGetError()));
}
}
+ @Override
protected void destroyImpl() throws GLException {
- if (!EGL.eglDestroyContext(((EGLDrawable)drawable).getDisplay(), contextHandle)) {
- final int eglError = EGL.eglGetError();
- if(EGL.EGL_SUCCESS != eglError) { /* oops, Mesa EGL impl. may return false, but has no EGL error */
- throw new GLException("Error destroying OpenGL context 0x" +
- Long.toHexString(contextHandle) + ": error code 0x" + Integer.toHexString(eglError));
- }
- }
+ destroyContextARBImpl(contextHandle);
}
+ @Override
protected long createContextARBImpl(long share, boolean direct, int ctp, int major, int minor) {
return 0; // FIXME
}
+ @Override
protected void destroyContextARBImpl(long _context) {
- // FIXME
+ if (!EGL.eglDestroyContext(drawable.getNativeSurface().getDisplayHandle(), _context)) {
+ final int eglError = EGL.eglGetError();
+ if(EGL.EGL_SUCCESS != eglError) { /* oops, Mesa EGL impl. may return false, but has no EGL error */
+ throw new GLException("Error destroying OpenGL context " + toHexString(_context) +
+ ": error code " + toHexString(eglError));
+ }
+ }
}
- protected boolean createImpl(GLContextImpl shareWith) throws GLException {
- long eglDisplay = ((EGLDrawable)drawable).getDisplay();
- EGLGraphicsConfiguration config = ((EGLDrawable)drawable).getGraphicsConfiguration();
- GLProfile glProfile = drawable.getGLProfile();
- long eglConfig = config.getNativeConfig();
- long shareWithHandle = EGL.EGL_NO_CONTEXT;
-
- if (eglDisplay == 0) {
+ @Override
+ protected boolean createImpl(final long shareWithHandle) throws GLException {
+ final EGLGraphicsConfiguration config = (EGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration();
+ final long eglDisplay = config.getScreen().getDevice().getHandle();
+ final GLProfile glProfile = drawable.getGLProfile();
+ final long eglConfig = config.getNativeConfig();
+ // 0 == EGL.EGL_NO_CONTEXT;
+
+ if ( 0 == eglDisplay ) {
throw new GLException("Error: attempted to create an OpenGL context without a display connection");
}
- if (eglConfig == 0) {
+ if ( 0 == eglConfig ) {
throw new GLException("Error: attempted to create an OpenGL context without a graphics configuration");
}
try {
// might be unavailable on EGL < 1.2
- if(!EGL.eglBindAPI(EGL.EGL_OPENGL_ES_API)) {
- throw new GLException("Catched: eglBindAPI to ES failed , error 0x"+Integer.toHexString(EGL.eglGetError()));
+ if( !EGL.eglBindAPI(EGL.EGL_OPENGL_ES_API) ) {
+ throw new GLException("Catched: eglBindAPI to ES failed , error "+toHexString(EGL.eglGetError()));
}
} catch (GLException glex) {
if (DEBUG) {
@@ -171,26 +181,29 @@ public abstract class EGLContext extends GLContextImpl {
}
}
- if (shareWith != null) {
- shareWithHandle = shareWith.getHandle();
- if (shareWithHandle == 0) {
- throw new GLException("GLContextShareSet returned an invalid OpenGL context");
- }
- }
+ // Cannot check extension 'EGL_KHR_create_context' before having one current!
- final IntBuffer contextAttrsNIO;
+ final IntBuffer contextAttrsNIO;
+ final int contextVersionReq, contextVersionAttr;
{
- final int[] contextAttrs = new int[] {
- EGL.EGL_CONTEXT_CLIENT_VERSION, -1,
- EGL.EGL_NONE
- };
- if (glProfile.usesNativeGLES2()) {
- contextAttrs[1] = 2;
- } else if (glProfile.usesNativeGLES1()) {
- contextAttrs[1] = 1;
+ if ( glProfile.usesNativeGLES3() ) {
+ contextVersionReq = 3;
+ if( GLRendererQuirks.existStickyDeviceQuirk( GLDrawableFactory.getEGLFactory().getDefaultDevice(), GLRendererQuirks.GLES3ViaEGLES2Config) ) {
+ contextVersionAttr = 2;
+ } else {
+ contextVersionAttr = 3;
+ }
+ } else if ( glProfile.usesNativeGLES2() ) {
+ contextVersionReq = 2;
+ contextVersionAttr = 2;
+ } else if ( glProfile.usesNativeGLES1() ) {
+ contextVersionReq = 1;
+ contextVersionAttr = 1;
} else {
throw new GLException("Error creating OpenGL context - invalid GLProfile: "+glProfile);
}
+ // EGLExt.EGL_CONTEXT_MAJOR_VERSION_KHR == EGL.EGL_CONTEXT_CLIENT_VERSION
+ final int[] contextAttrs = new int[] { EGL.EGL_CONTEXT_CLIENT_VERSION, contextVersionAttr, EGL.EGL_NONE };
contextAttrsNIO = Buffers.newDirectIntBuffer(contextAttrs);
}
contextHandle = EGL.eglCreateContext(eglDisplay, eglConfig, shareWithHandle, contextAttrsNIO);
@@ -200,31 +213,32 @@ public abstract class EGLContext extends GLContextImpl {
}
if (DEBUG) {
System.err.println(getThreadName() + ": Created OpenGL context 0x" +
- Long.toHexString(contextHandle) +
+ Long.toHexString(contextHandle) +
",\n\twrite surface 0x" + Long.toHexString(drawable.getHandle()) +
",\n\tread surface 0x" + Long.toHexString(drawableRead.getHandle())+
",\n\t"+this+
",\n\tsharing with 0x" + Long.toHexString(shareWithHandle));
}
- if (!EGL.eglMakeCurrent(((EGLDrawable)drawable).getDisplay(),
- drawable.getHandle(),
- drawableRead.getHandle(),
- contextHandle)) {
- throw new GLException("Error making context 0x" +
- Long.toHexString(contextHandle) + " current: error code " + EGL.eglGetError());
+ if (!EGL.eglMakeCurrent(eglDisplay, drawable.getHandle(), drawableRead.getHandle(), contextHandle)) {
+ throw new GLException("Error making context " +
+ toHexString(contextHandle) + " current: error code " + toHexString(EGL.eglGetError()));
}
- int ctp = CTX_PROFILE_ES;
- int major;
- if(glProfile.usesNativeGLES2()) {
- ctp |= CTX_IMPL_ES2_COMPAT;
- major = 2;
- } else {
- major = 1;
+ if( !setGLFunctionAvailability(true, contextVersionReq, 0, CTX_PROFILE_ES,
+ true /* strictMatch */, // always req. strict match
+ false /* withinGLVersionsMapping */) ) {
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": createImpl: setGLFunctionAvailability FAILED delete "+toHexString(contextHandle));
+ }
+ EGL.eglMakeCurrent(drawable.getNativeSurface().getDisplayHandle(), EGL.EGL_NO_SURFACE, EGL.EGL_NO_SURFACE, EGL.EGL_NO_CONTEXT);
+ EGL.eglDestroyContext(drawable.getNativeSurface().getDisplayHandle(), contextHandle);
+ contextHandle = 0;
+ return false;
+ } else {
+ return true;
}
- setGLFunctionAvailability(true, major, 0, ctp);
- return true;
}
+ @Override
protected final void updateGLXProcAddressTable() {
final AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration();
final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
@@ -255,17 +269,16 @@ public abstract class EGLContext extends GLContextImpl {
}
}
}
-
+
+ @Override
protected final StringBuilder getPlatformExtensionsStringImpl() {
- StringBuilder sb = new StringBuilder();
+ StringBuilder sb = new StringBuilder();
if (!eglQueryStringInitialized) {
- eglQueryStringAvailable =
- getDrawableImpl().getGLDynamicLookupHelper().dynamicLookupFunction("eglQueryString") != 0;
+ eglQueryStringAvailable = getDrawableImpl().getGLDynamicLookupHelper().isFunctionAvailable("eglQueryString");
eglQueryStringInitialized = true;
}
if (eglQueryStringAvailable) {
- final String ret = EGL.eglQueryString(((EGLDrawable)drawable).getDisplay(),
- EGL.EGL_EXTENSIONS);
+ final String ret = EGL.eglQueryString(drawable.getNativeSurface().getDisplayHandle(), EGL.EGL_EXTENSIONS);
if (DEBUG) {
System.err.println("EGL extensions: " + ret);
}
@@ -276,22 +289,63 @@ public abstract class EGLContext extends GLContextImpl {
@Override
protected boolean setSwapIntervalImpl(int interval) {
- // FIXME !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- // eglSwapInterval(..) issued:
- // Android 4.0.3 / Pandaboard ES / PowerVR SGX 540: crashes
- // FIXME !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- if( Platform.OSType.ANDROID == Platform.getOSType() && getGLRendererString(true).contains("powervr") ) {
- if(DEBUG) {
- System.err.println("Ignored: eglSwapInterval("+interval+") - cause: OS "+Platform.getOSType() + " / Renderer " + getGLRendererString(false));
- }
+ if( hasRendererQuirk(GLRendererQuirks.NoSetSwapInterval) ) {
return false;
}
- return EGL.eglSwapInterval(((EGLDrawable)drawable).getDisplay(), interval);
+ return EGL.eglSwapInterval(drawable.getNativeSurface().getDisplayHandle(), interval);
}
- public abstract void bindPbufferToTexture();
+ //
+ // Accessible ..
+ //
- public abstract void releasePbufferFromTexture();
+ /* pp */ void mapCurrentAvailableGLVersion(AbstractGraphicsDevice device) {
+ mapStaticGLVersion(device, ctxVersion.getMajor(), ctxVersion.getMinor(), ctxOptions);
+ }
+ /* pp */ int getContextOptions() { return ctxOptions; }
+ /* pp */ static void mapStaticGLESVersion(AbstractGraphicsDevice device, GLCapabilitiesImmutable caps) {
+ final GLProfile glp = caps.getGLProfile();
+ final int[] reqMajorCTP = new int[2];
+ GLContext.getRequestMajorAndCompat(glp, reqMajorCTP);
+ if( glp.isGLES() ) {
+ if( reqMajorCTP[0] >= 3 ) {
+ reqMajorCTP[1] |= GLContext.CTX_IMPL_ES3_COMPAT | GLContext.CTX_IMPL_ES2_COMPAT | GLContext.CTX_IMPL_FBO ;
+ } else if( reqMajorCTP[0] >= 2 ) {
+ reqMajorCTP[1] |= GLContext.CTX_IMPL_ES2_COMPAT | GLContext.CTX_IMPL_FBO ;
+ }
+ }
+ if( !caps.getHardwareAccelerated() ) {
+ reqMajorCTP[1] |= GLContext.CTX_IMPL_ACCEL_SOFT;
+ }
+ mapStaticGLVersion(device, reqMajorCTP[0], 0, reqMajorCTP[1]);
+ }
+ /* pp */ static void mapStaticGLVersion(AbstractGraphicsDevice device, int major, int minor, int ctp) {
+ if( 0 != ( ctp & GLContext.CTX_PROFILE_ES) ) {
+ // ES1, ES2, ES3, ..
+ mapStaticGLVersion(device, major /* reqMajor */, major, minor, ctp);
+ if( 3 == major ) {
+ // map ES2 -> ES3
+ mapStaticGLVersion(device, 2 /* reqMajor */, major, minor, ctp);
+ }
+ }
+ }
+ private static void mapStaticGLVersion(AbstractGraphicsDevice device, int reqMajor, int major, int minor, int ctp) {
+ GLContext.mapAvailableGLVersion(device, reqMajor, GLContext.CTX_PROFILE_ES, major, minor, ctp);
+ if(! ( device instanceof EGLGraphicsDevice ) ) {
+ final EGLGraphicsDevice eglDevice = new EGLGraphicsDevice(device.getHandle(), EGL.EGL_NO_DISPLAY, device.getConnection(), device.getUnitID(), null);
+ GLContext.mapAvailableGLVersion(eglDevice, reqMajor, GLContext.CTX_PROFILE_ES, major, minor, ctp);
+ }
+ }
+ protected static String getGLVersion(int major, int minor, int ctp, String gl_version) {
+ return GLContext.getGLVersion(major, minor, ctp, gl_version);
+ }
+
+ protected static boolean getAvailableGLVersionsSet(AbstractGraphicsDevice device) {
+ return GLContext.getAvailableGLVersionsSet(device);
+ }
+ protected static void setAvailableGLVersionsSet(AbstractGraphicsDevice device) {
+ GLContext.setAvailableGLVersionsSet(device);
+ }
protected static String toHexString(int hex) {
return GLContext.toHexString(hex);
@@ -299,25 +353,23 @@ public abstract class EGLContext extends GLContextImpl {
protected static String toHexString(long hex) {
return GLContext.toHexString(hex);
}
-
+
//----------------------------------------------------------------------
// Currently unimplemented stuff
//
+ @Override
protected void copyImpl(GLContext source, int mask) throws GLException {
throw new GLException("Not yet implemented");
}
-
- public ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3) {
- throw new GLException("Should not call this");
- }
-
- public boolean offscreenImageNeedsVerticalFlip() {
+ @Override
+ public final ByteBuffer glAllocateMemoryNV(int size, float readFrequency, float writeFrequency, float priority) {
throw new GLException("Should not call this");
}
- public int getOffscreenContextPixelDataType() {
+ @Override
+ public final void glFreeMemoryNV(ByteBuffer pointer) {
throw new GLException("Should not call this");
}
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
index e09400c09..c5f76f667 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
@@ -3,14 +3,14 @@
*
* 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
@@ -20,7 +20,7 @@
* 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.
@@ -29,105 +29,310 @@
package jogamp.opengl.egl;
import java.nio.IntBuffer;
+import java.util.Iterator;
+import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.nativewindow.ToolkitLock;
+import javax.media.opengl.GLException;
import jogamp.opengl.Debug;
-import com.jogamp.common.util.LongIntHashMap;
+import com.jogamp.common.util.LongObjectHashMap;
+import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
-/**
- * This implementation provides recursive calls to
+/**
+ * This implementation provides recursive calls to
* {@link EGL#eglInitialize(long, IntBuffer, IntBuffer)} and {@link EGL#eglTerminate(long)},
* where <code>eglInitialize(..)</code> is issued only for the 1st call per <code>eglDisplay</code>
* and <code>eglTerminate(..)</code> is issued only for the last call.
* <p>
* This class is required, due to implementation bugs within EGL where {@link EGL#eglTerminate(long)}
- * does not mark the resource for deletion when still in use, bug releases them immediatly.
+ * does not mark the resource for deletion when still in use, bug releases them immediately.
* </p>
*/
public class EGLDisplayUtil {
- protected static final boolean DEBUG = Debug.debug("EGL");
-
- static LongIntHashMap eglDisplayCounter;
-
+ private static final boolean DEBUG = Debug.debug("EGLDisplayUtil");
+ private static boolean useSingletonEGLDisplay = false;
+ private static EGLDisplayRef singletonEGLDisplay = null;
+
+ private static class EGLDisplayRef {
+ final long eglDisplay;
+ final Throwable createdStack;
+ int initRefCount;
+
+ /**
+ * Returns an already opened {@link EGLDisplayRef} or opens a new {@link EGLDisplayRef}.
+ * <p>
+ * Opened {@link EGLDisplayRef}s are mapped against their <code>eglDisplay</code> handle.
+ * </p>
+ * <p>
+ * Method utilizes {@link EGLDisplayRef}'s reference counter, i.e. increases it.
+ * </p>
+ * <p>
+ * An {@link EGLDisplayRef} is <i>opened</i> via {@link EGL#eglInitialize(long, IntBuffer, IntBuffer)}.
+ * </p>
+ */
+ static EGLDisplayRef getOrCreateOpened(final long eglDisplay, final IntBuffer major, final IntBuffer minor) {
+ EGLDisplayRef o = (EGLDisplayRef) openEGLDisplays.get(eglDisplay);
+ if( null == o ) {
+ if( EGL.eglInitialize(eglDisplay, major, minor) ) {
+ final EGLDisplayRef n = new EGLDisplayRef(eglDisplay);
+ openEGLDisplays.put(eglDisplay, n);
+ n.initRefCount++;
+ if( null == singletonEGLDisplay ) {
+ singletonEGLDisplay = n;
+ }
+ return n;
+ } else {
+ return null;
+ }
+ } else {
+ o.initRefCount++;
+ return o;
+ }
+ }
+
+ /**
+ * Closes an already opened {@link EGLDisplayRef}.
+ * <p>
+ * Method decreases a reference counter and closes the {@link EGLDisplayRef} if it reaches zero.
+ * </p>
+ * <p>
+ * An {@link EGLDisplayRef} is <i>closed</i> via {@link EGL#eglTerminate(long)}.
+ * </p>
+ */
+ static EGLDisplayRef closeOpened(final long eglDisplay, final boolean[] res) {
+ final EGLDisplayRef o = (EGLDisplayRef) openEGLDisplays.get(eglDisplay);
+ res[0] = true;
+ if( null != o ) {
+ if( 0 < o.initRefCount ) { // no negative refCount
+ o.initRefCount--;
+ if( 0 == o.initRefCount ) {
+ res[0] = EGL.eglTerminate(eglDisplay);
+ if( o == singletonEGLDisplay ) {
+ singletonEGLDisplay = null;
+ }
+ }
+ }
+ if( 0 >= o.initRefCount ) {
+ openEGLDisplays.remove(eglDisplay);
+ }
+ }
+ return o;
+ }
+
+ private EGLDisplayRef(long eglDisplay) {
+ this.eglDisplay = eglDisplay;
+ this.initRefCount = 0;
+ this.createdStack = DEBUG ? new Throwable() : null;
+ }
+
+ @Override
+ public String toString() {
+ return "EGLDisplayRef[0x"+Long.toHexString(eglDisplay)+": refCnt "+initRefCount+"]";
+ }
+ }
+ private static final LongObjectHashMap openEGLDisplays;
+
static {
- eglDisplayCounter = new LongIntHashMap();
- eglDisplayCounter.setKeyNotFoundValue(0);
+ openEGLDisplays = new LongObjectHashMap();
+ openEGLDisplays.setKeyNotFoundValue(null);
+ }
+
+ /**
+ * @return number of unclosed EGL Displays.<br>
+ */
+ public static int shutdown(boolean verbose) {
+ if(DEBUG || verbose || openEGLDisplays.size() > 0 ) {
+ System.err.println("EGLDisplayUtil.EGLDisplays: Shutdown (open: "+openEGLDisplays.size()+")");
+ if(DEBUG) {
+ Thread.dumpStack();
+ }
+ if( openEGLDisplays.size() > 0) {
+ dumpOpenDisplayConnections();
+ }
+ }
+ return openEGLDisplays.size();
+ }
+
+ public static void dumpOpenDisplayConnections() {
+ System.err.println("EGLDisplayUtil: Open EGL Display Connections: "+openEGLDisplays.size());
+ int i=0;
+ for(Iterator<LongObjectHashMap.Entry> iter = openEGLDisplays.iterator(); iter.hasNext(); i++) {
+ final LongObjectHashMap.Entry e = iter.next();
+ final EGLDisplayRef v = (EGLDisplayRef) e.value;
+ System.err.println("EGLDisplayUtil: Open["+i+"]: 0x"+Long.toHexString(e.key)+": "+v);
+ if(null != v.createdStack) {
+ v.createdStack.printStackTrace();
+ }
+ }
}
- public static long eglGetDisplay(long nativeDisplay_id) {
+ /* pp */ static synchronized void setSingletonEGLDisplayOnly(boolean v) { useSingletonEGLDisplay = v; }
+
+ private static synchronized long eglGetDisplay(long nativeDisplay_id) {
+ if( useSingletonEGLDisplay && null != singletonEGLDisplay ) {
+ if(DEBUG) {
+ System.err.println("EGLDisplayUtil.eglGetDisplay.s: eglDisplay("+EGLContext.toHexString(nativeDisplay_id)+"): "+
+ EGLContext.toHexString(singletonEGLDisplay.eglDisplay)+
+ ", "+((EGL.EGL_NO_DISPLAY != singletonEGLDisplay.eglDisplay)?"OK":"Failed")+", singletonEGLDisplay "+singletonEGLDisplay+" (use "+useSingletonEGLDisplay+")");
+ }
+ return singletonEGLDisplay.eglDisplay;
+ }
final long eglDisplay = EGL.eglGetDisplay(nativeDisplay_id);
if(DEBUG) {
- System.err.println("EGLDisplayUtil.eglGetDisplay(): eglDisplay("+EGLContext.toHexString(nativeDisplay_id)+"): "+
+ System.err.println("EGLDisplayUtil.eglGetDisplay.X: eglDisplay("+EGLContext.toHexString(nativeDisplay_id)+"): "+
EGLContext.toHexString(eglDisplay)+
- ", "+((EGL.EGL_NO_DISPLAY != eglDisplay)?"OK":"Failed"));
+ ", "+((EGL.EGL_NO_DISPLAY != eglDisplay)?"OK":"Failed")+", singletonEGLDisplay "+singletonEGLDisplay+" (use "+useSingletonEGLDisplay+")");
}
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
+
+ /**
+ * @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, IntBuffer, IntBuffer)} was successful, otherwise false
+ *
+ * @see EGL#eglInitialize(long, IntBuffer, IntBuffer)
+ */
+ private static synchronized boolean eglInitialize(long eglDisplay, IntBuffer major, IntBuffer minor) {
+ if( EGL.EGL_NO_DISPLAY == eglDisplay) {
+ return false;
+ }
+ final EGLDisplayRef d = EGLDisplayRef.getOrCreateOpened(eglDisplay, major, minor);
+ if(DEBUG) {
+ System.err.println("EGLDisplayUtil.eglInitialize("+EGLContext.toHexString(eglDisplay)+" ...): "+d+" = "+(null != d)+", singletonEGLDisplay "+singletonEGLDisplay+" (use "+useSingletonEGLDisplay+")");
+ // Thread.dumpStack();
+ }
+ return null != d;
+ }
+
+ /**
+ * @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)
+ */
+ private static synchronized int eglGetDisplayAndInitialize(long nativeDisplayID, long[] eglDisplay, int[] eglErr, IntBuffer major, IntBuffer minor) {
+ eglDisplay[0] = EGL.EGL_NO_DISPLAY;
+ final long _eglDisplay = eglGetDisplay( nativeDisplayID );
+ if ( EGL.EGL_NO_DISPLAY == _eglDisplay ) {
+ eglErr[0] = EGL.eglGetError();
+ return EGL.EGL_BAD_DISPLAY;
}
- long eglDisplay = EGLDisplayUtil.eglGetDisplay(nDisplay);
- if (eglDisplay == EGL.EGL_NO_DISPLAY && nDisplay != EGL.EGL_DEFAULT_DISPLAY && allowFallBackToDefault) {
+ if ( !eglInitialize( _eglDisplay, major, minor) ) {
+ eglErr[0] = EGL.eglGetError();
+ return EGL.EGL_NOT_INITIALIZED;
+ }
+ eglDisplay[0] = _eglDisplay;
+ return EGL.EGL_SUCCESS;
+ }
+
+ /**
+ * Attempts to {@link #eglGetDisplayAndInitialize(long, long[], int[], IntBuffer, IntBuffer)} with given <code>nativeDisplayID</code>.
+ * If this fails, method retries with <code>nativeDisplayID</code> {@link EGL#EGL_DEFAULT_DISPLAY} - the fallback mechanism.
+ * The actual used <code>nativeDisplayID</code> is returned in it's in/out array.
+ *
+ * @throws GLException if {@link EGL#eglGetDisplay(long)} or {@link EGL#eglInitialize(long, int[], int, int[], int)} fails incl fallback
+ * @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
+ */
+ private 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.eglGetDisplay(): Fall back to EGL_DEFAULT_DISPLAY");
+ 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];
}
- eglDisplay = EGLDisplayUtil.eglGetDisplay(EGL.EGL_DEFAULT_DISPLAY);
}
- return eglDisplay;
+ 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]));
}
-
- 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
- if(1==refCnt) {
- res = EGL.eglInitialize(eglDisplay, major, major_offset, minor, minor_offset);
- } else {
- res = true;
+
+ /**
+ * @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
+ */
+ private static synchronized boolean eglTerminate(long eglDisplay) {
+ if( EGL.EGL_NO_DISPLAY == eglDisplay) {
+ return false;
}
- eglDisplayCounter.put(eglDisplay, refCnt);
+ final boolean[] res = new boolean[1];
+ final EGLDisplayRef d = EGLDisplayRef.closeOpened(eglDisplay, res);
if(DEBUG) {
- System.err.println("EGL.eglInitialize(0x"+Long.toHexString(eglDisplay)+" ...): #"+refCnt+" = "+res);
+ System.err.println("EGLDisplayUtil.eglTerminate.X("+EGLContext.toHexString(eglDisplay)+" ...): "+d+" = "+res[0]+", singletonEGLDisplay "+singletonEGLDisplay+" (use "+useSingletonEGLDisplay+")");
+ // Thread.dumpStack();
}
- return res;
+ return res[0];
}
-
- public static synchronized boolean eglInitialize(long eglDisplay, IntBuffer major, IntBuffer minor) {
- final boolean res;
- final int refCnt = eglDisplayCounter.get(eglDisplay) + 1; // 0 + 1 = 1 -> 1st init
- if(1==refCnt) { // only initialize once
- res = EGL.eglInitialize(eglDisplay, major, minor);
- } else {
- res = true;
+
+ private static final EGLGraphicsDevice.EGLDisplayLifecycleCallback eglLifecycleCallback = new EGLGraphicsDevice.EGLDisplayLifecycleCallback() {
+ @Override
+ public long eglGetAndInitDisplay(long[] nativeDisplayID) {
+ return eglGetDisplayAndInitialize(nativeDisplayID);
}
- eglDisplayCounter.put(eglDisplay, refCnt);
- if(DEBUG) {
- System.err.println("EGL.eglInitialize(0x"+Long.toHexString(eglDisplay)+" ...): #"+refCnt+" = "+res);
+ @Override
+ public void eglTerminate(long eglDisplayHandle) {
+ EGLDisplayUtil.eglTerminate(eglDisplayHandle);
}
- return res;
+ };
+
+ /**
+ * Returns an uninitialized {@link EGLGraphicsDevice}. User needs to issue {@link EGLGraphicsDevice#open()} before usage.
+ * <p>
+ * Using {@link #eglGetDisplayAndInitialize(long[])} for the {@link EGLGraphicsDevice#open()} implementation
+ * and {@link #eglTerminate(long)} for {@link EGLGraphicsDevice#close()}.
+ * </p>
+ * <p>
+ * Using the default {@link ToolkitLock}, via {@link NativeWindowFactory#getDefaultToolkitLock(String, long)}.
+ * </p>
+ * @param nativeDisplayID
+ * @param connection
+ * @param unitID
+ * @return an uninitialized {@link EGLGraphicsDevice}
+ */
+ public static EGLGraphicsDevice eglCreateEGLGraphicsDevice(long nativeDisplayID, String connection, int unitID) {
+ return new EGLGraphicsDevice(nativeDisplayID, EGL.EGL_NO_DISPLAY, connection, unitID, eglLifecycleCallback);
}
-
- public static synchronized boolean eglTerminate(long eglDisplay) {
- 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
- res = EGL.eglTerminate(eglDisplay);
+
+ /**
+ * Returns an uninitialized {@link EGLGraphicsDevice}. User needs to issue {@link EGLGraphicsDevice#open()} before usage.
+ * <p>
+ * Using {@link #eglGetDisplayAndInitialize(long[])} for the {@link EGLGraphicsDevice#open()} implementation
+ * and {@link #eglTerminate(long)} for {@link EGLGraphicsDevice#close()}.
+ * </p>
+ * <p>
+ * Using the default {@link ToolkitLock}, via {@link NativeWindowFactory#getDefaultToolkitLock(String, long)}.
+ * </p>
+ * @param surface
+ * @return an uninitialized EGLGraphicsDevice
+ */
+ public static EGLGraphicsDevice eglCreateEGLGraphicsDevice(NativeSurface surface) {
+ final long nativeDisplayID;
+ if( NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false) ) {
+ nativeDisplayID = surface.getSurfaceHandle(); // don't even ask ..
} else {
- res = true;
- }
- if(0<=refCnt) { // no negative refCount
- eglDisplayCounter.put(eglDisplay, refCnt);
- }
- if(DEBUG) {
- System.err.println("EGL.eglTerminate(0x"+Long.toHexString(eglDisplay)+" ...): #"+refCnt+" = "+res);
+ nativeDisplayID = surface.getDisplayHandle(); // 0 == EGL.EGL_DEFAULT_DISPLAY
}
- return res;
+ final AbstractGraphicsDevice adevice = surface.getGraphicsConfiguration().getScreen().getDevice();
+ return new EGLGraphicsDevice(nativeDisplayID, EGL.EGL_NO_DISPLAY, adevice.getConnection(), adevice.getUnitID(), eglLifecycleCallback);
}
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
index b2119d728..f184edae3 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
@@ -1,22 +1,22 @@
/*
* Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
* Copyright (c) 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:
- *
+ *
* - Redistribution of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
- *
+ *
* - Redistribution 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.
- *
+ *
* Neither the name of Sun Microsystems, Inc. or the names of
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
- *
+ *
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
@@ -29,229 +29,146 @@
* DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
* ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
* SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
- *
+ *
* Sun gratefully acknowledges that this software was originally authored
* and developed by Kenneth Bradley Russell and Christopher John Kline.
*/
package jogamp.opengl.egl;
-import jogamp.opengl.GLDynamicLookupHelper;
-import jogamp.opengl.GLDrawableImpl;
+import java.nio.IntBuffer;
-import javax.media.nativewindow.*;
-import javax.media.nativewindow.VisualIDHolder.VIDType;
-import javax.media.opengl.*;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindow;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLException;
+
+import jogamp.opengl.GLDrawableImpl;
+import jogamp.opengl.GLDynamicLookupHelper;
-import com.jogamp.nativewindow.egl.*;
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
public abstract class EGLDrawable extends GLDrawableImpl {
- protected boolean ownEGLDisplay = false; // for destruction
- protected boolean ownEGLSurface = false; // for destruction
- private EGLGraphicsConfiguration eglConfig;
- protected long eglDisplay;
- protected long eglSurface;
- protected EGLDrawable(EGLDrawableFactory factory,
- NativeSurface component) throws GLException {
+ protected EGLDrawable(EGLDrawableFactory factory, NativeSurface component) throws GLException {
super(factory, component, false);
- eglSurface=EGL.EGL_NO_SURFACE;
- eglDisplay=0;
- }
-
- public long getDisplay() {
- return eglDisplay;
- }
-
- public long getHandle() {
- return eglSurface;
- }
-
- public EGLGraphicsConfiguration getGraphicsConfiguration() {
- return eglConfig;
- }
-
- public GLCapabilitiesImmutable getChosenGLCapabilities() {
- return (null==eglConfig)?super.getChosenGLCapabilities():(GLCapabilitiesImmutable)eglConfig.getChosenCapabilities();
}
+ @Override
public abstract GLContext createContext(GLContext shareWith);
- protected abstract long createSurface(long eglDpy, long eglNativeCfg, long surfaceHandle);
+ protected abstract long createSurface(EGLGraphicsConfiguration config, int width, int height, long nativeSurfaceHandle);
- private void recreateSurface() {
- // create a new EGLSurface ..
- if(EGL.EGL_NO_SURFACE!=eglSurface) {
- EGL.eglDestroySurface(eglDisplay, eglSurface);
- }
+ private final long createEGLSurface() {
+ final EGLWrappedSurface eglws = (EGLWrappedSurface) surface;
+ final EGLGraphicsConfiguration eglConfig = (EGLGraphicsConfiguration) eglws.getGraphicsConfiguration();
+ final NativeSurface upstreamSurface = eglws.getUpstreamSurface();
- if(DEBUG) {
- System.err.println(getThreadName() + ": createSurface using eglDisplay "+toHexString(eglDisplay)+", "+eglConfig);
- }
+ long eglSurface = createSurface(eglConfig, eglws.getWidth(), eglws.getHeight(), upstreamSurface.getSurfaceHandle());
- eglSurface = createSurface(eglDisplay, eglConfig.getNativeConfig(), surface.getSurfaceHandle());
- int eglError0 = EGL.EGL_SUCCESS;
+ int eglError0;
if (EGL.EGL_NO_SURFACE == eglSurface) {
eglError0 = EGL.eglGetError();
if(EGL.EGL_BAD_NATIVE_WINDOW == eglError0) {
- // Try window handle if available and differs (Windows HDC / HWND).
+ // Try window handle if available and differs (Windows HDC / HWND).
// ANGLE impl. required HWND on Windows.
- if(surface instanceof NativeWindow) {
- final NativeWindow nw = (NativeWindow) surface;
+ if(upstreamSurface instanceof NativeWindow) {
+ final NativeWindow nw = (NativeWindow) upstreamSurface;
if(nw.getWindowHandle() != nw.getSurfaceHandle()) {
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(eglConfig, eglws.getWidth(), eglws.getHeight(), nw.getWindowHandle());
if (EGL.EGL_NO_SURFACE == eglSurface) {
eglError0 = EGL.eglGetError();
}
}
}
}
+ } else {
+ eglError0 = EGL.EGL_SUCCESS;
}
if (EGL.EGL_NO_SURFACE == eglSurface) {
throw new GLException("Creation of window surface failed: "+eglConfig+", "+surface+", error "+toHexString(eglError0));
}
-
if(DEBUG) {
- System.err.println(getThreadName() + ": setSurface using component: handle "+toHexString(surface.getSurfaceHandle())+" -> "+toHexString(eglSurface));
+ System.err.println(getThreadName() + ": createEGLSurface handle "+toHexString(eglSurface));
}
+ return eglSurface;
}
@Override
- protected final void updateHandle() {
- if(ownEGLSurface) {
- recreateSurface();
+ protected final void createHandle() {
+ final EGLWrappedSurface eglws = (EGLWrappedSurface) surface;
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": createHandle of "+eglws);
+ }
+ if( eglws.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ) ) {
+ if( EGL.EGL_NO_SURFACE != eglws.getSurfaceHandle() ) {
+ throw new InternalError("Set surface but claimed to be invalid: "+eglws);
+ }
+ eglws.setSurfaceHandle( createEGLSurface() );
+ } else if( EGL.EGL_NO_SURFACE == eglws.getSurfaceHandle() ) {
+ throw new InternalError("Nil surface but claimed to be valid: "+eglws);
}
}
-
- protected void setRealizedImpl() {
- if (realized) {
- AbstractGraphicsConfiguration aConfig = surface.getGraphicsConfiguration();
- AbstractGraphicsDevice aDevice = aConfig.getScreen().getDevice();
- if(aDevice instanceof EGLGraphicsDevice) {
- if(DEBUG) {
- 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);
- }
- if(aConfig instanceof EGLGraphicsConfiguration) {
- eglConfig = (EGLGraphicsConfiguration) aConfig; // done ..
- if (null == eglConfig) {
- throw new GLException("Null EGLGraphicsConfiguration from "+aConfig);
- }
- int[] tmp = new int[1];
- if ( 0 != surface.getSurfaceHandle() &&
- EGL.eglQuerySurface(eglDisplay, 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));
- }
- } else {
- // EGLSurface is ours - subsequent updateHandle() will issue recreateSurface();
- ownEGLSurface=true;
- }
- } else {
- throw new GLException("EGLGraphicsDevice hold by non EGLGraphicsConfiguration: "+aConfig);
- }
- } else {
- if(DEBUG) {
- System.err.println(getThreadName() + ": EGLDrawable.setRealized(true): creating new EGL config - START");
- }
- // create a new EGL config ..
- ownEGLDisplay=true;
- // EGLSurface is ours ..
- ownEGLSurface=true;
+ @Override
+ protected void destroyHandle() {
+ final EGLWrappedSurface eglws = (EGLWrappedSurface) surface;
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": destroyHandle of "+eglws);
+ }
+ if( EGL.EGL_NO_SURFACE == eglws.getSurfaceHandle() ) {
+ throw new InternalError("Nil surface but claimed to be valid: "+eglws);
+ }
+ final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) eglws.getGraphicsConfiguration().getScreen().getDevice();
+ if( eglws.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ) ) {
+ EGL.eglDestroySurface(eglDevice.getHandle(), eglws.getSurfaceHandle());
+ eglws.setSurfaceHandle(EGL.EGL_NO_SURFACE);
+ }
+ }
- 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());
- 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()));
- if(0 == capsChosen.getEGLConfig()) {
- throw new GLException("Refreshing native EGLConfig handle failed: "+capsChosen+" of "+aConfig);
- }
- }
- eglConfig = new EGLGraphicsConfiguration(s, 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);
-
- if (null == eglConfig) {
- throw new GLException("Couldn't create EGLGraphicsConfiguration from "+s);
- } else if(DEBUG) {
- System.err.println(getThreadName() + ": Chosen eglConfig: "+eglConfig);
- }
- }
- // subsequent updateHandle() will issue recreateSurface();
- }
- if(DEBUG) {
- System.err.println(getThreadName() + ": EGLDrawable.setRealized(true): END: ownDisplay "+ownEGLDisplay+", ownSurface "+ownEGLSurface);
- }
- } else if (ownEGLSurface && eglSurface != EGL.EGL_NO_SURFACE) {
+ protected static boolean isValidEGLSurface(long eglDisplayHandle, long surfaceHandle) {
+ if( 0 == surfaceHandle ) {
+ return false;
+ }
+ final IntBuffer val = Buffers.newDirectIntBuffer(1);
+ final boolean eglSurfaceValid = EGL.eglQuerySurface(eglDisplayHandle, surfaceHandle, EGL.EGL_CONFIG_ID, val);
+ if( !eglSurfaceValid ) {
+ final int eglErr = EGL.eglGetError();
if(DEBUG) {
- System.err.println(getThreadName() + ": EGLDrawable.setRealized(false): ownDisplay "+ownEGLDisplay+", ownSurface "+ownEGLSurface+", eglDisplay: "+toHexString(eglDisplay)+", eglSurface: "+toHexString(eglSurface));
+ System.err.println(getThreadName() + ": EGLDrawable.isValidEGLSurface eglQuerySuface failed: error "+toHexString(eglErr)+", "+toHexString(surfaceHandle));
}
- // Destroy the window surface
- if (!EGL.eglDestroySurface(eglDisplay, 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;
}
+ return eglSurfaceValid;
}
- protected final void swapBuffersImpl() {
- // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers()
- if(!EGL.eglSwapBuffers(eglDisplay, eglSurface)) {
- throw new GLException("Error swapping buffers, eglError "+toHexString(EGL.eglGetError())+", "+this);
+ @Override
+ protected final void setRealizedImpl() {
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": EGLDrawable.setRealized("+realized+"): NOP - "+surface);
}
}
- /**
- * Surface not realizes yet (onscreen) .. Quering EGL surface size only makes sense for external drawable.
- * Leave it here for later impl. of an EGLExternalDrawable.
- public int getWidth() {
- int[] tmp = new int[1];
- if (!EGL.eglQuerySurface(eglDisplay, eglSurface, EGL.EGL_WIDTH, tmp, 0)) {
- throw new GLException("Error querying surface width, eglError "+toHexString(EGL.eglGetError()));
+ @Override
+ protected final void swapBuffersImpl(boolean doubleBuffered) {
+ if(doubleBuffered) {
+ final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) surface.getGraphicsConfiguration().getScreen().getDevice();
+ // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers()
+ if(!EGL.eglSwapBuffers(eglDevice.getHandle(), surface.getSurfaceHandle())) {
+ throw new GLException("Error swapping buffers, eglError "+toHexString(EGL.eglGetError())+", "+this);
+ }
}
- return tmp[0];
}
- public int getHeight() {
- int[] tmp = new int[1];
- if (!EGL.eglQuerySurface(eglDisplay, eglSurface, EGL.EGL_HEIGHT, tmp, 0)) {
- throw new GLException("Error querying surface height, eglError "+toHexString(EGL.eglGetError()));
- }
- return tmp[0];
- } */
-
+ @Override
public GLDynamicLookupHelper getGLDynamicLookupHelper() {
- if (getGLProfile().usesNativeGLES2()) {
+ if (getGLProfile().usesNativeGLES3()) {
+ return getFactoryImpl().getGLDynamicLookupHelper(3);
+ } else if (getGLProfile().usesNativeGLES2()) {
return getFactoryImpl().getGLDynamicLookupHelper(2);
} else if (getGLProfile().usesNativeGLES1()) {
return getFactoryImpl().getGLDynamicLookupHelper(1);
@@ -260,12 +177,13 @@ public abstract class EGLDrawable extends GLDrawableImpl {
}
}
+ @Override
public String toString() {
return getClass().getName()+"[realized "+isRealized()+
",\n\tfactory "+getFactory()+
",\n\tsurface "+getNativeSurface()+
- ",\n\teglSurface "+toHexString(eglSurface)+
- ",\n\teglConfig "+eglConfig+
+ ",\n\teglSurface "+toHexString(surface.getSurfaceHandle())+
+ ",\n\teglConfig "+surface.getGraphicsConfiguration()+
",\n\trequested "+getRequestedGLCapabilities()+
",\n\tchosen "+getChosenGLCapabilities()+"]";
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
index 4b77bfa87..9ee0134f1 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
@@ -1,22 +1,22 @@
/*
* Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
* Copyright (c) 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:
- *
+ *
* - Redistribution of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
- *
+ *
* - Redistribution 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.
- *
+ *
* Neither the name of Sun Microsystems, Inc. or the names of
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
- *
+ *
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
@@ -29,93 +29,109 @@
* DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
* ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
* SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
- *
+ *
* Sun gratefully acknowledges that this software was originally authored
* and developed by Kenneth Bradley Russell and Christopher John Kline.
*/
package jogamp.opengl.egl;
-import javax.media.nativewindow.*;
-import javax.media.opengl.*;
-import javax.media.opengl.GLProfile.ShutdownType;
-
-import com.jogamp.common.JogampRuntimeException;
-import com.jogamp.common.os.Platform;
-import com.jogamp.common.util.*;
-import com.jogamp.nativewindow.WrappedSurface;
-import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
-
-import jogamp.opengl.*;
-
+import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Set;
+
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.DefaultGraphicsScreen;
+import javax.media.nativewindow.MutableSurface;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+import javax.media.nativewindow.VisualIDHolder;
+import javax.media.opengl.GL;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesChooser;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
+
+import jogamp.nativewindow.WrappedSurface;
+import jogamp.opengl.Debug;
+import jogamp.opengl.GLContextImpl;
+import jogamp.opengl.GLDrawableFactoryImpl;
+import jogamp.opengl.GLDrawableImpl;
+import jogamp.opengl.GLDynamicLookupHelper;
+import jogamp.opengl.GLGraphicsConfigurationUtil;
+import jogamp.opengl.SharedResourceRunner;
+
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.common.nio.PointerBuffer;
+import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.ReflectionUtil;
+import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
+import com.jogamp.opengl.GLRendererQuirks;
public class EGLDrawableFactory extends GLDrawableFactoryImpl {
+ protected static final boolean DEBUG = GLDrawableFactoryImpl.DEBUG; // allow package access
+
+ /* package */ static final boolean QUERY_EGL_ES_NATIVE_TK;
+
+ static {
+ Debug.initSingleton();
+ QUERY_EGL_ES_NATIVE_TK = Debug.isPropertyDefined("jogl.debug.EGLDrawableFactory.QueryNativeTK", true);
+ }
+
private static GLDynamicLookupHelper eglES1DynamicLookupHelper = null;
private static GLDynamicLookupHelper eglES2DynamicLookupHelper = null;
- private static boolean isANGLE = false;
-
+
private static final boolean isANGLE(GLDynamicLookupHelper dl) {
if(Platform.OSType.WINDOWS == Platform.OS_TYPE) {
- final boolean r = 0 != dl.dynamicLookupFunction("eglQuerySurfacePointerANGLE") ||
- 0 != dl.dynamicLookupFunction("glBlitFramebufferANGLE") ||
- 0 != dl.dynamicLookupFunction("glRenderbufferStorageMultisampleANGLE");
- return r;
+ return dl.isFunctionAvailable("eglQuerySurfacePointerANGLE") ||
+ dl.isFunctionAvailable("glBlitFramebufferANGLE") ||
+ dl.isFunctionAvailable("glRenderbufferStorageMultisampleANGLE");
} else {
return false;
}
}
-
+
+ private static final boolean includesES1(GLDynamicLookupHelper dl) {
+ return dl.isFunctionAvailable("glLoadIdentity") &&
+ dl.isFunctionAvailable("glEnableClientState") &&
+ dl.isFunctionAvailable("glColorPointer");
+ }
+
public EGLDrawableFactory() {
super();
-
+
// Register our GraphicsConfigurationFactory implementations
// The act of constructing them causes them to be registered
EGLGraphicsConfigurationFactory.registerFactory();
// Check for other underlying stuff ..
- if(NativeWindowFactory.TYPE_X11.equals(NativeWindowFactory.getNativeWindowType(true))) {
+ if(NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(true)) {
+ hasX11 = true;
try {
ReflectionUtil.createInstance("jogamp.opengl.x11.glx.X11GLXGraphicsConfigurationFactory", EGLDrawableFactory.class.getClassLoader());
- } catch (JogampRuntimeException jre) { /* n/a .. */ }
+ } catch (Exception jre) { /* n/a .. */ }
}
- defaultDevice = new EGLGraphicsDevice(AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
-
- // FIXME: Probably need to move EGL from a static model
- // to a dynamic one, where there can be 2 instances
+ // FIXME: Probably need to move EGL from a static model
+ // to a dynamic one, where there can be 2 instances
// for each ES profile with their own ProcAddressTable.
synchronized(EGLDrawableFactory.class) {
- /**
- * Currently AMD's EGL impl. crashes at eglGetDisplay(EGL_DEFAULT_DISPLAY)
- *
- // Check Desktop ES2 Availability first (AMD, ..)
- if(null==eglES2DynamicLookupHelper) {
- GLDynamicLookupHelper tmp=null;
- try {
- tmp = new GLDynamicLookupHelper(new DesktopES2DynamicLibraryBundleInfo());
- } catch (GLException gle) {
- if(DEBUG) {
- gle.printStackTrace();
- }
- }
- if(null!=tmp && tmp.isLibComplete()) {
- eglES2DynamicLookupHelper = tmp;
- EGL.resetProcAddressTable(eglES2DynamicLookupHelper);
- if (GLProfile.DEBUG) {
- System.err.println("Info: EGLDrawableFactory: Desktop ES2 - OK");
- }
- } else if (GLProfile.DEBUG) {
- System.err.println("Info: EGLDrawableFactory: Desktop ES2 - NOPE");
- }
- } */
final boolean hasDesktopES2 = null != eglES2DynamicLookupHelper;
-
+
if(!hasDesktopES2 && null==eglES1DynamicLookupHelper) {
GLDynamicLookupHelper tmp=null;
try {
@@ -124,18 +140,18 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
if(DEBUG) {
gle.printStackTrace();
}
- }
+ }
if(null!=tmp && tmp.isLibComplete()) {
eglES1DynamicLookupHelper = tmp;
EGL.resetProcAddressTable(eglES1DynamicLookupHelper);
final boolean isANGLEES1 = isANGLE(eglES1DynamicLookupHelper);
isANGLE |= isANGLEES1;
- if (GLProfile.DEBUG) {
+ if (DEBUG || GLProfile.DEBUG) {
System.err.println("Info: EGLDrawableFactory: EGL ES1 - OK, isANGLE: "+isANGLEES1);
- }
- } else if (GLProfile.DEBUG) {
- System.err.println("Info: EGLDrawableFactory: EGL ES1 - NOPE");
- }
+ }
+ } else if (DEBUG || GLProfile.DEBUG) {
+ System.err.println("Info: EGLDrawableFactory: EGL ES1 - NOPE (ES1 lib)");
+ }
}
if(!hasDesktopES2 && null==eglES2DynamicLookupHelper) {
GLDynamicLookupHelper tmp=null;
@@ -145,196 +161,545 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
if(DEBUG) {
gle.printStackTrace();
}
- }
+ }
if(null!=tmp && tmp.isLibComplete()) {
eglES2DynamicLookupHelper = tmp;
EGL.resetProcAddressTable(eglES2DynamicLookupHelper);
+ final boolean includesES1 = null == eglES1DynamicLookupHelper && includesES1(eglES2DynamicLookupHelper);
+ if(includesES1) {
+ eglES1DynamicLookupHelper = tmp;
+ }
final boolean isANGLEES2 = isANGLE(eglES2DynamicLookupHelper);
isANGLE |= isANGLEES2;
- if (GLProfile.DEBUG) {
- System.err.println("Info: EGLDrawableFactory: EGL ES2 - OK, isANGLE: "+isANGLEES2);
- }
- } else if (GLProfile.DEBUG) {
+ if (DEBUG || GLProfile.DEBUG) {
+ System.err.println("Info: EGLDrawableFactory: EGL ES2 - OK (includesES1 "+includesES1+", isANGLE: "+isANGLEES2+")");
+ if(includesES1) {
+ System.err.println("Info: EGLDrawableFactory: EGL ES1 - OK (ES2 lib)");
+ }
+ }
+ } else if (DEBUG || GLProfile.DEBUG) {
System.err.println("Info: EGLDrawableFactory: EGL ES2 - NOPE");
- }
+ }
+ }
+ if( null != eglES2DynamicLookupHelper || null != eglES1DynamicLookupHelper ) {
+ if(isANGLE && !enableANGLE) {
+ if(DEBUG || GLProfile.DEBUG) {
+ System.err.println("Info: EGLDrawableFactory.init - EGL/ES2 ANGLE disabled");
+ }
+ } else {
+ if( isANGLE && ( DEBUG || GLProfile.DEBUG ) ) {
+ System.err.println("Info: EGLDrawableFactory.init - EGL/ES2 ANGLE enabled");
+ }
+ sharedMap = new HashMap<String /*uniqueKey*/, SharedResource>();
+ sharedMapCreateAttempt = new HashSet<String>();
+ // FIXME: defaultDevice.open() triggers eglInitialize(..) which crashed on Windows w/ Chrome/ANGLE, FF/ANGLE!
+ defaultDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
+ }
}
}
}
- protected final void destroy(ShutdownType shutdownType) {
+ @Override
+ protected final boolean isComplete() {
+ return null != sharedMap; // null != eglES2DynamicLookupHelper || null != eglES1DynamicLookupHelper;
+ }
+
+
+ @Override
+ protected final void shutdownImpl() {
+ if( DEBUG ) {
+ System.err.println("EGLDrawableFactory.shutdown");
+ }
if(null != sharedMap) {
+ if(DEBUG) {
+ dumpMap();
+ }
Collection<SharedResource> srl = sharedMap.values();
for(Iterator<SharedResource> sri = srl.iterator(); sri.hasNext(); ) {
SharedResource sr = sri.next();
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);
+ System.err.println("EGLDrawableFactory.shutdown: "+sr.device.toString());
}
+ sr.device.close();
}
sharedMap.clear();
+ sharedMapCreateAttempt.clear();
sharedMap = null;
+ sharedMapCreateAttempt = null;
+ }
+ if(null != defaultSharedResource) {
+ defaultSharedResource = null;
+ }
+ if(null != defaultDevice) {
+ defaultDevice.close();
+ defaultDevice = null;
}
- defaultDevice = null;
/**
* Pulling away the native library may cause havoc ..
*/
- if(ShutdownType.COMPLETE == shutdownType) {
- if(null != eglES1DynamicLookupHelper) {
- // eglES1DynamicLookupHelper.destroy();
- eglES1DynamicLookupHelper = null;
- }
- if(null != eglES2DynamicLookupHelper) {
- // eglES2DynamicLookupHelper.destroy();
- eglES2DynamicLookupHelper = null;
- }
+ if(null != eglES1DynamicLookupHelper) {
+ // eglES1DynamicLookupHelper.destroy();
+ eglES1DynamicLookupHelper = null;
+ }
+ if(null != eglES2DynamicLookupHelper) {
+ // eglES2DynamicLookupHelper.destroy();
+ eglES2DynamicLookupHelper = null;
}
EGLGraphicsConfigurationFactory.unregisterFactory();
+ EGLDisplayUtil.shutdown(DEBUG);
+ }
+
+ private void dumpMap() {
+ synchronized(sharedMap) {
+ System.err.println("EGLDrawableFactory.map "+sharedMap.size());
+ int i=0;
+ Set<String> keys = sharedMap.keySet();
+ for(Iterator<String> keyI = keys.iterator(); keyI.hasNext(); i++) {
+ String key = keyI.next();
+ SharedResource sr = sharedMap.get(key);
+ System.err.println("EGLDrawableFactory.map["+i+"] "+key+" -> "+sr.getDevice()+", "+
+ "es1 [avail "+sr.wasES1ContextCreated+", pbuffer "+sr.hasPBufferES1+", quirks "+sr.rendererQuirksES1+", ctp "+EGLContext.getGLVersion(1, 0, sr.ctpES1, null)+"], "+
+ "es2/3 [es2 "+sr.wasES2ContextCreated+", es3 "+sr.wasES3ContextCreated+", [pbuffer "+sr.hasPBufferES3ES2+", quirks "+sr.rendererQuirksES3ES2+", ctp "+EGLContext.getGLVersion(2, 0, sr.ctpES3ES2, null)+"]]");
+ }
+ ;
+ }
}
- private HashMap<String /*connection*/, SharedResource> sharedMap = new HashMap<String /*connection*/, SharedResource>();
- private EGLGraphicsDevice defaultDevice;
+ private HashMap<String /*uniqueKey*/, SharedResource> sharedMap = null;
+ private HashSet<String> sharedMapCreateAttempt = null;
+ private EGLGraphicsDevice defaultDevice = null;
+ private SharedResource defaultSharedResource = null;
+ private boolean isANGLE = false;
+ private boolean hasX11 = false;
- static class SharedResource {
+ static class SharedResource implements SharedResourceRunner.Resource {
private final EGLGraphicsDevice device;
- // private final EGLDrawable drawable;
// private final EGLContext contextES1;
// private final EGLContext contextES2;
+ // private final EGLContext contextES3;
private final boolean wasES1ContextCreated;
private final boolean wasES2ContextCreated;
+ private final boolean wasES3ContextCreated;
+ private final GLRendererQuirks rendererQuirksES1;
+ private final GLRendererQuirks rendererQuirksES3ES2;
+ private final int ctpES1;
+ private final int ctpES3ES2;
+ private final boolean hasPBufferES1;
+ private final boolean hasPBufferES3ES2;
- SharedResource(EGLGraphicsDevice dev, boolean wasContextES1Created, boolean wasContextES2Created
- /*EGLDrawable draw, EGLContext ctxES1, EGLContext ctxES2 */) {
+ SharedResource(EGLGraphicsDevice dev,
+ boolean wasContextES1Created, boolean hasPBufferES1, GLRendererQuirks rendererQuirksES1, int ctpES1,
+ boolean wasContextES2Created, boolean wasContextES3Created,
+ boolean hasPBufferES3ES2, GLRendererQuirks rendererQuirksES3ES2, int ctpES3ES2) {
this.device = dev;
- // this.drawable = draw;
// this.contextES1 = ctxES1;
- // this.contextES2 = ctxES2;
this.wasES1ContextCreated = wasContextES1Created;
+ this.hasPBufferES1= hasPBufferES1;
+ this.rendererQuirksES1 = rendererQuirksES1;
+ this.ctpES1 = ctpES1;
+
+ // this.contextES2 = ctxES2;
+ // this.contextES3 = ctxES3;
this.wasES2ContextCreated = wasContextES2Created;
+ this.wasES3ContextCreated = wasContextES3Created;
+ this.hasPBufferES3ES2= hasPBufferES3ES2;
+ this.rendererQuirksES3ES2 = rendererQuirksES3ES2;
+ this.ctpES3ES2 = ctpES3ES2;
}
- final EGLGraphicsDevice getDevice() { return device; }
- // final EGLDrawable getDrawable() { return drawable; }
+ @Override
+ public final boolean isValid() {
+ return wasES1ContextCreated || wasES2ContextCreated || wasES3ContextCreated;
+ }
+ @Override
+ public final EGLGraphicsDevice getDevice() { return device; }
// final EGLContext getContextES1() { return contextES1; }
// final EGLContext getContextES2() { return contextES2; }
- final boolean wasES1ContextAvailable() { return wasES1ContextCreated; }
- final boolean wasES2ContextAvailable() { return wasES2ContextCreated; }
+ // final EGLContext getContextES3() { return contextES3; }
+
+ @Override
+ public AbstractGraphicsScreen getScreen() {
+ return null;
+ }
+ @Override
+ public GLDrawableImpl getDrawable() {
+ return null;
+ }
+ @Override
+ public GLContextImpl getContext() {
+ return null;
+ }
+ @Override
+ public GLRendererQuirks getRendererQuirks() {
+ return null != rendererQuirksES3ES2 ? rendererQuirksES3ES2 : rendererQuirksES1 ;
+ }
}
+ @Override
public final AbstractGraphicsDevice getDefaultDevice() {
return defaultDevice;
}
+ @Override
public final boolean getIsDeviceCompatible(AbstractGraphicsDevice device) {
// via mappings (X11/WGL/.. -> EGL) we shall be able to handle all types.
- return null!=eglES2DynamicLookupHelper || null!=eglES1DynamicLookupHelper;
+ return null != sharedMap ; // null!=eglES2DynamicLookupHelper || null!=eglES1DynamicLookupHelper;
}
- /**
- private boolean isEGLContextAvailable(EGLGraphicsDevice sharedDevice, String profile) {
- boolean madeCurrent = false;
- final GLCapabilities caps = new GLCapabilities(GLProfile.get(profile));
- caps.setRedBits(5); caps.setGreenBits(5); caps.setBlueBits(5); caps.setAlphaBits(0);
- caps.setDoubleBuffered(false);
- caps.setOnscreen(false);
- caps.setPBuffer(true);
- final EGLDrawable drawable = (EGLDrawable) createGLDrawable( createOffscreenSurfaceImpl(sharedDevice, caps, caps, null, 64, 64) );
- if(null!=drawable) {
- final EGLContext context = (EGLContext) drawable.createContext(null);
- if (null != context) {
- context.setSynchronized(true);
- try {
- context.makeCurrent(); // could cause exception
- madeCurrent = context.isCurrent();
- } catch (GLException gle) {
- if (DEBUG) {
- System.err.println("EGLDrawableFactory.createShared: INFO: makeCurrent failed");
- gle.printStackTrace();
- }
- } finally {
- context.destroy();
- }
+ private static List<GLCapabilitiesImmutable> getAvailableEGLConfigs(EGLGraphicsDevice eglDisplay, GLCapabilitiesImmutable caps) {
+ final IntBuffer numConfigs = Buffers.newDirectIntBuffer(1);
+ if(!EGL.eglGetConfigs(eglDisplay.getHandle(), null, 0, numConfigs)) {
+ throw new GLException("EGLDrawableFactory.getAvailableEGLConfigs: Get maxConfigs (eglGetConfigs) call failed, error "+EGLContext.toHexString(EGL.eglGetError()));
+ }
+ if(0 < numConfigs.get(0)) {
+ final PointerBuffer configs = PointerBuffer.allocateDirect(numConfigs.get(0));
+ final IntBuffer attrs = EGLGraphicsConfiguration.GLCapabilities2AttribList(caps);
+ final int winattrmask = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(caps);
+ if( EGL.eglChooseConfig(eglDisplay.getHandle(), attrs, configs, configs.capacity(), numConfigs) && numConfigs.get(0) > 0) {
+ return EGLGraphicsConfigurationFactory.eglConfigs2GLCaps(eglDisplay, caps.getGLProfile(), configs, numConfigs.get(0), winattrmask, false /* forceTransparentFlag */, false /* onlyFirstValid */);
}
- drawable.destroy();
}
- return madeCurrent;
- } */
-
- /* package */ SharedResource getOrCreateEGLSharedResource(AbstractGraphicsDevice adevice) {
- if(null == eglES1DynamicLookupHelper && null == eglES2DynamicLookupHelper) {
- return null;
+ return new ArrayList<GLCapabilitiesImmutable>(0);
+ }
+
+ private static void dumpEGLInfo(final String prefix, final long eglDisplay) {
+ final String eglVendor = EGL.eglQueryString(eglDisplay, EGL.EGL_VENDOR);
+ final String eglClientAPIs = EGL.eglQueryString(eglDisplay, EGL.EGL_CLIENT_APIS);
+ final String eglVersion = EGL.eglQueryString(eglDisplay, EGL.EGL_VERSION);
+ System.err.println(prefix+"EGL vendor "+eglVendor+", version "+eglVersion+", clientAPIs "+eglClientAPIs);
+ }
+
+ private boolean mapAvailableEGLESConfig(AbstractGraphicsDevice adevice, int[] esProfile,
+ boolean[] hasPBuffer, GLRendererQuirks[] rendererQuirks, int[] ctp) {
+ final String profileString;
+ switch( esProfile[0] ) {
+ case 3:
+ profileString = GLProfile.GLES3; break;
+ case 2:
+ profileString = GLProfile.GLES2; break;
+ case 1:
+ profileString = GLProfile.GLES1; break;
+ default:
+ throw new GLException("Invalid ES profile number "+esProfile);
}
- String connection = adevice.getConnection();
- SharedResource sr;
- synchronized(sharedMap) {
- sr = (SharedResource) 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 ( !GLProfile.isAvailable(adevice, profileString) ) {
+ if( DEBUG ) {
+ System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig: "+profileString+" n/a on "+adevice);
}
- if (!EGLDisplayUtil.eglInitialize(eglDisplay, null, null)) {
- throw new GLException("eglInitialize failed"+", error 0x"+Integer.toHexString(EGL.eglGetError()));
+ return false;
+ }
+ final GLProfile glp = GLProfile.get(adevice, profileString) ;
+ final GLDrawableFactoryImpl desktopFactory = (GLDrawableFactoryImpl) GLDrawableFactory.getDesktopFactory();
+ final boolean initDefaultDevice = 0 == defaultDevice.getHandle(); // Note: GLProfile always triggers EGL device initialization first!
+ final boolean mapsADeviceToDefaultDevice = !QUERY_EGL_ES_NATIVE_TK || initDefaultDevice ||
+ null == desktopFactory || adevice instanceof EGLGraphicsDevice ;
+ if( DEBUG ) {
+ System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig: "+profileString+" ( "+esProfile+" ), "+
+ "defaultSharedResourceSet "+(null!=defaultSharedResource)+", mapsADeviceToDefaultDevice "+mapsADeviceToDefaultDevice+
+ " (QUERY_EGL_ES_NATIVE_TK "+QUERY_EGL_ES_NATIVE_TK+", hasDesktopFactory "+(null != desktopFactory)+
+ ", isEGLGraphicsDevice "+(adevice instanceof EGLGraphicsDevice)+")");
+ }
+
+ EGLGraphicsDevice eglDevice = null;
+ NativeSurface surface = null;
+ ProxySurface upstreamSurface = null; // X11, GLX, ..
+ ProxySurface downstreamSurface = null; // EGL
+ boolean success = false;
+ try {
+ final GLCapabilities reqCapsAny = new GLCapabilities(glp);
+ reqCapsAny.setRedBits(5); reqCapsAny.setGreenBits(5); reqCapsAny.setBlueBits(5); reqCapsAny.setAlphaBits(0);
+ reqCapsAny.setDoubleBuffered(false);
+
+ if( mapsADeviceToDefaultDevice ) {
+ // In this branch, any non EGL device is mapped to EGL default shared resources (default behavior).
+ // Only one default shared resource instance is ever be created.
+ if( initDefaultDevice ) {
+ defaultDevice.open();
+
+ // Probe for GLRendererQuirks.SingletonEGLDisplayOnly
+ final long secondEGLDisplay = EGL.eglGetDisplay(EGL.EGL_DEFAULT_DISPLAY);
+ if ( EGL.EGL_NO_DISPLAY == secondEGLDisplay ) {
+ final int[] quirks = { GLRendererQuirks.SingletonEGLDisplayOnly };
+ GLRendererQuirks.addStickyDeviceQuirks(adevice, quirks, 0, 1);
+ EGLDisplayUtil.setSingletonEGLDisplayOnly(true);
+ if(DEBUG) {
+ System.err.println("Quirk: "+GLRendererQuirks.toString(quirks[0])+": cause: Second eglGetDisplay(EGL_DEFAULT_DISPLAY) failed");
+ }
+ }
+ }
+ if( DEBUG ) {
+ dumpEGLInfo("EGLDrawableFactory.mapAvailableEGLESConfig: ", defaultDevice.getHandle());
+ }
+
+ final GLCapabilitiesImmutable reqCapsPBuffer = GLGraphicsConfigurationUtil.fixGLPBufferGLCapabilities(reqCapsAny);
+ final List<GLCapabilitiesImmutable> availablePBufferCapsL = getAvailableEGLConfigs(defaultDevice, reqCapsPBuffer);
+ hasPBuffer[0] = availablePBufferCapsL.size() > 0;
+
+ // 1st case: adevice is not the EGL default device, map default shared resources
+ if( adevice != defaultDevice ) {
+ if(null == defaultSharedResource) {
+ return false;
+ }
+ switch(esProfile[0]) {
+ case 3:
+ if( !defaultSharedResource.wasES3ContextCreated ) {
+ return false;
+ }
+ rendererQuirks[0] = defaultSharedResource.rendererQuirksES3ES2;
+ ctp[0] = defaultSharedResource.ctpES3ES2;
+ break;
+ case 2:
+ if( !defaultSharedResource.wasES2ContextCreated ) {
+ return false;
+ }
+ rendererQuirks[0] = defaultSharedResource.rendererQuirksES3ES2;
+ ctp[0] = defaultSharedResource.ctpES3ES2;
+ break;
+ case 1:
+ if( !defaultSharedResource.wasES1ContextCreated ) {
+ return false;
+ }
+ rendererQuirks[0] = defaultSharedResource.rendererQuirksES1;
+ ctp[0] = defaultSharedResource.ctpES1;
+ break;
+ }
+ if( null != rendererQuirks[0] ) {
+ GLRendererQuirks.addStickyDeviceQuirks(adevice, rendererQuirks[0]);
+ }
+ EGLContext.mapStaticGLVersion(adevice, esProfile[0], 0, ctp[0]);
+ return true;
+ }
+
+ // attempt to created the default shared resources ..
+
+ if( hasPBuffer[0] ) {
+ // 2nd case create defaultDevice shared resource using pbuffer surface
+ downstreamSurface = createDummySurfaceImpl(defaultDevice, false, reqCapsPBuffer, reqCapsPBuffer, null, 64, 64); // egl pbuffer offscreen
+ if( null != downstreamSurface ) {
+ downstreamSurface.createNotify();
+ }
+ surface = downstreamSurface;
+ } else {
+ // 3rd case fake creation of defaultDevice shared resource, no pbuffer available
+ final List<GLCapabilitiesImmutable> capsAnyL = getAvailableEGLConfigs(defaultDevice, reqCapsAny);
+ if(capsAnyL.size() > 0) {
+ final GLCapabilitiesImmutable chosenCaps = capsAnyL.get(0);
+ EGLContext.mapStaticGLESVersion(defaultDevice, chosenCaps);
+ success = true;
+ }
+ if(DEBUG) {
+ System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig() no pbuffer config available, detected !pbuffer config: "+success);
+ EGLGraphicsConfigurationFactory.printCaps("!PBufferCaps", capsAnyL, System.err);
+ }
+ }
+ eglDevice = defaultDevice; // reuse
+ } else {
+ // 4th case always creates a true mapping of given device to EGL
+ upstreamSurface = desktopFactory.createDummySurface(adevice, reqCapsAny, null, 64, 64); // X11, WGL, .. dummy window
+ if(null != upstreamSurface) {
+ upstreamSurface.createNotify();
+ }
+ surface = upstreamSurface;
+ eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(surface);
+ eglDevice.open();
+ if( DEBUG ) {
+ dumpEGLInfo("EGLDrawableFactory.mapAvailableEGLESConfig: ", eglDevice.getHandle());
+ }
+ hasPBuffer[0] = true;
}
- final EGLGraphicsDevice sharedDevice = new EGLGraphicsDevice(eglDisplay, connection, adevice.getUnitID());
- // final boolean madeCurrentES1 = isEGLContextAvailable(sharedDevice, GLProfile.GLES1);
- // final boolean madeCurrentES2 = isEGLContextAvailable(sharedDevice, GLProfile.GLES2);
- final boolean madeCurrentES1 = true; // FIXME
- final boolean madeCurrentES2 = true; // FIXME
- sr = new SharedResource(sharedDevice, madeCurrentES1, madeCurrentES2);
- synchronized(sharedMap) {
- sharedMap.put(connection, sr);
+
+ if(null != surface) {
+ final EGLDrawable drawable = (EGLDrawable) createOnscreenDrawableImpl ( surface ); // works w/ implicit pbuffer surface via proxy-hook
+ drawable.setRealized(true);
+ final EGLContext context = (EGLContext) drawable.createContext(null);
+ if (null != context) {
+ try {
+ context.makeCurrent(); // could cause exception
+ if(context.isCurrent()) {
+ final String glVersion = context.getGL().glGetString(GL.GL_VERSION);
+ if(null != glVersion) {
+ context.mapCurrentAvailableGLVersion(eglDevice);
+ if(eglDevice != adevice) {
+ context.mapCurrentAvailableGLVersion(adevice);
+ }
+ rendererQuirks[0] = context.getRendererQuirks();
+ ctp[0] = context.getContextOptions();
+ esProfile[0] = context.getGLVersionNumber().getMajor();
+ success = true;
+ } else {
+ // Oops .. something is wrong
+ if(DEBUG) {
+ System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig: "+eglDevice+", "+context.getGLVersion()+" - VERSION is null, dropping availability!");
+ }
+ }
+ }
+ } catch (Throwable t) {
+ if (DEBUG) {
+ System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig: INFO: context create/makeCurrent failed");
+ t.printStackTrace();
+ }
+ } finally {
+ context.destroy();
+ }
+ }
+ drawable.setRealized(false);
+ }
+ } catch (Throwable t) {
+ if(DEBUG) {
+ System.err.println("Catched Exception on thread "+getThreadName());
+ t.printStackTrace();
+ }
+ success = false;
+ } finally {
+ if(null != downstreamSurface) {
+ downstreamSurface.destroyNotify();
+ }
+ if( defaultDevice != eglDevice ) { // don't close default device
+ if(null != eglDevice) {
+ eglDevice.close();
+ }
+ if(null != upstreamSurface) {
+ upstreamSurface.destroyNotify();
+ }
}
- if (DEBUG) {
- System.err.println("EGLDrawableFactory.createShared: device: " + sharedDevice);
- System.err.println("EGLDrawableFactory.createShared: context ES1: " + madeCurrentES1);
- System.err.println("EGLDrawableFactory.createShared: context ES2: " + madeCurrentES2);
- }
}
- return sr;
+ return success;
}
- protected final Thread getSharedResourceThread() {
- return null;
+ private final boolean needsToCreateSharedResource(String key, SharedResource[] existing) {
+ synchronized(sharedMap) {
+ final SharedResource sr = sharedMap.get(key);
+ if( null == sr ) {
+ final boolean createAttempted = sharedMapCreateAttempt.contains(key);
+ if(!createAttempted) {
+ sharedMapCreateAttempt.add(key);
+ }
+ return !createAttempted;
+ } else {
+ if(null != existing) {
+ existing[0] = sr;
+ }
+ return false;
+ }
+ }
}
-
- protected final boolean createSharedResource(AbstractGraphicsDevice device) {
- try {
- SharedResource sr = getOrCreateEGLSharedResource(device);
- if(null!=sr) {
- return sr.wasES1ContextAvailable() || sr.wasES2ContextAvailable();
+
+ @Override
+ protected final SharedResource getOrCreateSharedResourceImpl(AbstractGraphicsDevice adevice) {
+ if(null == sharedMap) { // null == eglES1DynamicLookupHelper && null == eglES2DynamicLookupHelper
+ return null;
+ }
+
+ if( needsToCreateSharedResource(defaultDevice.getUniqueID(), null) ) {
+ if (DEBUG) {
+ System.err.println("EGLDrawableFactory.createShared: (defaultDevice): req. device: "+adevice+", defaultDevice "+defaultDevice);
+ Thread.dumpStack();
}
- } catch (GLException gle) {
- if(DEBUG) {
- System.err.println("Catched Exception while EGL Shared Resource initialization");
- gle.printStackTrace();
+ if(null != defaultSharedResource) {
+ dumpMap();
+ throw new InternalError("defaultSharedResource already exist: "+defaultSharedResource);
}
+ defaultSharedResource = createEGLSharedResourceImpl(defaultDevice);
+ }
+
+ final String key = adevice.getUniqueID();
+ if( defaultDevice.getUniqueID().equals(key) ) {
+ return defaultSharedResource;
+ } else {
+ if( null == defaultSharedResource) { // defaultDevice must be initialized before host-device
+ dumpMap();
+ throw new InternalError("defaultSharedResource does not exist");
+ }
+ final SharedResource[] existing = new SharedResource[] { null };
+ if ( !needsToCreateSharedResource(key, existing) ) {
+ return existing[0];
+ }
+ return createEGLSharedResourceImpl(adevice);
}
- return false;
}
-
- protected final GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device) {
- return null; // n/a for EGL .. since we don't keep the resources
+
+ private SharedResource createEGLSharedResourceImpl(AbstractGraphicsDevice adevice) {
+ final boolean madeCurrentES1;
+ boolean[] hasPBufferES1 = new boolean[] { false };
+ boolean[] hasPBufferES3ES2 = new boolean[] { false };
+ // EGLContext[] eglCtxES1 = new EGLContext[] { null };
+ // EGLContext[] eglCtxES2 = new EGLContext[] { null };
+ GLRendererQuirks[] rendererQuirksES1 = new GLRendererQuirks[] { null };
+ GLRendererQuirks[] rendererQuirksES3ES2 = new GLRendererQuirks[] { null };
+ int[] ctpES1 = new int[] { -1 };
+ int[] ctpES3ES2 = new int[] { -1 };
+
+
+ if (DEBUG) {
+ System.err.println("EGLDrawableFactory.createShared(): device "+adevice);
+ }
+
+ if( null != eglES1DynamicLookupHelper ) {
+ final int[] esProfile = { 1 };
+ madeCurrentES1 = mapAvailableEGLESConfig(adevice, esProfile, hasPBufferES1, rendererQuirksES1, ctpES1) && 1 == esProfile[0];
+ } else {
+ madeCurrentES1 = false;
+ }
+ boolean madeCurrentES2 = false;
+ boolean madeCurrentES3 = false;
+ if( null != eglES2DynamicLookupHelper ) {
+ // ES3 Query
+ final int[] esProfile = { 3 };
+ madeCurrentES3 = mapAvailableEGLESConfig(adevice, esProfile, hasPBufferES3ES2, rendererQuirksES3ES2, ctpES3ES2) && 3 == esProfile[0];
+ if( !madeCurrentES3 ) {
+ // ES2 Query, may result in ES3
+ esProfile[0] = 2;
+ if( mapAvailableEGLESConfig(adevice, esProfile, hasPBufferES3ES2, rendererQuirksES3ES2, ctpES3ES2) ) {
+ switch( esProfile[0] ) {
+ case 2: madeCurrentES2 = true; break;
+ case 3: madeCurrentES3 = true; break;
+ default: throw new InternalError("XXXX Got "+esProfile[0]);
+ }
+ }
+ }
+ }
+ if( !EGLContext.getAvailableGLVersionsSet(adevice) ) {
+ // Even though we override the non EGL native mapping intentionally,
+ // avoid exception due to double 'set' - carefull exception of the rule.
+ EGLContext.setAvailableGLVersionsSet(adevice);
+ }
+ if( hasX11 ) {
+ handleDontCloseX11DisplayQuirk(rendererQuirksES1[0]);
+ handleDontCloseX11DisplayQuirk(rendererQuirksES3ES2[0]);
+ }
+ final SharedResource sr = new SharedResource(defaultDevice, madeCurrentES1, hasPBufferES1[0], rendererQuirksES1[0], ctpES1[0],
+ madeCurrentES2, madeCurrentES3, hasPBufferES3ES2[0], rendererQuirksES3ES2[0], ctpES3ES2[0]);
+
+ synchronized(sharedMap) {
+ sharedMap.put(adevice.getUniqueID(), sr);
+ }
+ if (DEBUG) {
+ System.err.println("EGLDrawableFactory.createShared: devices: queried nativeTK "+QUERY_EGL_ES_NATIVE_TK+", adevice " + adevice + ", defaultDevice " + defaultDevice);
+ System.err.println("EGLDrawableFactory.createShared: context ES1: " + madeCurrentES1 + ", hasPBuffer "+hasPBufferES1[0]+", quirks "+rendererQuirksES1[0]);
+ System.err.println("EGLDrawableFactory.createShared: context ES2: " + madeCurrentES2 + ", hasPBuffer "+hasPBufferES3ES2[0]+", quirks "+rendererQuirksES3ES2[0]);
+ System.err.println("EGLDrawableFactory.createShared: context ES3: " + madeCurrentES3 + ", hasPBuffer "+hasPBufferES3ES2[0]+", quirks "+rendererQuirksES3ES2[0]);
+ dumpMap();
+ }
+ return sr;
}
-
- protected AbstractGraphicsDevice getOrCreateSharedDeviceImpl(AbstractGraphicsDevice device) {
- SharedResource sr = getOrCreateEGLSharedResource(device);
- if(null!=sr) {
- return sr.getDevice();
+
+ private void handleDontCloseX11DisplayQuirk(GLRendererQuirks quirks) {
+ if( null != quirks && quirks.exist( GLRendererQuirks.DontCloseX11Display ) ) {
+ jogamp.nativewindow.x11.X11Util.markAllDisplaysUnclosable();
}
+ }
+
+ @Override
+ protected final Thread getSharedResourceThread() {
return null;
}
- public boolean isANGLE() {
+ public final boolean isANGLE() {
return isANGLE;
}
-
+
+ @Override
public GLDynamicLookupHelper getGLDynamicLookupHelper(int esProfile) {
- if (2==esProfile) {
+ if ( 2==esProfile || 3==esProfile ) {
return eglES2DynamicLookupHelper;
} else if (1==esProfile) {
return eglES1DynamicLookupHelper;
@@ -343,20 +708,23 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
}
}
+ @Override
protected List<GLCapabilitiesImmutable> getAvailableCapabilitiesImpl(AbstractGraphicsDevice device) {
- if(null == eglES1DynamicLookupHelper && null == eglES2DynamicLookupHelper) {
+ if(null == sharedMap) { // null == eglES1DynamicLookupHelper && null == eglES2DynamicLookupHelper
return new ArrayList<GLCapabilitiesImmutable>(); // null
}
return EGLGraphicsConfigurationFactory.getAvailableCapabilities(this, device);
}
+ @Override
protected GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) {
if (target == null) {
throw new IllegalArgumentException("Null target");
}
- return new EGLOnscreenDrawable(this, target);
+ return new EGLOnscreenDrawable(this, EGLWrappedSurface.get(target));
}
+ @Override
protected GLDrawableImpl createOffscreenDrawableImpl(NativeSurface target) {
if (target == null) {
throw new IllegalArgumentException("Null target");
@@ -367,47 +735,104 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
throw new GLException("Non pbuffer not yet implemented");
}
// PBuffer GLDrawable Creation
- return new EGLPbufferDrawable(this, target);
+ return new EGLPbufferDrawable(this, EGLWrappedSurface.get(target));
}
- public boolean canCreateGLPbuffer(AbstractGraphicsDevice device) {
+ @Override
+ public boolean canCreateGLPbuffer(AbstractGraphicsDevice device, GLProfile glp) {
+ // SharedResource sr = getOrCreateEGLSharedResource(device);
+ // return sr.hasES1PBuffer() || sr.hasES2PBuffer();
return true;
}
- protected NativeSurface createOffscreenSurfaceImpl(AbstractGraphicsDevice device, GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, int width, int height) {
- WrappedSurface ns = new WrappedSurface(EGLGraphicsConfigurationFactory.createOffscreenGraphicsConfiguration(device, capsChosen, capsRequested, chooser));
- ns.surfaceSizeChanged(width, height);
- return ns;
+ @Override
+ protected ProxySurface createMutableSurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice,
+ GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested,
+ GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstreamHook) {
+ final boolean ownDevice;
+ final EGLGraphicsDevice device;
+ if( createNewDevice || ! (deviceReq instanceof EGLGraphicsDevice) ) {
+ final long nativeDisplayID = ( deviceReq instanceof EGLGraphicsDevice) ?
+ ( (EGLGraphicsDevice) deviceReq ).getNativeDisplayID() : deviceReq.getHandle() ;
+ device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(nativeDisplayID, deviceReq.getConnection(), deviceReq.getUnitID());
+ device.open();
+ ownDevice = true;
+ } else {
+ device = (EGLGraphicsDevice) deviceReq;
+ ownDevice = false;
+ }
+ final DefaultGraphicsScreen screen = new DefaultGraphicsScreen(device, 0);
+ final EGLGraphicsConfiguration config = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen, VisualIDHolder.VID_UNDEFINED, false);
+ if(null == config) {
+ throw new GLException("Choosing GraphicsConfiguration failed w/ "+capsChosen+" on "+screen);
+ }
+ return new WrappedSurface(config, 0, upstreamHook, ownDevice);
+ }
+
+ @Override
+ public final ProxySurface createDummySurfaceImpl(AbstractGraphicsDevice deviceReq, boolean createNewDevice,
+ GLCapabilitiesImmutable chosenCaps, GLCapabilitiesImmutable requestedCaps, GLCapabilitiesChooser chooser, int width, int height) {
+ chosenCaps = GLGraphicsConfigurationUtil.fixGLPBufferGLCapabilities(chosenCaps); // complete validation in EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(..) above
+ return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, new EGLDummyUpstreamSurfaceHook(width, height));
+ }
+
+ /**
+ * @param ms {@link MutableSurface} which dimensions and config are being used to create the pbuffer surface.
+ * It will also hold the resulting pbuffer surface handle.
+ * @param useTexture
+ * @return the passed {@link MutableSurface} which now has the EGL pbuffer surface set as it's handle
+ */
+ protected static MutableSurface createPBufferSurfaceImpl(MutableSurface ms, boolean useTexture) {
+ return null;
+ }
+ protected static long createPBufferSurfaceImpl(EGLGraphicsConfiguration config, int width, int height, boolean useTexture) {
+ final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) config.getScreen().getDevice();
+ final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
+ final int texFormat;
+
+ if(useTexture) {
+ texFormat = caps.getAlphaBits() > 0 ? EGL.EGL_TEXTURE_RGBA : EGL.EGL_TEXTURE_RGB ;
+ } else {
+ texFormat = EGL.EGL_NO_TEXTURE;
+ }
+
+ if (DEBUG) {
+ System.out.println("Pbuffer config: " + config);
+ }
+
+ final IntBuffer attrs = EGLGraphicsConfiguration.CreatePBufferSurfaceAttribList(width, height, texFormat);
+ final long surf = EGL.eglCreatePbufferSurface(eglDevice.getHandle(), config.getNativeConfig(), attrs);
+ if (EGL.EGL_NO_SURFACE==surf) {
+ throw new GLException("Creation of window surface (eglCreatePbufferSurface) failed, dim "+width+"x"+height+", "+eglDevice+", "+config+", error 0x"+Integer.toHexString(EGL.eglGetError()));
+ } else if(DEBUG) {
+ System.err.println("PBuffer setSurface result: eglSurface 0x"+Long.toHexString(surf));
+ }
+ return surf;
}
- protected ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice adevice, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) {
- // FIXME device/windowHandle -> screen ?!
- EGLGraphicsDevice device = (EGLGraphicsDevice) adevice;
- DefaultGraphicsScreen screen = new DefaultGraphicsScreen(device, 0);
- EGLGraphicsConfiguration cfg = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen, VisualIDHolder.VID_UNDEFINED, false);
- WrappedSurface ns = new WrappedSurface(cfg, windowHandle);
- return ns;
+ @Override
+ protected ProxySurface createProxySurfaceImpl(AbstractGraphicsDevice deviceReq, int screenIdx, long windowHandle, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream) {
+ final EGLGraphicsDevice eglDeviceReq = (EGLGraphicsDevice) deviceReq;
+ final EGLGraphicsDevice device = EGLDisplayUtil.eglCreateEGLGraphicsDevice(eglDeviceReq.getNativeDisplayID(), deviceReq.getConnection(), deviceReq.getUnitID());
+ device.open();
+ final DefaultGraphicsScreen screen = new DefaultGraphicsScreen(device, screenIdx);
+ final EGLGraphicsConfiguration cfg = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen, VisualIDHolder.VID_UNDEFINED, false);
+ return new WrappedSurface(cfg, windowHandle, upstream, true);
}
-
+
+ @Override
protected GLContext createExternalGLContextImpl() {
AbstractGraphicsScreen absScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_EGL);
return new EGLExternalContext(absScreen);
}
+ @Override
public boolean canCreateExternalGLDrawable(AbstractGraphicsDevice device) {
return false;
}
+ @Override
protected GLDrawable createExternalGLDrawableImpl() {
throw new GLException("Not yet implemented");
}
-
- public boolean canCreateContextOnJava2DSurface(AbstractGraphicsDevice device) {
- return false;
- }
-
- public GLContext createContextOnJava2DSurface(Object graphics, GLContext shareWith)
- throws GLException {
- throw new GLException("Unimplemented on this platform");
- }
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java b/src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java
new file mode 100644
index 000000000..818f32607
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java
@@ -0,0 +1,60 @@
+package jogamp.opengl.egl;
+
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+
+import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSize;
+import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
+
+/** Uses a PBuffer offscreen surface */
+public class EGLDummyUpstreamSurfaceHook extends UpstreamSurfaceHookMutableSize {
+ /**
+ * @param width the initial width as returned by {@link NativeSurface#getWidth()} via {@link UpstreamSurfaceHook#getWidth(ProxySurface)},
+ * not the actual dummy surface width.
+ * The latter is platform specific and small
+ * @param height the initial height as returned by {@link NativeSurface#getHeight()} via {@link UpstreamSurfaceHook#getHeight(ProxySurface)},
+ * not the actual dummy surface height,
+ * The latter is platform specific and small
+ */
+ public EGLDummyUpstreamSurfaceHook(int width, int height) {
+ super(width, height);
+ }
+
+ @Override
+ public final void create(ProxySurface s) {
+ final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) s.getGraphicsConfiguration().getScreen().getDevice();
+ eglDevice.lock();
+ try {
+ if(0 == eglDevice.getHandle()) {
+ eglDevice.open();
+ s.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE );
+ }
+ if( EGL.EGL_NO_SURFACE == s.getSurfaceHandle() ) {
+ s.setSurfaceHandle( EGLDrawableFactory.createPBufferSurfaceImpl((EGLGraphicsConfiguration)s.getGraphicsConfiguration(), 64, 64, false) );
+ s.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+ }
+ s.addUpstreamOptionBits(ProxySurface.OPT_UPSTREAM_WINDOW_INVISIBLE);
+ } finally {
+ eglDevice.unlock();
+ }
+ }
+
+ @Override
+ public final void destroy(ProxySurface s) {
+ if( s.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ) ) {
+ final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) s.getGraphicsConfiguration().getScreen().getDevice();
+ if( EGL.EGL_NO_SURFACE == s.getSurfaceHandle() ) {
+ throw new InternalError("Owns upstream surface, but no EGL surface: "+s);
+ }
+ eglDevice.lock();
+ try {
+ EGL.eglDestroySurface(eglDevice.getHandle(), s.getSurfaceHandle());
+ s.setSurfaceHandle(EGL.EGL_NO_SURFACE);
+ s.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+ } finally {
+ eglDevice.unlock();
+ }
+ }
+ }
+}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java
index fe9d7573d..ebe8f49c8 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java
@@ -3,14 +3,14 @@
*
* 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
@@ -20,15 +20,16 @@
* 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 jogamp.opengl.egl;
import com.jogamp.common.os.AndroidVersion;
+import com.jogamp.common.os.Platform;
import java.util.*;
@@ -38,10 +39,10 @@ import jogamp.opengl.*;
* Abstract implementation of the DynamicLookupHelper for EGL,
* which decouples it's dependencies to EGLDrawable.
*
- * Currently two implementations exist, one for ES1 and one for ES2.
+ * Currently two implementations exist, one for ES1 and one for ES3 and ES2.
*/
public abstract class EGLDynamicLibraryBundleInfo extends GLDynamicLibraryBundleInfo {
- static List<String> glueLibNames;
+ static final List<String> glueLibNames;
static {
glueLibNames = new ArrayList<String>();
glueLibNames.add("jogl_mobile");
@@ -51,27 +52,23 @@ public abstract class EGLDynamicLibraryBundleInfo extends GLDynamicLibraryBundle
super();
}
- /**
- * Might be a desktop GL library, and might need to allow symbol access to subsequent libs.
- *
- * This respects old DRI requirements:<br>
- * <pre>
- * http://dri.sourceforge.net/doc/DRIuserguide.html
- * </pre>
+ /**
+ * Returns <code>true</code> on <code>Android</code>,
+ * and <code>false</code> otherwise.
+ * <p>
+ * {@inheritDoc}
+ * </p>
*/
@Override
- public boolean shallLinkGlobal() { return true; }
-
- @Override
- public boolean shallLookupGlobal() {
- if ( AndroidVersion.isAvailable ) {
+ public final boolean shallLookupGlobal() {
+ if ( Platform.OSType.ANDROID == Platform.OS_TYPE ) {
// Android requires global symbol lookup
return true;
}
// default behavior for other platforms
return false;
}
-
+
@Override
public final List<String> getToolGetProcAddressFuncNameList() {
List<String> res = new ArrayList<String>();
@@ -93,26 +90,26 @@ public abstract class EGLDynamicLibraryBundleInfo extends GLDynamicLibraryBundle
return true;
}
}
-
- protected List<String> getEGLLibNamesList() {
+
+ protected final List<String> getEGLLibNamesList() {
List<String> eglLibNames = new ArrayList<String>();
-
- // this is the default EGL lib name, according to the spec
+
+ // this is the default EGL lib name, according to the spec
eglLibNames.add("libEGL.so.1");
-
+
// try these as well, if spec fails
eglLibNames.add("libEGL.so");
eglLibNames.add("EGL");
-
- // for windows distributions using the 'unlike' lib prefix,
+
+ // for windows distributions using the 'unlike' lib prefix,
// where our tool does not add it.
eglLibNames.add("libEGL");
-
+
return eglLibNames;
}
@Override
public final List<String> getGlueLibNames() {
return glueLibNames;
- }
+ }
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLES1DynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/egl/EGLES1DynamicLibraryBundleInfo.java
index 0a373eb7f..361ec26ff 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLES1DynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLES1DynamicLibraryBundleInfo.java
@@ -3,14 +3,14 @@
*
* 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
@@ -20,48 +20,49 @@
* 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 jogamp.opengl.egl;
import java.util.*;
-public class EGLES1DynamicLibraryBundleInfo extends EGLDynamicLibraryBundleInfo {
+public final class EGLES1DynamicLibraryBundleInfo extends EGLDynamicLibraryBundleInfo {
protected EGLES1DynamicLibraryBundleInfo() {
super();
}
- public List<List<String>> getToolLibNames() {
+ @Override
+ public final List<List<String>> getToolLibNames() {
final List<List<String>> libsList = new ArrayList<List<String>>();
{
final List<String> libsGL = new ArrayList<String>();
-
- // this is the default lib name, according to the spec
+
+ // this is the default lib name, according to the spec
libsGL.add("libGLESv1_CM.so.2");
-
+
// try these as well, if spec fails
libsGL.add("libGLESv1_CM.so");
- libsGL.add("GLESv1_CM");
+ libsGL.add("GLESv1_CM");
// alternative names
libsGL.add("GLES_CM");
libsGL.add("GLES_CL");
-
- // for windows distributions using the 'unlike' lib prefix,
+
+ // for windows distributions using the 'unlike' lib prefix,
// where our tool does not add it.
libsGL.add("libGLESv1_CM");
libsGL.add("libGLES_CM");
libsGL.add("libGLES_CL");
-
+
libsList.add(libsGL);
}
libsList.add(getEGLLibNamesList());
-
+
return libsList;
- }
+ }
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java
index d4ee852b1..74738463f 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java
@@ -3,14 +3,14 @@
*
* 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
@@ -20,49 +20,70 @@
* 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 jogamp.opengl.egl;
import java.util.*;
-public class EGLES2DynamicLibraryBundleInfo extends EGLDynamicLibraryBundleInfo {
+/**
+ * <p>
+ * Covering ES3 and ES2.
+ * </p>
+ */
+public final class EGLES2DynamicLibraryBundleInfo extends EGLDynamicLibraryBundleInfo {
protected EGLES2DynamicLibraryBundleInfo() {
super();
}
- public List<List<String>> getToolLibNames() {
+ @Override
+ public final List<List<String>> getToolLibNames() {
final List<List<String>> libsList = new ArrayList<List<String>>();
{
final List<String> libsGL = new ArrayList<String>();
-
- // this is the default lib name, according to the spec
+
+ // ES3: This is the default lib name, according to the spec
+ libsGL.add("libGLESv3.so.3");
+
+ // ES3: Try these as well, if spec fails
+ libsGL.add("libGLESv3.so");
+ libsGL.add("GLESv3");
+
+ // ES3: Alternative names
+ libsGL.add("GLES30");
+
+ // ES3: For windows distributions using the 'unlike' lib prefix
+ // where our tool does not add it.
+ libsGL.add("libGLESv3");
+ libsGL.add("libGLES30");
+
+ // ES2: This is the default lib name, according to the spec
libsGL.add("libGLESv2.so.2");
-
- // try these as well, if spec fails
- libsGL.add("libGLESv2.so");
+
+ // ES2: Try these as well, if spec fails
+ libsGL.add("libGLESv2.so");
libsGL.add("GLESv2");
- // alternative names
+ // ES2: Alternative names
libsGL.add("GLES20");
libsGL.add("GLESv2_CM");
- // for windows distributions using the 'unlike' lib prefix
+ // ES2: For windows distributions using the 'unlike' lib prefix
// where our tool does not add it.
libsGL.add("libGLESv2");
libsGL.add("libGLESv2_CM");
- libsGL.add("libGLES20");
-
+ libsGL.add("libGLES20");
+
libsList.add(libsGL);
}
libsList.add(getEGLLibNamesList());
-
+
return libsList;
- }
-
+ }
+
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java
index ff60a5262..aff18fc81 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java
@@ -1,21 +1,21 @@
/*
* Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
- *
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
- *
+ *
* - Redistribution of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
- *
+ *
* - Redistribution 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.
- *
+ *
* Neither the name of Sun Microsystems, Inc. or the names of
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
- *
+ *
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
@@ -28,7 +28,7 @@
* DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
* ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
* SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
- *
+ *
* Sun gratefully acknowledges that this software was originally authored
* and developed by Kenneth Bradley Russell and Christopher John Kline.
*/
@@ -36,51 +36,27 @@
package jogamp.opengl.egl;
import javax.media.opengl.*;
+
import jogamp.opengl.*;
+
import javax.media.nativewindow.*;
public class EGLExternalContext extends EGLContext {
- private GLContext lastContext;
public EGLExternalContext(AbstractGraphicsScreen screen) {
super(null, null);
GLContextShareSet.contextCreated(this);
- setGLFunctionAvailability(false, 0, 0, CTX_IS_ARB_CREATED|CTX_PROFILE_ES);
- getGLStateTracker().setEnabled(false); // external context usage can't track state in Java
- }
-
- public int makeCurrent() throws GLException {
- // Save last context if necessary to allow external GLContexts to
- // talk to other GLContexts created by this library
- GLContext cur = getCurrent();
- if (cur != null && cur != this) {
- lastContext = cur;
- setCurrent(null);
+ if( !setGLFunctionAvailability(false, 0, 0, CTX_PROFILE_ES, false /* strictMatch */, false /* withinGLVersionsMapping */) ) { // use GL_VERSION
+ throw new InternalError("setGLFunctionAvailability !strictMatch failed");
}
- return super.makeCurrent();
- }
-
- public void release() throws GLException {
- super.release();
- setCurrent(lastContext);
- lastContext = null;
- }
-
- protected void makeCurrentImpl() throws GLException {
+ getGLStateTracker().setEnabled(false); // external context usage can't track state in Java
}
+ @Override
protected void releaseImpl() throws GLException {
}
+ @Override
protected void destroyImpl() throws GLException {
}
-
- public void bindPbufferToTexture() {
- throw new GLException("Should not call this");
- }
-
- public void releasePbufferFromTexture() {
- throw new GLException("Should not call this");
- }
-
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java b/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java
index f813edf86..e28b53235 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java
@@ -33,39 +33,43 @@ import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
+import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
+
public class EGLGLCapabilities extends GLCapabilities {
private long eglcfg;
final private int eglcfgid;
- final private int renderableType;
+ final private int renderableType;
final private int nativeVisualID;
-
+
/**
- *
+ *
* @param eglcfg
* @param eglcfgid
* @param visualID native visualID if valid, otherwise VisualIDHolder.VID_UNDEFINED
- * @param glp desired GLProfile, or null if determined by renderableType
+ * @param glp desired GLProfile
* @param renderableType actual EGL renderableType
- *
+ *
* May throw GLException if given GLProfile is not compatible w/ renderableType
*/
public EGLGLCapabilities(long eglcfg, int eglcfgid, int visualID, GLProfile glp, int renderableType) {
- super( ( null != glp ) ? glp : getCompatible(renderableType) );
+ super( glp );
this.eglcfg = eglcfg;
this.eglcfgid = eglcfgid;
if(!isCompatible(glp, renderableType)) {
- throw new GLException("Incompatible "+glp+
- " with EGL-RenderableType["+renderableTypeToString(null, renderableType)+"]");
+ throw new GLException("Requested GLProfile "+glp+
+ " not compatible with EGL-RenderableType["+renderableTypeToString(null, renderableType)+"]");
}
this.renderableType = renderableType;
this.nativeVisualID = visualID;
}
+ @Override
public Object cloneMutable() {
return clone();
}
+ @Override
public Object clone() {
try {
return super.clone();
@@ -73,13 +77,13 @@ public class EGLGLCapabilities extends GLCapabilities {
throw new GLException(e);
}
}
-
+
final protected void setEGLConfig(long v) { eglcfg=v; }
final public long getEGLConfig() { return eglcfg; }
final public int getEGLConfigID() { return eglcfgid; }
final public int getRenderableType() { return renderableType; }
final public int getNativeVisualID() { return nativeVisualID; }
-
+
@Override
final public int getVisualID(VIDType type) throws NativeWindowException {
switch(type) {
@@ -90,43 +94,50 @@ public class EGLGLCapabilities extends GLCapabilities {
return getNativeVisualID();
default:
throw new NativeWindowException("Invalid type <"+type+">");
- }
+ }
}
-
+
public static boolean isCompatible(GLProfile glp, int renderableType) {
if(null == glp) {
return true;
}
- if(0 != (renderableType & EGL.EGL_OPENGL_ES_BIT) && glp.usesNativeGLES1()) {
+ if(0 != (renderableType & EGLExt.EGL_OPENGL_ES3_BIT_KHR) && glp.usesNativeGLES3()) {
return true;
}
if(0 != (renderableType & EGL.EGL_OPENGL_ES2_BIT) && glp.usesNativeGLES2()) {
return true;
}
+ if(0 != (renderableType & EGL.EGL_OPENGL_ES_BIT) && glp.usesNativeGLES1()) {
+ return true;
+ }
if(0 != (renderableType & EGL.EGL_OPENGL_BIT) && !glp.usesNativeGLES()) {
return true;
}
return false;
}
- public static GLProfile getCompatible(int renderableType) {
- if(0 != (renderableType & EGL.EGL_OPENGL_ES2_BIT) && GLProfile.isAvailable(GLProfile.GLES2)) {
- return GLProfile.get(GLProfile.GLES2);
+ public static GLProfile getCompatible(EGLGraphicsDevice device, int renderableType) {
+ if(0 != (renderableType & EGLExt.EGL_OPENGL_ES3_BIT_KHR) && GLProfile.isAvailable(device, GLProfile.GLES3)) {
+ return GLProfile.get(device, GLProfile.GLES3);
+ }
+ if(0 != (renderableType & EGL.EGL_OPENGL_ES2_BIT) && GLProfile.isAvailable(device, GLProfile.GLES2)) {
+ return GLProfile.get(device, GLProfile.GLES2);
}
- if(0 != (renderableType & EGL.EGL_OPENGL_ES_BIT) && GLProfile.isAvailable(GLProfile.GLES1)) {
- return GLProfile.get(GLProfile.GLES1);
+ if(0 != (renderableType & EGL.EGL_OPENGL_ES_BIT) && GLProfile.isAvailable(device, GLProfile.GLES1)) {
+ return GLProfile.get(device, GLProfile.GLES1);
}
if(0 != (renderableType & EGL.EGL_OPENGL_BIT)) {
- return GLProfile.getDefault();
+ return GLProfile.getDefault(device);
}
return null;
}
-
+
public static StringBuilder renderableTypeToString(StringBuilder sink, int renderableType) {
if(null == sink) {
sink = new StringBuilder();
}
boolean first=true;
+ sink.append("0x").append(Integer.toHexString(renderableType)).append(": ");
if(0 != (renderableType & EGL.EGL_OPENGL_BIT)) {
sink.append("GL"); first=false;
}
@@ -136,12 +147,16 @@ public class EGLGLCapabilities extends GLCapabilities {
if(0 != (renderableType & EGL.EGL_OPENGL_ES2_BIT)) {
if(!first) sink.append(", "); sink.append("GLES2"); first=false;
}
+ if(0 != (renderableType & EGLExt.EGL_OPENGL_ES3_BIT_KHR)) {
+ if(!first) sink.append(", "); sink.append("GLES3"); first=false;
+ }
if(0 != (renderableType & EGL.EGL_OPENVG_API)) {
if(!first) sink.append(", "); sink.append("VG"); first=false;
}
- return sink;
+ return sink;
}
-
+
+ @Override
public StringBuilder toString(StringBuilder sink) {
if(null == sink) {
sink = new StringBuilder();
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
index 875bcb95b..88ed0be92 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
@@ -1,22 +1,22 @@
/*
* Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
* Copyright (c) 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:
- *
+ *
* - Redistribution of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
- *
+ *
* - Redistribution 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.
- *
+ *
* Neither the name of Sun Microsystems, Inc. or the names of
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
- *
+ *
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
@@ -29,7 +29,7 @@
* DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
* ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
* SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
- *
+ *
* Sun gratefully acknowledges that this software was originally authored
* and developed by Kenneth Bradley Russell and Christopher John Kline.
*/
@@ -37,15 +37,16 @@
package jogamp.opengl.egl;
import java.nio.IntBuffer;
-import java.util.ArrayList;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.GraphicsConfigurationFactory;
import javax.media.nativewindow.VisualIDHolder;
import javax.media.opengl.DefaultGLCapabilitiesChooser;
import javax.media.opengl.GLCapabilitiesChooser;
import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
@@ -55,9 +56,14 @@ import com.jogamp.common.nio.Buffers;
import com.jogamp.common.nio.PointerBuffer;
import com.jogamp.nativewindow.MutableGraphicsConfiguration;
import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
+import com.jogamp.opengl.GLRendererQuirks;
public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration implements Cloneable {
-
+
+ private static final String dbgCfgFailIntro = "Info: EGLConfig could not retrieve ";
+ private static final String dbgCfgFailForConfig = " for config ";
+ private static final String dbgCfgFailError = ", error ";
+
public final long getNativeConfig() {
return ((EGLGLCapabilities)capabilitiesChosen).getEGLConfig();
}
@@ -66,13 +72,20 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
return ((EGLGLCapabilities)capabilitiesChosen).getEGLConfigID();
}
- EGLGraphicsConfiguration(AbstractGraphicsScreen absScreen,
+ EGLGraphicsConfiguration(AbstractGraphicsScreen absScreen,
EGLGLCapabilities capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) {
super(absScreen, capsChosen, capsRequested);
this.chooser = chooser;
}
- public static EGLGraphicsConfiguration create(GLCapabilitiesImmutable capsRequested, AbstractGraphicsScreen absScreen, int cfgID) {
+ /**
+ * @param capsRequested
+ * @param absScreen
+ * @param eglConfigID {@link EGL#EGL_CONFIG_ID} for which the config is being created for.
+ * @return
+ * @throws GLException if invalid EGL display.
+ */
+ public static EGLGraphicsConfiguration create(GLCapabilitiesImmutable capsRequested, AbstractGraphicsScreen absScreen, int eglConfigID) {
final AbstractGraphicsDevice absDevice = absScreen.getDevice();
if(null==absDevice || !(absDevice instanceof EGLGraphicsDevice)) {
throw new GLException("GraphicsDevice must be a valid EGLGraphicsDevice");
@@ -81,9 +94,11 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
if (dpy == EGL.EGL_NO_DISPLAY) {
throw new GLException("Invalid EGL display: "+absDevice);
}
- final long cfg = EGLConfigId2EGLConfig(dpy, cfgID);
+ final long cfg = EGLConfigId2EGLConfig(dpy, eglConfigID);
if(0 < cfg) {
- final EGLGLCapabilities caps = EGLConfig2Capabilities(capsRequested.getGLProfile(), dpy, cfg, false, capsRequested.isOnscreen(), capsRequested.isPBuffer(), false);
+ final GLRendererQuirks defaultQuirks = GLRendererQuirks.getStickyDeviceQuirks( GLDrawableFactory.getEGLFactory().getDefaultDevice() );
+ final int winattrmask = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsRequested);
+ final EGLGLCapabilities caps = EGLConfig2Capabilities(defaultQuirks, (EGLGraphicsDevice)absDevice, capsRequested.getGLProfile(), cfg, winattrmask, false);
return new EGLGraphicsConfiguration(absScreen, caps, capsRequested, new DefaultGLCapabilitiesChooser());
}
return null;
@@ -93,11 +108,12 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
public Object clone() {
return super.clone();
}
-
+
void updateGraphicsConfiguration() {
+ CapabilitiesImmutable capsChosen = getChosenCapabilities();
EGLGraphicsConfiguration newConfig = (EGLGraphicsConfiguration)
- GraphicsConfigurationFactory.getFactory(getScreen().getDevice()).chooseGraphicsConfiguration(
- getChosenCapabilities(), getRequestedCapabilities(), chooser, getScreen());
+ GraphicsConfigurationFactory.getFactory(getScreen().getDevice(), capsChosen).chooseGraphicsConfiguration(
+ capsChosen, getRequestedCapabilities(), chooser, getScreen(), VisualIDHolder.VID_UNDEFINED);
if(null!=newConfig) {
// FIXME: setScreen( ... );
setChosenCapabilities(newConfig.getChosenCapabilities());
@@ -108,260 +124,379 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
}
public static long EGLConfigId2EGLConfig(long display, int configID) {
- int[] attrs = new int[] {
+ final IntBuffer attrs = Buffers.newDirectIntBuffer(new int[] {
EGL.EGL_CONFIG_ID, configID,
EGL.EGL_NONE
- };
- PointerBuffer configs = PointerBuffer.allocateDirect(1);
- int[] numConfigs = new int[1];
+ });
+ final PointerBuffer configs = PointerBuffer.allocateDirect(1);
+ final IntBuffer numConfigs = Buffers.newDirectIntBuffer(1);
if (!EGL.eglChooseConfig(display,
- attrs, 0,
+ attrs,
configs, 1,
- numConfigs, 0)) {
+ numConfigs)) {
return 0;
}
- if (numConfigs[0] == 0) {
+ if (numConfigs.get(0) == 0) {
return 0;
}
return configs.get(0);
}
- static int EGLConfigDrawableTypeBits(final long display, final long config) {
+ public static boolean isEGLConfigValid(long display, long config) {
+ if(0 == config) {
+ return false;
+ }
+ final IntBuffer val = Buffers.newDirectIntBuffer(1);
+
+ // get the configID
+ if(!EGL.eglGetConfigAttrib(display, config, EGL.EGL_CONFIG_ID, val)) {
+ final int eglErr = EGL.eglGetError();
+ if(DEBUG) {
+ System.err.println(dbgCfgFailIntro+"EGL_CONFIG_ID"+dbgCfgFailForConfig+toHexString(config)+dbgCfgFailError+toHexString(eglErr));
+ }
+ return false;
+ }
+ return true;
+ }
+
+ static int EGLConfigDrawableTypeBits(final EGLGraphicsDevice device, final long config) {
int val = 0;
- int[] stype = new int[1];
- if(! EGL.eglGetConfigAttrib(display, config, EGL.EGL_SURFACE_TYPE, stype, 0)) {
+ final IntBuffer stype = Buffers.newDirectIntBuffer(1);
+ if(! EGL.eglGetConfigAttrib(device.getHandle(), config, EGL.EGL_SURFACE_TYPE, stype)) {
throw new GLException("Could not determine EGL_SURFACE_TYPE");
}
- if ( 0 != ( stype[0] & EGL.EGL_WINDOW_BIT ) ) {
+ final int _stype = stype.get(0);
+ if ( 0 != ( _stype & EGL.EGL_WINDOW_BIT ) ) {
val |= GLGraphicsConfigurationUtil.WINDOW_BIT;
}
- if ( 0 != ( stype[0] & EGL.EGL_PIXMAP_BIT ) ) {
+ if ( 0 != ( _stype & EGL.EGL_PIXMAP_BIT ) ) {
val |= GLGraphicsConfigurationUtil.BITMAP_BIT;
}
- if ( 0 != ( stype[0] & EGL.EGL_PBUFFER_BIT ) ) {
- val |= GLGraphicsConfigurationUtil.PBUFFER_BIT;
+ if ( 0 != ( _stype & EGL.EGL_PBUFFER_BIT ) ) {
+ val |= GLGraphicsConfigurationUtil.PBUFFER_BIT |
+ GLGraphicsConfigurationUtil.FBO_BIT;
}
-
return val;
}
- public static EGLGLCapabilities EGLConfig2Capabilities(GLProfile glp, long display, long config,
- boolean relaxed, boolean onscreen, boolean usePBuffer, boolean forceTransparentFlag) {
- ArrayList bucket = new ArrayList();
- final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer);
- if( EGLConfig2Capabilities(bucket, glp, display, config, winattrmask, forceTransparentFlag) ) {
- return (EGLGLCapabilities) bucket.get(0);
- } else if ( relaxed && EGLConfig2Capabilities(bucket, glp, display, config, GLGraphicsConfigurationUtil.ALL_BITS, forceTransparentFlag) ) {
- return (EGLGLCapabilities) bucket.get(0);
- }
- return null;
- }
-
- public static boolean EGLConfig2Capabilities(ArrayList capsBucket,
- GLProfile glp, long display, long config,
- int winattrmask, boolean forceTransparentFlag) {
- final int allDrawableTypeBits = EGLConfigDrawableTypeBits(display, config);
- final int drawableTypeBits = winattrmask & allDrawableTypeBits;
-
- if( 0 == drawableTypeBits ) {
- return false;
- }
-
- final IntBuffer val = Buffers.newDirectIntBuffer(1);
+ /**
+ * @param defaultQuirks GLRendererQuirks of the EGLDrawableFactory's defaultDevice
+ * @param device
+ * @param glp desired GLProfile, may be null
+ * @param config
+ * @param winattrmask
+ * @param forceTransparentFlag
+ * @return
+ */
+ public static EGLGLCapabilities EGLConfig2Capabilities(GLRendererQuirks defaultQuirks, EGLGraphicsDevice device, GLProfile glp,
+ long config, int winattrmask, boolean forceTransparentFlag) {
+ final long display = device.getHandle();
final int cfgID;
final int rType;
final int visualID;
-
+
+ final int _attributes[] = {
+ EGL.EGL_CONFIG_ID, // 0
+ EGL.EGL_RENDERABLE_TYPE,
+ EGL.EGL_NATIVE_VISUAL_ID,
+ EGL.EGL_CONFIG_CAVEAT,
+ EGL.EGL_RED_SIZE, // 4
+ EGL.EGL_GREEN_SIZE,
+ EGL.EGL_BLUE_SIZE,
+ EGL.EGL_ALPHA_SIZE, // 7
+ EGL.EGL_STENCIL_SIZE, // 8
+ EGL.EGL_DEPTH_SIZE,
+ EGL.EGL_TRANSPARENT_TYPE, // 10
+ EGL.EGL_TRANSPARENT_RED_VALUE,
+ EGL.EGL_TRANSPARENT_GREEN_VALUE,
+ EGL.EGL_TRANSPARENT_BLUE_VALUE,
+ EGL.EGL_SAMPLES, // 14
+ EGLExt.EGL_COVERAGE_BUFFERS_NV, // 15
+ EGLExt.EGL_COVERAGE_SAMPLES_NV
+ };
+ final IntBuffer attributes = Buffers.newDirectIntBuffer(_attributes);
+ final IntBuffer values = Buffers.newDirectIntBuffer(attributes.remaining());
+ EGL.eglGetConfigAttributes(display, config, attributes, values);
+
// get the configID
- if(!EGL.eglGetConfigAttrib(display, config, EGL.EGL_CONFIG_ID, val)) {
+ if( EGL.EGL_CONFIG_ID != attributes.get(0) ) {
if(DEBUG) {
// FIXME: this happens on a ATI PC Emulation ..
- System.err.println("EGL couldn't retrieve ConfigID for config "+toHexString(config)+", error "+toHexString(EGL.eglGetError()));
+ System.err.println(dbgCfgFailIntro+"ConfigID"+dbgCfgFailForConfig+toHexString(config)+dbgCfgFailError+toHexString(EGL.eglGetError()));
}
- return false;
+ return null;
}
- cfgID = val.get(0);
-
- if(!EGL.eglGetConfigAttrib(display, config, EGL.EGL_RENDERABLE_TYPE, val)) {
+ cfgID = values.get(0);
+
+ if( EGL.EGL_RENDERABLE_TYPE != attributes.get(1) ) {
if(DEBUG) {
- System.err.println("EGL couldn't retrieve EGL_RENDERABLE_TYPE for config "+toHexString(config)+", error "+toHexString(EGL.eglGetError()));
+ System.err.println(dbgCfgFailIntro+"EGL_RENDERABLE_TYPE"+dbgCfgFailForConfig+toHexString(config)+dbgCfgFailError+toHexString(EGL.eglGetError()));
}
- return false;
+ return null;
}
- rType = val.get(0);
-
- if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_NATIVE_VISUAL_ID, val)) {
- visualID = val.get(0);
+ {
+ final int rTypeOrig = values.get(1);
+ if( defaultQuirks.exist(GLRendererQuirks.GLES3ViaEGLES2Config) && 0 != ( EGL.EGL_OPENGL_ES2_BIT & rTypeOrig ) ) {
+ rType = rTypeOrig | EGLExt.EGL_OPENGL_ES3_BIT_KHR;
+ } else {
+ rType = rTypeOrig;
+ }
+ }
+
+ if( EGL.EGL_NATIVE_VISUAL_ID == attributes.get(2) ) {
+ visualID = values.get(2);
} else {
+ if(DEBUG) {
+ System.err.println(dbgCfgFailIntro+"EGL_NATIVE_VISUAL_ID"+dbgCfgFailForConfig+toHexString(config)+dbgCfgFailError+toHexString(EGL.eglGetError()));
+ }
visualID = VisualIDHolder.VID_UNDEFINED;
}
-
- EGLGLCapabilities caps = null;
+
+ EGLGLCapabilities caps = null;
try {
+ if(null == glp) {
+ glp = EGLGLCapabilities.getCompatible(device, rType);
+ }
+ if(!EGLGLCapabilities.isCompatible(glp, rType)) {
+ if(DEBUG) {
+ System.err.println("config "+toHexString(config)+": Requested GLProfile "+glp+
+ " with quirks "+defaultQuirks+" not compatible with EGL-RenderableType["+EGLGLCapabilities.renderableTypeToString(null, rType)+"]");
+ }
+ return null;
+ }
caps = new EGLGLCapabilities(config, cfgID, visualID, glp, rType);
} catch (GLException gle) {
if(DEBUG) {
System.err.println("config "+toHexString(config)+": "+gle);
}
- return false;
- }
-
- if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_RED_SIZE, val)) {
- caps.setRedBits(val.get(0));
+ return null;
}
- if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_GREEN_SIZE, val)) {
- caps.setGreenBits(val.get(0));
+
+ if( EGL.EGL_CONFIG_CAVEAT == attributes.get(3) ) {
+ if( EGL.EGL_SLOW_CONFIG == values.get(3) ) {
+ caps.setHardwareAccelerated(false);
+ }
+ } else if(DEBUG) {
+ System.err.println(dbgCfgFailIntro+"EGL_CONFIG_CAVEAT"+dbgCfgFailForConfig+toHexString(config)+dbgCfgFailError+toHexString(EGL.eglGetError()));
}
- if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_BLUE_SIZE, val)) {
- caps.setBlueBits(val.get(0));
+ // ALPHA shall be set at last - due to it's auto setting by the above (!opaque / samples)
+ if( EGL.EGL_RED_SIZE == attributes.get(4) ) {
+ caps.setRedBits(values.get(4));
+ } else if(DEBUG) {
+ System.err.println(dbgCfgFailIntro+"EGL_RED_SIZE"+dbgCfgFailForConfig+toHexString(config)+dbgCfgFailError+toHexString(EGL.eglGetError()));
}
- if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_ALPHA_SIZE, val)) {
- caps.setAlphaBits(val.get(0));
+ if( EGL.EGL_GREEN_SIZE == attributes.get(5) ) {
+ caps.setGreenBits(values.get(5));
+ } else if(DEBUG) {
+ System.err.println(dbgCfgFailIntro+"EGL_GREEN_SIZE"+dbgCfgFailForConfig+toHexString(config)+dbgCfgFailError+toHexString(EGL.eglGetError()));
}
- if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_STENCIL_SIZE, val)) {
- caps.setStencilBits(val.get(0));
+ if( EGL.EGL_BLUE_SIZE == attributes.get(6) ) {
+ caps.setBlueBits(values.get(6));
+ } else if(DEBUG) {
+ System.err.println(dbgCfgFailIntro+"EGL_BLUE_SIZE"+dbgCfgFailForConfig+toHexString(config)+dbgCfgFailError+toHexString(EGL.eglGetError()));
}
- if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_DEPTH_SIZE, val)) {
- caps.setDepthBits(val.get(0));
+ if( EGL.EGL_ALPHA_SIZE == attributes.get(7) ) {
+ caps.setAlphaBits(values.get(7));
+ } else if(DEBUG) {
+ System.err.println(dbgCfgFailIntro+"EGL_ALPHA_SIZE"+dbgCfgFailForConfig+toHexString(config)+dbgCfgFailError+toHexString(EGL.eglGetError()));
}
- if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_SAMPLES, val)) {
- caps.setSampleBuffers(val.get(0)>0?true:false);
- caps.setNumSamples(val.get(0));
+ if( EGL.EGL_STENCIL_SIZE == attributes.get(8) ) {
+ caps.setStencilBits(values.get(8));
+ } else if(DEBUG) {
+ System.err.println(dbgCfgFailIntro+"EGL_STENCIL_SIZE"+dbgCfgFailForConfig+toHexString(config)+dbgCfgFailError+toHexString(EGL.eglGetError()));
}
- if(!caps.getSampleBuffers()) {
- // try NV_coverage_sample extension
- if(EGL.eglGetConfigAttrib(display, config, EGLExt.EGL_COVERAGE_BUFFERS_NV, val)) {
- if(val.get(0)>0 &&
- EGL.eglGetConfigAttrib(display, config, EGLExt.EGL_COVERAGE_SAMPLES_NV, val)) {
- caps.setSampleExtension(GLGraphicsConfigurationUtil.NV_coverage_sample);
- caps.setSampleBuffers(true);
- caps.setNumSamples(val.get(0));
- }
- }
+ if( EGL.EGL_DEPTH_SIZE == attributes.get(9) ) {
+ caps.setDepthBits(values.get(9));
+ } else if(DEBUG) {
+ System.err.println(dbgCfgFailIntro+"EGL_DEPTH_SIZE"+dbgCfgFailForConfig+toHexString(config)+dbgCfgFailError+toHexString(EGL.eglGetError()));
}
- if(forceTransparentFlag) {
+ if( forceTransparentFlag ) {
caps.setBackgroundOpaque(false);
- } else if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_TRANSPARENT_TYPE, val)) {
- caps.setBackgroundOpaque(val.get(0) != EGL.EGL_TRANSPARENT_RGB);
+ } else if( EGL.EGL_TRANSPARENT_TYPE == attributes.get(10) ) {
+ caps.setBackgroundOpaque(values.get(10) != EGL.EGL_TRANSPARENT_RGB);
+ } else if(DEBUG) {
+ System.err.println(dbgCfgFailIntro+"EGL_TRANSPARENT_TYPE"+dbgCfgFailForConfig+toHexString(config)+dbgCfgFailError+toHexString(EGL.eglGetError()));
}
if(!caps.isBackgroundOpaque()) {
- if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_TRANSPARENT_RED_VALUE, val)) {
- caps.setTransparentRedValue(val.get(0)==EGL.EGL_DONT_CARE?-1:val.get(0));
+ if( EGL.EGL_TRANSPARENT_RED_VALUE == attributes.get(11) ) {
+ final int v = values.get(11);
+ caps.setTransparentRedValue(EGL.EGL_DONT_CARE==v?-1:v);
+ } else if(DEBUG) {
+ System.err.println(dbgCfgFailIntro+"EGL_TRANSPARENT_RED_VALUE"+dbgCfgFailForConfig+toHexString(config)+dbgCfgFailError+toHexString(EGL.eglGetError()));
}
- if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_TRANSPARENT_GREEN_VALUE, val)) {
- caps.setTransparentGreenValue(val.get(0)==EGL.EGL_DONT_CARE?-1:val.get(0));
+ if( EGL.EGL_TRANSPARENT_GREEN_VALUE == attributes.get(12) ) {
+ final int v = values.get(12);
+ caps.setTransparentGreenValue(EGL.EGL_DONT_CARE==v?-1:v);
+ } else if(DEBUG) {
+ System.err.println(dbgCfgFailIntro+"EGL_TRANSPARENT_GREEN_VALUE"+dbgCfgFailForConfig+toHexString(config)+dbgCfgFailError+toHexString(EGL.eglGetError()));
}
- if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_TRANSPARENT_BLUE_VALUE, val)) {
- caps.setTransparentBlueValue(val.get(0)==EGL.EGL_DONT_CARE?-1:val.get(0));
+ if( EGL.EGL_TRANSPARENT_BLUE_VALUE == attributes.get(13) ) {
+ final int v = values.get(13);
+ caps.setTransparentBlueValue(EGL.EGL_DONT_CARE==v?-1:v);
+ } else if(DEBUG) {
+ System.err.println(dbgCfgFailIntro+"EGL_TRANSPARENT_BLUE_VALUE"+dbgCfgFailForConfig+toHexString(config)+dbgCfgFailError+toHexString(EGL.eglGetError()));
}
- /** Not defined in EGL
- if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_TRANSPARENT_ALPHA_VALUE, val)) {
- caps.setTransparentAlphaValue(val.get(0)==EGL.EGL_DONT_CARE?-1:val.get(0));
+ /** Not defined in EGL
+ if( EGL.EGL_TRANSPARENT_ALPHA_VALUE == attributes.get(??) ) {
+ final int v = values.get(??);
+ caps.setTransparentAlphaValue(EGL.EGL_DONT_CARE==v?-1:v);
+ } else if(DEBUG) {
+ System.err.println(dbgStr01+"EGL_TRANSPARENT_ALPHA_VALUE"+dbgStr02+toHexString(config)+dbgEGLCfgFailError+toHexString(EGL.eglGetError()));
} */
}
- return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, caps, drawableTypeBits );
+ if( EGL.EGL_SAMPLES == attributes.get(14) ) {
+ final int numSamples = values.get(14);
+ caps.setSampleBuffers(numSamples>0?true:false);
+ caps.setNumSamples(numSamples);
+ } else if(DEBUG) {
+ System.err.println(dbgCfgFailIntro+"EGL_SAMPLES"+dbgCfgFailForConfig+toHexString(config)+dbgCfgFailError+toHexString(EGL.eglGetError()));
+ }
+ if(!caps.getSampleBuffers()) {
+ // try NV_coverage_sample extension
+ if( EGLExt.EGL_COVERAGE_BUFFERS_NV == attributes.get(15) ) {
+ final boolean enabled = values.get(15) > 0;
+ if( enabled && EGLExt.EGL_COVERAGE_SAMPLES_NV == attributes.get(16) ) {
+ caps.setSampleExtension(GLGraphicsConfigurationUtil.NV_coverage_sample);
+ caps.setSampleBuffers(true);
+ caps.setNumSamples(values.get(16));
+ } else if(DEBUG) {
+ System.err.println(dbgCfgFailIntro+"EGL_COVERAGE_SAMPLES_NV"+dbgCfgFailForConfig+toHexString(config)+dbgCfgFailError+toHexString(EGL.eglGetError()));
+ }
+ } /** else if(DEBUG) { // Not required - vendor extension - don't be verbose!
+ System.err.println(dbgCfgFailIntro+"EGL_COVERAGE_BUFFERS_NV"+dbgCfgFailForConfig+toHexString(config)+dbgCfgFailError+toHexString(EGL.eglGetError()));
+ } */
+ }
+
+ // Since the passed GLProfile may be null,
+ // we use EGL_RENDERABLE_TYPE derived profile as created in the EGLGLCapabilities constructor.
+ final int availableTypeBits = EGLConfigDrawableTypeBits(device, config);
+ final int drawableTypeBits = winattrmask & availableTypeBits;
+
+ if( 0 == drawableTypeBits ) {
+ return null;
+ }
+
+ return (EGLGLCapabilities) GLGraphicsConfigurationUtil.fixWinAttribBitsAndHwAccel(device, drawableTypeBits, caps);
}
- public static int[] GLCapabilities2AttribList(GLCapabilitiesImmutable caps) {
- int[] attrs = new int[32];
+ public static IntBuffer GLCapabilities2AttribList(GLCapabilitiesImmutable caps) {
+ final IntBuffer attrs = Buffers.newDirectIntBuffer(32);
int idx=0;
- attrs[idx++] = EGL.EGL_SURFACE_TYPE;
- attrs[idx++] = caps.isOnscreen() ? ( EGL.EGL_WINDOW_BIT ) : ( caps.isPBuffer() ? EGL.EGL_PBUFFER_BIT : EGL.EGL_PIXMAP_BIT ) ;
+ attrs.put(idx++, EGL.EGL_SURFACE_TYPE);
+ final int surfaceType;
+ if( caps.isOnscreen() ) {
+ surfaceType = EGL.EGL_WINDOW_BIT;
+ } else if( caps.isFBO() ) {
+ surfaceType = EGL.EGL_PBUFFER_BIT; // native replacement!
+ } else if( caps.isPBuffer() ) {
+ surfaceType = EGL.EGL_PBUFFER_BIT;
+ } else if( caps.isBitmap() ) {
+ surfaceType = EGL.EGL_PIXMAP_BIT;
+ } else {
+ throw new GLException("no surface type set in caps: "+caps);
+ }
+ attrs.put(idx++, surfaceType);
- attrs[idx++] = EGL.EGL_RED_SIZE;
- attrs[idx++] = caps.getRedBits();
+ attrs.put(idx++, EGL.EGL_RED_SIZE);
+ attrs.put(idx++, caps.getRedBits());
- attrs[idx++] = EGL.EGL_GREEN_SIZE;
- attrs[idx++] = caps.getGreenBits();
+ attrs.put(idx++, EGL.EGL_GREEN_SIZE);
+ attrs.put(idx++, caps.getGreenBits());
- attrs[idx++] = EGL.EGL_BLUE_SIZE;
- attrs[idx++] = caps.getBlueBits();
+ attrs.put(idx++, EGL.EGL_BLUE_SIZE);
+ attrs.put(idx++, caps.getBlueBits());
if(caps.getAlphaBits()>0) {
- attrs[idx++] = EGL.EGL_ALPHA_SIZE;
- attrs[idx++] = caps.getAlphaBits();
+ attrs.put(idx++, EGL.EGL_ALPHA_SIZE);
+ attrs.put(idx++, caps.getAlphaBits());
}
-
+
if(caps.getStencilBits()>0) {
- attrs[idx++] = EGL.EGL_STENCIL_SIZE;
- attrs[idx++] = caps.getStencilBits();
+ attrs.put(idx++, EGL.EGL_STENCIL_SIZE);
+ attrs.put(idx++, caps.getStencilBits());
}
- attrs[idx++] = EGL.EGL_DEPTH_SIZE;
- attrs[idx++] = caps.getDepthBits();
+ attrs.put(idx++, EGL.EGL_DEPTH_SIZE);
+ attrs.put(idx++, caps.getDepthBits());
if(caps.getSampleBuffers()) {
if(caps.getSampleExtension().equals(GLGraphicsConfigurationUtil.NV_coverage_sample)) {
- attrs[idx++] = EGLExt.EGL_COVERAGE_BUFFERS_NV;
- attrs[idx++] = 1;
- attrs[idx++] = EGLExt.EGL_COVERAGE_SAMPLES_NV;
- attrs[idx++] = caps.getNumSamples();
+ attrs.put(idx++, EGLExt.EGL_COVERAGE_BUFFERS_NV);
+ attrs.put(idx++, 1);
+ attrs.put(idx++, EGLExt.EGL_COVERAGE_SAMPLES_NV);
+ attrs.put(idx++, caps.getNumSamples());
} else {
// try default ..
- attrs[idx++] = EGL.EGL_SAMPLE_BUFFERS;
- attrs[idx++] = 1;
- attrs[idx++] = EGL.EGL_SAMPLES;
- attrs[idx++] = caps.getNumSamples();
+ attrs.put(idx++, EGL.EGL_SAMPLE_BUFFERS);
+ attrs.put(idx++, 1);
+ attrs.put(idx++, EGL.EGL_SAMPLES);
+ attrs.put(idx++, caps.getNumSamples());
}
}
- attrs[idx++] = EGL.EGL_TRANSPARENT_TYPE;
- attrs[idx++] = caps.isBackgroundOpaque() ? EGL.EGL_NONE : EGL.EGL_TRANSPARENT_TYPE;
+ attrs.put(idx++, EGL.EGL_TRANSPARENT_TYPE);
+ attrs.put(idx++, caps.isBackgroundOpaque() ? EGL.EGL_NONE : EGL.EGL_TRANSPARENT_TYPE);
// 22
if(!caps.isBackgroundOpaque()) {
- attrs[idx++] = EGL.EGL_TRANSPARENT_RED_VALUE;
- attrs[idx++] = caps.getTransparentRedValue()>=0?caps.getTransparentRedValue():EGL.EGL_DONT_CARE;
+ attrs.put(idx++, EGL.EGL_TRANSPARENT_RED_VALUE);
+ attrs.put(idx++, caps.getTransparentRedValue()>=0?caps.getTransparentRedValue():EGL.EGL_DONT_CARE);
- attrs[idx++] = EGL.EGL_TRANSPARENT_GREEN_VALUE;
- attrs[idx++] = caps.getTransparentGreenValue()>=0?caps.getTransparentGreenValue():EGL.EGL_DONT_CARE;
+ attrs.put(idx++, EGL.EGL_TRANSPARENT_GREEN_VALUE);
+ attrs.put(idx++, caps.getTransparentGreenValue()>=0?caps.getTransparentGreenValue():EGL.EGL_DONT_CARE);
- attrs[idx++] = EGL.EGL_TRANSPARENT_BLUE_VALUE;
- attrs[idx++] = caps.getTransparentBlueValue()>=0?caps.getTransparentBlueValue():EGL.EGL_DONT_CARE;
+ attrs.put(idx++, EGL.EGL_TRANSPARENT_BLUE_VALUE);
+ attrs.put(idx++, caps.getTransparentBlueValue()>=0?caps.getTransparentBlueValue():EGL.EGL_DONT_CARE);
/** Not define in EGL
- attrs[idx++] = EGL.EGL_TRANSPARENT_ALPHA_VALUE;
- attrs[idx++] = caps.getTransparentAlphaValue()>=0?caps.getTransparentAlphaValue():EGL.EGL_DONT_CARE; */
+ attrs.put(idx++, EGL.EGL_TRANSPARENT_ALPHA_VALUE;
+ attrs.put(idx++, caps.getTransparentAlphaValue()>=0?caps.getTransparentAlphaValue():EGL.EGL_DONT_CARE; */
}
- // 28
- attrs[idx++] = EGL.EGL_RENDERABLE_TYPE;
+ // 28
+ attrs.put(idx++, EGL.EGL_RENDERABLE_TYPE);
if(caps.getGLProfile().usesNativeGLES1()) {
- attrs[idx++] = EGL.EGL_OPENGL_ES_BIT;
+ attrs.put(idx++, EGL.EGL_OPENGL_ES_BIT);
} else if(caps.getGLProfile().usesNativeGLES2()) {
- attrs[idx++] = EGL.EGL_OPENGL_ES2_BIT;
+ attrs.put(idx++, EGL.EGL_OPENGL_ES2_BIT);
+ } else if(caps.getGLProfile().usesNativeGLES3()) {
+ if( GLRendererQuirks.existStickyDeviceQuirk(GLDrawableFactory.getEGLFactory().getDefaultDevice(), GLRendererQuirks.GLES3ViaEGLES2Config) ) {
+ attrs.put(idx++, EGL.EGL_OPENGL_ES2_BIT);
+ } else {
+ attrs.put(idx++, EGLExt.EGL_OPENGL_ES3_BIT_KHR);
+ }
} else {
- attrs[idx++] = EGL.EGL_OPENGL_BIT;
+ attrs.put(idx++, EGL.EGL_OPENGL_BIT);
}
// 30
- attrs[idx++] = EGL.EGL_NONE;
+ attrs.put(idx++, EGL.EGL_NONE);
return attrs;
}
- public static int[] CreatePBufferSurfaceAttribList(int width, int height, int texFormat) {
- int[] attrs = new int[16];
+ public static IntBuffer CreatePBufferSurfaceAttribList(int width, int height, int texFormat) {
+ IntBuffer attrs = Buffers.newDirectIntBuffer(16);
int idx=0;
- attrs[idx++] = EGL.EGL_WIDTH;
- attrs[idx++] = width;
+ attrs.put(idx++, EGL.EGL_WIDTH);
+ attrs.put(idx++, width);
- attrs[idx++] = EGL.EGL_HEIGHT;
- attrs[idx++] = height;
+ attrs.put(idx++, EGL.EGL_HEIGHT);
+ attrs.put(idx++, height);
- attrs[idx++] = EGL.EGL_TEXTURE_FORMAT;
- attrs[idx++] = texFormat;
+ attrs.put(idx++, EGL.EGL_TEXTURE_FORMAT);
+ attrs.put(idx++, texFormat);
- attrs[idx++] = EGL.EGL_TEXTURE_TARGET;
- attrs[idx++] = EGL.EGL_NO_TEXTURE==texFormat ? EGL.EGL_NO_TEXTURE : EGL.EGL_TEXTURE_2D;
+ attrs.put(idx++, EGL.EGL_TEXTURE_TARGET);
+ attrs.put(idx++, EGL.EGL_NO_TEXTURE==texFormat ? EGL.EGL_NO_TEXTURE : EGL.EGL_TEXTURE_2D);
- attrs[idx++] = EGL.EGL_NONE;
+ attrs.put(idx++, EGL.EGL_NONE);
return attrs;
}
@@ -376,6 +511,6 @@ public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration imple
}
- private GLCapabilitiesChooser chooser;
+ private final GLCapabilitiesChooser chooser;
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
index 904110eb2..5cfa378cb 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
@@ -1,22 +1,22 @@
/*
* Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
* Copyright (c) 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:
- *
+ *
* - Redistribution of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
- *
+ *
* - Redistribution 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.
- *
+ *
* Neither the name of Sun Microsystems, Inc. or the names of
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
- *
+ *
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
@@ -38,15 +38,14 @@ import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.CapabilitiesChooser;
import javax.media.nativewindow.CapabilitiesImmutable;
-import javax.media.nativewindow.DefaultGraphicsScreen;
import javax.media.nativewindow.GraphicsConfigurationFactory;
import javax.media.nativewindow.VisualIDHolder;
import javax.media.nativewindow.VisualIDHolder.VIDType;
import javax.media.nativewindow.NativeWindowFactory;
-
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesChooser;
import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
import javax.media.opengl.GLDrawableFactory;
@@ -54,6 +53,7 @@ import javax.media.opengl.GLDrawableFactory;
import com.jogamp.common.nio.Buffers;
import com.jogamp.common.nio.PointerBuffer;
import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
+import com.jogamp.opengl.GLRendererQuirks;
import jogamp.opengl.GLGraphicsConfigurationFactory;
import jogamp.opengl.GLGraphicsConfigurationUtil;
@@ -74,43 +74,51 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
static VisualIDHolder.VIDComparator EglCfgIDComparator = new VisualIDHolder.VIDComparator(VisualIDHolder.VIDType.EGL_CONFIG);
static GraphicsConfigurationFactory nativeGraphicsConfigurationFactory = null;
static GraphicsConfigurationFactory kdeglGraphicsConfigurationFactory = null;
-
+ static GraphicsConfigurationFactory fallbackGraphicsConfigurationFactory = null;
+
static void registerFactory() {
GraphicsConfigurationFactory eglFactory = new EGLGraphicsConfigurationFactory();
-
+
// become the pre-selector for X11/.. to match the native visual id w/ EGL, if native ES is selected
final String nwType = NativeWindowFactory.getNativeWindowType(false);
if(NativeWindowFactory.TYPE_X11 == nwType) {
- nativeGraphicsConfigurationFactory = GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.x11.X11GraphicsDevice.class, eglFactory);
+ nativeGraphicsConfigurationFactory = GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.x11.X11GraphicsDevice.class, GLCapabilitiesImmutable.class, eglFactory);
+ if(null != nativeGraphicsConfigurationFactory) {
+ fallbackGraphicsConfigurationFactory = nativeGraphicsConfigurationFactory;
+ } else {
+ fallbackGraphicsConfigurationFactory = GraphicsConfigurationFactory.getFactory(com.jogamp.nativewindow.x11.X11GraphicsDevice.class, CapabilitiesImmutable.class);
+ }
} /* else if(NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false)) {
nativeGraphicsConfigurationFactory = GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.windows.WindowsGraphicsDevice.class, eglFactory);
- } else if(NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false)) {
+ } else if(NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false)) {
} */
-
+
// become the selector for KD/EGL ..
- kdeglGraphicsConfigurationFactory = GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.egl.EGLGraphicsDevice.class, eglFactory);
+ kdeglGraphicsConfigurationFactory = GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.egl.EGLGraphicsDevice.class, GLCapabilitiesImmutable.class, eglFactory);
}
-
+
static void unregisterFactory() {
final String nwType = NativeWindowFactory.getNativeWindowType(false);
if(NativeWindowFactory.TYPE_X11 == nwType) {
- GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.x11.X11GraphicsDevice.class, nativeGraphicsConfigurationFactory);
+ GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.x11.X11GraphicsDevice.class, GLCapabilitiesImmutable.class, nativeGraphicsConfigurationFactory);
} /* else if(NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false)) {
GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.windows.WindowsGraphicsDevice.class, nativeGraphicsConfigurationFactory);
- } else if(NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false)) {
+ } else if(NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(false)) {
} */
nativeGraphicsConfigurationFactory = null;
-
- GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.egl.EGLGraphicsDevice.class, kdeglGraphicsConfigurationFactory);
+ fallbackGraphicsConfigurationFactory = null;
+
+ GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.egl.EGLGraphicsDevice.class, GLCapabilitiesImmutable.class, kdeglGraphicsConfigurationFactory);
kdeglGraphicsConfigurationFactory = null;
}
-
+
private EGLGraphicsConfigurationFactory() {
}
+ @Override
protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl (
CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested,
- CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) {
+ CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen, int nativeVisualID) {
if (absScreen == null) {
throw new IllegalArgumentException("This NativeWindowFactory accepts only AbstractGraphicsDevice objects");
}
@@ -132,21 +140,21 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
AbstractGraphicsDevice absDevice = absScreen.getDevice();
if(null==absDevice) {
throw new GLException("Null AbstractGraphicsDevice");
- }
-
+ }
+
AbstractGraphicsConfiguration cfg = null;
-
+
if( absDevice instanceof EGLGraphicsDevice ) {
cfg = chooseGraphicsConfigurationStatic((GLCapabilitiesImmutable) capsChosen,
(GLCapabilitiesImmutable) capsRequested,
(GLCapabilitiesChooser) chooser,
- absScreen, VisualIDHolder.VID_UNDEFINED, false);
+ absScreen, nativeVisualID, false);
} else {
- // handle non native cases (X11, ..)
- if(null == nativeGraphicsConfigurationFactory) {
- throw new InternalError("Native GraphicsConfigurationFactory is null, but call issued for device: "+absDevice+" of type "+absDevice.getClass().getSimpleName());
+ // handle non native cases (X11, ..)
+ if(null == fallbackGraphicsConfigurationFactory) {
+ throw new InternalError("Native fallback GraphicsConfigurationFactory is null, but call issued for device: "+absDevice+" of type "+absDevice.getClass().getSimpleName());
}
-
+
if(glCapsChosen.getGLProfile().usesNativeGLES()) {
if(DEBUG) {
System.err.println("EGLGraphicsConfigurationFactory.choose..: Handle native device "+absDevice.getClass().getSimpleName());
@@ -154,7 +162,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
cfg = chooseGraphicsConfigurationStatic((GLCapabilitiesImmutable) capsChosen,
(GLCapabilitiesImmutable) capsRequested,
(GLCapabilitiesChooser) chooser,
- absScreen, VisualIDHolder.VID_UNDEFINED, false);
+ absScreen, nativeVisualID, false);
if(null == cfg || VisualIDHolder.VID_UNDEFINED == cfg.getVisualID(VIDType.NATIVE)) {
cfg = null;
if(DEBUG) {
@@ -165,23 +173,25 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
if(null == cfg) {
// fwd to native config factory (only X11 for now)
if(DEBUG) {
- System.err.println("EGLGraphicsConfigurationFactory.choose..: Delegate to "+nativeGraphicsConfigurationFactory.getClass().getSimpleName());
+ System.err.println("EGLGraphicsConfigurationFactory.choose..: Delegate to "+fallbackGraphicsConfigurationFactory.getClass().getSimpleName());
}
- cfg = nativeGraphicsConfigurationFactory.chooseGraphicsConfiguration(capsChosen, capsRequested, chooser, absScreen);
- }
+ cfg = fallbackGraphicsConfigurationFactory.chooseGraphicsConfiguration(capsChosen, capsRequested, chooser, absScreen, nativeVisualID);
+ }
}
return cfg;
}
protected static List<GLCapabilitiesImmutable> getAvailableCapabilities(EGLDrawableFactory factory, AbstractGraphicsDevice device) {
- EGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateEGLSharedResource(device);
+ final EGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResourceImpl(device);
if(null == sharedResource) {
throw new GLException("Shared resource for device n/a: "+device);
}
- EGLGraphicsDevice eglDevice = sharedResource.getDevice();
- long eglDisplay = eglDevice.getHandle();
-
- List/*<EGLGLCapabilities>*/ availableCaps = null;
+ final EGLGraphicsDevice eglDevice = sharedResource.getDevice();
+ final long eglDisplay = eglDevice.getHandle();
+ if(0 == eglDisplay) {
+ throw new GLException("null eglDisplay");
+ }
+ List<GLCapabilitiesImmutable> availableCaps = null;
IntBuffer numConfigs = Buffers.newDirectIntBuffer(1);
if(!EGL.eglGetConfigs(eglDisplay, null, 0, numConfigs)) {
@@ -197,19 +207,18 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
throw new GLException("Graphics configuration get all configs (eglGetConfigs) call failed, error "+toHexString(EGL.eglGetError()));
}
if (numConfigs.get(0) > 0) {
- availableCaps = eglConfigs2GLCaps(null, eglDisplay, configs, numConfigs.get(0), GLGraphicsConfigurationUtil.ALL_BITS, false);
+ availableCaps = eglConfigs2GLCaps(eglDevice, null, configs, numConfigs.get(0), GLGraphicsConfigurationUtil.ALL_BITS, false /* forceTransparentFlag */, false /* onlyFirstValid */);
if( null != availableCaps && availableCaps.size() > 1) {
Collections.sort(availableCaps, EglCfgIDComparator);
}
}
-
return availableCaps;
}
public static EGLGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilitiesImmutable capsChosen,
GLCapabilitiesImmutable capsReq,
GLCapabilitiesChooser chooser,
- AbstractGraphicsScreen absScreen, int nativeVisualID,
+ AbstractGraphicsScreen absScreen, int nativeVisualID,
boolean forceTransparentFlag) {
if (capsChosen == null) {
capsChosen = new GLCapabilities(null);
@@ -222,101 +231,107 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
if(null==absDevice) {
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());
+ eglDevice.open();
+ ownEGLDisplay = true;
}
- EGLDrawableFactory factory = (EGLDrawableFactory) GLDrawableFactory.getEGLFactory();
- capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, factory.canCreateGLPbuffer(absDevice) );
-
- GLProfile glp = capsChosen.getGLProfile();
- GLCapabilities fixedCaps;
-
- EGLGraphicsConfiguration res = eglChooseConfig(eglDisplay, capsChosen, capsReq, chooser, absScreen, nativeVisualID, forceTransparentFlag);
+ final GLProfile glp = capsChosen.getGLProfile();
+ capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, GLDrawableFactory.getEGLFactory(), absDevice);
+ EGLGraphicsConfiguration res = eglChooseConfig(eglDevice, capsChosen, capsReq, chooser, absScreen, nativeVisualID, forceTransparentFlag);
if(null==res) {
if(DEBUG) {
System.err.println("eglChooseConfig failed with given capabilities "+capsChosen);
}
-
+
// Last try .. add a fixed embedded profile [ATI, Nokia, Intel, ..]
//
// rgb888 - d16, s4
- fixedCaps = new GLCapabilities(glp);
+ final GLCapabilities fixedCaps = new GLCapabilities(glp);
+ fixedCaps.setSampleBuffers(true);
+ fixedCaps.setNumSamples(4);
fixedCaps.setRedBits(8);
fixedCaps.setGreenBits(8);
fixedCaps.setBlueBits(8);
fixedCaps.setDepthBits(16);
- fixedCaps.setSampleBuffers(true);
- fixedCaps.setNumSamples(4);
+ if( !capsChosen.isOnscreen() ) {
+ fixedCaps.setOnscreen(false);
+ fixedCaps.setPBuffer(capsChosen.isPBuffer());
+ fixedCaps.setFBO(capsChosen.isFBO());
+ }
if(DEBUG) {
System.err.println("trying fixed caps (1): "+fixedCaps);
}
- res = eglChooseConfig(eglDisplay, fixedCaps, capsReq, chooser, absScreen, nativeVisualID, false);
+ res = eglChooseConfig(eglDevice, fixedCaps, capsReq, chooser, absScreen, nativeVisualID, false);
}
if(null==res) {
//
// rgb565 - d16, s0
- fixedCaps = new GLCapabilities(glp);
+ final GLCapabilities fixedCaps = new GLCapabilities(glp);
fixedCaps.setRedBits(5);
fixedCaps.setGreenBits(6);
fixedCaps.setBlueBits(5);
fixedCaps.setDepthBits(16);
+ if( !capsChosen.isOnscreen() ) {
+ fixedCaps.setOnscreen(false);
+ fixedCaps.setPBuffer(capsChosen.isPBuffer());
+ fixedCaps.setFBO(capsChosen.isFBO());
+ }
if(DEBUG) {
System.err.println("trying fixed caps (2): "+fixedCaps);
}
- res = eglChooseConfig(eglDisplay, fixedCaps, capsReq, chooser, absScreen, nativeVisualID, false);
+ res = eglChooseConfig(eglDevice, fixedCaps, capsReq, chooser, absScreen, nativeVisualID, false);
}
if(null==res) {
//
// rgb565 - d16, s4
- fixedCaps = new GLCapabilities(glp);
+ final GLCapabilities fixedCaps = new GLCapabilities(glp);
+ fixedCaps.setSampleBuffers(true);
+ fixedCaps.setNumSamples(4);
fixedCaps.setRedBits(5);
fixedCaps.setGreenBits(6);
fixedCaps.setBlueBits(5);
fixedCaps.setDepthBits(16);
- fixedCaps.setSampleBuffers(true);
- fixedCaps.setNumSamples(4);
+ if( !capsChosen.isOnscreen() ) {
+ fixedCaps.setOnscreen(false);
+ fixedCaps.setPBuffer(capsChosen.isPBuffer());
+ fixedCaps.setFBO(capsChosen.isFBO());
+ }
if(DEBUG) {
System.err.println("trying fixed caps (3): "+fixedCaps);
}
- res = eglChooseConfig(eglDisplay, fixedCaps, capsReq, chooser, absScreen, nativeVisualID, false);
+ res = eglChooseConfig(eglDevice, 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;
}
- static EGLGraphicsConfiguration eglChooseConfig(long eglDisplay,
+
+ static EGLGraphicsConfiguration eglChooseConfig(EGLGraphicsDevice device,
GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested,
GLCapabilitiesChooser chooser,
AbstractGraphicsScreen absScreen,
int nativeVisualID, boolean forceTransparentFlag) {
+ final long eglDisplay = device.getHandle();
final GLProfile glp = capsChosen.getGLProfile();
- final boolean onscreen = capsChosen.isOnscreen();
- final boolean usePBuffer = capsChosen.isPBuffer();
- final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer);
- List/*<EGLGLCapabilities>*/ availableCaps = null;
+ final int winattrmask = GLGraphicsConfigurationUtil.getExclusiveWinAttributeBits(capsChosen);
+ List<GLCapabilitiesImmutable> availableCaps = null;
int recommendedIndex = -1;
long recommendedEGLConfig = -1;
IntBuffer numConfigs = Buffers.newDirectIntBuffer(1);
@@ -327,35 +342,58 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
if(0 == numConfigs.get(0)) {
throw new GLException("EGLGraphicsConfiguration.eglChooseConfig: Get maxConfigs (eglGetConfigs) no configs");
}
+ final int numEGLConfigs = numConfigs.get(0);
if (DEBUG) {
- System.err.println("EGLGraphicsConfiguration.eglChooseConfig: eglChooseConfig maxConfigs: "+numConfigs.get(0));
- System.err.println("EGLGraphicsConfiguration.eglChooseConfig: eglDisplay "+toHexString(eglDisplay)+", "+capsChosen+", nativeVisualID "+toHexString(nativeVisualID));
+ System.err.println("EGLGraphicsConfiguration.eglChooseConfig: eglChooseConfig eglDisplay "+toHexString(eglDisplay)+
+ ", nativeVisualID "+toHexString(nativeVisualID)+
+ ", capsChosen "+capsChosen+", winbits "+GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrmask).toString()+
+ ", fboAvail "+GLContext.isFBOAvailable(device, glp)+
+ ", device "+device+", "+device.getUniqueID()+
+ ", numEGLConfigs "+numEGLConfigs);
}
- final IntBuffer attrs = Buffers.newDirectIntBuffer(EGLGraphicsConfiguration.GLCapabilities2AttribList(capsChosen));
+ final IntBuffer attrs = EGLGraphicsConfiguration.GLCapabilities2AttribList(capsChosen);
PointerBuffer configs = PointerBuffer.allocateDirect(numConfigs.get(0));
- // 1st choice: get GLCapabilities based on users GLCapabilities
+ // 1st choice: get GLCapabilities based on users GLCapabilities
// setting recommendedIndex as preferred choice
// skipped if nativeVisualID is given
- if( VisualIDHolder.VID_UNDEFINED != nativeVisualID || !EGL.eglChooseConfig(eglDisplay, attrs, configs, configs.capacity(), numConfigs) ) {
+ final boolean hasEGLChosenCaps;
+ if( VisualIDHolder.VID_UNDEFINED == nativeVisualID ) {
+ if( !EGL.eglChooseConfig(eglDisplay, attrs, configs, configs.capacity(), numConfigs) ) {
+ if(DEBUG) {
+ System.err.println("EGLGraphicsConfiguration.eglChooseConfig: #1 eglChooseConfig: false");
+ }
+ numConfigs.put(0, 0);
+ hasEGLChosenCaps = false;
+ } else {
+ hasEGLChosenCaps = numConfigs.get(0)>0;
+ }
+ } else {
if(DEBUG) {
- System.err.println("EGLGraphicsConfiguration.eglChooseConfig: #1 eglChooseConfig: false");
+ System.err.println("EGLGraphicsConfiguration.eglChooseConfig: Skipped due to given visualID: "+toHexString(nativeVisualID));
}
- } else if (numConfigs.get(0) > 0) {
- availableCaps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs.get(0), winattrmask, forceTransparentFlag);
+ hasEGLChosenCaps = false;
+ }
+ final boolean useRecommendedIndex = hasEGLChosenCaps && !forceTransparentFlag && capsChosen.isBackgroundOpaque(); // only use recommended idx if not translucent
+ final boolean skipCapsChooser = null == chooser && useRecommendedIndex; // fast path: skip choosing if using recommended idx and null chooser is used
+ if( hasEGLChosenCaps ) {
+ availableCaps = eglConfigs2GLCaps(device, glp, configs, numConfigs.get(0), winattrmask, forceTransparentFlag, skipCapsChooser /* onlyFirsValid */);
if(availableCaps.size() > 0) {
recommendedEGLConfig = configs.get(0);
recommendedIndex = 0;
if (DEBUG) {
System.err.println("EGLGraphicsConfiguration.eglChooseConfig: #1 eglChooseConfig: recommended fbcfg " + toHexString(recommendedEGLConfig) + ", idx " + recommendedIndex);
+ System.err.println("EGLGraphicsConfiguration.eglChooseConfig: #1 useRecommendedIndex "+useRecommendedIndex+", skipCapsChooser "+skipCapsChooser);
System.err.println("EGLGraphicsConfiguration.eglChooseConfig: #1 fbcfg caps " + availableCaps.get(recommendedIndex));
}
} else if (DEBUG) {
System.err.println("EGLGraphicsConfiguration.eglChooseConfig: #1 eglChooseConfig: no caps for recommended fbcfg " + toHexString(configs.get(0)));
+ System.err.println("EGLGraphicsConfiguration.eglChooseConfig: #1 useRecommendedIndex "+useRecommendedIndex+", skipCapsChooser "+skipCapsChooser);
}
} else if (DEBUG) {
System.err.println("EGLGraphicsConfiguration.eglChooseConfig: #1 eglChooseConfig: no configs");
+ System.err.println("EGLGraphicsConfiguration.eglChooseConfig: #1 useRecommendedIndex "+useRecommendedIndex+", skipCapsChooser "+skipCapsChooser);
}
// 2nd choice: get all GLCapabilities available, no preferred recommendedIndex available
@@ -368,7 +406,7 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
throw new GLException("EGLGraphicsConfiguration.eglChooseConfig: #2 Get all configs (eglGetConfigs) call failed, error "+toHexString(EGL.eglGetError()));
}
if (numConfigs.get(0) > 0) {
- availableCaps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs.get(0), winattrmask, forceTransparentFlag);
+ availableCaps = eglConfigs2GLCaps(device, glp, configs, numConfigs.get(0), winattrmask, forceTransparentFlag, false /* onlyFirsValid */);
}
}
@@ -376,10 +414,12 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
if(DEBUG) {
// FIXME: this happens on a ATI PC Emulation ..
System.err.println("EGLGraphicsConfiguration.eglChooseConfig: #2 Graphics configuration 1st choice and 2nd choice failed - no configs");
+ availableCaps = eglConfigs2GLCaps(device, glp, configs, numConfigs.get(0), GLGraphicsConfigurationUtil.ALL_BITS, forceTransparentFlag, false /* onlyFirsValid */);
+ printCaps("AllCaps", availableCaps, System.err);
}
return null;
}
-
+
if(DEBUG) {
System.err.println("EGLGraphicsConfiguration.eglChooseConfig: got configs: "+availableCaps.size());
for(int i=0; i<availableCaps.size(); i++) {
@@ -387,11 +427,16 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
}
}
- if( VisualIDHolder.VID_UNDEFINED != nativeVisualID ) {
- List/*<EGLGLCapabilities>*/ removedCaps = new ArrayList();
+ if( VisualIDHolder.VID_UNDEFINED != nativeVisualID ) { // implies !hasEGLChosenCaps
+ List<GLCapabilitiesImmutable> removedCaps = new ArrayList<GLCapabilitiesImmutable>();
for(int i=0; i<availableCaps.size(); ) {
- VisualIDHolder vidh = (VisualIDHolder) availableCaps.get(i);
- if(vidh.getVisualID(VIDType.NATIVE) != nativeVisualID) {
+ final GLCapabilitiesImmutable aCap = availableCaps.get(i);
+ if(aCap.getVisualID(VIDType.NATIVE) != nativeVisualID) {
+ if(DEBUG) { System.err.println("Remove["+i+"] (mismatch VisualID): "+aCap); }
+ removedCaps.add(availableCaps.remove(i));
+ } else if( 0 == aCap.getDepthBits() && 0 < capsChosen.getDepthBits() ) {
+ // Hack for HiSilicon/Vivante/Immersion.16 Renderer ..
+ if(DEBUG) { System.err.println("Remove["+i+"] (mismatch depth-bits): "+aCap); }
removedCaps.add(availableCaps.remove(i));
} else {
i++;
@@ -404,10 +449,18 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
}
} else if(DEBUG) {
System.err.println("EGLGraphicsConfiguration.eglChooseConfig: post filter nativeVisualID "+toHexString(nativeVisualID)+" got configs: "+availableCaps.size());
+ for(int i=0; i<availableCaps.size(); i++) {
+ System.err.println(i+": "+availableCaps.get(i));
+ }
}
}
- final int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex);
+ final int chosenIndex;
+ if( skipCapsChooser && 0 <= recommendedIndex ) {
+ chosenIndex = recommendedIndex;
+ } else {
+ chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex);
+ }
if ( 0 > chosenIndex ) {
if (DEBUG) {
System.err.println("EGLGraphicsConfiguration.eglChooseConfig: #2 chooseCapabilities failed");
@@ -415,46 +468,32 @@ public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFact
return null;
}
final EGLGLCapabilities chosenCaps = (EGLGLCapabilities) availableCaps.get(chosenIndex);
+ final EGLGraphicsConfiguration res = new EGLGraphicsConfiguration(absScreen, chosenCaps, capsRequested, chooser);
if (DEBUG) {
- System.err.println("EGLGraphicsConfiguration.eglChooseConfig: X chosen :"+chosenIndex+", eglConfig: "+toHexString(chosenCaps.getEGLConfig())+", "+chosenCaps);
+ System.err.println("EGLGraphicsConfiguration.eglChooseConfig: X chosen :"+chosenIndex+", eglConfig: "+toHexString(chosenCaps.getEGLConfig())+": "+res);
}
- return new EGLGraphicsConfiguration(absScreen, chosenCaps, capsRequested, chooser);
+ return res;
}
- static List/*<GLCapabilitiesImmutable>*/ eglConfigs2GLCaps(GLProfile glp, long eglDisplay, PointerBuffer configs, int num, int winattrmask, boolean forceTransparentFlag) {
- ArrayList caps = new ArrayList(num);
+ static List<GLCapabilitiesImmutable> eglConfigs2GLCaps(EGLGraphicsDevice device, GLProfile glp, PointerBuffer configs, int num, int winattrmask, boolean forceTransparentFlag, boolean onlyFirstValid) {
+ final GLRendererQuirks defaultQuirks = GLRendererQuirks.getStickyDeviceQuirks( GLDrawableFactory.getEGLFactory().getDefaultDevice() );
+ List<GLCapabilitiesImmutable> bucket = new ArrayList<GLCapabilitiesImmutable>(num);
for(int i=0; i<num; i++) {
- EGLGraphicsConfiguration.EGLConfig2Capabilities(caps, glp, eglDisplay, configs.get(i), winattrmask, forceTransparentFlag);
+ final GLCapabilitiesImmutable caps = EGLGraphicsConfiguration.EGLConfig2Capabilities(defaultQuirks, device, glp, configs.get(i), winattrmask, forceTransparentFlag);
+ if(null != caps) {
+ bucket.add(caps);
+ if(onlyFirstValid) {
+ break;
+ }
+ }
}
- return caps;
+ return bucket;
}
- static void printCaps(String prefix, List/*GLCapabilitiesImmutable*/ caps, PrintStream out) {
+ static void printCaps(String prefix, List<GLCapabilitiesImmutable> caps, PrintStream out) {
for(int i=0; i<caps.size(); i++) {
out.println(prefix+"["+i+"] "+caps.get(i));
}
}
-
- static EGLGraphicsConfiguration createOffscreenGraphicsConfiguration(AbstractGraphicsDevice device, GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsReq, GLCapabilitiesChooser chooser) {
- if(capsChosen.isOnscreen()) {
- throw new GLException("Error: Onscreen set: "+capsChosen);
- }
-
- if(capsChosen.getDoubleBuffered()) {
- // OFFSCREEN !DOUBLE_BUFFER // FIXME DBLBUFOFFSCRN
- GLCapabilities caps2 = (GLCapabilities) capsChosen.cloneMutable();
- caps2.setDoubleBuffered(false);
- capsChosen = caps2;
- }
-
- DefaultGraphicsScreen screen = new DefaultGraphicsScreen(device, 0);
- EGLGraphicsConfiguration eglConfig = chooseGraphicsConfigurationStatic(capsChosen, capsReq, chooser, screen, VisualIDHolder.VID_UNDEFINED, false);
- if (null == eglConfig) {
- throw new GLException("Couldn't create EGLGraphicsConfiguration from "+screen);
- } else if(DEBUG) {
- System.err.println("Chosen eglConfig: "+eglConfig);
- }
- return eglConfig;
- }
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenContext.java
deleted file mode 100644
index dd0a3db3a..000000000
--- a/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenContext.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * - Redistribution of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistribution 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.
- *
- * Neither the name of Sun Microsystems, Inc. or the names of
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * This software is provided "AS IS," without a warranty of any kind. ALL
- * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
- * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
- * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
- * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
- * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
- * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
- * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
- * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
- * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
- * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
- *
- * Sun gratefully acknowledges that this software was originally authored
- * and developed by Kenneth Bradley Russell and Christopher John Kline.
- */
-
-package jogamp.opengl.egl;
-
-import javax.media.nativewindow.*;
-import javax.media.opengl.*;
-import jogamp.opengl.*;
-import com.jogamp.gluegen.runtime.ProcAddressTable;
-import java.nio.*;
-import java.util.*;
-
-public class EGLOnscreenContext extends EGLContext {
- public EGLOnscreenContext(EGLOnscreenDrawable drawable, GLContext shareWith) {
- super(drawable, shareWith);
- }
-
- public void bindPbufferToTexture() {
- throw new GLException("Should not call this");
- }
-
- public void releasePbufferFromTexture() {
- throw new GLException("Should not call this");
- }
-
-}
-
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java
index 42f067b29..065f80dcb 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java
@@ -1,22 +1,22 @@
/*
* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
* Copyright (c) 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:
- *
+ *
* - Redistribution of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
- *
+ *
* - Redistribution 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.
- *
+ *
* Neither the name of Sun Microsystems, Inc. or the names of
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
- *
+ *
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
@@ -29,11 +29,11 @@
* DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
* ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
* SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
- *
+ *
* You acknowledge that this software is not designed or intended for use
* in the design, construction, operation or maintenance of any nuclear
* facility.
- *
+ *
* Sun gratefully acknowledges that this software was originally authored
* and developed by Kenneth Bradley Russell and Christopher John Kline.
*/
@@ -48,12 +48,14 @@ public class EGLOnscreenDrawable extends EGLDrawable {
super(factory, component);
}
+ @Override
public GLContext createContext(GLContext shareWith) {
- return new EGLOnscreenContext(this, shareWith);
+ return new EGLContext(this, shareWith);
}
- protected long createSurface(long eglDpy, long eglNativeCfg, long surfaceHandle) {
- return EGL.eglCreateWindowSurface(eglDpy, eglNativeCfg, surfaceHandle, null);
+ @Override
+ protected long createSurface(EGLGraphicsConfiguration config, int width, int height, long nativeSurfaceHandle) {
+ return EGL.eglCreateWindowSurface(config.getScreen().getDevice().getHandle(), config.getNativeConfig(), nativeSurfaceHandle, null);
}
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferContext.java
deleted file mode 100644
index 2cad7daac..000000000
--- a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferContext.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * - Redistribution of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistribution 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.
- *
- * Neither the name of Sun Microsystems, Inc. or the names of
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * This software is provided "AS IS," without a warranty of any kind. ALL
- * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
- * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
- * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
- * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
- * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
- * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
- * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
- * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
- * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
- * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
- *
- * Sun gratefully acknowledges that this software was originally authored
- * and developed by Kenneth Bradley Russell and Christopher John Kline.
- */
-
-package jogamp.opengl.egl;
-
-import javax.media.nativewindow.*;
-import javax.media.opengl.*;
-import jogamp.opengl.*;
-import com.jogamp.gluegen.runtime.ProcAddressTable;
-import java.nio.*;
-import java.util.*;
-
-public class EGLPbufferContext extends EGLContext {
- public EGLPbufferContext(EGLPbufferDrawable drawable, GLContext shareWith) {
- super(drawable, shareWith);
- }
-
- public int getFloatingPointMode() {
- return 0; // FIXME ??
- }
-
- public void bindPbufferToTexture() {
- throw new GLException("Not yet implemented");
- }
-
- public void releasePbufferFromTexture() {
- throw new GLException("Not yet implemented");
- }
-}
-
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
index 28a23d294..45e39f5d1 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
@@ -1,22 +1,22 @@
/*
* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
* Copyright (c) 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:
- *
+ *
* - Redistribution of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
- *
+ *
* - Redistribution 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.
- *
+ *
* Neither the name of Sun Microsystems, Inc. or the names of
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
- *
+ *
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
@@ -29,64 +29,35 @@
* DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
* ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
* SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
- *
+ *
* You acknowledge that this software is not designed or intended for use
* in the design, construction, operation or maintenance of any nuclear
* facility.
- *
+ *
* Sun gratefully acknowledges that this software was originally authored
* and developed by Kenneth Bradley Russell and Christopher John Kline.
*/
package jogamp.opengl.egl;
-import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.NativeSurface;
-import javax.media.nativewindow.SurfaceChangeable;
-import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
-import javax.media.opengl.GLException;
public class EGLPbufferDrawable extends EGLDrawable {
- private int texFormat;
protected static final boolean useTexture = false; // No yet ..
protected EGLPbufferDrawable(EGLDrawableFactory factory, NativeSurface target) {
super(factory, target);
}
- protected void destroyImpl() {
- setRealized(false);
- }
-
- protected long createSurface(long eglDpy, long eglNativeCfg, long surfaceHandle) {
- final AbstractGraphicsConfiguration config = getNativeSurface().getGraphicsConfiguration();
- final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
-
- if(useTexture) {
- texFormat = caps.getAlphaBits() > 0 ? EGL.EGL_TEXTURE_RGBA : EGL.EGL_TEXTURE_RGB ;
- } else {
- texFormat = EGL.EGL_NO_TEXTURE;
- }
-
- if (DEBUG) {
- System.out.println("Pbuffer config: " + config);
- }
-
- NativeSurface nw = getNativeSurface();
- int[] attrs = EGLGraphicsConfiguration.CreatePBufferSurfaceAttribList(nw.getWidth(), nw.getHeight(), texFormat);
- long surf = EGL.eglCreatePbufferSurface(eglDpy, eglNativeCfg, attrs, 0);
- if (EGL.EGL_NO_SURFACE==surf) {
- throw new GLException("Creation of window surface (eglCreatePbufferSurface) failed, dim "+nw.getWidth()+"x"+nw.getHeight()+", error 0x"+Integer.toHexString(EGL.eglGetError()));
- } else if(DEBUG) {
- System.err.println("PBuffer setSurface result: eglSurface 0x"+Long.toHexString(surf));
- }
- ((SurfaceChangeable)nw).setSurfaceHandle(surf);
- return surf;
+ @Override
+ protected long createSurface(EGLGraphicsConfiguration config, int width, int height, long nativeSurfaceHandle) {
+ return EGLDrawableFactory.createPBufferSurfaceImpl(config, width, height, false);
}
+ @Override
public GLContext createContext(GLContext shareWith) {
- return new EGLPbufferContext(this, shareWith);
+ return new EGLContext(this, shareWith);
}
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java b/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java
new file mode 100644
index 000000000..5b911576e
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java
@@ -0,0 +1,217 @@
+package jogamp.opengl.egl;
+
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.DefaultGraphicsScreen;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+import javax.media.nativewindow.VisualIDHolder.VIDType;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLException;
+
+import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
+
+/**
+ * <pre>
+ * EGLWrappedSurface [ is_a -> WrappedSurface -> ProxySurfaceImpl -> ProxySurface -> MutableSurface -> NativeSurface] has_a
+ * EGLUpstreamSurfaceHook [ is_a -> UpstreamSurfaceHook.MutableSize -> UpstreamSurfaceHook ] has_a
+ * NativeSurface (i.e. native X11 surface)
+ * </pre>
+ */
+public class EGLUpstreamSurfaceHook implements UpstreamSurfaceHook.MutableSize {
+ protected static final boolean DEBUG = EGLDrawableFactory.DEBUG;
+ private final NativeSurface upstreamSurface;
+ private final UpstreamSurfaceHook.MutableSize upstreamSurfaceHookMutableSize;
+
+ public EGLUpstreamSurfaceHook(NativeSurface upstream) {
+ upstreamSurface = upstream;
+ if(upstreamSurface instanceof ProxySurface) {
+ final UpstreamSurfaceHook ush = ((ProxySurface)upstreamSurface).getUpstreamSurfaceHook();
+ if(ush instanceof UpstreamSurfaceHook.MutableSize) {
+ // offscreen NativeSurface w/ MutableSize (default)
+ upstreamSurfaceHookMutableSize = (UpstreamSurfaceHook.MutableSize) ush;
+ } else {
+ upstreamSurfaceHookMutableSize = null;
+ }
+ } else {
+ upstreamSurfaceHookMutableSize = null;
+ }
+ }
+
+ public final NativeSurface getUpstreamSurface() { return upstreamSurface; }
+
+ static String getThreadName() { return Thread.currentThread().getName(); }
+
+ @Override
+ public final void setSize(int width, int height) {
+ if(null != upstreamSurfaceHookMutableSize) {
+ upstreamSurfaceHookMutableSize.setSize(width, height);
+ }
+ }
+
+ @Override
+ public final void create(ProxySurface surface) {
+ final String dbgPrefix;
+ if(DEBUG) {
+ dbgPrefix = getThreadName() + ": EGLUpstreamSurfaceHook.create( up "+upstreamSurface.getClass().getSimpleName()+" -> this "+surface.getClass().getSimpleName()+" ): ";
+ System.err.println(dbgPrefix+this);
+ } else {
+ dbgPrefix = null;
+ }
+
+ if(upstreamSurface instanceof ProxySurface) {
+ // propagate createNotify(..) so upstreamSurface will be created
+ ((ProxySurface)upstreamSurface).createNotify();
+ }
+
+ // lock upstreamSurface, so it can be used in case EGLDisplay is derived from it!
+ if(NativeSurface.LOCK_SURFACE_NOT_READY >= upstreamSurface.lockSurface()) {
+ throw new GLException("Could not lock: "+upstreamSurface);
+ }
+ try {
+ evalUpstreamSurface(dbgPrefix, surface);
+ } finally {
+ upstreamSurface.unlockSurface();
+ }
+ }
+
+ private final void evalUpstreamSurface(String dbgPrefix, ProxySurface surface) {
+ //
+ // evaluate nature of upstreamSurface, may create EGL instances if required
+ //
+
+ boolean isEGLSurfaceValid = true; // assume yes
+
+ final EGLGraphicsDevice eglDevice;
+ final AbstractGraphicsConfiguration aConfig;
+ {
+ final AbstractGraphicsConfiguration surfaceConfig = surface.getGraphicsConfiguration();
+ final AbstractGraphicsDevice surfaceDevice = null != surfaceConfig ? surfaceConfig.getScreen().getDevice() : null;
+ if(DEBUG) {
+ System.err.println(dbgPrefix+"SurfaceDevice: "+surfaceDevice.getClass().getSimpleName()+", hash 0x"+Integer.toHexString(surfaceDevice.hashCode())+", "+surfaceDevice);
+ System.err.println(dbgPrefix+"SurfaceConfig: "+surfaceConfig.getClass().getSimpleName()+", hash 0x"+Integer.toHexString(surfaceConfig.hashCode())+", "+surfaceConfig);
+ }
+
+ final AbstractGraphicsConfiguration upstreamConfig = upstreamSurface.getGraphicsConfiguration();
+ final AbstractGraphicsDevice upstreamDevice = upstreamConfig.getScreen().getDevice();
+ if(DEBUG) {
+ System.err.println(dbgPrefix+"UpstreamDevice: "+upstreamDevice.getClass().getSimpleName()+", hash 0x"+Integer.toHexString(upstreamDevice.hashCode())+", "+upstreamDevice);
+ System.err.println(dbgPrefix+"UpstreamConfig: "+upstreamConfig.getClass().getSimpleName()+", hash 0x"+Integer.toHexString(upstreamConfig.hashCode())+", "+upstreamConfig);
+ }
+
+ if( surfaceDevice instanceof EGLGraphicsDevice ) {
+ eglDevice = (EGLGraphicsDevice) surfaceDevice;
+ aConfig = surfaceConfig;
+ if(DEBUG) {
+ System.err.println(dbgPrefix+"Reusing this eglDevice: "+eglDevice+", using this config "+aConfig.getClass().getSimpleName()+" "+aConfig);
+ }
+ if(EGL.EGL_NO_DISPLAY == eglDevice.getHandle()) {
+ eglDevice.open();
+ isEGLSurfaceValid = false;
+ surface.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE );
+ }
+ } else if( upstreamDevice instanceof EGLGraphicsDevice ) {
+ eglDevice = (EGLGraphicsDevice) upstreamDevice;
+ aConfig = upstreamConfig;
+ if(DEBUG) {
+ System.err.println(dbgPrefix+"Reusing upstream eglDevice: "+eglDevice+", using upstream config "+aConfig.getClass().getSimpleName()+" "+aConfig);
+ }
+ if(EGL.EGL_NO_DISPLAY == eglDevice.getHandle()) {
+ eglDevice.open();
+ isEGLSurfaceValid = false;
+ surface.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE );
+ }
+ } else {
+ eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(upstreamSurface);
+ eglDevice.open();
+ aConfig = upstreamConfig;
+ isEGLSurfaceValid = false;
+ surface.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_DEVICE );
+ }
+ }
+
+ final GLCapabilitiesImmutable capsRequested = (GLCapabilitiesImmutable) aConfig.getRequestedCapabilities();
+ final EGLGraphicsConfiguration eglConfig;
+ if( aConfig instanceof EGLGraphicsConfiguration ) {
+ // Config is already in EGL type - reuse ..
+ final EGLGLCapabilities capsChosen = (EGLGLCapabilities) aConfig.getChosenCapabilities();
+ if( !isEGLSurfaceValid || !EGLGraphicsConfiguration.isEGLConfigValid(eglDevice.getHandle(), capsChosen.getEGLConfig()) ) {
+ // '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 with error "+EGLContext.toHexString(EGL.eglGetError())+": "+eglDevice+", "+capsChosen+" of "+aConfig);
+ }
+ final AbstractGraphicsScreen eglScreen = new DefaultGraphicsScreen(eglDevice, aConfig.getScreen().getIndex());
+ eglConfig = new EGLGraphicsConfiguration(eglScreen, capsChosen, capsRequested, null);
+ if(DEBUG) {
+ System.err.println(dbgPrefix+"Refreshing eglConfig: "+eglConfig);
+ }
+ isEGLSurfaceValid = false;
+ } else {
+ eglConfig = (EGLGraphicsConfiguration) aConfig;
+ if(DEBUG) {
+ System.err.println(dbgPrefix+"Reusing eglConfig: "+eglConfig);
+ }
+ }
+ } else {
+ final AbstractGraphicsScreen eglScreen = new DefaultGraphicsScreen(eglDevice, aConfig.getScreen().getIndex());
+ eglConfig = EGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(
+ capsRequested, capsRequested, null, eglScreen, aConfig.getVisualID(VIDType.NATIVE), false /* forceTransparencyFlag */);
+
+ if (null == eglConfig) {
+ throw new GLException("Couldn't create EGLGraphicsConfiguration from "+eglScreen);
+ } else if(DEBUG) {
+ System.err.println(dbgPrefix+"Chosen eglConfig: "+eglConfig);
+ }
+ isEGLSurfaceValid = false;
+ }
+ surface.setGraphicsConfiguration(eglConfig);
+
+ if(isEGLSurfaceValid) {
+ isEGLSurfaceValid = EGLDrawable.isValidEGLSurface(eglDevice.getHandle(), upstreamSurface.getSurfaceHandle());
+ }
+ if(isEGLSurfaceValid) {
+ surface.setSurfaceHandle(upstreamSurface.getSurfaceHandle());
+ surface.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+ if(DEBUG) {
+ System.err.println(dbgPrefix+"Fin: Already valid EGL surface - use as-is: "+upstreamSurface);
+ }
+ } else {
+ surface.setSurfaceHandle(EGL.EGL_NO_SURFACE);
+ surface.addUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ); // create/destroy in EGLDrawable
+ if(DEBUG) {
+ System.err.println(dbgPrefix+"Fin: EGL surface n/a - TBD: "+upstreamSurface);
+ }
+ }
+ }
+
+ @Override
+ public final void destroy(ProxySurface surface) {
+ if(EGLDrawableFactory.DEBUG) {
+ System.err.println("EGLUpstreamSurfaceHook.destroy("+surface.getClass().getSimpleName()+"): "+this);
+ }
+ surface.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
+ if(upstreamSurface instanceof ProxySurface) {
+ ((ProxySurface)upstreamSurface).destroyNotify();
+ }
+ }
+
+ @Override
+ public final int getWidth(ProxySurface s) {
+ return upstreamSurface.getWidth();
+ }
+
+ @Override
+ public final int getHeight(ProxySurface s) {
+ return upstreamSurface.getHeight();
+ }
+
+ @Override
+ public String toString() {
+ final String us_s = null != upstreamSurface ? ( upstreamSurface.getClass().getName() + ": 0x" + Long.toHexString(upstreamSurface.getSurfaceHandle()) ) : "nil";
+ return "EGLUpstreamSurfaceHook[ "+ upstreamSurface.getWidth() + "x" + upstreamSurface.getHeight() + ", " + us_s+ "]";
+ }
+
+}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLWrappedSurface.java b/src/jogl/classes/jogamp/opengl/egl/EGLWrappedSurface.java
new file mode 100644
index 000000000..e6d43d957
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLWrappedSurface.java
@@ -0,0 +1,34 @@
+package jogamp.opengl.egl;
+
+import javax.media.nativewindow.NativeSurface;
+
+import jogamp.nativewindow.WrappedSurface;
+
+/**
+ * <pre>
+ * EGLWrappedSurface [ is_a -> WrappedSurface -> ProxySurfaceImpl -> ProxySurface -> MutableSurface -> NativeSurface] has_a
+ * EGLUpstreamSurfaceHook [ is_a -> UpstreamSurfaceHook.MutableSize -> UpstreamSurfaceHook ] has_a
+ * NativeSurface (i.e. native X11 surface)
+ * </pre>
+ */
+public class EGLWrappedSurface extends WrappedSurface {
+
+ public static EGLWrappedSurface get(NativeSurface surface) {
+ if(surface instanceof EGLWrappedSurface) {
+ return (EGLWrappedSurface)surface;
+ }
+ return new EGLWrappedSurface(surface);
+ }
+
+ public EGLWrappedSurface(NativeSurface surface) {
+ super(surface.getGraphicsConfiguration(), EGL.EGL_NO_SURFACE, new EGLUpstreamSurfaceHook(surface), false /* tbd in UpstreamSurfaceHook */);
+ if(EGLDrawableFactory.DEBUG) {
+ System.err.println("EGLWrappedSurface.ctor(): "+this);
+ }
+ }
+
+ @Override
+ public final NativeSurface getUpstreamSurface() {
+ return ((EGLUpstreamSurfaceHook)super.getUpstreamSurfaceHook()).getUpstreamSurface();
+ }
+}