aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl/classes')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/FBObject.java48
-rw-r--r--src/jogl/classes/com/jogamp/opengl/GLDrawableFactory.java83
-rw-r--r--src/jogl/classes/com/jogamp/opengl/GLProfile.java178
-rw-r--r--src/jogl/classes/com/jogamp/opengl/JoglVersion.java13
-rw-r--r--src/jogl/classes/jogamp/opengl/DummyGLExtProcAddressTable.java61
-rw-r--r--src/jogl/classes/jogamp/opengl/GLContextImpl.java11
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java77
-rw-r--r--src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java6
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLGLnDynamicLibraryBundleInfo.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/ios/eagl/IOSEAGLContext.java477
-rw-r--r--src/jogl/classes/jogamp/opengl/ios/eagl/IOSEAGLDrawable.java90
-rw-r--r--src/jogl/classes/jogamp/opengl/ios/eagl/IOSEAGLDrawableFactory.java453
-rw-r--r--src/jogl/classes/jogamp/opengl/ios/eagl/IOSEAGLDynamicLibraryBundleInfo.java83
-rw-r--r--src/jogl/classes/jogamp/opengl/ios/eagl/IOSEAGLGraphicsConfiguration.java62
-rw-r--r--src/jogl/classes/jogamp/opengl/ios/eagl/IOSEAGLGraphicsConfigurationFactory.java87
-rw-r--r--src/jogl/classes/jogamp/opengl/ios/eagl/IOSOnscreenEAGLDrawable.java45
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDynamicLibraryBundleInfo.java1
17 files changed, 1663 insertions, 114 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/FBObject.java b/src/jogl/classes/com/jogamp/opengl/FBObject.java
index c36727fe4..00a560fc7 100644
--- a/src/jogl/classes/com/jogamp/opengl/FBObject.java
+++ b/src/jogl/classes/com/jogamp/opengl/FBObject.java
@@ -34,7 +34,6 @@ import com.jogamp.opengl.GL;
import com.jogamp.opengl.GL2ES2;
import com.jogamp.opengl.GL2ES3;
import com.jogamp.opengl.GL2GL3;
-import com.jogamp.opengl.GL3;
import com.jogamp.opengl.GLBase;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLCapabilitiesImmutable;
@@ -43,6 +42,7 @@ import com.jogamp.opengl.GLException;
import com.jogamp.opengl.GLProfile;
import jogamp.opengl.Debug;
+import jogamp.opengl.ios.eagl.EAGL;
import com.jogamp.common.ExceptionUtils;
import com.jogamp.common.util.PropertyAccess;
@@ -483,6 +483,48 @@ public class FBObject {
@Override
public final ColorAttachment getColorAttachment() { return this; }
+ @Override
+ public boolean initialize(final GL gl) throws GLException {
+ final boolean init = 0 == getName();
+ if( init ) {
+ final boolean checkError = DEBUG || GLContext.DEBUG_GL;
+ if( checkError ) {
+ checkPreGLError(gl);
+ }
+ final int[] name = new int[] { -1 };
+ gl.glGenRenderbuffers(1, name, 0);
+ setName(name[0]);
+
+ gl.glBindRenderbuffer(GL.GL_RENDERBUFFER, getName());
+ if( getSamples() > 0 ) {
+ ((GL2ES3)gl).glRenderbufferStorageMultisample(GL.GL_RENDERBUFFER, getSamples(), format, getWidth(), getHeight());
+ } else {
+ // FIXME: Need better way to inject the IOS EAGL Layer into FBObject
+ // FIXME: May want to implement optional injection of a BufferStorage SPI?
+ final GLContext ctx = gl.getContext();
+ final Long iosEAGLLayer = (Long) ctx.getAttachedObject("IOS_EAGL_LAYER");
+ if( null != iosEAGLLayer ) {
+ EAGL.eaglBindDrawableStorageToRenderbuffer(gl.getContext().contextHandle, GL.GL_RENDERBUFFER, iosEAGLLayer.longValue());
+ } else {
+ gl.glRenderbufferStorage(GL.GL_RENDERBUFFER, format, getWidth(), getHeight());
+ }
+ }
+ if( checkError ) {
+ final int glerr = gl.glGetError();
+ if(GL.GL_NO_ERROR != glerr) {
+ gl.glDeleteRenderbuffers(1, name, 0);
+ setName(0);
+ throw new GLException("GL Error "+toHexString(glerr)+" while creating "+this);
+ }
+ }
+ if(DEBUG) {
+ System.err.println("Attachment.init.X: "+this);
+ }
+ }
+ return init;
+ }
+
+
}
/** Texture FBO attachment */
@@ -1250,7 +1292,7 @@ public class FBObject {
return("FBO missing read buffer");
case GL.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
return("FBO missing multisample buffer");
- case GL3.GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
+ case GL3ES3.GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
return("FBO missing layer targets");
case GL.GL_FRAMEBUFFER_UNSUPPORTED:
@@ -1281,7 +1323,7 @@ public class FBObject {
case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
case GL.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
- case GL3.GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
+ case GL3ES3.GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
if(0 == colorbufferCount || null == depth) {
// we are in transition
return true;
diff --git a/src/jogl/classes/com/jogamp/opengl/GLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/GLDrawableFactory.java
index 51da34ce0..1fe42a332 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLDrawableFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLDrawableFactory.java
@@ -43,6 +43,7 @@ package com.jogamp.opengl;
import java.util.ArrayList;
import java.util.List;
+import com.jogamp.common.os.Platform;
import com.jogamp.common.util.PropertyAccess;
import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.opengl.GLAutoDrawableDelegate;
@@ -57,6 +58,7 @@ import com.jogamp.nativewindow.NativeWindowFactory;
import com.jogamp.nativewindow.ProxySurface;
import com.jogamp.nativewindow.UpstreamSurfaceHook;
+import jogamp.common.os.PlatformPropsImpl;
import jogamp.opengl.Debug;
/** <p> Provides a virtual machine- and operating system-independent
@@ -137,6 +139,8 @@ public abstract class GLDrawableFactory {
factoryClassName = "jogamp.opengl.windows.wgl.WindowsWGLDrawableFactory";
} else if ( nwt == NativeWindowFactory.TYPE_MACOSX ) {
factoryClassName = "jogamp.opengl.macosx.cgl.MacOSXCGLDrawableFactory";
+ } else if ( nwt == NativeWindowFactory.TYPE_IOS ) {
+ factoryClassName = "jogamp.opengl.ios.eagl.IOSEAGLDrawableFactory";
} else {
// may use egl*Factory ..
if (DEBUG || GLProfile.DEBUG) {
@@ -144,7 +148,7 @@ public abstract class GLDrawableFactory {
}
}
}
- if ( !GLProfile.disableOpenGLDesktop ) {
+ if ( !GLProfile.disableOpenGLDesktop || GLProfile.disabledEGL ) {
if ( null != factoryClassName ) {
if (DEBUG || GLProfile.DEBUG) {
System.err.println("GLDrawableFactory.static - Native OS Factory for: "+nwt+": "+factoryClassName);
@@ -168,7 +172,7 @@ public abstract class GLDrawableFactory {
System.err.println("Info: GLDrawableFactory.static - Desktop GLDrawableFactory - disabled!");
}
- if(!GLProfile.disableOpenGLES) {
+ if(!GLProfile.disableOpenGLES && !GLProfile.disabledEGL) {
try {
tmp = (GLDrawableFactory) ReflectionUtil.createInstance("jogamp.opengl.egl.EGLDrawableFactory", cl);
} catch (final Exception jre) {
@@ -434,6 +438,15 @@ public abstract class GLDrawableFactory {
/**
* Returns the sole GLDrawableFactory instance for the desktop (X11, WGL, ..) if exist or null
+ * <p>
+ * To fetch the appropriate {@link GLDrawableFactory} for native desktop
+ * or mobile, use {@link #getFactory(boolean)}.
+ * </p>
+ * <p>
+ * It is possible that the desktop {@link GLDrawableFactory} will be used for
+ * native mobile GL profiles, e.g. {@link Platform.OSType#IOS}.
+ * </p>
+ * @return the matching {@link GLDrawableFactory} or {@code null} if none is available
*/
public static GLDrawableFactory getDesktopFactory() {
GLProfile.initSingleton();
@@ -441,7 +454,16 @@ public abstract class GLDrawableFactory {
}
/**
- * Returns the sole GLDrawableFactory instance for EGL if exist or null
+ * Returns the sole {@link GLDrawableFactory} instance for EGL if exist or null.
+ * <p>
+ * To fetch the appropriate {@link GLDrawableFactory} for native desktop
+ * or mobile, use {@link #getFactory(boolean)}.
+ * </p>
+ * <p>
+ * It is possible that a non EGL {@link GLDrawableFactory} will be used for
+ * native mobile GL profiles, e.g. {@link Platform.OSType#IOS}.
+ * </p>
+ * @return the matching {@link GLDrawableFactory} or {@code null} if none is available
*/
public static GLDrawableFactory getEGLFactory() {
GLProfile.initSingleton();
@@ -449,34 +471,61 @@ public abstract class GLDrawableFactory {
}
/**
- * Returns the sole GLDrawableFactory instance.
+ * Returns the sole {@link GLDrawableFactory} instance.
*
- * @param glProfile GLProfile to determine the factory type, ie EGLDrawableFactory,
- * or one of the native GLDrawableFactory's, ie X11/GLX, Windows/WGL or MacOSX/CGL.
+ * @param glProfile GLProfile to determine the factory type, ie for native mobile GL or native desktop GL.
+ * @return the matching {@link GLDrawableFactory}
+ * @throws GLException if no matching {@link GLDrawableFactory} exists
*/
public static GLDrawableFactory getFactory(final GLProfile glProfile) throws GLException {
- return getFactoryImpl(glProfile.getImplName());
+ final GLDrawableFactory f = getFactoryImpl(glProfile.getImplName());
+ if( null != f ) {
+ return f;
+ }
+ throw new GLException("No GLDrawableFactory available for profile: "+glProfile);
}
-
- protected static GLDrawableFactory getFactoryImpl(final String glProfileImplName) throws GLException {
- if ( GLProfile.usesNativeGLES(glProfileImplName) ) {
- if(null!=eglFactory) {
+ /**
+ * Returns the sole {@link GLDrawableFactory} instance, either for mobile if {@code usesNativeGLES} is true,
+ * or for desktop otherwise.
+ * @param useNativeGLES request native mobile GLES support if true
+ * @return the matching {@link GLDrawableFactory} or {@code null} if none is available
+ */
+ public static GLDrawableFactory getFactory(final boolean useNativeGLES) {
+ GLProfile.initSingleton();
+ return getFactoryImpl( useNativeGLES );
+ }
+ protected static GLDrawableFactory getFactoryImpl(final String glProfileImplName) {
+ return getFactoryImpl( GLProfile.usesNativeGLES(glProfileImplName) );
+ }
+ protected static GLDrawableFactory getFactoryImpl(final boolean useNativeGLES) {
+ if( useNativeGLES ) {
+ if(null!=eglFactory && eglFactory.hasOpenGLESSupport() ) {
return eglFactory;
}
- } else if(null!=nativeOSFactory) {
- return nativeOSFactory;
+ if(null!=nativeOSFactory && nativeOSFactory.hasOpenGLESSupport() ) {
+ return nativeOSFactory;
+ }
+ } else {
+ if(null!=nativeOSFactory && nativeOSFactory.hasOpenGLDesktopSupport() ) {
+ return nativeOSFactory;
+ }
}
- throw new GLException("No GLDrawableFactory available for profile: "+glProfileImplName);
+ return null;
}
-
- protected static GLDrawableFactory getFactoryImpl(final AbstractGraphicsDevice device) throws GLException {
+ /**
+ * Returns the sole {@link GLDrawableFactory} matching the given {@link AbstractGraphicsDevice} instance,
+ * which will be suitable either for native mobile or native desktop.
+ * @param device the queries {@link AbstractGraphicsDevice} seeking for its matching factory
+ * @return the matching {@link GLDrawableFactory} or {@code null} if none is available
+ */
+ public static GLDrawableFactory getFactory(final AbstractGraphicsDevice device) {
if(null != nativeOSFactory && nativeOSFactory.getIsDeviceCompatible(device)) {
return nativeOSFactory;
}
if(null != eglFactory && eglFactory.getIsDeviceCompatible(device)) {
return eglFactory;
}
- throw new GLException("No native platform GLDrawableFactory, nor EGLDrawableFactory available: "+device);
+ return null;
}
/**
diff --git a/src/jogl/classes/com/jogamp/opengl/GLProfile.java b/src/jogl/classes/com/jogamp/opengl/GLProfile.java
index e19535e5d..0e0d45444 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLProfile.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLProfile.java
@@ -86,7 +86,7 @@ public class GLProfile {
* and if one platform may have a buggy implementation,
* setting the property <code>jogl.disable.openglcore</code> disables querying possible existing native OpenGL core profiles.
* <p>
- * This exclusion is disabled for {@link Platform.OSType#MACOS}.
+ * This exclusion is disabled for {@link Platform.OSType#MACOS} and {@link Platform.OSType#IOS}.
* </p>
*/
public static final boolean disableOpenGLCore;
@@ -99,7 +99,7 @@ public class GLProfile {
* This exclusion also disables {@link #disableOpenGLES OpenGL ES}.
* </p>
* <p>
- * This exclusion is disabled for {@link Platform.OSType#MACOS}.
+ * This exclusion is disabled for {@link Platform.OSType#MACOS} and {@link Platform.OSType#IOS}.
* </p>
*/
public static final boolean disableOpenGLARBContext;
@@ -119,6 +119,13 @@ public class GLProfile {
public static final boolean disableOpenGLDesktop;
/**
+ * In case no EGL implementation is available
+ * like on the {@link Platform.OSType#IOS} platform,
+ * this is set to {@code true}.
+ */
+ public static final boolean disabledEGL;
+
+ /**
* Disable surfaceless OpenGL context capability and its probing
* by setting the property <code>jogl.disable.surfacelesscontext</code>.
* <p>
@@ -145,11 +152,13 @@ public class GLProfile {
static {
// Also initializes TempJarCache if shall be used.
Platform.initSingleton();
- final boolean isOSX = Platform.OSType.MACOS == Platform.getOSType();
+ final boolean isIOS = Platform.OSType.IOS == Platform.getOSType();
+ final boolean isOSXorIOS = Platform.OSType.MACOS == Platform.getOSType() || isIOS;
DEBUG = Debug.debug("GLProfile");
- disableOpenGLCore = PropertyAccess.isPropertyDefined("jogl.disable.openglcore", true) && !isOSX;
- disableOpenGLARBContext = PropertyAccess.isPropertyDefined("jogl.disable.openglarbcontext", true) && !isOSX;
+ disabledEGL = isIOS;
+ disableOpenGLCore = PropertyAccess.isPropertyDefined("jogl.disable.openglcore", true) && !isOSXorIOS;
+ disableOpenGLARBContext = PropertyAccess.isPropertyDefined("jogl.disable.openglarbcontext", true) && !isOSXorIOS;
disableOpenGLES = disableOpenGLARBContext || PropertyAccess.isPropertyDefined("jogl.disable.opengles", true);
disableOpenGLDesktop = PropertyAccess.isPropertyDefined("jogl.disable.opengldesktop", true);
disableSurfacelessContext = PropertyAccess.isPropertyDefined("jogl.disable.surfacelesscontext", true);
@@ -243,7 +252,7 @@ public class GLProfile {
initLock.unlock();
}
if(DEBUG) {
- if( justInitialized && ( hasGL234Impl || hasGL234OnEGLImpl || hasGLES1Impl || hasGLES3Impl ) ) {
+ if( justInitialized && ( hasGL234Impl || hasGL234OnMobileImpl || hasGLES1Impl || hasGLES3Impl ) ) {
System.err.println(JoglVersion.getDefaultOpenGLInfo(defaultDevice, null, true));
}
}
@@ -671,6 +680,18 @@ public class GLProfile {
public static final String[] GL_PROFILE_LIST_MIN_DESKTOP = new String[] { GL2, GL3bc, GL4bc, GL3, GL4 };
/**
+ * Order of maximum original mobile profiles.
+ *
+ * <ul>
+ * <li> GLES3 </li>
+ * <li> GLES2 </li>
+ * <li> GLES1 </li>
+ * </ul>
+ *
+ */
+ public static final String[] GL_PROFILE_LIST_MAX_MOBILE = new String[] { GLES3, GLES2, GLES1 };
+
+ /**
* Order of maximum fixed function profiles
*
* <ul>
@@ -1627,10 +1648,10 @@ public class GLProfile {
private static /*final*/ boolean hasDesktopGLFactory;
private static /*final*/ boolean hasGL234Impl;
- private static /*final*/ boolean hasEGLFactory;
+ private static /*final*/ boolean hasMobileFactory;
private static /*final*/ boolean hasGLES3Impl;
private static /*final*/ boolean hasGLES1Impl;
- private static /*final*/ boolean hasGL234OnEGLImpl;
+ private static /*final*/ boolean hasGL234OnMobileImpl;
private static /*final*/ Constructor<?> ctorGL234Impl;
private static /*final*/ Constructor<?> ctorGLES3Impl;
private static /*final*/ Constructor<?> ctorGLES1Impl;
@@ -1638,7 +1659,7 @@ public class GLProfile {
private static /*final*/ Constructor<?> ctorGLES3ProcAddr;
private static /*final*/ Constructor<?> ctorGLES1ProcAddr;
- private static /*final*/ GLDrawableFactoryImpl eglFactory = null;
+ private static /*final*/ GLDrawableFactoryImpl mobileFactory = null;
private static /*final*/ GLDrawableFactoryImpl desktopFactory = null;
private static /*final*/ AbstractGraphicsDevice defaultDevice = null;
@@ -1683,7 +1704,7 @@ public class GLProfile {
ctorGL234ProcAddr = null;
}
}
- hasGL234OnEGLImpl = hasGL234Impl;
+ hasGL234OnMobileImpl = hasGL234Impl;
// depends on hasEGLFactory
{
@@ -1748,7 +1769,7 @@ public class GLProfile {
try {
desktopFactory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactoryImpl(GL2);
if(null != desktopFactory) {
- final DesktopGLDynamicLookupHelper glLookupHelper = (DesktopGLDynamicLookupHelper) desktopFactory.getGLDynamicLookupHelper(2, GLContext.CTX_PROFILE_COMPAT);
+ final GLDynamicLookupHelper glLookupHelper = desktopFactory.getGLDynamicLookupHelper(2, GLContext.CTX_PROFILE_COMPAT);
hasGL234Impl = null!=glLookupHelper && glLookupHelper.isLibComplete() && hasGL234Impl;
hasDesktopGLFactory = hasGL234Impl;
}
@@ -1777,48 +1798,46 @@ public class GLProfile {
defaultDesktopDevice = desktopFactory.getDefaultDevice();
}
- if ( ReflectionUtil.isClassAvailable("jogamp.opengl.egl.EGLDrawableFactory", classloader) ) {
- t=null;
- try {
- eglFactory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactoryImpl(GLES2);
- if(null != eglFactory) {
- // update hasGLES1Impl, hasGLES3Impl, hasGL234OnEGLImpl based on library completion
- final GLDynamicLookupHelper es2DynLookup = eglFactory.getGLDynamicLookupHelper(2, GLContext.CTX_PROFILE_ES);
- final GLDynamicLookupHelper es1DynLookup = eglFactory.getGLDynamicLookupHelper(1, GLContext.CTX_PROFILE_ES);
- final GLDynamicLookupHelper glXDynLookup = eglFactory.getGLDynamicLookupHelper(3, GLContext.CTX_PROFILE_CORE);
- hasGLES3Impl = null!=es2DynLookup && es2DynLookup.isLibComplete() && hasGLES3Impl;
- hasGLES1Impl = null!=es1DynLookup && es1DynLookup.isLibComplete() && hasGLES1Impl;
- hasGL234OnEGLImpl = null!=glXDynLookup && glXDynLookup.isLibComplete() && hasGL234OnEGLImpl;
- hasEGLFactory = hasGLES3Impl || hasGLES1Impl || hasGL234OnEGLImpl;
- }
- } catch (final LinkageError le) {
- t=le;
- } catch (final SecurityException se) {
- t=se;
- } catch (final NullPointerException npe) {
- t=npe;
- } catch (final RuntimeException re) {
- t=re;
+ t=null;
+ try {
+ mobileFactory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactoryImpl(GLES2);
+ if(null != mobileFactory) {
+ // update hasGLES1Impl, hasGLES3Impl, hasGL234OnEGLImpl based on library completion
+ final GLDynamicLookupHelper es2DynLookup = mobileFactory.getGLDynamicLookupHelper(2, GLContext.CTX_PROFILE_ES);
+ final GLDynamicLookupHelper es1DynLookup = mobileFactory.getGLDynamicLookupHelper(1, GLContext.CTX_PROFILE_ES);
+ final GLDynamicLookupHelper glXDynLookup = mobileFactory.getGLDynamicLookupHelper(3, GLContext.CTX_PROFILE_CORE);
+ hasGLES3Impl = null!=es2DynLookup && es2DynLookup.isLibComplete() && hasGLES3Impl;
+ hasGLES1Impl = null!=es1DynLookup && es1DynLookup.isLibComplete() && hasGLES1Impl;
+ hasGL234OnMobileImpl = null!=glXDynLookup && glXDynLookup.isLibComplete() && hasGL234OnMobileImpl;
+ hasMobileFactory = hasGLES3Impl || hasGLES1Impl || hasGL234OnMobileImpl;
}
- if(DEBUG) {
- if(null!=t) {
- t.printStackTrace();
- }
+ } catch (final LinkageError le) {
+ t=le;
+ } catch (final SecurityException se) {
+ t=se;
+ } catch (final NullPointerException npe) {
+ t=npe;
+ } catch (final RuntimeException re) {
+ t=re;
+ }
+ if(DEBUG) {
+ if(null!=t) {
+ t.printStackTrace();
}
}
- final AbstractGraphicsDevice defaultEGLDevice;
- if(null == eglFactory) {
- hasEGLFactory = false;
- hasGL234OnEGLImpl= false;
+ final AbstractGraphicsDevice defaultMobileDevice;
+ if(null == mobileFactory) {
+ hasMobileFactory = false;
+ hasGL234OnMobileImpl= false;
hasGLES3Impl = false;
hasGLES1Impl = false;
- defaultEGLDevice = null;
+ defaultMobileDevice = null;
if(DEBUG) {
- System.err.println("Info: GLProfile.init - EGL GLDrawable factory not available");
+ System.err.println("Info: GLProfile.init - Mobile GLDrawable factory not available");
}
} else {
- defaultEGLDevice = eglFactory.getDefaultDevice();
+ defaultMobileDevice = mobileFactory.getDefaultDevice();
}
if( null != defaultDesktopDevice ) {
@@ -1826,10 +1845,10 @@ public class GLProfile {
if(DEBUG) {
System.err.println("Info: GLProfile.init - Default device is desktop derived: "+defaultDevice);
}
- } else if ( null != defaultEGLDevice ) {
- defaultDevice = defaultEGLDevice;
+ } else if ( null != defaultMobileDevice ) {
+ defaultDevice = defaultMobileDevice;
if(DEBUG) {
- System.err.println("Info: GLProfile.init - Default device is EGL derived: "+defaultDevice);
+ System.err.println("Info: GLProfile.init - Default device is mobile derived: "+defaultDevice);
}
} else {
if(DEBUG) {
@@ -1839,22 +1858,22 @@ public class GLProfile {
}
// we require to initialize the EGL device 1st, if available
- final boolean addedEGLProfile = null != defaultEGLDevice ? initProfilesForDevice(defaultEGLDevice) : false;
+ final boolean addedMobileProfile = null != defaultMobileDevice ? initProfilesForDevice(defaultMobileDevice) : false;
final boolean addedDesktopProfile = null != defaultDesktopDevice ? initProfilesForDevice(defaultDesktopDevice) : false;
- final boolean addedAnyProfile = addedEGLProfile || addedDesktopProfile ;
+ final boolean addedAnyProfile = addedMobileProfile || addedDesktopProfile ;
if(DEBUG) {
- System.err.println("GLProfile.init addedAnyProfile "+addedAnyProfile+" (desktop: "+addedDesktopProfile+", egl "+addedEGLProfile+")");
+ System.err.println("GLProfile.init addedAnyProfile "+addedAnyProfile+" (desktop: "+addedDesktopProfile+", mobile "+addedMobileProfile+")");
System.err.println("GLProfile.init isAWTAvailable "+isAWTAvailable);
System.err.println("GLProfile.init hasDesktopGLFactory "+hasDesktopGLFactory);
System.err.println("GLProfile.init hasGL234Impl "+hasGL234Impl);
- System.err.println("GLProfile.init hasEGLFactory "+hasEGLFactory);
+ System.err.println("GLProfile.init hasMobileFactory "+hasMobileFactory);
System.err.println("GLProfile.init hasGLES1Impl "+hasGLES1Impl);
System.err.println("GLProfile.init hasGLES3Impl "+hasGLES3Impl);
- System.err.println("GLProfile.init hasGL234OnEGLImpl "+hasGL234OnEGLImpl);
+ System.err.println("GLProfile.init hasGL234OnEGLImpl "+hasGL234OnMobileImpl);
System.err.println("GLProfile.init defaultDevice "+defaultDevice);
System.err.println("GLProfile.init defaultDevice Desktop "+defaultDesktopDevice);
- System.err.println("GLProfile.init defaultDevice EGL "+defaultEGLDevice);
+ System.err.println("GLProfile.init defaultDevice Mobile "+defaultMobileDevice);
System.err.println("GLProfile.init profile order "+array2String(GL_PROFILE_LIST_ALL));
}
}
@@ -1869,22 +1888,25 @@ public class GLProfile {
}
initLock.lock();
try {
- final GLDrawableFactory factory = GLDrawableFactory.getFactoryImpl(device);
- factory.enterThreadCriticalZone();
- try {
- return initProfilesForDeviceCritical(device);
- } finally {
- factory.leaveThreadCriticalZone();
+ final GLDrawableFactory factory = GLDrawableFactory.getFactory(device);
+ if( null != factory ) {
+ factory.enterThreadCriticalZone();
+ try {
+ return initProfilesForDeviceCritical(device);
+ } finally {
+ factory.leaveThreadCriticalZone();
+ }
}
} finally {
initLock.unlock();
}
+ return false;
}
private static boolean initProfilesForDeviceCritical(final AbstractGraphicsDevice device) {
final boolean isSet = GLContext.getAvailableGLVersionsSet(device);
if(DEBUG) {
- System.err.println("Info: GLProfile.initProfilesForDevice: "+device+" ("+device.getClass().getName()+"), isSet "+isSet+", hasDesktopGLFactory "+hasDesktopGLFactory+", hasEGLFactory "+hasEGLFactory);
+ System.err.println("Info: GLProfile.initProfilesForDevice: "+device+" ("+device.getClass().getName()+"), isSet "+isSet+", hasDesktopGLFactory "+hasDesktopGLFactory+", hasEGLFactory "+hasMobileFactory);
}
if(isSet) {
// Avoid recursion and check whether impl. is sane!
@@ -1899,7 +1921,7 @@ public class GLProfile {
HashMap<String, GLProfile> mappedDesktopProfiles = null;
boolean addedDesktopProfile = false;
HashMap<String, GLProfile> mappedEGLProfiles = null;
- boolean addedEGLProfile = false;
+ boolean addedMobileProfile = false;
final boolean deviceIsDesktopCompatible = hasDesktopGLFactory && desktopFactory.getIsDeviceCompatible(device);
@@ -1930,20 +1952,20 @@ public class GLProfile {
}
}
- final boolean deviceIsEGLCompatible = hasEGLFactory && eglFactory.getIsDeviceCompatible(device);
+ final boolean deviceIsMobileCompatible = hasMobileFactory && mobileFactory.getIsDeviceCompatible(device);
// also test GLES1, GLES2 and GLES3 on desktop, since we have implementations / emulations available.
- if( deviceIsEGLCompatible ) {
+ if( deviceIsMobileCompatible ) {
// 1st pretend we have all EGL profiles ..
computeProfileMap(device, true /* desktopCtxUndef*/, true /* esCtxUndef */);
// Triggers eager initialization of share context in GLDrawableFactory for the device,
// hence querying all available GLProfiles
- final Thread sharedResourceThread = eglFactory.getSharedResourceThread();
+ final Thread sharedResourceThread = mobileFactory.getSharedResourceThread();
if(null != sharedResourceThread) {
initLock.addOwner(sharedResourceThread);
}
- final boolean eglSharedCtxAvail = eglFactory.createSharedResource(device);
+ final boolean eglSharedCtxAvail = mobileFactory.createSharedResource(device);
if(null != sharedResourceThread) {
initLock.removeOwner(sharedResourceThread);
}
@@ -1952,28 +1974,28 @@ public class GLProfile {
throw new InternalError("Available GLVersions not set for "+device);
}
mappedEGLProfiles = computeProfileMap(device, false /* desktopCtxUndef*/, false /* esCtxUndef */);
- addedEGLProfile = mappedEGLProfiles.size() > 0;
+ addedMobileProfile = mappedEGLProfiles.size() > 0;
}
if (DEBUG) {
- System.err.println("GLProfile.initProfilesForDevice: "+device+": egl Shared Ctx "+eglSharedCtxAvail+
- ", profiles: "+(addedEGLProfile ? mappedEGLProfiles.size() : 0));
+ System.err.println("GLProfile.initProfilesForDevice: "+device+": mobile Shared Ctx "+eglSharedCtxAvail+
+ ", profiles: "+(addedMobileProfile ? mappedEGLProfiles.size() : 0));
}
}
- if( !addedDesktopProfile && !addedEGLProfile ) {
+ if( !addedDesktopProfile && !addedMobileProfile ) {
setProfileMap(device, new HashMap<String /*GLProfile_name*/, GLProfile>()); // empty
if(DEBUG) {
System.err.println("GLProfile: device could not be initialized: "+device);
System.err.println("GLProfile: compatible w/ desktop: "+deviceIsDesktopCompatible+
- ", egl "+deviceIsEGLCompatible);
+ ", mobile "+deviceIsMobileCompatible);
System.err.println("GLProfile: desktoplFactory "+desktopFactory);
- System.err.println("GLProfile: eglFactory "+eglFactory);
+ System.err.println("GLProfile: mobileFactory "+mobileFactory);
System.err.println("GLProfile: hasGLES1Impl "+hasGLES1Impl);
System.err.println("GLProfile: hasGLES3Impl "+hasGLES3Impl);
}
} else {
final HashMap<String, GLProfile> mappedAllProfiles = new HashMap<String, GLProfile>();
- if( addedEGLProfile ) {
+ if( addedMobileProfile ) {
mappedAllProfiles.putAll(mappedEGLProfiles);
}
if( addedDesktopProfile ) {
@@ -1985,7 +2007,7 @@ public class GLProfile {
GLContext.setAvailableGLVersionsSet(device, true);
if (DEBUG) {
- System.err.println("GLProfile.initProfilesForDevice: "+device.getUniqueID()+": added profile(s): desktop "+addedDesktopProfile+", egl "+addedEGLProfile);
+ System.err.println("GLProfile.initProfilesForDevice: "+device.getUniqueID()+": added profile(s): desktop "+addedDesktopProfile+", mobile "+addedMobileProfile);
System.err.println("GLProfile.initProfilesForDevice: "+device.getUniqueID()+": "+glAvailabilityToString(device));
if(addedDesktopProfile) {
dumpGLInfo(desktopFactory, device);
@@ -1993,16 +2015,16 @@ public class GLProfile {
for(int i=0; i<availCaps.size(); i++) {
System.err.println(availCaps.get(i));
}
- } else if(addedEGLProfile) {
- dumpGLInfo(eglFactory, device);
- final List<GLCapabilitiesImmutable> availCaps = eglFactory.getAvailableCapabilities(device);
+ } else if(addedMobileProfile) {
+ dumpGLInfo(mobileFactory, device);
+ final List<GLCapabilitiesImmutable> availCaps = mobileFactory.getAvailableCapabilities(device);
for(int i=0; i<availCaps.size(); i++) {
System.err.println(availCaps.get(i));
}
}
}
- return addedDesktopProfile || addedEGLProfile;
+ return addedDesktopProfile || addedMobileProfile;
}
private static void dumpGLInfo(final GLDrawableFactoryImpl factory, final AbstractGraphicsDevice device) {
@@ -2106,7 +2128,7 @@ public class GLProfile {
* Returns the profile implementation
*/
private static String computeProfileImpl(final AbstractGraphicsDevice device, final String profile, final boolean desktopCtxUndef, final boolean esCtxUndef, final boolean isHardwareRasterizer[]) {
- final boolean hasAnyGL234Impl = hasGL234Impl || hasGL234OnEGLImpl;
+ final boolean hasAnyGL234Impl = hasGL234Impl || hasGL234OnMobileImpl;
final boolean hardwareRasterizer[] = new boolean[1];
if ( GL2ES1 == profile ) {
final boolean gles1Available;
diff --git a/src/jogl/classes/com/jogamp/opengl/JoglVersion.java b/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
index 560d99025..92511dc11 100644
--- a/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
+++ b/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
@@ -69,11 +69,12 @@ public class JoglVersion extends JogampVersion {
return toString(gl, null).toString();
}
- public static StringBuilder getAvailableCapabilitiesInfo(final GLDrawableFactory factory, final AbstractGraphicsDevice device, StringBuilder sb) {
+ public static StringBuilder getAvailableCapabilitiesInfo(final AbstractGraphicsDevice device, StringBuilder sb) {
if(null==sb) {
sb = new StringBuilder();
}
boolean done = false;
+ final GLDrawableFactory factory = GLDrawableFactory.getFactory(device);
if(null!=factory) {
try {
final List<GLCapabilitiesImmutable> availCaps = factory.getAvailableCapabilities(device);
@@ -100,10 +101,12 @@ public class JoglVersion extends JogampVersion {
device = GLProfile.getDefaultDevice();
}
sb.append(Platform.getNewline()).append(Platform.getNewline());
- sb.append("Desktop Capabilities: ").append(Platform.getNewline());
- getAvailableCapabilitiesInfo(GLDrawableFactory.getDesktopFactory(), device, sb);
- sb.append("EGL Capabilities: ").append(Platform.getNewline());
- getAvailableCapabilitiesInfo(GLDrawableFactory.getEGLFactory(), device, sb);
+ try {
+ sb.append("Capabilities for ").append(device.toString()).append(Platform.getNewline());
+ getAvailableCapabilitiesInfo(device, sb);
+ } catch (final GLException gle) {
+ System.err.println(gle.getMessage());
+ }
return sb;
}
diff --git a/src/jogl/classes/jogamp/opengl/DummyGLExtProcAddressTable.java b/src/jogl/classes/jogamp/opengl/DummyGLExtProcAddressTable.java
new file mode 100644
index 000000000..1cde06e3c
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/DummyGLExtProcAddressTable.java
@@ -0,0 +1,61 @@
+/**
+ * Copyright 2019 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;
+
+import com.jogamp.gluegen.runtime.ProcAddressTable;
+import com.jogamp.common.util.SecurityUtil;
+
+/**
+ * Representing the non-existing platform GL extension, i.e. a dummy type.
+ * <p>
+ * This table is a cache of pointers to the dynamically-linkable C library.
+ * </p>
+ * @see ProcAddressTable
+ */
+public final class DummyGLExtProcAddressTable extends ProcAddressTable {
+
+ public DummyGLExtProcAddressTable(){ super(); }
+
+ public DummyGLExtProcAddressTable(final com.jogamp.gluegen.runtime.FunctionAddressResolver resolver){ super(resolver); }
+
+ @Override
+ protected boolean isFunctionAvailableImpl(final String functionNameUsr) throws IllegalArgumentException {
+ return false;
+ }
+ @Override
+ public long getAddressFor(final String functionNameUsr) throws SecurityException, IllegalArgumentException {
+ SecurityUtil.checkAllLinkPermission();
+ final String functionNameBase = com.jogamp.gluegen.runtime.opengl.GLNameResolver.normalizeVEN(com.jogamp.gluegen.runtime.opengl.GLNameResolver.normalizeARB(functionNameUsr, true), true);
+ // The user is calling a bogus function or one which is not
+ // runtime linked
+ throw new RuntimeException(
+ "WARNING: Address field query failed for \"" + functionNameBase + "\"/\"" + functionNameUsr +
+ "\"; it's either statically linked or address field is not a known " +
+ "function");
+ }
+}
diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
index 6866374bc..84c62b95d 100644
--- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
@@ -2442,10 +2442,13 @@ public abstract class GLContextImpl extends GLContext {
GLRendererQuirks.pushStickyDeviceQuirks(factoryDefaultDevice, quirks);
}
if( isES ) {
- final AbstractGraphicsDevice eglFactoryDefaultDevice = GLDrawableFactory.getEGLFactory().getDefaultDevice();
- if( !GLRendererQuirks.areSameStickyDevice(eglFactoryDefaultDevice, adevice) &&
- !GLRendererQuirks.areSameStickyDevice(eglFactoryDefaultDevice, factoryDefaultDevice) ) {
- GLRendererQuirks.pushStickyDeviceQuirks(eglFactoryDefaultDevice, quirks);
+ final GLDrawableFactory mobileFactory = GLDrawableFactory.getFactory(true);
+ if( null != factory ) {
+ final AbstractGraphicsDevice esFactoryDefaultDevice = mobileFactory.getDefaultDevice();
+ if( !GLRendererQuirks.areSameStickyDevice(esFactoryDefaultDevice, adevice) &&
+ !GLRendererQuirks.areSameStickyDevice(esFactoryDefaultDevice, factoryDefaultDevice) ) {
+ GLRendererQuirks.pushStickyDeviceQuirks(esFactoryDefaultDevice, quirks);
+ }
}
}
}
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
index dfe6bdd9f..2e108d3ce 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
@@ -68,12 +68,16 @@ import com.jogamp.opengl.GLOffscreenAutoDrawable;
import com.jogamp.opengl.GLProfile;
import com.jogamp.common.ExceptionUtils;
+import com.jogamp.common.os.Platform;
import com.jogamp.nativewindow.MutableGraphicsConfiguration;
import com.jogamp.nativewindow.DelegatedUpstreamSurfaceHookWithSurfaceSize;
+import com.jogamp.nativewindow.GenericUpstreamSurfacelessHook;
import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSize;
import com.jogamp.opengl.GLAutoDrawableDelegate;
import com.jogamp.opengl.GLRendererQuirks;
+import jogamp.common.os.PlatformPropsImpl;
+
/** Extends GLDrawableFactory with a few methods for handling
typically software-accelerated offscreen rendering (Device
@@ -275,8 +279,18 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
GLDrawable result = null;
adevice.lock();
try {
+ final boolean forceOnscreenFBOLayer;
+ final boolean useFBORendertarget;
+ if( chosenCaps.isOnscreen() && Platform.OSType.IOS == PlatformPropsImpl.OS_TYPE ) // FIXME: avoid hardcoding?
+ {
+ forceOnscreenFBOLayer = true;
+ useFBORendertarget = true;
+ } else {
+ forceOnscreenFBOLayer = false;
+ useFBORendertarget = false;
+ }
final OffscreenLayerSurface ols = NativeWindowFactory.getOffscreenLayerSurface(target, true);
- if(null != ols) {
+ if(null != ols || forceOnscreenFBOLayer ) {
final GLCapabilitiesImmutable chosenCapsMod = GLGraphicsConfigurationUtil.fixOffscreenGLCapabilities(chosenCaps, this, adevice);
// layered surface -> Offscreen/[FBO|PBuffer]
@@ -284,12 +298,15 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
throw new GLException("Neither FBO nor Pbuffer is available for "+chosenCapsMod+", "+target);
}
config.setChosenCapabilities(chosenCapsMod);
- ols.setChosenCapabilities(chosenCapsMod);
+ if( null != ols ) {
+ ols.setChosenCapabilities(chosenCapsMod);
+ }
if(DEBUG) {
System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OnscreenDrawable -> Offscreen-Layer");
System.err.println("chosenCaps: "+chosenCaps);
System.err.println("chosenCapsMod: "+chosenCapsMod);
System.err.println("OffscreenLayerSurface: **** "+ols);
+ System.err.println("forceOnscreenFBOLayer: **** "+forceOnscreenFBOLayer+", useFBORendertarget "+useFBORendertarget);
System.err.println("Target: **** "+target);
ExceptionUtils.dumpStack(System.err);
}
@@ -297,7 +314,7 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
throw new IllegalArgumentException("Passed NativeSurface must implement SurfaceChangeable for offscreen layered surface: "+target);
}
if( chosenCapsMod.isFBO() ) {
- result = createFBODrawableImpl(target, chosenCapsMod, 0);
+ result = createFBODrawableImpl(target, chosenCapsMod, useFBORendertarget?-1:0);
} else {
result = createOffscreenDrawableImpl(target);
}
@@ -433,6 +450,60 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
new UpstreamSurfaceHookMutableSize(width, height) ) );
}
+ /**
+ * Quick path to produce a Surfaceless resizable FBO Drawable.
+ * <p>
+ * Caller has to be sure Surfaceless context as well as FBO is supported
+ * on the platform, no checks will be made.
+ * </p>
+ * @param device2Use actual device to be used
+ * @param capsRequested
+ * @param width
+ * @param height
+ */
+ protected final GLFBODrawableImpl createSurfacelessFBODrawable(final AbstractGraphicsDevice device2Use,
+ final GLCapabilitiesImmutable capsRequested,
+ final int width, final int height) {
+ if(width<=0 || height<=0) {
+ throw new GLException("initial size must be positive (were (" + width + " x " + height + "))");
+ }
+ final GLCapabilities capsChosen = (GLCapabilities) capsRequested.cloneMutable();
+ {
+ capsChosen.setOnscreen(false);
+ capsChosen.setFBO( true );
+ capsChosen.setPBuffer( false );
+ capsChosen.setBitmap( false );
+ }
+ // final ProxySurface surface = createSurfacelessImpl(device2Use, false, glCapsMin, capsRequested, null, width, height);
+ final GLCapabilitiesImmutable surfaceCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(capsRequested);
+ final ProxySurface surface = createMutableSurfaceImpl(device2Use, false /* createNewDevice */, surfaceCaps, capsRequested, null, new GenericUpstreamSurfacelessHook(width, height));
+
+ final GLDrawableImpl dummyDrawable = createOnscreenDrawableImpl(surface);
+ return new GLFBODrawableImpl.ResizeableImpl(this, dummyDrawable, surface, capsChosen, 0);
+ }
+ /**
+ * Quick path to produce a Surfaceless Drawable.
+ * <p>
+ * Caller has to be sure Surfaceless context is supported
+ * on the platform, no checks will be made.
+ * </p>
+ * @param device2Use actual device to be used
+ * @param capsRequested
+ * @param width
+ * @param height
+ */
+ protected final GLDrawableImpl createSurfacelessDrawable(final AbstractGraphicsDevice device2Use,
+ final GLCapabilitiesImmutable capsRequested,
+ final int width, final int height) {
+ if(width<=0 || height<=0) {
+ throw new GLException("initial size must be positive (were (" + width + " x " + height + "))");
+ }
+ // final ProxySurface surface = createSurfacelessImpl(device2Use, false, glCapsMin, capsRequested, null, width, height);
+ final GLCapabilitiesImmutable surfaceCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(capsRequested);
+ final ProxySurface surface = createMutableSurfaceImpl(device2Use, false /* createNewDevice */, surfaceCaps, capsRequested, null, new GenericUpstreamSurfacelessHook(width, height));
+ return createOnscreenDrawableImpl(surface);
+ }
+
@Override
public final GLDrawable createDummyDrawable(final AbstractGraphicsDevice deviceReq, final boolean createNewDevice, final GLCapabilitiesImmutable capsRequested, final GLCapabilitiesChooser chooser) {
final AbstractGraphicsDevice device = createNewDevice ? getOrCreateSharedDevice(deviceReq) : deviceReq;
diff --git a/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
index cddaebe25..64cca7bdd 100644
--- a/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
@@ -87,17 +87,17 @@ public class GLFBODrawableImpl extends GLDrawableImpl implements GLFBODrawable {
* @param parent
* @param surface
* @param fboCaps the requested FBO capabilities
- * @param textureUnit
+ * @param textureUnit if valid, i.e. >= 0, signals {@link #FBOMODE_USE_TEXTURE}, otherwise a color renderbuffer is assumed
*/
protected GLFBODrawableImpl(final GLDrawableFactoryImpl factory, final GLDrawableImpl parent, final NativeSurface surface,
final GLCapabilitiesImmutable fboCaps, final int textureUnit) {
super(factory, surface, fboCaps, false);
this.initialized = false;
- this.fboModeBits = FBOMODE_USE_TEXTURE;
+ this.fboModeBits = textureUnit>=0 ? FBOMODE_USE_TEXTURE : 0;
this.parent = parent;
this.origParentChosenCaps = getChosenGLCapabilities(); // just to avoid null, will be reset at initialize(..)
- this.texUnit = textureUnit;
+ this.texUnit = textureUnit>=0 ? textureUnit : 0;
this.samples = fboCaps.getNumSamples();
this.fboResetQuirk = false;
this.swapBufferContext = null;
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGLnDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/egl/EGLGLnDynamicLibraryBundleInfo.java
index 6a3a20100..b30a901f4 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGLnDynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGLnDynamicLibraryBundleInfo.java
@@ -59,7 +59,7 @@ public final class EGLGLnDynamicLibraryBundleInfo extends EGLDynamicLibraryBundl
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() ) {
+ } else if( Platform.OSType.WINDOWS == osType ) {
libsGL.add("OpenGL32");
} else {
// this is the default lib name, according to the spec
diff --git a/src/jogl/classes/jogamp/opengl/ios/eagl/IOSEAGLContext.java b/src/jogl/classes/jogamp/opengl/ios/eagl/IOSEAGLContext.java
new file mode 100644
index 000000000..57c20d465
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/ios/eagl/IOSEAGLContext.java
@@ -0,0 +1,477 @@
+/**
+ * Copyright 2019 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.ios.eagl;
+
+import java.util.Map;
+
+import com.jogamp.nativewindow.AbstractGraphicsConfiguration;
+import com.jogamp.nativewindow.AbstractGraphicsDevice;
+import com.jogamp.nativewindow.MutableGraphicsConfiguration;
+import com.jogamp.nativewindow.OffscreenLayerSurface;
+import com.jogamp.opengl.FBObject;
+import com.jogamp.opengl.GL;
+import com.jogamp.opengl.GLCapabilitiesImmutable;
+import com.jogamp.opengl.GLContext;
+import com.jogamp.opengl.GLException;
+import com.jogamp.opengl.GLFBODrawable;
+import com.jogamp.opengl.GLProfile;
+
+import jogamp.nativewindow.ios.IOSUtil;
+import jogamp.opengl.GLContextImpl;
+import jogamp.opengl.GLDrawableImpl;
+import jogamp.opengl.GLDynamicLookupHelper;
+import jogamp.opengl.GLFBODrawableImpl;
+import jogamp.opengl.GLFBODrawableImpl.SwapBufferContext;
+import jogamp.opengl.DummyGLExtProcAddressTable;
+import jogamp.opengl.ios.eagl.IOSEAGLDrawable.GLBackendType;
+
+import com.jogamp.common.os.Platform;
+import com.jogamp.gluegen.runtime.ProcAddressTable;
+import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
+import com.jogamp.opengl.GLRendererQuirks;
+
+public class IOSEAGLContext extends GLContextImpl
+{
+ // Abstract interface for implementation of this context
+ protected interface GLBackendImpl {
+ /** Indicating CALayer, i.e. onscreen rendering using offscreen layer. */
+ boolean isUsingCAEAGLLayer();
+ long create(long share, int ctp, int major, int minor);
+ boolean destroy(long ctx);
+ void associateDrawable(boolean bound);
+ boolean makeCurrent(long ctx);
+ boolean release(long ctx);
+ }
+
+ static boolean isGLProfileSupported(final int ctp, final int major, final int minor) {
+ if( 0 == ( CTX_PROFILE_ES & ctp ) ) {
+ // only ES profiles supported
+ return false;
+ }
+ return true;
+ }
+ static int GLProfile2EAGLProfileValue(final int ctp, final int major, final int minor) {
+ if(!isGLProfileSupported(ctp, major, minor)) {
+ throw new GLException("OpenGL profile not supported.0: "+getGLVersion(major, minor, ctp, "@GLProfile2EAGLProfileValue"));
+ }
+ switch( major ) {
+ case 1:
+ return EAGL.kEAGLRenderingAPIOpenGLES1;
+ case 2:
+ return EAGL.kEAGLRenderingAPIOpenGLES2;
+ case 3:
+ return EAGL.kEAGLRenderingAPIOpenGLES3;
+ }
+ throw new GLException("OpenGL profile not supported.1: "+getGLVersion(major, minor, ctp, "@GLProfile2EAGLProfileValue"));
+ }
+
+ private boolean haveSetOpenGLMode = false;
+ private GLBackendType openGLMode = GLBackendType.CAEAGL_LAYER;
+
+ // Implementation object (either NSOpenGL-based or CGL-based)
+ protected GLBackendImpl impl;
+
+ // CGL extension functions.
+ private DummyGLExtProcAddressTable cglExtProcAddressTable;
+
+ private int lastWidth, lastHeight;
+
+ protected IOSEAGLContext(final GLDrawableImpl drawable,
+ final GLContext shareWith) {
+ super(drawable, shareWith);
+ initOpenGLImpl(getOpenGLMode());
+ }
+
+ @Override
+ protected void resetStates(final boolean isInit) {
+ // no inner state _cglExt = null;
+ super.resetStates(isInit);
+ }
+
+ @Override
+ public Object getPlatformGLExtensions() {
+ return null;
+ }
+
+ @Override
+ public final ProcAddressTable getPlatformExtProcAddressTable() {
+ return getCGLExtProcAddressTable();
+ }
+
+ public final DummyGLExtProcAddressTable getCGLExtProcAddressTable() {
+ return cglExtProcAddressTable;
+ }
+
+ @Override
+ protected Map<String, String> getFunctionNameMap() { return null; }
+
+ @Override
+ protected Map<String, String> getExtensionNameMap() { return null; }
+
+ @Override
+ protected long createContextARBImpl(final long share, final boolean direct, final int ctp, final int major, final int minor) {
+ if(!isGLProfileSupported(ctp, major, minor)) {
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": createContextARBImpl: Not supported "+getGLVersion(major, minor, ctp, "@creation on iOS "+Platform.getOSVersionNumber()));
+ }
+ return 0;
+ }
+
+ // Will throw exception upon error
+ long ctx = impl.create(share, ctp, major, minor);
+ if(0 != ctx) {
+ if (!impl.makeCurrent(ctx)) {
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": createContextARB couldn't make current "+getGLVersion(major, minor, ctp, "@creation"));
+ }
+ impl.release(ctx);
+ impl.destroy(ctx);
+ ctx = 0;
+ } else if(DEBUG) {
+ System.err.println(getThreadName() + ": createContextARBImpl: OK "+getGLVersion(major, minor, ctp, "@creation")+", share "+share+", direct "+direct+" on iOS "+Platform.getOSVersionNumber());
+ }
+ } else if(DEBUG) {
+ System.err.println(getThreadName() + ": createContextARBImpl: NO "+getGLVersion(major, minor, ctp, "@creation on iOS "+Platform.getOSVersionNumber()));
+ }
+ return ctx;
+ }
+
+ @Override
+ protected void destroyContextARBImpl(final long _context) {
+ impl.release(_context);
+ impl.destroy(_context);
+ }
+
+ @Override
+ public final boolean isGLReadDrawableAvailable() {
+ return false;
+ }
+
+ @Override
+ protected boolean createImpl(final long shareWithHandle) throws GLException {
+ final MutableGraphicsConfiguration config = (MutableGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration();
+ final AbstractGraphicsDevice device = config.getScreen().getDevice();
+ final GLCapabilitiesImmutable glCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
+ final GLProfile glp = glCaps.getGLProfile();
+ final boolean createContextARBAvailable = isCreateContextARBAvail(device);
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": IOSEAGLContext.createImpl: START "+glCaps+", share "+toHexString(shareWithHandle));
+ System.err.println(getThreadName() + ": Use ARB[avail["+getCreateContextARBAvailStr(device)+
+ "] -> "+createContextARBAvailable+"]]");
+ }
+ if( !glp.isGLES() ) {
+ throw new GLException("Desktop OpenGL profile not supported on iOS "+Platform.getOSVersionNumber()+": "+glp);
+ }
+ contextHandle = createContextARB(shareWithHandle, true);
+ return 0 != contextHandle;
+ }
+
+ @Override
+ protected void makeCurrentImpl() throws GLException {
+ /** FIXME: won't work w/ special drawables (like FBO) - check for CGL mode regressions!
+ *
+ if (getOpenGLMode() != ((IOSEAGLDrawable)drawable).getOpenGLMode()) {
+ setOpenGLMode(((IOSEAGLDrawable)drawable).getOpenGLMode());
+ } */
+ if ( !impl.makeCurrent(contextHandle) ) {
+ throw new GLException("Error making Context current: "+this);
+ }
+ drawableUpdatedNotify();
+ }
+
+ @Override
+ protected void releaseImpl() throws GLException {
+ if (!impl.release(contextHandle)) {
+ throw new GLException("Error releasing OpenGL Context: "+this);
+ }
+ }
+
+ @Override
+ protected void destroyImpl() throws GLException {
+ if(!impl.destroy(contextHandle)) {
+ throw new GLException("Error destroying OpenGL Context: "+this);
+ }
+ }
+
+ @Override
+ protected void drawableUpdatedNotify() throws GLException {
+ if( drawable.getChosenGLCapabilities().isOnscreen() ) {
+ final int w = drawable.getSurfaceWidth();
+ final int h = drawable.getSurfaceHeight();
+ // final boolean sizeChanged = w != lastWidth || h != lastHeight;
+ if(drawable instanceof GLFBODrawable) {
+ final GLFBODrawable fbod = (GLFBODrawable) drawable;
+ final FBObject.Colorbuffer col = fbod.getColorbuffer(GL.GL_FRONT); // FIXME GL_BACK swap ..
+ final int renderbuffer = col.getName();
+ EAGL.eaglPresentRenderbuffer(contextHandle, renderbuffer);
+ }
+ // TODO: Check for resize ...
+ lastWidth = w;
+ lastHeight = h;
+ }
+ }
+
+ @Override
+ protected void associateDrawable(final boolean bound) {
+ // context stuff depends on drawable stuff
+ if(bound) {
+ final GLDrawableImpl drawable = getDrawableImpl();
+ if( drawable instanceof GLFBODrawableImpl ) {
+ final GLFBODrawableImpl fboDrawable = (GLFBODrawableImpl) drawable;
+ fboDrawable.setSwapBufferContext(new SwapBufferContext() {
+ @Override
+ public void swapBuffers(final boolean doubleBuffered) {
+ EAGL.eaglPresentRenderbuffer(contextHandle, GL.GL_RENDERBUFFER);
+ } } );
+ }
+ // FIXME: Need better way to inject the IOS EAGL Layer into FBObject
+ // FIXME: May want to implement optional injection of a BufferStorage SPI?
+ // FBObject.ColorAttachment.initialize(GL): EAGL.eaglBindDrawableStorageToRenderbuffer(contextHandle, GL.GL_RENDERBUFFER, eaglLayer);
+ final long eaglLayer = IOSUtil.GetCAEAGLLayer(drawable.getNativeSurface().getSurfaceHandle());
+ System.err.println("EAGL: Ctx attach EAGLLayer 0x"+Long.toHexString(eaglLayer));
+ attachObject("IOS_EAGL_LAYER", new Long(eaglLayer));
+
+ super.associateDrawable(true); // 1) init drawable stuff (FBO init, ..)
+ impl.associateDrawable(true); // 2) init context stuff
+ } else {
+ impl.associateDrawable(false); // 1) free context stuff
+ super.associateDrawable(false); // 2) free drawable stuff
+
+ EAGL.eaglBindDrawableStorageToRenderbuffer(contextHandle, GL.GL_RENDERBUFFER, 0);
+ detachObject("IOS_EAGL_LAYER");
+ }
+ }
+
+ @Override
+ protected void copyImpl(final GLContext source, final int mask) throws GLException {
+ throw new GLException("copyImpl n/a: "+this);
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Ignoring {@code contextFQN}, using {@code iOS}-{@link AbstractGraphicsDevice#getUniqueID()}.
+ * </p>
+ */
+ @Override
+ protected final void updateGLXProcAddressTable(final String contextFQN, final GLDynamicLookupHelper dlh) {
+ if( null == dlh ) {
+ throw new GLException("No GLDynamicLookupHelper for "+this);
+ }
+ final AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration();
+ final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
+ final String key = "iOS-"+adevice.getUniqueID();
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": Initializing EAGL extension address table: "+key);
+ }
+ ProcAddressTable table = null;
+ synchronized(mappedContextTypeObjectLock) {
+ table = mappedGLXProcAddress.get( key );
+ }
+ if(null != table) {
+ cglExtProcAddressTable = (DummyGLExtProcAddressTable) table;
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": GLContext CGL ProcAddressTable reusing key("+key+") -> "+toHexString(table.hashCode()));
+ }
+ } else {
+ cglExtProcAddressTable = new DummyGLExtProcAddressTable(new GLProcAddressResolver());
+ resetProcAddressTable(getCGLExtProcAddressTable(), dlh);
+ synchronized(mappedContextTypeObjectLock) {
+ mappedGLXProcAddress.put(key, getCGLExtProcAddressTable());
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": GLContext CGL ProcAddressTable mapping key("+key+") -> "+toHexString(getCGLExtProcAddressTable().hashCode()));
+ }
+ }
+ }
+ }
+
+ @Override
+ protected final StringBuilder getPlatformExtensionsStringImpl() {
+ return new StringBuilder();
+ }
+
+ // Support for "mode switching" as described in IOSEAGLDrawable
+ public void setOpenGLMode(final GLBackendType mode) {
+ if (mode == openGLMode) {
+ return;
+ }
+ if (haveSetOpenGLMode) {
+ throw new GLException("Can't switch between using EAGL and ... more than once");
+ }
+ destroyImpl();
+ ((IOSEAGLDrawable)drawable).setOpenGLMode(mode);
+ if (DEBUG) {
+ System.err.println("IOSEAGLContext: Switching context mode " + openGLMode + " -> " + mode);
+ }
+ initOpenGLImpl(mode);
+ openGLMode = mode;
+ haveSetOpenGLMode = true;
+ }
+ public final GLBackendType getOpenGLMode() { return openGLMode; }
+
+ protected void initOpenGLImpl(final GLBackendType backend) {
+ switch (backend) {
+ case CAEAGL_LAYER:
+ impl = new CAEAGLLayerImpl();
+ break;
+ default:
+ throw new InternalError("Illegal implementation mode " + backend);
+ }
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append(getClass().getSimpleName());
+ sb.append(" [");
+ super.append(sb);
+ sb.append("] ");
+ return sb.toString();
+ }
+
+ class CAEAGLLayerImpl implements GLBackendImpl {
+ private final OffscreenLayerSurface backingLayerHost = null;
+
+ @Override
+ public boolean isUsingCAEAGLLayer() { return null != backingLayerHost; }
+
+ /** Only returns a valid UIView. If !UIView, return null and mark isFBO or isSurfaceless. */
+ private long getUIViewHandle(final boolean[] isFBO, final boolean[] isSurfaceless) {
+ final long uiViewHandle;
+ if(drawable instanceof GLFBODrawableImpl) {
+ uiViewHandle = 0;
+ isFBO[0] = true;
+ isSurfaceless[0] = false;
+ if(DEBUG) {
+ System.err.println("UI viewHandle.1: GLFBODrawableImpl drawable: isFBO "+isFBO[0]+", isSurfaceless "+isSurfaceless[0]+", "+drawable.getClass().getName()+",\n\t"+drawable);
+ }
+ } else {
+ final long drawableHandle = drawable.getHandle();
+ final boolean isUIView = IOSUtil.isUIView(drawableHandle);
+ final boolean isUIWindow = IOSUtil.isUIWindow(drawableHandle);
+ isFBO[0] = false;
+ isSurfaceless[0] = false;
+
+ if( isUIView ) {
+ uiViewHandle = drawableHandle;
+ } else if( isUIWindow ) {
+ uiViewHandle = IOSUtil.GetUIView(drawableHandle, true /* only EAGL */);
+ } else if( isSurfaceless() ) {
+ isSurfaceless[0] = true;
+ uiViewHandle = 0;
+ } else {
+ throw new GLException("Drawable's handle neither NSView, NSWindow nor PBuffer: drawableHandle "+toHexString(drawableHandle)+", isNSView "+isUIView+", isNSWindow "+isUIWindow+", isFBO "+isFBO[0]+", "+drawable.getClass().getName()+",\n\t"+drawable);
+ }
+ if(DEBUG) {
+ System.err.println("NS viewHandle.2: drawableHandle "+toHexString(drawableHandle)+" -> nsViewHandle "+toHexString(uiViewHandle)+": isNSView "+isUIView+", isNSWindow "+isUIWindow+", isFBO "+isFBO[0]+", isSurfaceless "+isSurfaceless[0]+", "+drawable.getClass().getName()+",\n\t"+drawable);
+ }
+ }
+ return uiViewHandle;
+ }
+
+ @Override
+ public long create(final long share, final int ctp, final int major, final int minor) {
+ long ctx = 0;
+ final MutableGraphicsConfiguration config = (MutableGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration();
+ final GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable)config.getChosenCapabilities();
+ // Create new context
+ if (DEBUG) {
+ System.err.println("Share context for EAGL-based context is " + toHexString(share));
+ }
+ final boolean isFBO = drawable instanceof GLFBODrawableImpl;
+ final int api = GLProfile2EAGLProfileValue(ctp, major, minor);
+ if( 0 != share ) {
+ ctx = EAGL.eaglCreateContextShared(api, EAGL.eaglGetSharegroup(share));
+ } else {
+ ctx = EAGL.eaglCreateContext(api);
+ }
+ if (0 != ctx) {
+ final GLCapabilitiesImmutable fixedCaps;
+ if( isFBO ) {
+ fixedCaps = chosenCaps;
+ } else {
+ if( DEBUG ) {
+ System.err.println("Warning: CAEAGLLayer w/ non FBO caps");
+ }
+ fixedCaps = chosenCaps;
+ }
+ if(DEBUG) {
+ System.err.println("NS create backingLayerHost: "+backingLayerHost);
+ System.err.println("NS create share: "+share);
+ System.err.println("NS create drawable type: "+drawable.getClass().getName());
+ System.err.println("NS create chosenCaps: "+chosenCaps);
+ System.err.println("NS create fixedCaps: "+fixedCaps);
+ System.err.println("NS create drawable native-handle: "+toHexString(drawable.getHandle()));
+ System.err.println("NS create surface native-handle: "+toHexString(drawable.getNativeSurface().getSurfaceHandle()));
+ // Thread.dumpStack();
+ }
+ config.setChosenCapabilities(fixedCaps);
+ if(DEBUG) {
+ System.err.println("EAGL create fixedCaps: "+fixedCaps);
+ }
+ }
+ return ctx;
+ }
+
+ @Override
+ public boolean destroy(final long ctx) {
+ return EAGL.eaglDeleteContext(ctx, true /* releaseOnMainThread */);
+ }
+
+ @Override
+ public void associateDrawable(final boolean bound) {
+ }
+
+ @Override
+ public boolean makeCurrent(final long ctx) {
+ return EAGL.eaglMakeCurrentContext(ctx);
+ }
+
+ @Override
+ public boolean release(final long ctx) {
+ try {
+ if( hasRendererQuirk(GLRendererQuirks.GLFlushBeforeRelease) && null != IOSEAGLContext.this.getGLProcAddressTable() ) {
+ gl.glFlush();
+ }
+ } catch (final GLException gle) {
+ if(DEBUG) {
+ System.err.println("IOSEAGLContext.CGLImpl.release: INFO: glFlush() caught exception:");
+ gle.printStackTrace();
+ }
+ }
+ return EAGL.eaglMakeCurrentContext(0);
+ }
+ }
+
+ @Override
+ protected Integer setSwapIntervalImpl2(final int interval) {
+ // TODO
+ return null;
+ }
+}
diff --git a/src/jogl/classes/jogamp/opengl/ios/eagl/IOSEAGLDrawable.java b/src/jogl/classes/jogamp/opengl/ios/eagl/IOSEAGLDrawable.java
new file mode 100644
index 000000000..a851e60c6
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/ios/eagl/IOSEAGLDrawable.java
@@ -0,0 +1,90 @@
+/**
+ * Copyright 2019 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.ios.eagl;
+
+import com.jogamp.nativewindow.NativeSurface;
+import com.jogamp.opengl.GL;
+import com.jogamp.opengl.GLContext;
+import com.jogamp.opengl.GLDrawableFactory;
+import com.jogamp.opengl.GLException;
+
+import jogamp.opengl.GLDrawableImpl;
+
+public abstract class IOSEAGLDrawable extends GLDrawableImpl {
+ public enum GLBackendType {
+ /** Default OpenGL Backend */
+ CAEAGL_LAYER(0);
+
+ public final int id;
+
+ GLBackendType(final int id){
+ this.id = id;
+ }
+ }
+
+ private boolean haveSetOpenGLMode = false;
+ private GLBackendType openGLMode = GLBackendType.CAEAGL_LAYER;
+
+ public IOSEAGLDrawable(final GLDrawableFactory factory, final NativeSurface comp, final boolean realized) {
+ super(factory, comp, realized);
+ initOpenGLImpl(getOpenGLMode());
+ }
+
+ @Override
+ protected void setRealizedImpl() {
+ }
+
+ @Override
+ protected void associateContext(final GLContext ctx, final boolean bound) {
+ }
+
+ @Override
+ protected final void swapBuffersImpl(final boolean doubleBuffered) {
+ }
+
+ // Support for "mode switching" as described in MacOSXCGLDrawable
+ public void setOpenGLMode(final GLBackendType mode) {
+ if (mode == openGLMode) {
+ return;
+ }
+ if (haveSetOpenGLMode) {
+ throw new GLException("Can't switch between using NSOpenGLPixelBuffer and CGLPBufferObj more than once");
+ }
+ setRealized(false);
+ if (DEBUG) {
+ System.err.println("MacOSXCGLDrawable: Switching context mode " + openGLMode + " -> " + mode);
+ }
+ initOpenGLImpl(mode);
+ openGLMode = mode;
+ haveSetOpenGLMode = true;
+ }
+ public final GLBackendType getOpenGLMode() { return openGLMode; }
+
+ protected void initOpenGLImpl(final GLBackendType backend) { /* nop */ }
+
+}
diff --git a/src/jogl/classes/jogamp/opengl/ios/eagl/IOSEAGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/ios/eagl/IOSEAGLDrawableFactory.java
new file mode 100644
index 000000000..3c3f1edb8
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/ios/eagl/IOSEAGLDrawableFactory.java
@@ -0,0 +1,453 @@
+/**
+ * Copyright 2019 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.ios.eagl;
+
+import java.nio.Buffer;
+import java.nio.ShortBuffer;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+
+import com.jogamp.nativewindow.AbstractGraphicsDevice;
+import com.jogamp.nativewindow.AbstractGraphicsScreen;
+import com.jogamp.nativewindow.DefaultGraphicsScreen;
+import com.jogamp.nativewindow.NativeSurface;
+import com.jogamp.nativewindow.ProxySurface;
+import com.jogamp.nativewindow.UpstreamSurfaceHook;
+import com.jogamp.nativewindow.ios.IOSGraphicsDevice;
+import com.jogamp.opengl.GL;
+import com.jogamp.opengl.GLCapabilities;
+import com.jogamp.opengl.GLCapabilitiesChooser;
+import com.jogamp.opengl.GLCapabilitiesImmutable;
+import com.jogamp.opengl.GLContext;
+import com.jogamp.opengl.GLDrawable;
+import com.jogamp.opengl.GLException;
+import com.jogamp.opengl.GLProfile;
+
+import jogamp.nativewindow.WrappedSurface;
+import jogamp.nativewindow.ios.IOSDummyUpstreamSurfaceHook;
+import jogamp.opengl.GLContextImpl;
+import jogamp.opengl.GLDrawableFactoryImpl;
+import jogamp.opengl.GLDrawableImpl;
+import jogamp.opengl.GLDynamicLookupHelper;
+import jogamp.opengl.GLGraphicsConfigurationUtil;
+import jogamp.opengl.SharedResourceRunner;
+
+import com.jogamp.nativewindow.GenericUpstreamSurfacelessHook;
+import com.jogamp.opengl.GLExtensions;
+import com.jogamp.opengl.GLRendererQuirks;
+
+public class IOSEAGLDrawableFactory extends GLDrawableFactoryImpl {
+ private static final boolean DEBUG_SHAREDCTX = DEBUG || GLContext.DEBUG;
+
+ private static GLDynamicLookupHelper iosEAGLDynamicLookupHelper = null;
+
+ public IOSEAGLDrawableFactory() {
+ super();
+
+ synchronized(IOSEAGLDrawableFactory.class) {
+ if(null==iosEAGLDynamicLookupHelper) {
+ GLDynamicLookupHelper tmp = null;
+ try {
+ tmp = new GLDynamicLookupHelper(new IOSEAGLDynamicLibraryBundleInfo());
+ } catch (final GLException gle) {
+ if(DEBUG) {
+ gle.printStackTrace();
+ }
+ }
+ if(null!=tmp && tmp.isLibComplete()) {
+ iosEAGLDynamicLookupHelper = tmp;
+ }
+ }
+ }
+
+ defaultDevice = new IOSGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
+
+ if(null!=iosEAGLDynamicLookupHelper) {
+ // Register our GraphicsConfigurationFactory implementations
+ // The act of constructing them causes them to be registered
+ IOSEAGLGraphicsConfigurationFactory.registerFactory();
+ sharedMap = new HashMap<String, SharedResource>();
+ }
+ }
+
+ @Override
+ protected final boolean isComplete() {
+ return null != iosEAGLDynamicLookupHelper;
+ }
+
+ @Override
+ protected final void shutdownImpl() {
+ if( DEBUG ) {
+ System.err.println("IOSEAGLDrawableFactory.shutdown");
+ }
+ if(null != sharedMap) {
+ sharedMap.clear();
+ sharedMap = null;
+ }
+ defaultDevice = null;
+ /**
+ * Pulling away the native library may cause havoc ..
+ *
+ macOSXCGLDynamicLookupHelper.destroy();
+ */
+ iosEAGLDynamicLookupHelper = null;
+ }
+
+ @Override
+ public final GLDynamicLookupHelper getGLDynamicLookupHelper(final int majorVersion, final int contextOptions) {
+ return iosEAGLDynamicLookupHelper;
+ }
+
+ private HashMap<String, SharedResource> sharedMap = new HashMap<String, SharedResource>();
+ private IOSGraphicsDevice defaultDevice;
+
+ static class SharedResource implements SharedResourceRunner.Resource {
+ // private IOSEAGLDrawable drawable;
+ // private IOSEAGLContext context;
+ private final GLRendererQuirks glRendererQuirks;
+ IOSGraphicsDevice device;
+ boolean valid;
+ boolean hasNPOTTextures;
+ boolean hasRECTTextures;
+ boolean hasAppleFloatPixels;
+
+ SharedResource(final IOSGraphicsDevice device, final boolean valid,
+ final boolean hasNPOTTextures, final boolean hasRECTTextures, final boolean hasAppletFloatPixels
+ /* IOSEAGLDrawable draw, IOSEAGLContext ctx */, final GLRendererQuirks glRendererQuirks) {
+ // drawable = draw;
+ // this.context = ctx;
+ this.glRendererQuirks = glRendererQuirks;
+ this.device = device;
+ this.valid = valid;
+ this.hasNPOTTextures = hasNPOTTextures;
+ this.hasRECTTextures = hasRECTTextures;
+ this.hasAppleFloatPixels = hasAppletFloatPixels;
+ }
+ @Override
+ public final boolean isAvailable() {
+ return valid;
+ }
+ @Override
+ public final IOSGraphicsDevice getDevice() { return device; }
+ // final IOSEAGLContext getContext() { return context; }
+ final boolean isNPOTTextureAvailable() { return hasNPOTTextures; }
+ final boolean isRECTTextureAvailable() { return hasRECTTextures; }
+ final boolean isAppleFloatPixelsAvailable() { return hasAppleFloatPixels; }
+ @Override
+ public final AbstractGraphicsScreen getScreen() {
+ return null;
+ }
+ @Override
+ public final GLDrawableImpl getDrawable() {
+ return null;
+ }
+ @Override
+ public GLContextImpl getContext() {
+ return null;
+ }
+ @Override
+ public GLRendererQuirks getRendererQuirks(final GLProfile glp) {
+ return glRendererQuirks;
+ }
+ }
+
+ @Override
+ public final AbstractGraphicsDevice getDefaultDevice() {
+ return defaultDevice;
+ }
+
+ @Override
+ public final boolean getIsDeviceCompatible(final AbstractGraphicsDevice device) {
+ if(null!=iosEAGLDynamicLookupHelper && device instanceof IOSGraphicsDevice) {
+ return true;
+ }
+ return false;
+ }
+
+ private final HashSet<String> devicesTried = new HashSet<String>();
+
+ private boolean getDeviceTried(final String connection) {
+ synchronized (devicesTried) {
+ return devicesTried.contains(connection);
+ }
+ }
+ private void addDeviceTried(final String connection) {
+ synchronized (devicesTried) {
+ devicesTried.add(connection);
+ }
+ }
+ private void removeDeviceTried(final String connection) {
+ synchronized (devicesTried) {
+ devicesTried.remove(connection);
+ }
+ }
+
+ @Override
+ protected final SharedResource getOrCreateSharedResourceImpl(final AbstractGraphicsDevice adevice) {
+ final String connection = adevice.getConnection();
+ SharedResource sr;
+ synchronized(sharedMap) {
+ sr = sharedMap.get(connection);
+ }
+ if(null==sr && !getDeviceTried(connection)) {
+ addDeviceTried(connection);
+ final IOSGraphicsDevice device = new IOSGraphicsDevice(adevice.getUnitID());
+ GLDrawable drawable = null;
+ GLDrawable zeroDrawable = null;
+ GLContextImpl context = null;
+ boolean contextIsCurrent = false;
+ device.lock();
+ try {
+ final GLProfile glp = GLProfile.get(device, GLProfile.GL_PROFILE_LIST_MAX_MOBILE, false);
+ if (null == glp) {
+ throw new GLException("Couldn't get default GLProfile for device: "+device);
+ }
+ final GLCapabilitiesImmutable caps = new GLCapabilities(glp);
+ // drawable = createSurfacelessFBODrawable(device, caps, 64, 64);
+ drawable = createSurfacelessDrawable(device, caps, 64, 64);
+
+ drawable.setRealized(true);
+
+ context = (IOSEAGLContext) drawable.createContext(null);
+ if (null == context) {
+ throw new GLException("Couldn't create shared context for drawable: "+drawable);
+ }
+ contextIsCurrent = GLContext.CONTEXT_NOT_CURRENT != context.makeCurrent();
+
+ final boolean allowsSurfacelessCtx;
+ final boolean hasNPOTTextures;
+ final boolean hasRECTTextures;
+ final boolean hasAppleFloatPixels;
+ final GLRendererQuirks glRendererQuirks;
+ if( contextIsCurrent ) {
+ // We allow probing surfaceless for even the compatible 2.1 context,
+ // which we probably have right here - since OSX may support this.
+ // Otherwise, we cannot map the quirk to the device.
+ if( probeSurfacelessCtx(context, false /* restoreDrawable */) ) {
+ allowsSurfacelessCtx = true;
+ zeroDrawable = context.getGLDrawable();
+ } else {
+ allowsSurfacelessCtx = false;
+ }
+ final GL gl = context.getGL();
+ hasNPOTTextures = gl.isNPOTTextureAvailable();
+ hasRECTTextures = gl.isExtensionAvailable(GLExtensions.EXT_texture_rectangle);
+ hasAppleFloatPixels = gl.isExtensionAvailable(GLExtensions.APPLE_float_pixels);
+ glRendererQuirks = context.getRendererQuirks();
+ } else {
+ allowsSurfacelessCtx = false;
+ hasNPOTTextures = false;
+ hasRECTTextures = false;
+ hasAppleFloatPixels = false;
+ glRendererQuirks = null;
+ }
+ sr = new SharedResource(device, contextIsCurrent, hasNPOTTextures, hasRECTTextures, hasAppleFloatPixels, glRendererQuirks);
+ if ( DEBUG_SHAREDCTX ) {
+ System.err.println("SharedDevice: " + device);
+ System.err.println("SharedContext: " + context + ", madeCurrent " + contextIsCurrent);
+ System.err.println(" NPOT "+hasNPOTTextures+", RECT "+hasRECTTextures+", FloatPixels "+hasAppleFloatPixels);
+ System.err.println(" allowsSurfacelessCtx "+allowsSurfacelessCtx);
+ System.err.println(" glRendererQuirks "+glRendererQuirks);
+ }
+ synchronized(sharedMap) {
+ sharedMap.put(connection, sr);
+ }
+ } catch (final Throwable t) {
+ throw new GLException("IOSEAGLDrawableFactory - Could not initialize shared resources for "+adevice, t);
+ } finally {
+ if( null != context ) {
+ try {
+ context.destroy();
+ } catch (final GLException gle) {
+ if ( DEBUG_SHAREDCTX ) {
+ System.err.println("IOSEAGLDrawableFactory.createShared: INFO: destroy caught exception:");
+ gle.printStackTrace();
+ }
+ }
+ }
+ if( null != zeroDrawable ) {
+ zeroDrawable.setRealized(false);
+ }
+ if( null != drawable ) {
+ drawable.setRealized(false);
+ }
+ device.unlock();
+ removeDeviceTried(connection);
+ }
+ }
+ return sr;
+ }
+
+ @Override
+ protected final Thread getSharedResourceThread() {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This factory never supports native desktop OpenGL profiles.
+ * </p>
+ */
+ @Override
+ public final boolean hasOpenGLDesktopSupport() { return false; }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This factory always supports native GLES profiles.
+ * </p>
+ */
+ @Override
+ public final boolean hasOpenGLESSupport() { return true; }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Always returns false.
+ * </p>
+ */
+ @Override
+ public final boolean hasMajorMinorCreateContextARB() { return false; }
+
+ @Override
+ protected List<GLCapabilitiesImmutable> getAvailableCapabilitiesImpl(final AbstractGraphicsDevice device) {
+ return IOSEAGLGraphicsConfiguration.getAvailableCapabilities(this, device);
+ }
+
+ @Override
+ protected GLDrawableImpl createOnscreenDrawableImpl(final NativeSurface target) {
+ if (target == null) {
+ throw new IllegalArgumentException("Null target");
+ }
+ return new IOSOnscreenEAGLDrawable(this, target);
+ }
+
+ @Override
+ protected GLDrawableImpl createOffscreenDrawableImpl(final NativeSurface target) {
+ throw new GLException("Only FBO is supported for offscreen");
+ }
+
+ @Override
+ public boolean canCreateGLPbuffer(final AbstractGraphicsDevice device, final GLProfile glp) {
+ return false;
+ }
+
+ @Override
+ protected ProxySurface createMutableSurfaceImpl(final AbstractGraphicsDevice deviceReq, final boolean createNewDevice,
+ final GLCapabilitiesImmutable capsChosen, final GLCapabilitiesImmutable capsRequested,
+ final GLCapabilitiesChooser chooser, final UpstreamSurfaceHook upstreamHook) {
+ final IOSGraphicsDevice device;
+ if( createNewDevice || !(deviceReq instanceof IOSGraphicsDevice) ) {
+ device = new IOSGraphicsDevice(deviceReq.getUnitID());
+ } else {
+ device = (IOSGraphicsDevice)deviceReq;
+ }
+ final AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, 0);
+ final IOSEAGLGraphicsConfiguration config = IOSEAGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen, true);
+ if(null == config) {
+ throw new GLException("Choosing GraphicsConfiguration failed w/ "+capsChosen+" on "+screen);
+ }
+ return new WrappedSurface(config, 0, upstreamHook, createNewDevice);
+ }
+
+ @Override
+ public final ProxySurface createDummySurfaceImpl(final AbstractGraphicsDevice deviceReq, final boolean createNewDevice,
+ GLCapabilitiesImmutable chosenCaps, final GLCapabilitiesImmutable requestedCaps, final GLCapabilitiesChooser chooser, final int width, final int height) {
+ chosenCaps = GLGraphicsConfigurationUtil.fixOnscreenGLCapabilities(chosenCaps);
+ return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser,
+ new IOSDummyUpstreamSurfaceHook(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);
+ return createMutableSurfaceImpl(deviceReq, createNewDevice, chosenCaps, requestedCaps, chooser, new GenericUpstreamSurfacelessHook(width, height));
+ }
+
+ @Override
+ protected ProxySurface createProxySurfaceImpl(final AbstractGraphicsDevice deviceReq, final int screenIdx, final long windowHandle, final GLCapabilitiesImmutable capsRequested, final GLCapabilitiesChooser chooser, final UpstreamSurfaceHook upstream) {
+ final IOSGraphicsDevice device = new IOSGraphicsDevice(deviceReq.getUnitID());
+ final AbstractGraphicsScreen screen = new DefaultGraphicsScreen(device, screenIdx);
+ final IOSEAGLGraphicsConfiguration config = IOSEAGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsRequested, capsRequested, chooser, screen, true);
+ return new WrappedSurface(config, windowHandle, upstream, true);
+ }
+
+ @Override
+ protected GLContext createExternalGLContextImpl() {
+ throw new GLException("Not implemented");
+ }
+
+ @Override
+ public boolean canCreateExternalGLDrawable(final AbstractGraphicsDevice device) {
+ return false;
+ }
+
+ @Override
+ protected GLDrawable createExternalGLDrawableImpl() {
+ throw new GLException("Not implemented");
+ }
+
+ //------------------------------------------------------
+ // Gamma-related functionality
+ //
+
+ private static final int GAMMA_RAMP_LENGTH = 256;
+
+ /** Returns the length of the computed gamma ramp for this OS and
+ hardware. Returns 0 if gamma changes are not supported. */
+ @Override
+ protected int getGammaRampLength(final NativeSurface surface) {
+ return GAMMA_RAMP_LENGTH;
+ }
+
+ @Override
+ protected boolean setGammaRamp(final NativeSurface surface, final float[] ramp) {
+ // final FloatBuffer rampNIO = Buffers.newDirectFloatBuffer(ramp);
+ return false; // TODO CGL.setGammaRamp(ramp.length, rampNIO, rampNIO, rampNIO);
+ }
+
+ @Override
+ protected Buffer getGammaRamp(final NativeSurface surface) {
+ return ShortBuffer.allocate(0); // return a dummy gamma ramp default for reset
+ }
+
+ @Override
+ protected void resetGammaRamp(final NativeSurface surface, final Buffer originalGammaRamp) {
+ // TODO CGL.resetGammaRamp();
+ }
+
+ @Override
+ protected final void resetGammaRamp(final DeviceScreenID deviceScreenID, final Buffer originalGammaRamp) {
+ // TODO CGL.resetGammaRamp();
+ }
+
+}
diff --git a/src/jogl/classes/jogamp/opengl/ios/eagl/IOSEAGLDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/ios/eagl/IOSEAGLDynamicLibraryBundleInfo.java
new file mode 100644
index 000000000..c418cd682
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/ios/eagl/IOSEAGLDynamicLibraryBundleInfo.java
@@ -0,0 +1,83 @@
+/**
+ * Copyright 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:
+ *
+ * 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.ios.eagl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import jogamp.opengl.GLDynamicLibraryBundleInfo;
+
+public final class IOSEAGLDynamicLibraryBundleInfo extends GLDynamicLibraryBundleInfo {
+ private static final List<String> glueLibNames;
+ static {
+ glueLibNames = new ArrayList<String>();
+ glueLibNames.add("jogl_mobile");
+ }
+ protected IOSEAGLDynamicLibraryBundleInfo() {
+ super();
+ }
+
+ @Override
+ public boolean shallLookupGlobal() { return true; }
+
+ @Override
+ public final List<List<String>> getToolLibNames() {
+ final List<List<String>> libsList = new ArrayList<List<String>>();
+ final List<String> libsGL = new ArrayList<String>();
+ libsGL.add("OpenGLES"); // actually used '/Library/Frameworks/OpenGLES.framework/OpenGLES'
+ libsList.add(libsGL);
+ return libsList;
+ }
+
+ @Override
+ public final List<String> getToolGetProcAddressFuncNameList() {
+ return null;
+ /** OSX manual says: NSImage use is discouraged
+ List res = new ArrayList();
+ res.add("GetProcAddress"); // dummy
+ return res; */
+ }
+
+ @Override
+ public final long toolGetProcAddress(final long toolGetProcAddressHandle, final String funcName) {
+ // return EAGL.getProcAddress(funcName);
+ return 0;
+ }
+
+ @Override
+ public final List<String> getGlueLibNames() {
+ return glueLibNames;
+ }
+
+ @Override
+ public boolean useToolGetProcAdressFirst(final String funcName) {
+ return true;
+ }
+}
+
diff --git a/src/jogl/classes/jogamp/opengl/ios/eagl/IOSEAGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/ios/eagl/IOSEAGLGraphicsConfiguration.java
new file mode 100644
index 000000000..18e597065
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/ios/eagl/IOSEAGLGraphicsConfiguration.java
@@ -0,0 +1,62 @@
+/**
+ * Copyright 2019 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.ios.eagl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.jogamp.nativewindow.AbstractGraphicsDevice;
+import com.jogamp.nativewindow.AbstractGraphicsScreen;
+import com.jogamp.opengl.GLCapabilitiesImmutable;
+import com.jogamp.opengl.GLException;
+
+import com.jogamp.nativewindow.MutableGraphicsConfiguration;
+
+public class IOSEAGLGraphicsConfiguration extends MutableGraphicsConfiguration implements Cloneable {
+
+ IOSEAGLGraphicsConfiguration(final AbstractGraphicsScreen screen,
+ final GLCapabilitiesImmutable capsChosen, final GLCapabilitiesImmutable capsRequested) {
+ super(screen, capsChosen, capsRequested);
+ }
+
+ @Override
+ public Object clone() {
+ return super.clone();
+ }
+
+ protected static List<GLCapabilitiesImmutable> getAvailableCapabilities(final IOSEAGLDrawableFactory factory, final AbstractGraphicsDevice device) {
+ final IOSEAGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResourceImpl(device);
+ if(null == sharedResource) {
+ throw new GLException("Shared resource for device n/a: "+device);
+ }
+ // MacOSXGraphicsDevice osxDevice = sharedResource.getDevice();
+ return new ArrayList<GLCapabilitiesImmutable>(0);
+ }
+}
+
diff --git a/src/jogl/classes/jogamp/opengl/ios/eagl/IOSEAGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/ios/eagl/IOSEAGLGraphicsConfigurationFactory.java
new file mode 100644
index 000000000..3a4f1a354
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/ios/eagl/IOSEAGLGraphicsConfigurationFactory.java
@@ -0,0 +1,87 @@
+/**
+ * Copyright 2019 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.ios.eagl;
+
+import jogamp.opengl.GLGraphicsConfigurationFactory;
+import jogamp.opengl.GLGraphicsConfigurationUtil;
+
+import com.jogamp.nativewindow.AbstractGraphicsConfiguration;
+import com.jogamp.nativewindow.AbstractGraphicsDevice;
+import com.jogamp.nativewindow.AbstractGraphicsScreen;
+import com.jogamp.nativewindow.CapabilitiesChooser;
+import com.jogamp.nativewindow.CapabilitiesImmutable;
+import com.jogamp.nativewindow.GraphicsConfigurationFactory;
+import com.jogamp.opengl.GLCapabilitiesChooser;
+import com.jogamp.opengl.GLCapabilitiesImmutable;
+import com.jogamp.opengl.GLDrawableFactory;
+
+
+public class IOSEAGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory {
+ static void registerFactory() {
+ GraphicsConfigurationFactory.registerFactory(com.jogamp.nativewindow.ios.IOSGraphicsDevice.class, GLCapabilitiesImmutable.class, new IOSEAGLGraphicsConfigurationFactory());
+ }
+ private IOSEAGLGraphicsConfigurationFactory() {
+ }
+
+ @Override
+ protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl(
+ final CapabilitiesImmutable capsChosen, final CapabilitiesImmutable capsRequested,
+ final CapabilitiesChooser chooser, final AbstractGraphicsScreen absScreen, final int nativeVisualID) {
+
+ if (absScreen == null) {
+ throw new IllegalArgumentException("AbstractGraphicsScreen is null");
+ }
+
+ if (! (capsChosen instanceof GLCapabilitiesImmutable) ) {
+ throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilities objects - chosen");
+ }
+
+ if (! (capsRequested instanceof GLCapabilitiesImmutable) ) {
+ throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilities objects - requested");
+ }
+
+ if (chooser != null && !(chooser instanceof GLCapabilitiesChooser)) {
+ throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects");
+ }
+
+ return chooseGraphicsConfigurationStatic((GLCapabilitiesImmutable)capsChosen, (GLCapabilitiesImmutable)capsRequested, (GLCapabilitiesChooser)chooser, absScreen, false);
+ }
+
+ static IOSEAGLGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilitiesImmutable capsChosen,
+ final GLCapabilitiesImmutable capsRequested,
+ final GLCapabilitiesChooser chooser,
+ final AbstractGraphicsScreen absScreen, final boolean usePBuffer) {
+ if (absScreen == null) {
+ throw new IllegalArgumentException("AbstractGraphicsScreen is null");
+ }
+ final AbstractGraphicsDevice device = absScreen.getDevice();
+ capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, GLDrawableFactory.getDesktopFactory(), device);
+
+ return new IOSEAGLGraphicsConfiguration(absScreen, capsChosen, capsRequested);
+ }
+}
diff --git a/src/jogl/classes/jogamp/opengl/ios/eagl/IOSOnscreenEAGLDrawable.java b/src/jogl/classes/jogamp/opengl/ios/eagl/IOSOnscreenEAGLDrawable.java
new file mode 100644
index 000000000..04b80a858
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/ios/eagl/IOSOnscreenEAGLDrawable.java
@@ -0,0 +1,45 @@
+/**
+ * Copyright 2019 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.ios.eagl;
+
+import com.jogamp.nativewindow.NativeSurface;
+import com.jogamp.opengl.GLContext;
+import com.jogamp.opengl.GLDrawableFactory;
+
+public class IOSOnscreenEAGLDrawable extends IOSEAGLDrawable {
+
+ protected IOSOnscreenEAGLDrawable(final GLDrawableFactory factory, final NativeSurface component) {
+ super(factory, component, false);
+ }
+
+ @Override
+ public GLContext createContext(final GLContext shareWith) {
+ return new IOSEAGLContext(this, shareWith);
+ }
+
+}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDynamicLibraryBundleInfo.java
index 5cf4f36a1..c5fc4e74a 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDynamicLibraryBundleInfo.java
@@ -42,6 +42,7 @@ public final class MacOSXCGLDynamicLibraryBundleInfo extends DesktopGLDynamicLib
public final List<List<String>> getToolLibNames() {
final List<List<String>> libsList = new ArrayList<List<String>>();
final List<String> libsGL = new ArrayList<String>();
+ // libsGL.add("OpenGL"); // Actual canonical lib. TODO re-validate?
libsGL.add("/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib");
libsGL.add("GL");
libsList.add(libsGL);