aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/jogamp/opengl/egl
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl/classes/jogamp/opengl/egl')
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/DesktopES2DynamicLibraryBundleInfo.java9
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLContext.java289
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java38
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java106
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java1039
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java1
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java16
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLES1DynamicLibraryBundleInfo.java3
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java3
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLGLnDynamicLibraryBundleInfo.java83
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java23
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java61
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java63
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLSurface.java165
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java45
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLWrappedSurface.java30
18 files changed, 1209 insertions, 769 deletions
diff --git a/src/jogl/classes/jogamp/opengl/egl/DesktopES2DynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/egl/DesktopES2DynamicLibraryBundleInfo.java
index 8c6091273..245b6a945 100644
--- a/src/jogl/classes/jogamp/opengl/egl/DesktopES2DynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/egl/DesktopES2DynamicLibraryBundleInfo.java
@@ -28,9 +28,12 @@
package jogamp.opengl.egl;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.List;
-import jogamp.opengl.*;
+import com.jogamp.opengl.egl.EGL;
+
+import jogamp.opengl.GLDynamicLibraryBundleInfo;
/**
* Implementation of the DynamicLookupHelper for Desktop ES2 (AMD, ..)
@@ -56,7 +59,7 @@ public final class DesktopES2DynamicLibraryBundleInfo extends GLDynamicLibraryBu
@Override
public final long toolGetProcAddress(final long toolGetProcAddressHandle, final String funcName) {
- return EGL.eglGetProcAddress(toolGetProcAddressHandle, funcName);
+ return EGLContext.eglGetProcAddress(toolGetProcAddressHandle, funcName);
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
index 964401244..b3c848012 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
@@ -50,20 +50,31 @@ import javax.media.opengl.GLProfile;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableImpl;
+import jogamp.opengl.egl.EGLExtImpl;
+import jogamp.opengl.egl.EGLExtProcAddressTable;
+import com.jogamp.common.ExceptionUtils;
import com.jogamp.common.nio.Buffers;
import com.jogamp.gluegen.runtime.ProcAddressTable;
import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
import com.jogamp.opengl.GLRendererQuirks;
+import com.jogamp.opengl.egl.EGL;
+import com.jogamp.opengl.egl.EGLExt;
public class EGLContext extends GLContextImpl {
- private boolean eglQueryStringInitialized;
- private boolean eglQueryStringAvailable;
- private EGLExt _eglExt;
// Table that holds the addresses of the native C-language entry points for
// EGL extension functions.
private EGLExtProcAddressTable eglExtProcAddressTable;
+ private EGLExtImpl eglExtImpl;
+
+ static final int CTX_PROFILE_COMPAT = GLContext.CTX_PROFILE_COMPAT;
+ static final int CTX_PROFILE_CORE = GLContext.CTX_PROFILE_CORE;
+ static final int CTX_PROFILE_ES = GLContext.CTX_PROFILE_ES;
+
+ public static String getGLProfile(final int major, final int minor, final int ctp) throws GLException {
+ return GLContext.getGLProfile(major, minor, ctp);
+ }
EGLContext(final GLDrawableImpl drawable,
final GLContext shareWith) {
@@ -72,10 +83,8 @@ public class EGLContext extends GLContextImpl {
@Override
protected void resetStates(final boolean isInit) {
- eglQueryStringInitialized = false;
- eglQueryStringAvailable = false;
eglExtProcAddressTable = null;
- // no inner state _eglExt = null;
+ eglExtImpl = null;
super.resetStates(isInit);
}
@@ -84,11 +93,8 @@ public class EGLContext extends GLContextImpl {
return getEGLExt();
}
- public EGLExt getEGLExt() {
- if (_eglExt == null) {
- _eglExt = new EGLExtImpl(this);
- }
- return _eglExt;
+ public final EGLExt getEGLExt() {
+ return eglExtImpl;
}
@Override
@@ -96,10 +102,6 @@ public class EGLContext extends GLContextImpl {
return eglExtProcAddressTable;
}
- public final EGLExtProcAddressTable getEGLExtProcAddressTable() {
- return eglExtProcAddressTable;
- }
-
@Override
protected Map<String, String> getFunctionNameMap() { return null; }
@@ -140,11 +142,6 @@ public class EGLContext extends GLContextImpl {
}
@Override
- protected long createContextARBImpl(final long share, final boolean direct, final int ctp, final int major, final int minor) {
- return 0; // FIXME
- }
-
- @Override
protected void destroyContextARBImpl(final long _context) {
if (!EGL.eglDestroyContext(drawable.getNativeSurface().getDisplayHandle(), _context)) {
final int eglError = EGL.eglGetError();
@@ -155,14 +152,35 @@ public class EGLContext extends GLContextImpl {
}
}
+ private static final int ctx_attribs_idx_major = 0;
+ private static final int ctx_attribs_rom[] = {
+ /* 0 */ EGLExt.EGL_CONTEXT_MAJOR_VERSION_KHR, 0, // alias of EGL.EGL_CONTEXT_CLIENT_VERSION
+ /* 2 */ EGL.EGL_NONE, EGL.EGL_NONE, // EGLExt.EGL_CONTEXT_MINOR_VERSION_KHR
+ /* 4 */ EGL.EGL_NONE, EGL.EGL_NONE, // EGLExt.EGL_CONTEXT_FLAGS_KHR
+ /* 6 */ EGL.EGL_NONE, EGL.EGL_NONE, // EGLExt.EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR
+ /* 8 */ EGL.EGL_NONE, EGL.EGL_NONE, // EGLExt.EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR
+ /* 10 */ EGL.EGL_NONE
+ };
+
@Override
- protected boolean createImpl(final long shareWithHandle) throws GLException {
+ protected long createContextARBImpl(final long share, final boolean direct, final int ctp, final int reqMajor, final int reqMinor) {
final EGLGraphicsConfiguration config = (EGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration();
- final long eglDisplay = config.getScreen().getDevice().getHandle();
- final GLProfile glProfile = drawable.getGLProfile();
+ final EGLGraphicsDevice device = (EGLGraphicsDevice) config.getScreen().getDevice();
+ final long eglDisplay = device.getHandle();
final long eglConfig = config.getNativeConfig();
- // 0 == EGL.EGL_NO_CONTEXT;
-
+ final EGLDrawableFactory factory = (EGLDrawableFactory) drawable.getFactoryImpl();
+
+ final boolean useKHRCreateContext = !GLProfile.disableOpenGLARBContext && factory.hasDefaultDeviceKHRCreateContext();
+ final boolean ctDesktopGL = 0 == ( GLContext.CTX_PROFILE_ES & ctp );
+ final boolean ctBwdCompat = 0 != ( CTX_PROFILE_COMPAT & ctp ) ;
+ final boolean ctFwdCompat = 0 != ( CTX_OPTION_FORWARD & ctp ) ;
+ final boolean ctDebug = 0 != ( CTX_OPTION_DEBUG & ctp ) ;
+
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": EGLContext.createContextARBImpl: Start "+getGLVersion(reqMajor, reqMinor, ctp, "@creation")
+ + ", useKHRCreateContext "+useKHRCreateContext
+ + ", device "+device);
+ }
if ( 0 == eglDisplay ) {
throw new GLException("Error: attempted to create an OpenGL context without a display connection");
}
@@ -170,72 +188,150 @@ public class EGLContext extends GLContextImpl {
throw new GLException("Error: attempted to create an OpenGL context without a graphics configuration");
}
+ if( !useKHRCreateContext && ctDesktopGL ) {
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": EGLContext.createContextARBImpl: DesktopGL not avail "+getGLVersion(reqMajor, reqMinor, ctp, "@creation"));
+ }
+ return 0; // n/a
+ }
try {
// might be unavailable on EGL < 1.2
- if( !EGL.eglBindAPI(EGL.EGL_OPENGL_ES_API) ) {
- throw new GLException("Caught: eglBindAPI to ES failed , error "+toHexString(EGL.eglGetError()));
+ if( !EGL.eglBindAPI( ctDesktopGL ? EGL.EGL_OPENGL_API : EGL.EGL_OPENGL_ES_API) ) {
+ throw new GLException("Caught: eglBindAPI to "+(ctDesktopGL ? "ES" : "GL")+" failed , error "+toHexString(EGL.eglGetError())+" - "+getGLVersion(reqMajor, reqMinor, ctp, "@creation"));
}
} catch (final GLException glex) {
if (DEBUG) {
- glex.printStackTrace();
+ ExceptionUtils.dumpThrowable("", glex);
}
}
- // Cannot check extension 'EGL_KHR_create_context' before having one current!
+ final int useMajor;
+ if( reqMajor >= 3 &&
+ GLRendererQuirks.existStickyDeviceQuirk( GLDrawableFactory.getEGLFactory().getDefaultDevice(), GLRendererQuirks.GLES3ViaEGLES2Config) ) {
+ useMajor = 2;
+ } else {
+ useMajor = reqMajor;
+ }
+
+ final IntBuffer attribs = Buffers.newDirectIntBuffer(ctx_attribs_rom);
+ if( useKHRCreateContext ) {
+ attribs.put(ctx_attribs_idx_major + 1, useMajor);
- final IntBuffer contextAttrsNIO;
- final int contextVersionReq, contextVersionAttr;
- {
- if ( glProfile.usesNativeGLES3() ) {
- contextVersionReq = 3;
- if( GLRendererQuirks.existStickyDeviceQuirk( GLDrawableFactory.getEGLFactory().getDefaultDevice(), GLRendererQuirks.GLES3ViaEGLES2Config) ) {
- contextVersionAttr = 2;
+ int index = ctx_attribs_idx_major + 2;
+
+ /** if( ctDesktopGL && reqMinor >= 0 ) { // FIXME: No minor version probing for ES currently!
+ attribs.put(index + 0, EGLExt.EGL_CONTEXT_MINOR_VERSION_KHR);
+ attribs.put(index + 1, reqMinor);
+ index += 2;
+ } */
+
+ if( ctDesktopGL && ( useMajor > 3 || useMajor == 3 && reqMinor >= 2 ) ) {
+ attribs.put(index + 0, EGLExt.EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR);
+ if( ctBwdCompat ) {
+ attribs.put(index + 1, EGLExt.EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR);
} else {
- contextVersionAttr = 3;
+ attribs.put(index + 1, EGLExt.EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR);
+ }
+ index += 2;
+ }
+ int flags = 0;
+ if( ctDesktopGL && useMajor >= 3 && !ctBwdCompat && ctFwdCompat ) {
+ flags |= EGLExt.EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
+ }
+ if( ctDebug ) {
+ flags |= EGLExt.EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
+ }
+ // TODO: flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR
+ if( 0 != flags ) {
+ attribs.put(index + 0, EGLExt.EGL_CONTEXT_FLAGS_KHR);
+ attribs.put(index + 1, flags);
+ index += 2;
+ }
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": EGLContext.createContextARBImpl: attrs.1: major "+useMajor+", flags "+toHexString(flags)+", index "+index);
+ }
+ } else {
+ attribs.put(ctx_attribs_idx_major + 1, useMajor);
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": EGLContext.createContextARBImpl: attrs.2: major "+useMajor);
+ }
+ }
+
+ long ctx=0;
+ try {
+ ctx = EGL.eglCreateContext(eglDisplay, eglConfig, share, attribs);
+ } catch (final RuntimeException re) {
+ if(DEBUG) {
+ System.err.println(getThreadName()+": Info: EGLContext.createContextARBImpl glXCreateContextAttribsARB failed with "+getGLVersion(reqMajor, reqMinor, ctp, "@creation"));
+ ExceptionUtils.dumpThrowable("", re);
+ }
+ }
+
+ if(0!=ctx) {
+ if (!EGL.eglMakeCurrent(eglDisplay, drawable.getHandle(), drawableRead.getHandle(), ctx)) {
+ if(DEBUG) {
+ System.err.println(getThreadName()+": EGLContext.createContextARBImpl couldn't make current "+getGLVersion(reqMajor, reqMinor, ctp, "@creation")+" - error "+toHexString(EGL.eglGetError()));
}
+ // release & destroy
+ EGL.eglMakeCurrent(eglDisplay, EGL.EGL_NO_SURFACE, EGL.EGL_NO_SURFACE, EGL.EGL_NO_CONTEXT);
+ EGL.eglDestroyContext(eglDisplay, ctx);
+ ctx = 0;
+ } else if (DEBUG) {
+ System.err.println(getThreadName() + ": EGLContext.createContextARBImpl: OK "+getGLVersion(reqMajor, reqMinor, ctp, "@creation")+", share "+share+", direct "+direct);
+ }
+ } else if (DEBUG) {
+ System.err.println(getThreadName() + ": EGLContext.createContextARBImpl: NO "+getGLVersion(reqMajor, reqMinor, ctp, "@creation")+" - error "+toHexString(EGL.eglGetError()));
+ }
+
+ return ctx;
+ }
+
+ @Override
+ protected boolean createImpl(final long shareWithHandle) throws GLException {
+ final EGLGraphicsConfiguration config = (EGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration();
+ final AbstractGraphicsDevice device = config.getScreen().getDevice();
+ final boolean availableGLVersionsSet = GLContext.getAvailableGLVersionsSet(device);
+
+ if( !GLProfile.disableOpenGLARBContext && availableGLVersionsSet ) {
+ contextHandle = createContextARB(shareWithHandle, true);
+ if( 0 == contextHandle ) {
+ throw new GLException(getThreadName()+": Unable to create temp OpenGL context(0) on eglDevice "+device+
+ ", eglConfig "+config+", "+drawable.getGLProfile()+", shareWith "+toHexString(shareWithHandle)+", error "+toHexString(EGL.eglGetError()));
+ }
+ } else {
+ final GLProfile glProfile = drawable.getGLProfile();
+ final int reqMajor;
+ if ( glProfile.usesNativeGLES3() ) {
+ reqMajor = 3;
} else if ( glProfile.usesNativeGLES2() ) {
- contextVersionReq = 2;
- contextVersionAttr = 2;
+ reqMajor = 2;
} else if ( glProfile.usesNativeGLES1() ) {
- contextVersionReq = 1;
- contextVersionAttr = 1;
+ reqMajor = 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);
- if (contextHandle == 0) {
- throw new GLException("Error creating OpenGL context: eglDisplay "+toHexString(eglDisplay)+
- ", eglConfig "+config+", "+glProfile+", shareWith "+toHexString(shareWithHandle)+", error "+toHexString(EGL.eglGetError()));
+ final int ctp = GLContext.CTX_PROFILE_ES | getContextCreationFlags();
+ contextHandle = createContextARBImpl(shareWithHandle, true, ctp, reqMajor, 0);
+ if( 0 == contextHandle ) {
+ throw new GLException(getThreadName()+": Unable to create temp OpenGL context(1) on eglDevice "+device+
+ ", eglConfig "+config+", "+drawable.getGLProfile()+", shareWith "+toHexString(shareWithHandle)+", error "+toHexString(EGL.eglGetError()));
+ }
+ if( !setGLFunctionAvailability(true, reqMajor, 0, ctp, false /* strictMatch */, false /* withinGLVersionsMapping */) ) {
+ 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;
+ throw new InternalError("setGLFunctionAvailability !strictMatch failed");
+ }
}
if (DEBUG) {
- System.err.println(getThreadName() + ": Created OpenGL context 0x" +
+ System.err.println(getThreadName() + ": EGLContext.createImpl: Created OpenGL context 0x" +
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(eglDisplay, drawable.getHandle(), drawableRead.getHandle(), contextHandle)) {
- throw new GLException("Error making context " +
- toHexString(contextHandle) + " current: error code " + toHexString(EGL.eglGetError()));
- }
- 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;
- }
+ return true;
}
@Override
@@ -246,8 +342,6 @@ public class EGLContext extends GLContextImpl {
if (DEBUG) {
System.err.println(getThreadName() + ": Initializing EGLextension address table: "+key);
}
- eglQueryStringInitialized = false;
- eglQueryStringAvailable = false;
ProcAddressTable table = null;
synchronized(mappedContextTypeObjectLock) {
@@ -258,31 +352,52 @@ public class EGLContext extends GLContextImpl {
if(DEBUG) {
System.err.println(getThreadName() + ": GLContext EGL ProcAddressTable reusing key("+key+") -> "+toHexString(table.hashCode()));
}
+ if( null == eglExtImpl || eglExtImpl.getProcAdressTable() != eglExtProcAddressTable ) {
+ eglExtImpl = new EGLExtImpl(this, eglExtProcAddressTable);
+ }
} else {
eglExtProcAddressTable = new EGLExtProcAddressTable(new GLProcAddressResolver());
- resetProcAddressTable(getEGLExtProcAddressTable());
+ resetProcAddressTable(eglExtProcAddressTable);
synchronized(mappedContextTypeObjectLock) {
- mappedGLXProcAddress.put(key, getEGLExtProcAddressTable());
+ mappedGLXProcAddress.put(key, eglExtProcAddressTable);
if(DEBUG) {
- System.err.println(getThreadName() + ": GLContext EGL ProcAddressTable mapping key("+key+") -> "+toHexString(getEGLExtProcAddressTable().hashCode()));
+ System.err.println(getThreadName() + ": GLContext EGL ProcAddressTable mapping key("+key+") -> "+toHexString(eglExtProcAddressTable.hashCode()));
}
}
+ eglExtImpl = new EGLExtImpl(this, eglExtProcAddressTable);
}
}
@Override
protected final StringBuilder getPlatformExtensionsStringImpl() {
+ final EGLGraphicsDevice device = (EGLGraphicsDevice) drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice();
+ return getPlatformExtensionsStringImpl(device);
+ }
+ final static StringBuilder getPlatformExtensionsStringImpl(final EGLGraphicsDevice device) {
final StringBuilder sb = new StringBuilder();
- if (!eglQueryStringInitialized) {
- eglQueryStringAvailable = getDrawableImpl().getGLDynamicLookupHelper().isFunctionAvailable("eglQueryString");
- eglQueryStringInitialized = true;
- }
- if (eglQueryStringAvailable) {
- final String ret = EGL.eglQueryString(drawable.getNativeSurface().getDisplayHandle(), EGL.EGL_EXTENSIONS);
+ device.lock();
+ try{
+ final long handle = device.getHandle();
if (DEBUG) {
- System.err.println("EGL extensions: " + ret);
+ System.err.println("EGL PlatformExtensions: Device "+device);
+ EGLDrawableFactory.dumpEGLInfo("EGL PlatformExtensions: ", handle);
}
- sb.append(ret);
+ if( device.getEGLVersion().compareTo(Version1_5) >= 0 ) {
+ final String ret = EGL.eglQueryString(EGL.EGL_NO_DISPLAY, EGL.EGL_EXTENSIONS);
+ if (DEBUG) {
+ System.err.println("EGL extensions (Client): " + ret);
+ }
+ sb.append(ret).append(" ");
+ }
+ if( 0 != handle ) {
+ final String ret = EGL.eglQueryString(handle, EGL.EGL_EXTENSIONS);
+ if (DEBUG) {
+ System.err.println("EGL extensions (Server): " + ret);
+ }
+ sb.append(ret).append(" ");
+ }
+ } finally {
+ device.unlock();
}
return sb;
}
@@ -295,6 +410,16 @@ public class EGLContext extends GLContextImpl {
return EGL.eglSwapInterval(drawable.getNativeSurface().getDisplayHandle(), interval);
}
+ static long eglGetProcAddress(final long eglGetProcAddressHandle, final String procname)
+ {
+ if (0 == eglGetProcAddressHandle) {
+ throw new GLException("Passed null pointer for method \"eglGetProcAddress\"");
+ }
+ return dispatch_eglGetProcAddress0(procname, eglGetProcAddressHandle);
+ }
+ /** Entry point to C language function: <code> __EGLFuncPtr eglGetProcAddress(const char * procname) </code> <br>Part of <code>EGL_VERSION_1_X</code> */
+ static private native long dispatch_eglGetProcAddress0(String procname, long procAddress);
+
//
// Accessible ..
//
@@ -343,8 +468,8 @@ public class EGLContext extends GLContextImpl {
protected static boolean getAvailableGLVersionsSet(final AbstractGraphicsDevice device) {
return GLContext.getAvailableGLVersionsSet(device);
}
- protected static void setAvailableGLVersionsSet(final AbstractGraphicsDevice device) {
- GLContext.setAvailableGLVersionsSet(device);
+ protected static void setAvailableGLVersionsSet(final AbstractGraphicsDevice device, final boolean set) {
+ GLContext.setAvailableGLVersionsSet(device, set);
}
protected static String toHexString(final int hex) {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
index 9499c70f4..199b20464 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDisplayUtil.java
@@ -39,8 +39,11 @@ import javax.media.opengl.GLException;
import jogamp.opengl.Debug;
+import com.jogamp.common.ExceptionUtils;
+import com.jogamp.common.nio.Buffers;
import com.jogamp.common.util.LongObjectHashMap;
import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
+import com.jogamp.opengl.egl.EGL;
/**
* This implementation provides recursive calls to
@@ -148,7 +151,7 @@ public class EGLDisplayUtil {
if(DEBUG || verbose || openEGLDisplays.size() > 0 ) {
System.err.println("EGLDisplayUtil.EGLDisplays: Shutdown (open: "+openEGLDisplays.size()+")");
if(DEBUG) {
- Thread.dumpStack();
+ ExceptionUtils.dumpStack(System.err);
}
if( openEGLDisplays.size() > 0) {
dumpOpenDisplayConnections();
@@ -198,17 +201,30 @@ public class EGLDisplayUtil {
*
* @see EGL#eglInitialize(long, IntBuffer, IntBuffer)
*/
- private static synchronized boolean eglInitialize(final long eglDisplay, final IntBuffer major, final IntBuffer minor) {
+ private static synchronized boolean eglInitialize(final long eglDisplay, final int[] major, final int[] minor) {
if( EGL.EGL_NO_DISPLAY == eglDisplay) {
return false;
}
- final EGLDisplayRef d = EGLDisplayRef.getOrCreateOpened(eglDisplay, major, minor);
+ final EGLDisplayRef d = EGLDisplayRef.getOrCreateOpened(eglDisplay, _eglMajorVersion, _eglMinorVersion);
+ final int _major = _eglMajorVersion.get(0);
+ final int _minor = _eglMinorVersion.get(0);
+ if( null != major && null != minor ) {
+ if( null != d ) {
+ major[0] = _major;
+ minor[0] = _minor;
+ } else {
+ major[0] = 0;
+ minor[0] = 0;
+ }
+ }
if(DEBUG) {
- System.err.println("EGLDisplayUtil.eglInitialize("+EGLContext.toHexString(eglDisplay)+" ...): "+d+" = "+(null != d)+", singletonEGLDisplay "+singletonEGLDisplay+" (use "+useSingletonEGLDisplay+")");
+ System.err.println("EGLDisplayUtil.eglInitialize("+EGLContext.toHexString(eglDisplay)+" ...): "+d+" = "+(null != d)+", eglVersion "+_major+"."+_minor+", singletonEGLDisplay "+singletonEGLDisplay+" (use "+useSingletonEGLDisplay+")");
// Thread.dumpStack();
}
return null != d;
}
+ private static final IntBuffer _eglMajorVersion = Buffers.newDirectIntBuffer(1);
+ private static final IntBuffer _eglMinorVersion = Buffers.newDirectIntBuffer(1);
/**
* @param nativeDisplayID
@@ -222,7 +238,7 @@ public class EGLDisplayUtil {
* @see #eglGetDisplay(long)
* @see #eglInitialize(long, IntBuffer, IntBuffer)
*/
- private static synchronized int eglGetDisplayAndInitialize(final long nativeDisplayID, final long[] eglDisplay, final int[] eglErr, final IntBuffer major, final IntBuffer minor) {
+ private static synchronized int eglGetDisplayAndInitialize(final long nativeDisplayID, final long[] eglDisplay, final int[] eglErr, final int[] major, final int[] minor) {
eglDisplay[0] = EGL.EGL_NO_DISPLAY;
final long _eglDisplay = eglGetDisplay( nativeDisplayID );
if ( EGL.EGL_NO_DISPLAY == _eglDisplay ) {
@@ -244,13 +260,15 @@ public class EGLDisplayUtil {
*
* @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
+ * @param major
+ * @param minor
* @return the initialized EGL display ID
* @throws GLException if not successful
*/
- private static synchronized long eglGetDisplayAndInitialize(final long[] nativeDisplayID) {
+ private static synchronized long eglGetDisplayAndInitialize(final long[] nativeDisplayID, final int[] major, final int[] minor) {
final long[] eglDisplay = new long[1];
final int[] eglError = new int[1];
- int eglRes = EGLDisplayUtil.eglGetDisplayAndInitialize(nativeDisplayID[0], eglDisplay, eglError, null, null);
+ int eglRes = EGLDisplayUtil.eglGetDisplayAndInitialize(nativeDisplayID[0], eglDisplay, eglError, major, minor);
if( EGL.EGL_SUCCESS == eglRes ) {
return eglDisplay[0];
}
@@ -258,7 +276,7 @@ public class EGLDisplayUtil {
if(DEBUG) {
System.err.println("EGLDisplayUtil.eglGetAndInitDisplay failed with native "+EGLContext.toHexString(nativeDisplayID[0])+", error "+EGLContext.toHexString(eglRes)+"/"+EGLContext.toHexString(eglError[0])+" - fallback!");
}
- eglRes = EGLDisplayUtil.eglGetDisplayAndInitialize(EGL.EGL_DEFAULT_DISPLAY, eglDisplay, eglError, null, null);
+ eglRes = EGLDisplayUtil.eglGetDisplayAndInitialize(EGL.EGL_DEFAULT_DISPLAY, eglDisplay, eglError, major, minor);
if( EGL.EGL_SUCCESS == eglRes ) {
nativeDisplayID[0] = EGL.EGL_DEFAULT_DISPLAY;
return eglDisplay[0];
@@ -286,8 +304,8 @@ public class EGLDisplayUtil {
private static final EGLGraphicsDevice.EGLDisplayLifecycleCallback eglLifecycleCallback = new EGLGraphicsDevice.EGLDisplayLifecycleCallback() {
@Override
- public long eglGetAndInitDisplay(final long[] nativeDisplayID) {
- return eglGetDisplayAndInitialize(nativeDisplayID);
+ public long eglGetAndInitDisplay(final long[] nativeDisplayID, final int[] major, final int[] minor) {
+ return eglGetDisplayAndInitialize(nativeDisplayID, major, minor);
}
@Override
public void eglTerminate(final long eglDisplayHandle) {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
index bacf9f18e..5b080a183 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
@@ -36,114 +36,66 @@
package jogamp.opengl.egl;
-import java.nio.IntBuffer;
-
-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.nativewindow.ProxySurfaceImpl;
import jogamp.opengl.GLDrawableImpl;
import jogamp.opengl.GLDynamicLookupHelper;
-import com.jogamp.common.nio.Buffers;
import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
+import com.jogamp.opengl.egl.EGL;
-public abstract class EGLDrawable extends GLDrawableImpl {
+public class EGLDrawable extends GLDrawableImpl {
+ static boolean DEBUG = GLDrawableImpl.DEBUG;
- protected EGLDrawable(final EGLDrawableFactory factory, final NativeSurface component) throws GLException {
+ protected EGLDrawable(final EGLDrawableFactory factory, final EGLSurface component) throws GLException {
super(factory, component, false);
}
@Override
- public abstract GLContext createContext(GLContext shareWith);
-
- protected abstract long createSurface(EGLGraphicsConfiguration config, int width, int height, long nativeSurfaceHandle);
-
- private final long createEGLSurface() {
- final EGLWrappedSurface eglws = (EGLWrappedSurface) surface;
- final EGLGraphicsConfiguration eglConfig = (EGLGraphicsConfiguration) eglws.getGraphicsConfiguration();
- final NativeSurface upstreamSurface = eglws.getUpstreamSurface();
-
- long eglSurface = createSurface(eglConfig, eglws.getSurfaceWidth(), eglws.getSurfaceHeight(), upstreamSurface.getSurfaceHandle());
-
- 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).
- // ANGLE impl. required HWND on Windows.
- 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(eglConfig, eglws.getSurfaceWidth(), eglws.getSurfaceHeight(), 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() + ": createEGLSurface handle "+toHexString(eglSurface));
- }
- return eglSurface;
+ public final GLContext createContext(final GLContext shareWith) {
+ return new EGLContext(this, shareWith);
}
@Override
protected final void createHandle() {
- final EGLWrappedSurface eglws = (EGLWrappedSurface) surface;
+ final EGLSurface eglSurf = (EGLSurface) surface;
if(DEBUG) {
- System.err.println(getThreadName() + ": createHandle of "+eglws);
+ System.err.println(getThreadName() + ": createHandle of "+eglSurf);
+ ProxySurfaceImpl.dumpHierarchy(System.err, eglSurf);
}
- 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);
+ if( eglSurf.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ) ) {
+ if( EGL.EGL_NO_SURFACE != eglSurf.getSurfaceHandle() ) {
+ throw new InternalError("Set surface but claimed to be invalid: "+eglSurf);
+ }
+ if( !eglSurf.containsUpstreamOptionBits( ProxySurface.OPT_UPSTREAM_SURFACELESS ) ) {
+ eglSurf.setEGLSurfaceHandle();
}
- eglws.setSurfaceHandle( createEGLSurface() );
- } else if( EGL.EGL_NO_SURFACE == eglws.getSurfaceHandle() ) {
- throw new InternalError("Nil surface but claimed to be valid: "+eglws);
+ } else if( EGL.EGL_NO_SURFACE == eglSurf.getSurfaceHandle() ) {
+ throw new InternalError("Nil surface but claimed to be valid: "+eglSurf);
}
}
@Override
protected void destroyHandle() {
- final EGLWrappedSurface eglws = (EGLWrappedSurface) surface;
+ final EGLSurface eglSurf = (EGLSurface) surface;
+ final long eglSurfHandle = eglSurf.getSurfaceHandle();
if(DEBUG) {
- System.err.println(getThreadName() + ": destroyHandle of "+eglws);
+ System.err.println(getThreadName() + ": destroyHandle of "+eglSurf);
}
- 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);
- }
- }
-
- protected static boolean isValidEGLSurface(final long eglDisplayHandle, final long surfaceHandle) {
- if( 0 == surfaceHandle ) {
- return false;
+ if( !eglSurf.containsUpstreamOptionBits( ProxySurface.OPT_UPSTREAM_SURFACELESS ) &&
+ EGL.EGL_NO_SURFACE == eglSurfHandle ) {
+ throw new InternalError("Nil surface but claimed to be valid: "+eglSurf);
}
- 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.isValidEGLSurface eglQuerySuface failed: error "+toHexString(eglErr)+", "+toHexString(surfaceHandle));
+ final EGLGraphicsDevice eglDevice = (EGLGraphicsDevice) eglSurf.getGraphicsConfiguration().getScreen().getDevice();
+ if( eglSurf.containsUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE ) ) {
+ if( EGL.EGL_NO_SURFACE != eglSurfHandle ) {
+ EGL.eglDestroySurface(eglDevice.getHandle(), eglSurfHandle);
+ eglSurf.setSurfaceHandle(EGL.EGL_NO_SURFACE);
}
}
- return eglSurfaceValid;
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
index 2edb22314..967bcb6da 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
@@ -40,7 +40,6 @@ 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;
@@ -66,7 +65,6 @@ import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
import jogamp.common.os.PlatformPropsImpl;
-import jogamp.nativewindow.WrappedSurface;
import jogamp.opengl.Debug;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableFactoryImpl;
@@ -75,13 +73,18 @@ import jogamp.opengl.GLDynamicLookupHelper;
import jogamp.opengl.GLGraphicsConfigurationUtil;
import jogamp.opengl.SharedResourceRunner;
+import com.jogamp.common.ExceptionUtils;
import com.jogamp.common.nio.Buffers;
import com.jogamp.common.nio.PointerBuffer;
+import com.jogamp.common.os.DynamicLookupHelper;
import com.jogamp.common.os.Platform;
import com.jogamp.common.util.PropertyAccess;
import com.jogamp.common.util.ReflectionUtil;
+import com.jogamp.common.util.VersionNumber;
+import com.jogamp.nativewindow.GenericUpstreamSurfacelessHook;
import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
import com.jogamp.opengl.GLRendererQuirks;
+import com.jogamp.opengl.egl.EGL;
public class EGLDrawableFactory extends GLDrawableFactoryImpl {
protected static final boolean DEBUG = GLDrawableFactoryImpl.DEBUG; // allow package access
@@ -93,8 +96,10 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
QUERY_EGL_ES_NATIVE_TK = PropertyAccess.isPropertyDefined("jogl.debug.EGLDrawableFactory.QueryNativeTK", true);
}
+ private static boolean eglDynamicLookupHelperInit = false;
private static GLDynamicLookupHelper eglES1DynamicLookupHelper = null;
private static GLDynamicLookupHelper eglES2DynamicLookupHelper = null;
+ private static GLDynamicLookupHelper eglGLnDynamicLookupHelper = null;
private static final boolean isANGLE(final GLDynamicLookupHelper dl) {
if(Platform.OSType.WINDOWS == PlatformPropsImpl.OS_TYPE) {
@@ -112,50 +117,100 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
dl.isFunctionAvailable("glColorPointer");
}
- public EGLDrawableFactory() {
- super();
-
- // Register our GraphicsConfigurationFactory implementations
- // The act of constructing them causes them to be registered
- EGLGraphicsConfigurationFactory.registerFactory();
+ private static class EGLFeatures {
+ public final String vendor;
+ public final VersionNumber version;
+ public final boolean hasGLAPI;
+ public final boolean hasKHRCreateContext;
+ public final boolean hasKHRSurfaceless;
- // Check for other underlying stuff ..
- if(NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(true)) {
- hasX11 = true;
- try {
- ReflectionUtil.createInstance("jogamp.opengl.x11.glx.X11GLXGraphicsConfigurationFactory", EGLDrawableFactory.class.getClassLoader());
- } catch (final Exception jre) { /* n/a .. */ }
+ public EGLFeatures(final EGLGraphicsDevice device) {
+ final long eglDisplay = device.getHandle();
+ vendor = EGL.eglQueryString(eglDisplay, EGL.EGL_VENDOR);
+ if(DEBUG) {
+ System.err.println("EGLFeatures on device "+device+", vendor "+vendor);
+ }
+ version = device.getEGLVersion();
+ final boolean hasEGL_1_4 = version.compareTo(GLContext.Version1_4) >= 0;
+ final boolean hasEGL_1_5 = version.compareTo(GLContext.Version1_5) >= 0;
+ {
+ final String eglClientAPIStr = EGL.eglQueryString(eglDisplay, EGL.EGL_CLIENT_APIS);
+ final String[] eglClientAPIs = eglClientAPIStr.split("\\s");
+ boolean _hasGLAPI = false;
+ for(int i=eglClientAPIs.length-1; i>=0; i--) {
+ _hasGLAPI = eglClientAPIs[i].equals("OpenGL");
+ }
+ hasGLAPI = _hasGLAPI;
+ if(DEBUG) {
+ System.err.println(" Client APIs: "+eglClientAPIStr+"; has OpenGL "+hasGLAPI);
+ }
+ }
+ {
+ final String extensions = EGLContext.getPlatformExtensionsStringImpl(device).toString();
+ if( hasEGL_1_5 ) {
+ // subsumed in EGL 1.5
+ hasKHRCreateContext = true;
+ hasKHRSurfaceless = true;
+ } else {
+ if( hasEGL_1_4 ) {
+ hasKHRCreateContext = extensions.contains("EGL_KHR_create_context");
+ } else {
+ hasKHRCreateContext = false;
+ }
+ hasKHRSurfaceless = extensions.contains("EGL_KHR_surfaceless_context");
+ }
+ if(DEBUG) {
+ System.err.println(" Extensions: "+extensions);
+ System.err.println(" KHR_create_context: "+hasKHRCreateContext);
+ System.err.println(" KHR_surfaceless_context: "+hasKHRSurfaceless);
+ }
+ }
+ }
+ public final String toString() {
+ return "EGLFeatures[vendor "+vendor+", version "+version+
+ ", has[GL-API "+hasGLAPI+", KHR[CreateContext "+hasKHRCreateContext+", Surfaceless "+hasKHRSurfaceless+"]]]";
}
+ }
+
+ static class EGLAcc extends EGL {
+ protected static boolean resetProcAddressTable(final DynamicLookupHelper lookup) {
+ return EGL.resetProcAddressTable(lookup);
+ }
+ }
+ static final String eglInitializeFuncName = "eglInitialize";
- // 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.
+ public EGLDrawableFactory() {
+ super();
synchronized(EGLDrawableFactory.class) {
- final boolean hasDesktopES2 = null != eglES2DynamicLookupHelper;
+ if( eglDynamicLookupHelperInit ) {
+ return;
+ }
+ eglDynamicLookupHelperInit = true;
- if(!hasDesktopES2 && null==eglES1DynamicLookupHelper) {
- GLDynamicLookupHelper tmp=null;
+ // Check for other underlying stuff ..
+ if(NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(true)) {
+ hasX11 = true;
try {
- tmp = new GLDynamicLookupHelper(new EGLES1DynamicLibraryBundleInfo());
- } catch (final GLException gle) {
- if(DEBUG) {
- gle.printStackTrace();
- }
- }
- if(null!=tmp && tmp.isLibComplete()) {
- eglES1DynamicLookupHelper = tmp;
- EGL.resetProcAddressTable(eglES1DynamicLookupHelper);
- final boolean isANGLEES1 = isANGLE(eglES1DynamicLookupHelper);
- isANGLE |= isANGLEES1;
- if (DEBUG || GLProfile.DEBUG) {
- System.err.println("Info: EGLDrawableFactory: EGL ES1 - OK, isANGLE: "+isANGLEES1);
- }
- } else if (DEBUG || GLProfile.DEBUG) {
- System.err.println("Info: EGLDrawableFactory: EGL ES1 - NOPE (ES1 lib)");
- }
+ ReflectionUtil.createInstance("jogamp.opengl.x11.glx.X11GLXGraphicsConfigurationFactory", EGLDrawableFactory.class.getClassLoader());
+ } catch (final Exception jre) { /* n/a .. */ }
}
- if(!hasDesktopES2 && null==eglES2DynamicLookupHelper) {
+
+ /**
+ * 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.
+ *
+ * Since EGL is designed to be static
+ * we validate the function address of 'eglInitialize'
+ * with all EGL/ES and EGL/GL combinations.
+ * In case this address doesn't match the primary tuple EGL/ES2
+ * the profile is skipped!
+ */
+ boolean eglTableReset = false;
+ long eglInitializeAddress = 0;
+ // Setup: eglES2DynamicLookupHelper[, eglES1DynamicLookupHelper]
+ {
GLDynamicLookupHelper tmp=null;
try {
tmp = new GLDynamicLookupHelper(new EGLES2DynamicLibraryBundleInfo());
@@ -164,9 +219,9 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
gle.printStackTrace();
}
}
- if(null!=tmp && tmp.isLibComplete()) {
+ if( null != tmp && tmp.isLibComplete() && true == ( eglTableReset = EGLAcc.resetProcAddressTable(tmp) ) ) {
+ eglInitializeAddress = tmp.dynamicLookupFunction(eglInitializeFuncName);
eglES2DynamicLookupHelper = tmp;
- EGL.resetProcAddressTable(eglES2DynamicLookupHelper);
final boolean includesES1 = null == eglES1DynamicLookupHelper && includesES1(eglES2DynamicLookupHelper);
if(includesES1) {
eglES1DynamicLookupHelper = tmp;
@@ -174,7 +229,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
final boolean isANGLEES2 = isANGLE(eglES2DynamicLookupHelper);
isANGLE |= isANGLEES2;
if (DEBUG || GLProfile.DEBUG) {
- System.err.println("Info: EGLDrawableFactory: EGL ES2 - OK (includesES1 "+includesES1+", isANGLE: "+isANGLEES2+")");
+ System.err.println("Info: EGLDrawableFactory: EGL ES2 - OK (includesES1 "+includesES1+", isANGLE: "+isANGLEES2+", eglInitialize 0x"+Long.toHexString(eglInitializeAddress)+")");
if(includesES1) {
System.err.println("Info: EGLDrawableFactory: EGL ES1 - OK (ES2 lib)");
}
@@ -183,7 +238,85 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
System.err.println("Info: EGLDrawableFactory: EGL ES2 - NOPE");
}
}
- if( null != eglES2DynamicLookupHelper || null != eglES1DynamicLookupHelper ) {
+ // Setup: eglES1DynamicLookupHelper
+ if( null == eglES1DynamicLookupHelper ) {
+ GLDynamicLookupHelper tmp=null;
+ try {
+ tmp = new GLDynamicLookupHelper(new EGLES1DynamicLibraryBundleInfo());
+ } catch (final GLException gle) {
+ if(DEBUG) {
+ gle.printStackTrace();
+ }
+ }
+ if( null != tmp && tmp.isLibComplete() ) {
+ final boolean ok;
+ final long _eglInitializeAddress;
+ if( !eglTableReset ) {
+ if( true == ( eglTableReset = EGLAcc.resetProcAddressTable(tmp) ) ) {
+ _eglInitializeAddress = tmp.dynamicLookupFunction(eglInitializeFuncName);
+ eglInitializeAddress = _eglInitializeAddress;
+ ok = true;
+ } else {
+ _eglInitializeAddress = 0;
+ ok = false;
+ }
+ } else {
+ _eglInitializeAddress = tmp.dynamicLookupFunction(eglInitializeFuncName);
+ ok = _eglInitializeAddress == eglInitializeAddress;
+ }
+ if( ok ) {
+ eglES1DynamicLookupHelper = tmp;
+ final boolean isANGLEES1 = isANGLE(eglES1DynamicLookupHelper);
+ isANGLE |= isANGLEES1;
+ if (DEBUG || GLProfile.DEBUG) {
+ System.err.println("Info: EGLDrawableFactory: EGL ES1 - OK (isANGLE: "+isANGLEES1+", eglTableReset "+eglTableReset+", eglInitialize 0x"+Long.toHexString(_eglInitializeAddress)+")");
+ }
+ } else if (DEBUG || GLProfile.DEBUG) {
+ System.err.println("Info: EGLDrawableFactory: EGL ES1 - NOPE (ES1 proc, eglTableReset "+eglTableReset+", eglInitialize 0x"+Long.toHexString(_eglInitializeAddress)+")");
+ }
+ } else if (DEBUG || GLProfile.DEBUG) {
+ System.err.println("Info: EGLDrawableFactory: EGL ES1 - NOPE (ES1 lib)");
+ }
+ }
+ // Setup: eglGLnDynamicLookupHelper
+ if( null == eglGLnDynamicLookupHelper ) {
+ GLDynamicLookupHelper tmp=null;
+ try {
+ tmp = new GLDynamicLookupHelper(new EGLGLnDynamicLibraryBundleInfo());
+ } catch (final GLException gle) {
+ if(DEBUG) {
+ gle.printStackTrace();
+ }
+ }
+ if( null != tmp && tmp.isLibComplete() ) {
+ final boolean ok;
+ final long _eglInitializeAddress;
+ if( !eglTableReset ) {
+ if( true == ( eglTableReset = EGLAcc.resetProcAddressTable(tmp) ) ) {
+ _eglInitializeAddress = tmp.dynamicLookupFunction(eglInitializeFuncName);
+ eglInitializeAddress = _eglInitializeAddress;
+ ok = true;
+ } else {
+ _eglInitializeAddress = 0;
+ ok = false;
+ }
+ } else {
+ _eglInitializeAddress = tmp.dynamicLookupFunction(eglInitializeFuncName);
+ ok = _eglInitializeAddress == eglInitializeAddress;
+ }
+ if( ok ) {
+ eglGLnDynamicLookupHelper = tmp;
+ if (DEBUG || GLProfile.DEBUG) {
+ System.err.println("Info: EGLDrawableFactory: EGL GLn - OK (eglTableReset "+eglTableReset+", eglInitialize 0x"+Long.toHexString(_eglInitializeAddress)+")");
+ }
+ } else if (DEBUG || GLProfile.DEBUG) {
+ System.err.println("Info: EGLDrawableFactory: EGL GLn - NOPE (GLn proc, eglTableReset "+eglTableReset+", eglInitialize 0x"+Long.toHexString(_eglInitializeAddress)+")");
+ }
+ } else if (DEBUG || GLProfile.DEBUG) {
+ System.err.println("Info: EGLDrawableFactory: EGL GLn - NOPE (GLn lib)");
+ }
+ }
+ if( null != eglES2DynamicLookupHelper || null != eglES1DynamicLookupHelper || null != eglGLnDynamicLookupHelper ) {
if(isANGLE && !GLProfile.enableANGLE) {
if(DEBUG || GLProfile.DEBUG) {
System.err.println("Info: EGLDrawableFactory.init - EGL/ES2 ANGLE disabled");
@@ -192,13 +325,22 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
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>();
+ // Register our GraphicsConfigurationFactory implementations
+ // The act of constructing them causes them to be registered
+ EGLGraphicsConfigurationFactory.registerFactory();
+
+ sharedMap = new HashMap<String, SharedResourceRunner.Resource>();
+
// 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);
+
+ // Init shared resources off thread
+ // Will be released via ShutdownHook
+ sharedResourceRunner = new SharedResourceRunner(new SharedResourceImplementation());
+ sharedResourceRunner.start();
}
}
- }
+ } // synchronized(EGLDrawableFactory.class)
}
@Override
@@ -212,26 +354,15 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
if( DEBUG ) {
System.err.println("EGLDrawableFactory.shutdown");
}
+ if(null != sharedResourceRunner) {
+ sharedResourceRunner.stop();
+ sharedResourceRunner = null;
+ }
if(null != sharedMap) {
- if(DEBUG) {
- dumpMap();
- }
- final Collection<SharedResource> srl = sharedMap.values();
- for(final Iterator<SharedResource> sri = srl.iterator(); sri.hasNext(); ) {
- final SharedResource sr = sri.next();
- if(DEBUG) {
- 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;
@@ -247,6 +378,10 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
// eglES2DynamicLookupHelper.destroy();
eglES2DynamicLookupHelper = null;
}
+ if(null != eglGLnDynamicLookupHelper) {
+ // eglGLDynamicLookupHelper.destroy();
+ eglGLnDynamicLookupHelper = null;
+ }
EGLGraphicsConfigurationFactory.unregisterFactory();
EGLDisplayUtil.shutdown(DEBUG);
}
@@ -258,65 +393,59 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
final Set<String> keys = sharedMap.keySet();
for(final Iterator<String> keyI = keys.iterator(); keyI.hasNext(); i++) {
final String key = keyI.next();
- final 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)+"]]");
+ final SharedResource sr = (SharedResource) sharedMap.get(key);
+ System.err.println("EGLDrawableFactory.map["+i+"] "+key+" -> "+sr.getDevice()+", avail "+sr.isAvailable+
+ "gln [quirks "+sr.rendererQuirksGLn+", ctp "+EGLContext.getGLVersion(3, 0, sr.ctpGLn, null)+"], "+
+ "es1 [quirks "+sr.rendererQuirksES1+", ctp "+EGLContext.getGLVersion(1, 0, sr.ctpES1, null)+"], "+
+ "es2/3 [quirks "+sr.rendererQuirksES3ES2+", ctp "+EGLContext.getGLVersion(2, 0, sr.ctpES3ES2, null)+"]");
}
;
}
}
- 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;
+ private EGLGraphicsDevice defaultDevice = null;
+ private EGLFeatures defaultDeviceEGLFeatures;
+ private SharedResourceRunner sharedResourceRunner;
+ private HashMap<String /* uniqueKey */, SharedResourceRunner.Resource> sharedMap;
static class SharedResource implements SharedResourceRunner.Resource {
- private final EGLGraphicsDevice device;
+ private EGLGraphicsDevice device;
// 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(final EGLGraphicsDevice dev,
- final boolean wasContextES1Created, final boolean hasPBufferES1, final GLRendererQuirks rendererQuirksES1, final int ctpES1,
- final boolean wasContextES2Created, final boolean wasContextES3Created,
- final boolean hasPBufferES3ES2, final GLRendererQuirks rendererQuirksES3ES2, final int ctpES3ES2) {
+ final boolean isAvailable;
+ final GLRendererQuirks rendererQuirksGLn;
+ final GLRendererQuirks rendererQuirksES1;
+ final GLRendererQuirks rendererQuirksES3ES2;
+ final int ctpGLn;
+ final int ctpES1;
+ final int ctpES3ES2;
+
+ SharedResource(final EGLGraphicsDevice dev, final boolean isAvailable,
+ final GLRendererQuirks rendererQuirksGLn, final int ctpGLn,
+ final GLRendererQuirks rendererQuirksES1, final int ctpES1,
+ final GLRendererQuirks rendererQuirksES3ES2, final int ctpES3ES2) {
this.device = dev;
- // this.contextES1 = ctxES1;
- this.wasES1ContextCreated = wasContextES1Created;
- this.hasPBufferES1= hasPBufferES1;
+ this.isAvailable = isAvailable;
+
+ this.rendererQuirksGLn = rendererQuirksGLn;
+ this.ctpGLn = ctpGLn;
+
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;
}
+
@Override
- public final boolean isValid() {
- return wasES1ContextCreated || wasES2ContextCreated || wasES3ContextCreated;
+ public final boolean isAvailable() {
+ return isAvailable;
}
@Override
public final EGLGraphicsDevice getDevice() { return device; }
- // final EGLContext getContextES1() { return contextES1; }
- // final EGLContext getContextES2() { return contextES2; }
- // final EGLContext getContextES3() { return contextES3; }
@Override
public AbstractGraphicsScreen getScreen() {
@@ -331,368 +460,424 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
return null;
}
@Override
- public GLRendererQuirks getRendererQuirks() {
- return null != rendererQuirksES3ES2 ? rendererQuirksES3ES2 : rendererQuirksES1 ;
+ public GLRendererQuirks getRendererQuirks(final GLProfile glp) {
+ if( null == glp ) {
+ if( null != rendererQuirksES3ES2 ) {
+ return rendererQuirksES3ES2;
+ } else if( null != rendererQuirksES1 ) {
+ return rendererQuirksES1;
+ } else {
+ return rendererQuirksGLn;
+ }
+ } else if( !glp.isGLES() ) {
+ return rendererQuirksGLn;
+ } else if( glp.isGLES1() ) {
+ return rendererQuirksES1;
+ } else {
+ return rendererQuirksES3ES2;
+ }
}
- }
-
- @Override
- public final AbstractGraphicsDevice getDefaultDevice() {
- return defaultDevice;
- }
+ }
- @Override
- public final boolean getIsDeviceCompatible(final AbstractGraphicsDevice device) {
- // via mappings (X11/WGL/.. -> EGL) we shall be able to handle all types.
- return null != sharedMap ; // null!=eglES2DynamicLookupHelper || null!=eglES1DynamicLookupHelper;
- }
+ class SharedResourceImplementation implements SharedResourceRunner.Implementation {
+ @Override
+ public void clear() {
+ sharedMap.clear();
+ }
+ @Override
+ public SharedResourceRunner.Resource mapPut(final AbstractGraphicsDevice device, final SharedResourceRunner.Resource resource) {
+ return sharedMap.put(device.getConnection(), resource);
+ }
+ @Override
+ public SharedResourceRunner.Resource mapGet(final AbstractGraphicsDevice device) {
+ return sharedMap.get(device.getConnection());
+ }
+ @Override
+ public Collection<SharedResourceRunner.Resource> mapValues() {
+ return sharedMap.values();
+ }
- private static List<GLCapabilitiesImmutable> getAvailableEGLConfigs(final EGLGraphicsDevice eglDisplay, final 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()));
+ @Override
+ public boolean isDeviceSupported(final AbstractGraphicsDevice device) {
+ return null != sharedMap; // null != eglES2DynamicLookupHelper || null != eglES1DynamicLookupHelper
}
- 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 */);
+
+ @Override
+ public SharedResourceRunner.Resource createSharedResource(final AbstractGraphicsDevice adevice) {
+ adevice.lock();
+ try {
+ return createEGLSharedResourceImpl(adevice);
+ } catch (final Throwable t) {
+ throw new GLException("EGLGLXDrawableFactory - Could not initialize shared resources for "+adevice, t);
+ } finally {
+ adevice.unlock();
}
}
- 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(final AbstractGraphicsDevice adevice, final int[] esProfile,
- final boolean[] hasPBuffer, final GLRendererQuirks[] rendererQuirks, final 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[0]);
- }
- if ( !GLProfile.isAvailable(adevice, profileString) ) {
- if( DEBUG ) {
- System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig: "+profileString+" n/a on "+adevice);
+ private SharedResource createEGLSharedResourceImpl(final AbstractGraphicsDevice adevice) {
+ final GLRendererQuirks[] rendererQuirksES1 = new GLRendererQuirks[] { null };
+ final GLRendererQuirks[] rendererQuirksES3ES2 = new GLRendererQuirks[] { null };
+ final GLRendererQuirks[] rendererQuirksGLn = new GLRendererQuirks[] { null };
+ final int[] ctpES1 = new int[] { EGLContext.CTX_PROFILE_ES };
+ final int[] ctpES3ES2 = new int[] { EGLContext.CTX_PROFILE_ES };
+ final int[] ctpGLn = new int[] { EGLContext.CTX_PROFILE_CORE };
+
+ if (DEBUG) {
+ System.err.println("EGLDrawableFactory.createShared(): device "+adevice);
}
- 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[0]+" ), "+
- "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");
+
+ boolean madeCurrentES1 = false;
+ boolean madeCurrentES2 = false;
+ boolean madeCurrentES3 = false;
+ boolean madeCurrentGLn = false;
+
+ if( null != eglGLnDynamicLookupHelper ) {
+ // OpenGL 3.1 core -> GL3
+ final int[] major = { 3 };
+ final int[] minor = { 1 }; // FIXME: No minor version probing for ES currently!
+ madeCurrentGLn = mapAvailableEGLESConfig(adevice, major, minor,
+ ctpGLn, rendererQuirksGLn) && 0 != major[0];
+ } else {
+ madeCurrentGLn = false;
+ }
+ if( null != eglES1DynamicLookupHelper ) {
+ final int[] major = { 1 };
+ final int[] minor = { 0 };
+ madeCurrentES1 = mapAvailableEGLESConfig(adevice, major, minor,
+ ctpES1, rendererQuirksES1) && 1 == major[0];
+ } else {
+ madeCurrentES1 = false;
+ }
+ if( null != eglES2DynamicLookupHelper ) {
+ // ES3 Query
+ final int[] major = { 3 };
+ final int[] minor = { 0 };
+ madeCurrentES3 = mapAvailableEGLESConfig(adevice, major, minor,
+ ctpES3ES2, rendererQuirksES3ES2) && 3 == major[0];
+ if( !madeCurrentES3 ) {
+ // ES2 Query, may result in ES3
+ major[0] = 2;
+ if( mapAvailableEGLESConfig(adevice, major, minor,
+ ctpES3ES2, rendererQuirksES3ES2) )
+ {
+ switch( major[0] ) {
+ case 2: madeCurrentES2 = true; break;
+ case 3: madeCurrentES3 = true; break;
+ default: throw new InternalError("XXXX Got "+major[0]);
}
}
}
+ }
+
+ if( !EGLContext.getAvailableGLVersionsSet(adevice) ) {
+ // Even though we override the non EGL native mapping intentionally,
+ // avoid exception due to double 'set' - careful exception of the rule.
+ EGLContext.setAvailableGLVersionsSet(adevice, true);
+ }
+ if( hasX11 ) {
+ handleDontCloseX11DisplayQuirk(rendererQuirksES1[0]);
+ handleDontCloseX11DisplayQuirk(rendererQuirksES3ES2[0]);
+ }
+ final SharedResource sr = new SharedResource(defaultDevice,
+ madeCurrentGLn || madeCurrentES1 || madeCurrentES2 || madeCurrentES3,
+ rendererQuirksGLn[0], ctpGLn[0],
+ rendererQuirksES1[0], ctpES1[0],
+ rendererQuirksES3ES2[0], ctpES3ES2[0]);
+
+ 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 GLn: " + madeCurrentGLn + ", quirks "+rendererQuirksGLn[0]);
+ System.err.println("EGLDrawableFactory.createShared: context ES1: " + madeCurrentES1 + ", quirks "+rendererQuirksES1[0]);
+ System.err.println("EGLDrawableFactory.createShared: context ES2: " + madeCurrentES2 + ", quirks "+rendererQuirksES3ES2[0]);
+ System.err.println("EGLDrawableFactory.createShared: context ES3: " + madeCurrentES3 + ", quirks "+rendererQuirksES3ES2[0]);
+ dumpMap();
+ }
+ return sr;
+ }
+
+ private void handleDontCloseX11DisplayQuirk(final GLRendererQuirks quirks) {
+ if( null != quirks && quirks.exist( GLRendererQuirks.DontCloseX11Display ) ) {
+ jogamp.nativewindow.x11.X11Util.markAllDisplaysUnclosable();
+ }
+ }
+
+ private boolean mapAvailableEGLESConfig(final AbstractGraphicsDevice adevice,
+ final int[] majorVersion, final int[] minorVersion,
+ final int[] ctxProfile, final GLRendererQuirks[] rendererQuirks) {
+ final String profileString = EGLContext.getGLProfile(majorVersion[0], minorVersion[0], ctxProfile[0]);
+
+ if ( !GLProfile.isAvailable(adevice, profileString) ) {
if( DEBUG ) {
- dumpEGLInfo("EGLDrawableFactory.mapAvailableEGLESConfig: ", defaultDevice.getHandle());
+ System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig: "+profileString+" n/a on "+adevice);
}
+ 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;
+ // FIXME || adevice instanceof EGLGraphicsDevice ;
+ if( DEBUG ) {
+ System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig: "+profileString+" ( "+majorVersion[0]+" ), "+
+ "mapsADeviceToDefaultDevice "+mapsADeviceToDefaultDevice+
+ " (QUERY_EGL_ES_NATIVE_TK "+QUERY_EGL_ES_NATIVE_TK+", initDefaultDevice "+initDefaultDevice+", hasDesktopFactory "+(null != desktopFactory)+
+ ", isEGLGraphicsDevice "+(adevice instanceof EGLGraphicsDevice)+")");
+ }
- 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;
+ boolean hasPBuffer;
+ EGLGraphicsDevice eglDevice = null;
+ EGLFeatures eglFeatures = null;
+ NativeSurface surface = null;
+ ProxySurface upstreamSurface = null; // X11, GLX, ..
+ ProxySurface downstreamSurface = null; // EGL
+ boolean allowsSurfacelessCtx = false;
+ 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();
+ defaultDeviceEGLFeatures = new EGLFeatures(defaultDevice);
+
+ // Probe for GLRendererQuirks.SingletonEGLDisplayOnly
+ final long secondEGLDisplay = EGL.eglGetDisplay(EGL.EGL_DEFAULT_DISPLAY);
+ if ( EGL.EGL_NO_DISPLAY == secondEGLDisplay ) {
+ final int quirk = GLRendererQuirks.SingletonEGLDisplayOnly;
+ GLRendererQuirks.addStickyDeviceQuirk(adevice, quirk);
+ EGLDisplayUtil.setSingletonEGLDisplayOnly(true);
+ if(DEBUG) {
+ System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+": cause: Second eglGetDisplay(EGL_DEFAULT_DISPLAY) failed");
}
- rendererQuirks[0] = defaultSharedResource.rendererQuirksES1;
- ctp[0] = defaultSharedResource.ctpES1;
- break;
+ }
}
- if( null != rendererQuirks[0] ) {
- GLRendererQuirks.addStickyDeviceQuirks(adevice, rendererQuirks[0]);
+ eglDevice = defaultDevice; // reuse
+ eglFeatures = defaultDeviceEGLFeatures;
+ if( DEBUG ) {
+ System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig.0: "+eglFeatures);
}
- 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;
+ if( !glp.isGLES() && !eglFeatures.hasGLAPI ) {
+ if(DEBUG) {
+ System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig() OpenGL API not supported (1)");
+ }
+ } else {
+ final GLCapabilitiesImmutable reqCapsPBuffer = GLGraphicsConfigurationUtil.fixGLPBufferGLCapabilities(reqCapsAny);
+ final List<GLCapabilitiesImmutable> availablePBufferCapsL = getAvailableEGLConfigs(eglDevice, reqCapsPBuffer);
+ hasPBuffer = availablePBufferCapsL.size() > 0;
+
+ // attempt to created the default shared resources ..
+ if( hasPBuffer ) {
+ // 2nd case create defaultDevice shared resource using pbuffer surface
+ downstreamSurface = createDummySurfaceImpl(eglDevice, 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(eglDevice, reqCapsAny);
+ if(capsAnyL.size() > 0) {
+ final GLCapabilitiesImmutable chosenCaps = capsAnyL.get(0);
+ EGLContext.mapStaticGLESVersion(eglDevice, chosenCaps);
+ success = true;
+ }
+ if(DEBUG) {
+ System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig() no pbuffer config available, detected !pbuffer config: "+success);
+ EGLGraphicsConfigurationFactory.printCaps("!PBufferCaps", capsAnyL, System.err);
+ }
+ }
}
} 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();
- eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(upstreamSurface);
- eglDevice.open();
- if( DEBUG ) {
- dumpEGLInfo("EGLDrawableFactory.mapAvailableEGLESConfig: ", eglDevice.getHandle());
+ // 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();
+ eglDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(upstreamSurface);
+ eglDevice.open();
+ eglFeatures = new EGLFeatures(eglDevice);
+ if( DEBUG ) {
+ System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig.1: "+eglFeatures);
+ }
+ if( !glp.isGLES() && !eglFeatures.hasGLAPI ) {
+ if(DEBUG) {
+ System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig() OpenGL API not supported (2)");
+ }
+ // disposed at finalized: eglDevice, upstreamSurface
+ } else {
+ hasPBuffer = true;
+ surface = upstreamSurface;
+ }
}
- hasPBuffer[0] = true;
- surface = upstreamSurface;
}
- }
- 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!");
+ if(null != surface) {
+ GLDrawableImpl zeroDrawable = null;
+ final EGLDrawable drawable = (EGLDrawable) createOnscreenDrawableImpl ( surface );
+ drawable.setRealized(true);
+ final EGLContext context = (EGLContext) drawable.createContext(null);
+ if (null != context) {
+ try {
+ if( GLContext.CONTEXT_NOT_CURRENT != context.makeCurrent() ) { // could cause exception
+ // context.isCurrent() !
+ final String glVersionString = context.getGL().glGetString(GL.GL_VERSION);
+ if(null != glVersionString) {
+ context.mapCurrentAvailableGLVersion(eglDevice);
+ if(eglDevice != adevice) {
+ context.mapCurrentAvailableGLVersion(adevice);
+ }
+
+ if( eglFeatures.hasKHRSurfaceless &&
+ !context.hasRendererQuirk(GLRendererQuirks.NoSurfacelessCtx) )
+ {
+ try {
+ final ProxySurface zeroSurface = createSurfacelessImpl(eglDevice, true, reqCapsAny, reqCapsAny, null, 64, 64);
+ zeroDrawable = createOnscreenDrawableImpl(zeroSurface);
+ zeroDrawable.setRealized(true);
+
+ // Since sharedContext is still current,
+ // will keep sharedContext current w/ zeroDrawable or throws GLException
+ context.setGLDrawable(zeroDrawable, false);
+ allowsSurfacelessCtx = true; // if setGLDrawable is successful, i.e. no GLException
+
+ // no switch back, will be destroyed anyways
+ // context.setGLDrawable(drawable, false);
+ } catch (final Throwable t) {
+ if( DEBUG ) {
+ ExceptionUtils.dumpThrowable("", t);
+ }
+ }
+ }
+ if( !allowsSurfacelessCtx ) {
+ final int quirk = GLRendererQuirks.NoSurfacelessCtx;
+ if(DEBUG) {
+ System.err.println("Quirk: "+GLRendererQuirks.toString(quirk)+" -> "+eglDevice+": cause: probe");
+ }
+ final GLRendererQuirks glrq = context.getRendererQuirks();
+ if( null != glrq ) {
+ glrq.addQuirk(quirk);
+ }
+ GLRendererQuirks.addStickyDeviceQuirk(eglDevice, quirk);
+ }
+ rendererQuirks[0] = context.getRendererQuirks();
+ ctxProfile[0] = context.getContextOptions();
+ majorVersion[0] = context.getGLVersionNumber().getMajor();
+ minorVersion[0] = context.getGLVersionNumber().getMinor();
+ success = true;
+ } else {
+ // Oops .. something is wrong
+ if(DEBUG) {
+ System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig: "+eglDevice+", "+context.getGLVersion()+" - VERSION is null, dropping availability!");
+ }
}
}
+ } catch (final Throwable t) {
+ if (DEBUG) {
+ System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig: INFO: context create/makeCurrent failed");
+ t.printStackTrace();
+ }
+ } finally {
+ if( context.isCreated() ) {
+ context.destroy();
+ }
}
- } catch (final Throwable t) {
- if (DEBUG) {
- System.err.println("EGLDrawableFactory.mapAvailableEGLESConfig: INFO: context create/makeCurrent failed");
- t.printStackTrace();
- }
- } finally {
- context.destroy();
}
+ if( null != zeroDrawable ) {
+ zeroDrawable.setRealized(false);
+ }
+ drawable.setRealized(false);
}
- drawable.setRealized(false);
- }
- } catch (final Throwable t) {
- if(DEBUG) {
- System.err.println("Caught 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();
+ } catch (final Throwable t) {
+ if(DEBUG) {
+ System.err.println("Caught exception on thread "+getThreadName());
+ t.printStackTrace();
}
- if(null != upstreamSurface) {
- upstreamSurface.destroyNotify();
+ success = false;
+ } finally {
+ if(null != downstreamSurface) {
+ downstreamSurface.destroyNotify();
}
- }
- }
- return success;
- }
-
- private final boolean needsToCreateSharedResource(final String key, final SharedResource[] existing) {
- synchronized(sharedMap) {
- final SharedResource sr = sharedMap.get(key);
- if( null == sr ) {
- final boolean createAttempted = sharedMapCreateAttempt.contains(key);
- if(!createAttempted) {
- sharedMapCreateAttempt.add(key);
+ if( defaultDevice != eglDevice ) { // don't close default device
+ if(null != eglDevice) {
+ eglDevice.close();
+ }
}
- return !createAttempted;
- } else {
- if(null != existing) {
- existing[0] = sr;
+ if(null != upstreamSurface) {
+ upstreamSurface.destroyNotify();
}
- return false;
}
+ return success;
}
- }
- @Override
- protected final SharedResource getOrCreateSharedResourceImpl(final AbstractGraphicsDevice adevice) {
- if(null == sharedMap) { // null == eglES1DynamicLookupHelper && null == eglES2DynamicLookupHelper
- return null;
- }
-
- if( needsToCreateSharedResource(defaultDevice.getUniqueID(), null) ) {
+ @Override
+ public void releaseSharedResource(final SharedResourceRunner.Resource shared) {
+ final SharedResource sr = (SharedResource) shared;
if (DEBUG) {
- System.err.println("EGLDrawableFactory.createShared: (defaultDevice): req. device: "+adevice+", defaultDevice "+defaultDevice);
- Thread.dumpStack();
- }
- if(null != defaultSharedResource) {
- dumpMap();
- throw new InternalError("defaultSharedResource already exist: "+defaultSharedResource);
+ System.err.println("Shutdown Shared:");
+ System.err.println("Device : " + sr.device);
+ ExceptionUtils.dumpStack(System.err);
}
- 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];
+ if (null != sr.device) {
+ // may cause JVM SIGSEGV:
+ sr.device.close();
+ sr.device = null;
}
- return createEGLSharedResourceImpl(adevice);
}
}
- private SharedResource createEGLSharedResourceImpl(final AbstractGraphicsDevice adevice) {
- final boolean madeCurrentES1;
- final boolean[] hasPBufferES1 = new boolean[] { false };
- final boolean[] hasPBufferES3ES2 = new boolean[] { false };
- // EGLContext[] eglCtxES1 = new EGLContext[] { null };
- // EGLContext[] eglCtxES2 = new EGLContext[] { null };
- final GLRendererQuirks[] rendererQuirksES1 = new GLRendererQuirks[] { null };
- final GLRendererQuirks[] rendererQuirksES3ES2 = new GLRendererQuirks[] { null };
- final int[] ctpES1 = new int[] { -1 };
- final int[] ctpES3ES2 = new int[] { -1 };
+ public final boolean hasDefaultDeviceKHRCreateContext() {
+ return defaultDeviceEGLFeatures.hasKHRCreateContext;
+ }
+ @Override
+ public final AbstractGraphicsDevice getDefaultDevice() {
+ return defaultDevice;
+ }
- if (DEBUG) {
- System.err.println("EGLDrawableFactory.createShared(): device "+adevice);
- }
+ @Override
+ public final boolean getIsDeviceCompatible(final AbstractGraphicsDevice device) {
+ // via mappings (X11/WGL/.. -> EGL) we shall be able to handle all types.
+ return null != sharedMap ; // null!=eglES2DynamicLookupHelper || null!=eglES1DynamicLookupHelper;
+ }
- 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);
+ private static List<GLCapabilitiesImmutable> getAvailableEGLConfigs(final EGLGraphicsDevice eglDisplay, final 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( hasX11 ) {
- handleDontCloseX11DisplayQuirk(rendererQuirksES1[0]);
- handleDontCloseX11DisplayQuirk(rendererQuirksES3ES2[0]);
+ 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 */);
+ }
}
- final SharedResource sr = new SharedResource(defaultDevice, madeCurrentES1, hasPBufferES1[0], rendererQuirksES1[0], ctpES1[0],
- madeCurrentES2, madeCurrentES3, hasPBufferES3ES2[0], rendererQuirksES3ES2[0], ctpES3ES2[0]);
+ return new ArrayList<GLCapabilitiesImmutable>(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;
+ 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 eglClientVersion = EGL.eglQueryString(EGL.EGL_NO_DISPLAY, EGL.EGL_VERSION);
+ final String eglServerVersion = EGL.eglQueryString(eglDisplay, EGL.EGL_VERSION);
+ System.err.println(prefix+"EGL vendor "+eglVendor+", version [client "+eglClientVersion+", server "+eglServerVersion+"], clientAPIs "+eglClientAPIs);
}
- private void handleDontCloseX11DisplayQuirk(final GLRendererQuirks quirks) {
- if( null != quirks && quirks.exist( GLRendererQuirks.DontCloseX11Display ) ) {
- jogamp.nativewindow.x11.X11Util.markAllDisplaysUnclosable();
- }
+ @Override
+ protected final SharedResource getOrCreateSharedResourceImpl(final AbstractGraphicsDevice adevice) {
+ return (SharedResource) sharedResourceRunner.getOrCreateShared(adevice);
}
@Override
protected final Thread getSharedResourceThread() {
- return null;
+ return sharedResourceRunner.start();
}
public final boolean isANGLE() {
@@ -706,7 +891,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
} else if (1==esProfile) {
return eglES1DynamicLookupHelper;
} else {
- throw new GLException("Unsupported: ES"+esProfile);
+ return eglGLnDynamicLookupHelper;
}
}
@@ -723,7 +908,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
if (target == null) {
throw new IllegalArgumentException("Null target");
}
- return new EGLOnscreenDrawable(this, EGLWrappedSurface.get(target));
+ return new EGLDrawable(this, EGLSurface.get(target));
}
@Override
@@ -737,7 +922,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
throw new GLException("Non pbuffer not yet implemented");
}
// PBuffer GLDrawable Creation
- return new EGLPbufferDrawable(this, EGLWrappedSurface.get(target));
+ return new EGLDrawable(this, EGLSurface.get(target));
}
@Override
@@ -747,28 +932,35 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
return true;
}
- @Override
- protected ProxySurface createMutableSurfaceImpl(final AbstractGraphicsDevice deviceReq, final boolean createNewDevice,
- final GLCapabilitiesImmutable capsChosen, final GLCapabilitiesImmutable capsRequested,
- final GLCapabilitiesChooser chooser, final UpstreamSurfaceHook upstreamHook) {
- final boolean ownDevice;
+ private final EGLGraphicsConfiguration evalConfig(final boolean[] ownDevice, final AbstractGraphicsDevice deviceReq, final boolean createNewDevice,
+ final GLCapabilitiesImmutable capsChosen, final GLCapabilitiesImmutable capsRequested,
+ final GLCapabilitiesChooser chooser) {
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;
+ ownDevice[0] = true;
} else {
device = (EGLGraphicsDevice) deviceReq;
- ownDevice = false;
+ ownDevice[0] = 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);
+ return config;
+ }
+
+ @Override
+ protected final ProxySurface createMutableSurfaceImpl(final AbstractGraphicsDevice deviceReq, final boolean createNewDevice,
+ final GLCapabilitiesImmutable capsChosen, final GLCapabilitiesImmutable capsRequested,
+ final GLCapabilitiesChooser chooser, final UpstreamSurfaceHook upstreamHook) {
+ final boolean[] ownDevice = { false };
+ final EGLGraphicsConfiguration config = evalConfig(ownDevice, deviceReq, createNewDevice, capsChosen, capsRequested, chooser);
+ return EGLSurface.createWrapped(config, 0, upstreamHook, ownDevice[0]);
}
@Override
@@ -778,6 +970,15 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, new EGLDummyUpstreamSurfaceHook(width, height));
}
+ @Override
+ public final ProxySurface createSurfacelessImpl(final AbstractGraphicsDevice deviceReq, final boolean createNewDevice,
+ GLCapabilitiesImmutable chosenCaps, final GLCapabilitiesImmutable requestedCaps, final GLCapabilitiesChooser chooser, final int width, final int height) {
+ chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(chosenCaps);
+ final boolean[] ownDevice = { false };
+ final EGLGraphicsConfiguration config = evalConfig(ownDevice, deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser);
+ return EGLSurface.createSurfaceless(config, new GenericUpstreamSurfacelessHook(width, height), ownDevice[0]);
+ }
+
/**
* @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.
@@ -813,13 +1014,15 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
}
@Override
- protected ProxySurface createProxySurfaceImpl(final AbstractGraphicsDevice deviceReq, final int screenIdx, final long windowHandle, final GLCapabilitiesImmutable capsRequested, final GLCapabilitiesChooser chooser, final UpstreamSurfaceHook upstream) {
+ protected ProxySurface createProxySurfaceImpl(final AbstractGraphicsDevice deviceReq, final int screenIdx, final long windowHandle,
+ final GLCapabilitiesImmutable capsRequested, final GLCapabilitiesChooser chooser,
+ final 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);
+ return EGLSurface.createWrapped(cfg, windowHandle, upstream, true);
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java b/src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java
index f00d7059d..0757bd98e 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDummyUpstreamSurfaceHook.java
@@ -6,6 +6,7 @@ import javax.media.nativewindow.UpstreamSurfaceHook;
import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSize;
import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
+import com.jogamp.opengl.egl.EGL;
/** Uses a PBuffer offscreen surface */
public class EGLDummyUpstreamSurfaceHook extends UpstreamSurfaceHookMutableSize {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java
index 05dae0b9d..1b433cc30 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java
@@ -28,13 +28,15 @@
package jogamp.opengl.egl;
-import com.jogamp.common.os.AndroidVersion;
-import com.jogamp.common.os.Platform;
-
-import java.util.*;
+import java.util.ArrayList;
+import java.util.List;
import jogamp.common.os.PlatformPropsImpl;
-import jogamp.opengl.*;
+import jogamp.opengl.GLDynamicLibraryBundleInfo;
+
+import com.jogamp.common.os.AndroidVersion;
+import com.jogamp.common.os.Platform;
+import com.jogamp.opengl.egl.EGL;
/**
* Abstract implementation of the DynamicLookupHelper for EGL,
@@ -43,7 +45,7 @@ import jogamp.opengl.*;
* Currently two implementations exist, one for ES1 and one for ES3 and ES2.
*/
public abstract class EGLDynamicLibraryBundleInfo extends GLDynamicLibraryBundleInfo {
- static final List<String> glueLibNames;
+ private static final List<String> glueLibNames;
static {
glueLibNames = new ArrayList<String>();
glueLibNames.add("jogl_mobile");
@@ -79,7 +81,7 @@ public abstract class EGLDynamicLibraryBundleInfo extends GLDynamicLibraryBundle
@Override
public final long toolGetProcAddress(final long toolGetProcAddressHandle, final String funcName) {
- return EGL.eglGetProcAddress(toolGetProcAddressHandle, funcName);
+ return EGLContext.eglGetProcAddress(toolGetProcAddressHandle, funcName);
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLES1DynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/egl/EGLES1DynamicLibraryBundleInfo.java
index 361ec26ff..3c7ee410a 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLES1DynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLES1DynamicLibraryBundleInfo.java
@@ -28,7 +28,8 @@
package jogamp.opengl.egl;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.List;
public final class EGLES1DynamicLibraryBundleInfo extends EGLDynamicLibraryBundleInfo {
protected EGLES1DynamicLibraryBundleInfo() {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java
index 74738463f..d37efc455 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java
@@ -28,7 +28,8 @@
package jogamp.opengl.egl;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.List;
/**
* <p>
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java b/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java
index a8dd7d5c8..258765ba3 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGLCapabilities.java
@@ -34,6 +34,8 @@ import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
+import com.jogamp.opengl.egl.EGL;
+import com.jogamp.opengl.egl.EGLExt;
public class EGLGLCapabilities extends GLCapabilities {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGLnDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/egl/EGLGLnDynamicLibraryBundleInfo.java
new file mode 100644
index 000000000..6a3a20100
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGLnDynamicLibraryBundleInfo.java
@@ -0,0 +1,83 @@
+/**
+ * Copyright 2014 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package jogamp.opengl.egl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.jogamp.common.os.Platform;
+
+/**
+ * <p>
+ * Covering Desktop GL
+ * </p>
+ */
+public final class EGLGLnDynamicLibraryBundleInfo extends EGLDynamicLibraryBundleInfo {
+ private static final List<String> glueLibNames;
+ static {
+ glueLibNames = new ArrayList<String>();
+ glueLibNames.add("jogl_desktop");
+ }
+
+ protected EGLGLnDynamicLibraryBundleInfo() {
+ super();
+ }
+
+ @Override
+ public final List<List<String>> getToolLibNames() {
+ final List<List<String>> libsList = new ArrayList<List<String>>();
+ {
+ final List<String> libsGL = new ArrayList<String>();
+
+ final Platform.OSType osType = Platform.getOSType();
+ if( Platform.OSType.MACOS == osType ) {
+ libsGL.add("/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib");
+ libsGL.add("GL");
+ } else if( Platform.OSType.WINDOWS == Platform.getOSType() ) {
+ libsGL.add("OpenGL32");
+ } else {
+ // this is the default lib name, according to the spec
+ libsGL.add("libGL.so.1");
+
+ // try this one as well, if spec fails
+ libsGL.add("libGL.so");
+
+ // last but not least .. the generic one
+ libsGL.add("GL");
+ }
+
+ libsList.add(libsGL);
+ }
+ libsList.add(getEGLLibNamesList());
+
+ return libsList;
+ }
+
+}
+
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
index 1d90e63af..6f0d7ae4d 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
@@ -57,6 +57,8 @@ import com.jogamp.common.nio.PointerBuffer;
import com.jogamp.nativewindow.MutableGraphicsConfiguration;
import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
import com.jogamp.opengl.GLRendererQuirks;
+import com.jogamp.opengl.egl.EGL;
+import com.jogamp.opengl.egl.EGLExt;
public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration implements Cloneable {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
index d4e5e7d62..4aa34ce4e 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
@@ -33,36 +33,37 @@
package jogamp.opengl.egl;
+import java.io.PrintStream;
+import java.nio.IntBuffer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.CapabilitiesChooser;
import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.GraphicsConfigurationFactory;
+import javax.media.nativewindow.NativeWindowFactory;
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.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
-import javax.media.opengl.GLDrawableFactory;
+
+import jogamp.opengl.GLGraphicsConfigurationFactory;
+import jogamp.opengl.GLGraphicsConfigurationUtil;
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;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.io.PrintStream;
-import java.nio.IntBuffer;
+import com.jogamp.opengl.egl.EGL;
/** Subclass of GraphicsConfigurationFactory used when non-AWT tookits
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java
deleted file mode 100644
index 4c018fe25..000000000
--- a/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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
- * 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.
- *
- * 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.opengl.*;
-import javax.media.nativewindow.*;
-
-public class EGLOnscreenDrawable extends EGLDrawable {
- protected EGLOnscreenDrawable(final EGLDrawableFactory factory, final NativeSurface component) throws GLException {
- super(factory, component);
- }
-
- @Override
- public GLContext createContext(final GLContext shareWith) {
- return new EGLContext(this, shareWith);
- }
-
- @Override
- protected long createSurface(final EGLGraphicsConfiguration config, final int width, final int height, final long nativeSurfaceHandle) {
- return EGL.eglCreateWindowSurface(config.getScreen().getDevice().getHandle(), config.getNativeConfig(), nativeSurfaceHandle, null);
- }
-}
-
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
deleted file mode 100644
index 8842edbc0..000000000
--- a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * 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
- * 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.
- *
- * 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.NativeSurface;
-import javax.media.opengl.GLContext;
-
-public class EGLPbufferDrawable extends EGLDrawable {
- protected static final boolean useTexture = false; // No yet ..
-
- protected EGLPbufferDrawable(final EGLDrawableFactory factory, final NativeSurface target) {
- super(factory, target);
- }
-
- @Override
- protected long createSurface(final EGLGraphicsConfiguration config, final int width, final int height, final long nativeSurfaceHandle) {
- return EGLDrawableFactory.createPBufferSurfaceImpl(config, width, height, false);
- }
-
- @Override
- public GLContext createContext(final GLContext shareWith) {
- return new EGLContext(this, shareWith);
- }
-}
-
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLSurface.java b/src/jogl/classes/jogamp/opengl/egl/EGLSurface.java
new file mode 100644
index 000000000..796a9e2c8
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLSurface.java
@@ -0,0 +1,165 @@
+/**
+ * Copyright 2014 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package jogamp.opengl.egl;
+
+import java.nio.IntBuffer;
+
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindow;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.UpstreamSurfaceHook;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLException;
+
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.nativewindow.GenericUpstreamSurfacelessHook;
+import com.jogamp.opengl.egl.EGL;
+
+import jogamp.nativewindow.ProxySurfaceImpl;
+import jogamp.nativewindow.WrappedSurface;
+import jogamp.opengl.GLDrawableImpl;
+
+/**
+ * <pre>
+ * EGLSurface [ is_a -> WrappedSurface -> ProxySurfaceImpl -> ProxySurface -> MutableSurface -> NativeSurface] has_a
+ * EGLUpstreamSurfaceHook [ is_a -> UpstreamSurfaceHook.MutableSize -> UpstreamSurfaceHook ] has_a
+ * NativeSurface (e.g. native [X11, WGL, ..] surface, or WrappedSurface, ..)
+ * </pre>
+ */
+public class EGLSurface extends WrappedSurface {
+ static boolean DEBUG = EGLDrawable.DEBUG || ProxySurface.DEBUG;
+
+ public static EGLSurface get(final NativeSurface surface) {
+ if(surface instanceof EGLSurface) {
+ return (EGLSurface)surface;
+ }
+ return new EGLSurface(surface);
+ }
+ private EGLSurface(final NativeSurface surface) {
+ super(surface.getGraphicsConfiguration(), EGL.EGL_NO_SURFACE, new EGLUpstreamSurfaceHook(surface), false /* tbd in UpstreamSurfaceHook */);
+ if(EGLDrawableFactory.DEBUG) {
+ System.err.println("EGLSurface.ctor().1: "+this);
+ ProxySurfaceImpl.dumpHierarchy(System.err, this);
+ }
+ }
+
+ public static EGLSurface createWrapped(final EGLGraphicsConfiguration cfg, final long handle,
+ final UpstreamSurfaceHook upstream, final boolean ownsDevice) {
+ return new EGLSurface(cfg, handle, upstream, ownsDevice);
+ }
+ private EGLSurface(final EGLGraphicsConfiguration cfg, final long handle,
+ final UpstreamSurfaceHook upstream, final boolean ownsDevice) {
+ super(cfg, EGL.EGL_NO_SURFACE, new EGLUpstreamSurfaceHook(cfg, handle, upstream, ownsDevice), false /* tbd in UpstreamSurfaceHook */);
+ if(EGLDrawableFactory.DEBUG) {
+ System.err.println("EGLSurface.ctor().2: "+this);
+ ProxySurfaceImpl.dumpHierarchy(System.err, this);
+ }
+ }
+
+ public static EGLSurface createSurfaceless(final EGLGraphicsConfiguration cfg, final GenericUpstreamSurfacelessHook upstream, final boolean ownsDevice) {
+ return new EGLSurface(cfg, upstream, ownsDevice);
+ }
+ private EGLSurface(final EGLGraphicsConfiguration cfg, final GenericUpstreamSurfacelessHook upstream, final boolean ownsDevice) {
+ super(cfg, EGL.EGL_NO_SURFACE, upstream, ownsDevice);
+ if(EGLDrawableFactory.DEBUG) {
+ System.err.println("EGLSurface.ctor().3: "+this);
+ ProxySurfaceImpl.dumpHierarchy(System.err, this);
+ }
+ }
+
+ public void setEGLSurfaceHandle() throws GLException {
+ setSurfaceHandle( createEGLSurfaceHandle() );
+ }
+ private long createEGLSurfaceHandle() throws GLException {
+ final EGLGraphicsConfiguration config = (EGLGraphicsConfiguration) getGraphicsConfiguration();
+ final NativeSurface nativeSurface = getUpstreamSurface();
+ final boolean isPBuffer = ((GLCapabilitiesImmutable) config.getChosenCapabilities()).isPBuffer();
+
+ long eglSurface = createEGLSurfaceHandle(isPBuffer, true /* useSurfaceHandle */, config, nativeSurface);
+ if ( EGL.EGL_NO_SURFACE == eglSurface ) {
+ final int eglError0 = EGL.eglGetError();
+ if( EGL.EGL_BAD_NATIVE_WINDOW == eglError0 && !isPBuffer ) {
+ // Try window handle if available and differs (Windows HDC / HWND).
+ // ANGLE impl. required HWND on Windows.
+ if( hasUniqueNativeWindowHandle(nativeSurface) ) {
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": Info: Creation of window surface w/ surface handle failed: "+config+", error "+GLDrawableImpl.toHexString(eglError0)+", retry w/ windowHandle");
+ }
+ eglSurface = createEGLSurfaceHandle(isPBuffer, false /* useSurfaceHandle */, config, nativeSurface);
+ if (EGL.EGL_NO_SURFACE == eglSurface) {
+ throw new GLException("Creation of window surface w/ window handle failed: "+config+", "+this+", error "+GLDrawableImpl.toHexString(EGL.eglGetError()));
+ }
+ } else {
+ throw new GLException("Creation of window surface w/ surface handle failed (2): "+config+", "+this+", error "+GLDrawableImpl.toHexString(eglError0));
+ }
+ } else {
+ throw new GLException("Creation of window surface w/ surface handle failed (1): "+config+", "+this+", error "+GLDrawableImpl.toHexString(eglError0));
+ }
+ }
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": createEGLSurface handle "+GLDrawableImpl.toHexString(eglSurface));
+ }
+ return eglSurface;
+ }
+ private long createEGLSurfaceHandle(final boolean isPBuffer, final boolean useSurfaceHandle,
+ final EGLGraphicsConfiguration config, final NativeSurface nativeSurface) {
+ if( isPBuffer ) {
+ return EGLDrawableFactory.createPBufferSurfaceImpl(config, getSurfaceWidth(), getSurfaceHeight(), false);
+ } else {
+ if( useSurfaceHandle ) {
+ return EGL.eglCreateWindowSurface(config.getScreen().getDevice().getHandle(),
+ config.getNativeConfig(),
+ nativeSurface.getSurfaceHandle(), null);
+ } else {
+ return EGL.eglCreateWindowSurface(config.getScreen().getDevice().getHandle(),
+ config.getNativeConfig(),
+ ((NativeWindow)nativeSurface).getWindowHandle(), null);
+ }
+ }
+ }
+ private static boolean hasUniqueNativeWindowHandle(final NativeSurface nativeSurface) {
+ return nativeSurface instanceof NativeWindow &&
+ ((NativeWindow)nativeSurface).getWindowHandle() != nativeSurface.getSurfaceHandle();
+ }
+ static String getThreadName() { return Thread.currentThread().getName(); }
+
+ public static boolean isValidEGLSurfaceHandle(final long eglDisplayHandle, final long eglSurfaceHandle) {
+ if( 0 == eglSurfaceHandle ) {
+ return false;
+ }
+ final IntBuffer val = Buffers.newDirectIntBuffer(1);
+ final boolean eglSurfaceValid = EGL.eglQuerySurface(eglDisplayHandle, eglSurfaceHandle, EGL.EGL_CONFIG_ID, val);
+ if( !eglSurfaceValid ) {
+ final int eglErr = EGL.eglGetError();
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": EGLSurface.isValidEGLSurfaceHandle eglQuerySuface failed: error "+GLDrawableImpl.toHexString(eglErr)+", "+GLDrawableImpl.toHexString(eglSurfaceHandle));
+ }
+ }
+ return eglSurfaceValid;
+ }
+}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java b/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java
index cc15f0cd6..92e13dc61 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLUpstreamSurfaceHook.java
@@ -1,3 +1,30 @@
+/**
+ * Copyright 2014 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
package jogamp.opengl.egl;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
@@ -11,13 +38,16 @@ import javax.media.nativewindow.VisualIDHolder.VIDType;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLException;
+import jogamp.nativewindow.WrappedSurface;
+
import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
+import com.jogamp.opengl.egl.EGL;
/**
* <pre>
- * EGLWrappedSurface [ is_a -> WrappedSurface -> ProxySurfaceImpl -> ProxySurface -> MutableSurface -> NativeSurface] has_a
+ * EGLSurface [ is_a -> WrappedSurface -> ProxySurfaceImpl -> ProxySurface -> MutableSurface -> NativeSurface] has_a
* EGLUpstreamSurfaceHook [ is_a -> UpstreamSurfaceHook.MutableSize -> UpstreamSurfaceHook ] has_a
- * NativeSurface (e.g. native X11 surface)
+ * NativeSurface (e.g. native [X11, WGL, ..] surface, or WrappedSurface, ..)
* </pre>
*/
public class EGLUpstreamSurfaceHook implements UpstreamSurfaceHook.MutableSize {
@@ -40,6 +70,11 @@ public class EGLUpstreamSurfaceHook implements UpstreamSurfaceHook.MutableSize {
}
}
+ public EGLUpstreamSurfaceHook(final EGLGraphicsConfiguration cfg, final long handle,
+ final UpstreamSurfaceHook upstream, final boolean ownsDevice) {
+ this( new WrappedSurface(cfg, handle, upstream, ownsDevice) );
+ }
+
static String getThreadName() { return Thread.currentThread().getName(); }
/**
@@ -176,10 +211,10 @@ public class EGLUpstreamSurfaceHook implements UpstreamSurfaceHook.MutableSize {
}
surface.setGraphicsConfiguration(eglConfig);
- if(isEGLSurfaceValid) {
- isEGLSurfaceValid = EGLDrawable.isValidEGLSurface(eglDevice.getHandle(), upstreamSurface.getSurfaceHandle());
+ if( isEGLSurfaceValid ) {
+ isEGLSurfaceValid = EGLSurface.isValidEGLSurfaceHandle(eglDevice.getHandle(), upstreamSurface.getSurfaceHandle());
}
- if(isEGLSurfaceValid) {
+ if( isEGLSurfaceValid ) {
surface.setSurfaceHandle(upstreamSurface.getSurfaceHandle());
surface.clearUpstreamOptionBits( ProxySurface.OPT_PROXY_OWNS_UPSTREAM_SURFACE );
if(DEBUG) {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLWrappedSurface.java b/src/jogl/classes/jogamp/opengl/egl/EGLWrappedSurface.java
deleted file mode 100644
index 89024eed3..000000000
--- a/src/jogl/classes/jogamp/opengl/egl/EGLWrappedSurface.java
+++ /dev/null
@@ -1,30 +0,0 @@
-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(final NativeSurface surface) {
- if(surface instanceof EGLWrappedSurface) {
- return (EGLWrappedSurface)surface;
- }
- return new EGLWrappedSurface(surface);
- }
-
- public EGLWrappedSurface(final 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);
- }
- }
-
-}