aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/jogamp/opengl
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2019-06-23 08:03:04 +0200
committerSven Gothel <[email protected]>2019-06-23 08:03:04 +0200
commitbba73bc096250a3c7fc036d84b1ea054d1b70b06 (patch)
treeed02575eac2a46bd49627444dcce972946ae8d2e /src/jogl/classes/jogamp/opengl
parent154e91978498d8b6db9ce34a1f06b298bcf4c361 (diff)
iOS: Initial working commit supporting iOS (ipad pro 11)
using our OpenJFK 9 x86_64 and arm64 build. Test demo class is 'com.jogamp.opengl.demos.ios.Hello', residing in the new demo folder 'src/demos/com/jogamp/opengl/demos/ios/Hello.java'. This commit does not yet include a working NEWT specialization for iOS, but it shall followup soon. Instead this commit demonstrates JOGL operating on native UIWindow, UIView and CAEAGLLayer as provided by Nativewindow's IOSUtil. Test Video https://www.youtube.com/watch?v=Z4lUQNFTGMI +++ Notable bug: The FBO used and sharing the COLORBUFFER RENDERBUFFER memory resources with CAEAGLLayer to be displayed in the UIView seemingly cannot handle GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24 or GL_DEPTH_COMPONENT32 depth buffer - none at all (Device + Simulation). Therefor the default demo GLEventListener chosen here don't require a depth buffer ;-) This issue can hopefully be mitigated with other means than using a flat FBO sink similar to FBO multisampling.
Diffstat (limited to 'src/jogl/classes/jogamp/opengl')
-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
13 files changed, 1444 insertions, 11 deletions
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);