diff options
Diffstat (limited to 'src/jogl/classes/jogamp/opengl/macosx/cgl')
4 files changed, 357 insertions, 152 deletions
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java index 45c8b9304..1fe47f60b 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java @@ -41,9 +41,7 @@ package jogamp.opengl.macosx.cgl; import java.nio.ByteBuffer; -import java.security.AccessController; import java.util.Map; -import java.util.StringTokenizer; import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.AbstractGraphicsDevice; @@ -53,7 +51,6 @@ import javax.media.opengl.GLContext; import javax.media.opengl.GLException; import javax.media.opengl.GLProfile; -import jogamp.opengl.Debug; import jogamp.opengl.GLContextImpl; import jogamp.opengl.GLContextShareSet; import jogamp.opengl.GLDrawableImpl; @@ -61,6 +58,8 @@ import jogamp.opengl.GLGraphicsConfigurationUtil; import jogamp.opengl.macosx.cgl.MacOSXCGLDrawable.GLBackendType; import com.jogamp.common.nio.PointerBuffer; +import com.jogamp.common.os.Platform; +import com.jogamp.common.util.VersionNumber; import com.jogamp.gluegen.runtime.ProcAddressTable; import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver; @@ -71,25 +70,53 @@ public abstract class MacOSXCGLContext extends GLContextImpl // NSOpenGL-based or CGL-based) protected interface GLBackendImpl { boolean isNSContext(); - boolean create(long share); - boolean destroy(); + long create(long share, int ctp, int major, int minor); + boolean destroy(long ctx); boolean copyImpl(long src, int mask); - boolean makeCurrent(); - boolean release(); + boolean makeCurrent(long ctx); + boolean release(long ctx); boolean setSwapInterval(int interval); boolean swapBuffers(boolean isOnscreen); } - private static boolean isTigerOrLater; + /* package */ static final boolean isTigerOrLater; + /* package */ static final boolean isLionOrLater; static { - String osVersion = Debug.getProperty("os.version", false, AccessController.getContext()); - StringTokenizer tok = new StringTokenizer(osVersion, ". "); - int major = Integer.parseInt(tok.nextToken()); - int minor = Integer.parseInt(tok.nextToken()); - isTigerOrLater = ((major > 10) || (minor > 3)); + final VersionNumber osvn = Platform.getOSVersionNumber(); + isTigerOrLater = osvn.getMajor() > 10 || ( osvn.getMajor() == 10 && osvn.getMinor() >= 4 ); + isLionOrLater = osvn.getMajor() > 10 || ( osvn.getMajor() == 10 && osvn.getMinor() >= 7 ); } + static boolean isGLProfileSupported(int ctp, int major, int minor) { + boolean ctBwdCompat = 0 != ( CTX_PROFILE_COMPAT & ctp ) ; + boolean ctCore = 0 != ( CTX_PROFILE_CORE & ctp ) ; + + // We exclude 3.0, since we would map it's core to GL2. Hence we force mapping 2.1 to GL2 + if(3==major && 1<=minor && minor<=2) { + // [3.1..3.2] -> GL3* + if(ctBwdCompat) { + return false; + } + return ctCore; + } else if(major<3) { + // < 3.0 -> GL2 + return true; + } + return false; // 3.0 && > 3.2 + } + static int GLProfile2CGLOGLProfileValue(int ctp, int major, int minor) { + if(!MacOSXCGLContext.isGLProfileSupported(ctp, major, minor)) { + throw new GLException("OpenGL profile not supported: "+getGLVersion(major, minor, ctp, "@GLProfile2CGLOGLProfileVersion")); + } + boolean ctCore = 0 != ( CTX_PROFILE_CORE & ctp ) ; + if( major == 3 && minor >= 1 && ctCore ) { + return CGL.kCGLOGLPVersion_3_2_Core; + } else { + return CGL.kCGLOGLPVersion_Legacy; + } + } + private boolean haveSetOpenGLMode = false; private GLBackendType openGLMode = GLBackendType.NSOPENGL; @@ -141,11 +168,35 @@ public abstract class MacOSXCGLContext extends GLContextImpl protected Map<String, String> getExtensionNameMap() { return null; } protected long createContextARBImpl(long share, boolean direct, int ctp, int major, int minor) { - return 0; // FIXME + if(!isGLProfileSupported(ctp, major, minor)) { + if(DEBUG) { + System.err.println(getThreadName() + ": createContextARBImpl: Not supported "+getGLVersion(major, minor, ctp, "@creation on OSX "+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 OSX "+Platform.getOSVersionNumber()); + } + } else if(DEBUG) { + System.err.println(getThreadName() + ": createContextARBImpl: NO "+getGLVersion(major, minor, ctp, "@creation on OSX "+Platform.getOSVersionNumber())); + } + return ctx; } protected void destroyContextARBImpl(long _context) { - // FIXME + impl.release(_context); + impl.destroy(_context); } public final boolean isGLReadDrawableAvailable() { @@ -169,9 +220,9 @@ public abstract class MacOSXCGLContext extends GLContextImpl !isTigerOrLater) { throw new GLException("Floating-point pbuffers supported only on OS X 10.4 or later"); } - GLProfile glProfile = capabilitiesChosen.getGLProfile(); - if(glProfile.isGL3()) { - throw new GLException("GL3 profile currently not supported on MacOSX, due to the lack of a OpenGL 3.1 implementation"); + GLProfile glp = capabilitiesChosen.getGLProfile(); + if(glp.isGLES1() || glp.isGLES2() || glp.isGL4() || glp.isGL3() && !isLionOrLater) { + throw new GLException("OpenGL profile not supported on MacOSX "+Platform.getOSVersionNumber()+": "+glp); } if (DEBUG) { System.err.println("!!! Share context is " + toHexString(share) + " for " + this); @@ -181,19 +232,8 @@ public abstract class MacOSXCGLContext extends GLContextImpl protected boolean createImpl() throws GLException { long share = createImplPreset(); - - // Will throw exception upon error - if(!impl.create(share)) { - return false; - } - if (!impl.makeCurrent()) { - throw new GLException("Error making Context (NS:"+isNSContext()+") current"); - } - setGLFunctionAvailability(true, true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); - if (DEBUG) { - System.err.println("!!! Created " + this); - } - return true; + contextHandle = createContextARB(share, true); + return 0 != contextHandle; } protected void makeCurrentImpl(boolean newCreated) throws GLException { @@ -201,19 +241,19 @@ public abstract class MacOSXCGLContext extends GLContextImpl setOpenGLMode(((MacOSXCGLDrawable)drawable).getOpenGLMode()); } - if (!impl.makeCurrent()) { + if (!impl.makeCurrent(contextHandle)) { throw new GLException("Error making Context current: "+this); } } protected void releaseImpl() throws GLException { - if (!impl.release()) { + if (!impl.release(contextHandle)) { throw new GLException("Error releasing OpenGL Context: "+this); } } protected void destroyImpl() throws GLException { - if(!impl.destroy()) { + if(!impl.destroy(contextHandle)) { throw new GLException("Error destroying OpenGL Context: "+this); } } @@ -365,10 +405,11 @@ public abstract class MacOSXCGLContext extends GLContextImpl class NSOpenGLImpl implements GLBackendImpl { public boolean isNSContext() { return true; } - public boolean create(long share) { + public long create(long share, int ctp, int major, int minor) { + long ctx = 0; MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities(); - long pixelFormat = MacOSXCGLGraphicsConfiguration.GLCapabilities2NSPixelFormat(chosenCaps); + long pixelFormat = MacOSXCGLGraphicsConfiguration.GLCapabilities2NSPixelFormat(chosenCaps, ctp, major, minor); if (pixelFormat == 0) { throw new GLException("Unable to allocate pixel format with requested GLCapabilities"); } @@ -376,47 +417,45 @@ public abstract class MacOSXCGLContext extends GLContextImpl try { int[] viewNotReady = new int[1]; // Try to allocate a context with this - contextHandle = CGL.createContext(share, + ctx = CGL.createContext(share, drawable.getHandle(), pixelFormat, chosenCaps.isBackgroundOpaque(), viewNotReady, 0); - if (0 == contextHandle) { + if (0 == ctx) { if (viewNotReady[0] == 1) { if (DEBUG) { System.err.println("!!! View not ready for " + getClass().getName()); } - // View not ready at the window system level -- this is OK - return false; + // View not ready at the window system level } - throw new GLException("Error creating NSOpenGLContext with requested pixel format"); + return 0; } if (!chosenCaps.isPBuffer() && !chosenCaps.isBackgroundOpaque()) { // Set the context opacity - CGL.setContextOpacity(contextHandle, 0); + CGL.setContextOpacity(ctx, 0); + } + + if(DEBUG) { + GLCapabilitiesImmutable caps0 = MacOSXCGLGraphicsConfiguration.NSPixelFormat2GLCapabilities(null, pixelFormat); + System.err.println("NS created(>=lion "+isLionOrLater+"): "+caps0); } - GLCapabilitiesImmutable caps = MacOSXCGLGraphicsConfiguration.NSPixelFormat2GLCapabilities(chosenCaps.getGLProfile(), pixelFormat); caps = GLGraphicsConfigurationUtil.fixOpaqueGLCapabilities(caps, chosenCaps.isBackgroundOpaque()); config.setChosenCapabilities(caps); if(caps.isPBuffer()) { // Must now associate the pbuffer with our newly-created context - CGL.setContextPBuffer(contextHandle, drawable.getHandle()); + CGL.setContextPBuffer(ctx, drawable.getHandle()); } } finally { CGL.deletePixelFormat(pixelFormat); } - if (!CGL.makeCurrentContext(contextHandle)) { - throw new GLException("Error making Context (NS) current"); - } - setGLFunctionAvailability(true, true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); - GLContextShareSet.contextCreated(MacOSXCGLContext.this); - return true; + return ctx; } - public boolean destroy() { - return CGL.deleteContext(contextHandle, true); + public boolean destroy(long ctx) { + return CGL.deleteContext(ctx, true); } public boolean copyImpl(long src, int mask) { @@ -424,12 +463,12 @@ public abstract class MacOSXCGLContext extends GLContextImpl return true; } - public boolean makeCurrent() { - return CGL.makeCurrentContext(contextHandle); + public boolean makeCurrent(long ctx) { + return CGL.makeCurrentContext(ctx); } - public boolean release() { - return CGL.clearCurrentContext(contextHandle); + public boolean release(long ctx) { + return CGL.clearCurrentContext(ctx); } public boolean setSwapInterval(int interval) { @@ -447,81 +486,47 @@ public abstract class MacOSXCGLContext extends GLContextImpl class CGLImpl implements GLBackendImpl { public boolean isNSContext() { return false; } - public boolean create(long share) { - DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + public long create(long share, int ctp, int major, int minor) { + long ctx = 0; + MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable)config.getChosenCapabilities(); - - // Set up pixel format attributes - int[] attrs = new int[256]; - int i = 0; - if(chosenCaps.isPBuffer()) { - attrs[i++] = CGL.kCGLPFAPBuffer; - } - if (chosenCaps.getPbufferFloatingPointBuffers()) { - attrs[i++] = CGL.kCGLPFAColorFloat; - } - if (chosenCaps.getDoubleBuffered()) { - attrs[i++] = CGL.kCGLPFADoubleBuffer; - } - if (chosenCaps.getStereo()) { - attrs[i++] = CGL.kCGLPFAStereo; - } - attrs[i++] = CGL.kCGLPFAColorSize; - attrs[i++] = (chosenCaps.getRedBits() + - chosenCaps.getGreenBits() + - chosenCaps.getBlueBits()); - attrs[i++] = CGL.kCGLPFAAlphaSize; - attrs[i++] = chosenCaps.getAlphaBits(); - attrs[i++] = CGL.kCGLPFADepthSize; - attrs[i++] = chosenCaps.getDepthBits(); - // FIXME: should validate stencil size as is done in MacOSXWindowSystemInterface.m - attrs[i++] = CGL.kCGLPFAStencilSize; - attrs[i++] = chosenCaps.getStencilBits(); - attrs[i++] = CGL.kCGLPFAAccumSize; - attrs[i++] = (chosenCaps.getAccumRedBits() + - chosenCaps.getAccumGreenBits() + - chosenCaps.getAccumBlueBits() + - chosenCaps.getAccumAlphaBits()); - if (chosenCaps.getSampleBuffers()) { - attrs[i++] = CGL.kCGLPFASampleBuffers; - attrs[i++] = 1; - attrs[i++] = CGL.kCGLPFASamples; - attrs[i++] = chosenCaps.getNumSamples(); - } - - // Use attribute array to select pixel format - PointerBuffer fmt = PointerBuffer.allocateDirect(1); - long[] numScreens = new long[1]; - int res = CGL.CGLChoosePixelFormat(attrs, 0, fmt, numScreens, 0); - if (res != CGL.kCGLNoError) { - throw new GLException("Error code " + res + " while choosing pixel format"); + long pixelFormat = MacOSXCGLGraphicsConfiguration.GLCapabilities2CGLPixelFormat(chosenCaps, ctp, major, minor); + if (pixelFormat == 0) { + throw new GLException("Unable to allocate pixel format with requested GLCapabilities"); } + config.setChosenPixelFormat(pixelFormat); try { // Create new context - PointerBuffer ctx = PointerBuffer.allocateDirect(1); + PointerBuffer ctxPB = PointerBuffer.allocateDirect(1); if (DEBUG) { System.err.println("Share context for CGL-based pbuffer context is " + toHexString(share)); } - res = CGL.CGLCreateContext(fmt.get(0), share, ctx); + int res = CGL.CGLCreateContext(pixelFormat, share, ctxPB); if (res != CGL.kCGLNoError) { throw new GLException("Error code " + res + " while creating context"); } if(chosenCaps.isPBuffer()) { // Attach newly-created context to the pbuffer - res = CGL.CGLSetPBuffer(ctx.get(0), drawable.getHandle(), 0, 0, 0); + res = CGL.CGLSetPBuffer(ctxPB.get(0), drawable.getHandle(), 0, 0, 0); if (res != CGL.kCGLNoError) { throw new GLException("Error code " + res + " while attaching context to pbuffer"); } } - contextHandle = ctx.get(0); + ctx = ctxPB.get(0); + if(0!=ctx) { + if(DEBUG) { + GLCapabilitiesImmutable caps0 = MacOSXCGLGraphicsConfiguration.CGLPixelFormat2GLCapabilities(pixelFormat); + System.err.println("NS created: "+caps0); + } + } } finally { - CGL.CGLDestroyPixelFormat(fmt.get(0)); + CGL.CGLDestroyPixelFormat(pixelFormat); } - return true; + return ctx; } - public boolean destroy() { - return CGL.CGLDestroyContext(contextHandle) == CGL.kCGLNoError; + public boolean destroy(long ctx) { + return CGL.CGLDestroyContext(ctx) == CGL.kCGLNoError; } public boolean copyImpl(long src, int mask) { @@ -529,11 +534,11 @@ public abstract class MacOSXCGLContext extends GLContextImpl return true; } - public boolean makeCurrent() { - return CGL.CGLSetCurrentContext(contextHandle) == CGL.kCGLNoError; + public boolean makeCurrent(long ctx) { + return CGL.CGLSetCurrentContext(ctx) == CGL.kCGLNoError; } - public boolean release() { + public boolean release(long ctx) { return (CGL.CGLSetCurrentContext(0) == CGL.kCGLNoError); } diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java index 90232457c..5c726bc54 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java @@ -40,19 +40,34 @@ package jogamp.opengl.macosx.cgl; -import java.nio.*; +import java.nio.Buffer; import java.util.HashMap; import java.util.List; -import javax.media.nativewindow.*; +import javax.media.nativewindow.AbstractGraphicsConfiguration; +import javax.media.nativewindow.AbstractGraphicsDevice; +import javax.media.nativewindow.AbstractGraphicsScreen; +import javax.media.nativewindow.DefaultGraphicsScreen; +import javax.media.nativewindow.NativeSurface; +import javax.media.nativewindow.NativeWindowFactory; +import javax.media.nativewindow.ProxySurface; import javax.media.nativewindow.macosx.MacOSXGraphicsDevice; -import javax.media.opengl.*; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLCapabilitiesChooser; +import javax.media.opengl.GLCapabilitiesImmutable; +import javax.media.opengl.GLContext; +import javax.media.opengl.GLDrawable; +import javax.media.opengl.GLException; +import javax.media.opengl.GLProfile; -import com.jogamp.common.JogampRuntimeException; -import com.jogamp.common.util.*; -import java.util.ArrayList; -import jogamp.opengl.*; import jogamp.nativewindow.WrappedSurface; +import jogamp.opengl.DesktopGLDynamicLookupHelper; +import jogamp.opengl.GLDrawableFactoryImpl; +import jogamp.opengl.GLDrawableImpl; +import jogamp.opengl.GLDynamicLookupHelper; + +import com.jogamp.common.JogampRuntimeException; +import com.jogamp.common.util.ReflectionUtil; public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { private static final DesktopGLDynamicLookupHelper macOSXCGLDynamicLookupHelper; @@ -94,13 +109,20 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { } static class SharedResource { - private MacOSXCGLDrawable drawable; - private MacOSXCGLContext context; - - SharedResource(MacOSXCGLDrawable draw, MacOSXCGLContext ctx) { - drawable = draw; - context = ctx; + // private MacOSXCGLDrawable drawable; + // private MacOSXCGLContext context; + MacOSXGraphicsDevice device; + boolean wasContextCreated; + + SharedResource(MacOSXGraphicsDevice device, boolean wasContextCreated + /* MacOSXCGLDrawable draw, MacOSXCGLContext ctx */) { + // drawable = draw; + // context = ctx; + this.device = device; + this.wasContextCreated = wasContextCreated; } + final MacOSXGraphicsDevice getDevice() { return device; } + final boolean wasContextAvailable() { return wasContextCreated; } } HashMap/*<connection, SharedResource>*/ sharedMap = new HashMap(); MacOSXGraphicsDevice defaultDevice; @@ -116,9 +138,66 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { return false; } + private boolean isOSXContextAvailable(AbstractGraphicsDevice sharedDevice) { + boolean madeCurrent = false; + GLProfile glp = GLProfile.get(sharedDevice, GLProfile.GL_PROFILE_LIST_MIN_DESKTOP); + if (null == glp) { + throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice); + } + final GLCapabilities caps = new GLCapabilities(glp); + caps.setRedBits(5); caps.setGreenBits(5); caps.setBlueBits(5); caps.setAlphaBits(0); + caps.setDoubleBuffered(false); + caps.setOnscreen(false); + caps.setPBuffer(true); + final MacOSXCGLDrawable drawable = (MacOSXCGLDrawable) createGLDrawable( createOffscreenSurfaceImpl(sharedDevice, caps, caps, null, 64, 64) ); + if(null!=drawable) { + final GLContext context = drawable.createContext(null); + if (null != context) { + context.setSynchronized(true); + try { + context.makeCurrent(); // could cause exception + madeCurrent = context.isCurrent(); + } catch (GLException gle) { + if (DEBUG) { + System.err.println("MacOSXCGLDrawableFactory.createShared: INFO: makeCurrent failed"); + gle.printStackTrace(); + } + } finally { + context.destroy(); + } + } + drawable.destroy(); + } + return madeCurrent; + } + + /* package */ SharedResource getOrCreateOSXSharedResource(AbstractGraphicsDevice adevice) { + String connection = adevice.getConnection(); + SharedResource sr; + synchronized(sharedMap) { + sr = (SharedResource) sharedMap.get(connection); + } + if(null==sr) { + final MacOSXGraphicsDevice sharedDevice = new MacOSXGraphicsDevice(adevice.getUnitID()); + final boolean madeCurrent = isOSXContextAvailable(sharedDevice); + sr = new SharedResource(sharedDevice, madeCurrent); + synchronized(sharedMap) { + sharedMap.put(connection, sr); + } + if (DEBUG) { + System.err.println("MacOSXCGLDrawableFactory.createShared: device: " + sharedDevice); + System.err.println("MacOSXCGLDrawableFactory.createShared: context: " + madeCurrent); + } + } + return sr; + } + public final boolean getWasSharedContextCreated(AbstractGraphicsDevice device) { - // FIXME: not implemented .. needs a dummy OSX surface - return false; + SharedResource sr = getOrCreateOSXSharedResource(device); + if(null!=sr) { + return sr.wasContextAvailable(); + } + return false; } protected final GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device) { @@ -127,13 +206,17 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { } protected AbstractGraphicsDevice getOrCreateSharedDeviceImpl(AbstractGraphicsDevice device) { - return device; // nothing to do, no native open device + SharedResource sr = getOrCreateOSXSharedResource(device); + if(null!=sr) { + return sr.getDevice(); + } + return null; } protected final void shutdownInstance() {} protected List<GLCapabilitiesImmutable> getAvailableCapabilitiesImpl(AbstractGraphicsDevice device) { - return new ArrayList<GLCapabilitiesImmutable>(0); + return MacOSXCGLGraphicsConfiguration.getAvailableCapabilities(this, device); } protected GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) { @@ -185,7 +268,7 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { } protected GLContext createExternalGLContextImpl() { - return MacOSXExternalCGLContext.create(this, null); + return MacOSXExternalCGLContext.create(this); } public boolean canCreateExternalGLDrawable(AbstractGraphicsDevice device) { diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java index 0d73b6b9c..a429720db 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java @@ -36,8 +36,18 @@ package jogamp.opengl.macosx.cgl; -import javax.media.nativewindow.*; -import javax.media.opengl.*; +import java.util.ArrayList; +import java.util.List; + +import javax.media.nativewindow.AbstractGraphicsDevice; +import javax.media.nativewindow.AbstractGraphicsScreen; +import javax.media.nativewindow.DefaultGraphicsConfiguration; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLCapabilitiesImmutable; +import javax.media.opengl.GLException; +import javax.media.opengl.GLProfile; + +import com.jogamp.common.nio.PointerBuffer; public class MacOSXCGLGraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable { long pixelformat; @@ -61,7 +71,17 @@ public class MacOSXCGLGraphicsConfiguration extends DefaultGraphicsConfiguration super.setChosenCapabilities(caps); } + protected static List<GLCapabilitiesImmutable> getAvailableCapabilities(MacOSXCGLDrawableFactory factory, AbstractGraphicsDevice device) { + MacOSXCGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateOSXSharedResource(device); + if(null == sharedResource) { + throw new GLException("Shared resource for device n/a: "+device); + } + // MacOSXGraphicsDevice osxDevice = sharedResource.getDevice(); + return new ArrayList<GLCapabilitiesImmutable>(0); + } + static final int[] cglInternalAttributeToken = new int[] { + CGL.kCGLPFAOpenGLProfile, CGL.kCGLPFAColorFloat, CGL.NSOpenGLPFAPixelBuffer, CGL.NSOpenGLPFADoubleBuffer, @@ -74,12 +94,22 @@ public class MacOSXCGLGraphicsConfiguration extends DefaultGraphicsConfiguration CGL.NSOpenGLPFASampleBuffers, CGL.NSOpenGLPFASamples }; - static int[] GLCapabilities2AttribList(GLCapabilitiesImmutable caps) { - int[] ivalues = new int[cglInternalAttributeToken.length]; - - for (int idx = 0; idx < cglInternalAttributeToken.length; idx++) { - int attr = cglInternalAttributeToken[idx]; + static int[] GLCapabilities2NSAttribList(GLCapabilitiesImmutable caps, int ctp, int major, int minor) { + int len = cglInternalAttributeToken.length; + int off = 0; + if ( !MacOSXCGLContext.isLionOrLater ) { + // no OpenGLProfile + off++; + len--; + } + int[] ivalues = new int[len]; + + for (int idx = 0; idx < len; idx++) { + final int attr = cglInternalAttributeToken[idx+off]; switch (attr) { + case CGL.kCGLPFAOpenGLProfile: + ivalues[idx] = MacOSXCGLContext.GLProfile2CGLOGLProfileValue(ctp, major, minor); + break; case CGL.kCGLPFAColorFloat: ivalues[idx] = caps.getPbufferFloatingPointBuffers() ? 1 : 0; break; @@ -131,21 +161,88 @@ public class MacOSXCGLGraphicsConfiguration extends DefaultGraphicsConfiguration return ivalues; } - static long GLCapabilities2NSPixelFormat(GLCapabilitiesImmutable caps) { - int[] ivalues = GLCapabilities2AttribList(caps); - return CGL.createPixelFormat(cglInternalAttributeToken, 0, cglInternalAttributeToken.length, ivalues, 0); + static long GLCapabilities2NSPixelFormat(GLCapabilitiesImmutable caps, int ctp, int major, int minor) { + int len = cglInternalAttributeToken.length; + int off = 0; + if ( !MacOSXCGLContext.isLionOrLater ) { + // no OpenGLProfile + off++; + len--; + } + int[] ivalues = GLCapabilities2NSAttribList(caps, ctp, major, minor); + return CGL.createPixelFormat(cglInternalAttributeToken, off, len, ivalues, 0); } static GLCapabilitiesImmutable NSPixelFormat2GLCapabilities(GLProfile glp, long pixelFormat) { return PixelFormat2GLCapabilities(glp, pixelFormat, true); } - static GLCapabilitiesImmutable CGLPixelFormat2GLCapabilities(GLProfile glp, long pixelFormat) { - return PixelFormat2GLCapabilities(glp, pixelFormat, false); + static long GLCapabilities2CGLPixelFormat(GLCapabilitiesImmutable caps, int ctp, int major, int minor) { + // Set up pixel format attributes + int[] attrs = new int[256]; + int i = 0; + if(MacOSXCGLContext.isLionOrLater) { + attrs[i++] = CGL.kCGLPFAOpenGLProfile; + attrs[i++] = MacOSXCGLContext.GLProfile2CGLOGLProfileValue(ctp, major, minor); + } + if(caps.isPBuffer()) { + attrs[i++] = CGL.kCGLPFAPBuffer; + } + if (caps.getPbufferFloatingPointBuffers()) { + attrs[i++] = CGL.kCGLPFAColorFloat; + } + if (caps.getDoubleBuffered()) { + attrs[i++] = CGL.kCGLPFADoubleBuffer; + } + if (caps.getStereo()) { + attrs[i++] = CGL.kCGLPFAStereo; + } + attrs[i++] = CGL.kCGLPFAColorSize; + attrs[i++] = (caps.getRedBits() + + caps.getGreenBits() + + caps.getBlueBits()); + attrs[i++] = CGL.kCGLPFAAlphaSize; + attrs[i++] = caps.getAlphaBits(); + attrs[i++] = CGL.kCGLPFADepthSize; + attrs[i++] = caps.getDepthBits(); + // FIXME: should validate stencil size as is done in MacOSXWindowSystemInterface.m + attrs[i++] = CGL.kCGLPFAStencilSize; + attrs[i++] = caps.getStencilBits(); + attrs[i++] = CGL.kCGLPFAAccumSize; + attrs[i++] = (caps.getAccumRedBits() + + caps.getAccumGreenBits() + + caps.getAccumBlueBits() + + caps.getAccumAlphaBits()); + if (caps.getSampleBuffers()) { + attrs[i++] = CGL.kCGLPFASampleBuffers; + attrs[i++] = 1; + attrs[i++] = CGL.kCGLPFASamples; + attrs[i++] = caps.getNumSamples(); + } + + // Use attribute array to select pixel format + PointerBuffer fmt = PointerBuffer.allocateDirect(1); + long[] numScreens = new long[1]; + int res = CGL.CGLChoosePixelFormat(attrs, 0, fmt, numScreens, 0); + if (res != CGL.kCGLNoError) { + throw new GLException("Error code " + res + " while choosing pixel format"); + } + return fmt.get(0); + } + + static GLCapabilitiesImmutable CGLPixelFormat2GLCapabilities(long pixelFormat) { + return PixelFormat2GLCapabilities(null, pixelFormat, false); } private static GLCapabilitiesImmutable PixelFormat2GLCapabilities(GLProfile glp, long pixelFormat, boolean nsUsage) { - int[] ivalues = new int[cglInternalAttributeToken.length]; + int len = cglInternalAttributeToken.length; + int off = 0; + if ( !MacOSXCGLContext.isLionOrLater ) { + // no OpenGLProfile + off++; + len--; + } + int[] ivalues = new int[len]; // On this platform the pixel format is associated with the // context and not the drawable. However it's a reasonable @@ -155,14 +252,34 @@ public class MacOSXCGLGraphicsConfiguration extends DefaultGraphicsConfiguration // Note: These restrictions of the platform's API might be considered as a bug anyways. // Figure out what attributes we really got - GLCapabilities caps = new GLCapabilities(glp); if(nsUsage) { - CGL.queryPixelFormat(pixelFormat, cglInternalAttributeToken, 0, cglInternalAttributeToken.length, ivalues, 0); + CGL.queryPixelFormat(pixelFormat, cglInternalAttributeToken, off, len, ivalues, 0); } else { - CGL.CGLQueryPixelFormat(pixelFormat, cglInternalAttributeToken, 0, cglInternalAttributeToken.length, ivalues, 0); + CGL.CGLQueryPixelFormat(pixelFormat, cglInternalAttributeToken, off, len, ivalues, 0); + } + if(null == glp && MacOSXCGLContext.isLionOrLater) { + // pre-scan for OpenGL Profile + for (int i = 0; i < len; i++) { + if(CGL.kCGLPFAOpenGLProfile == cglInternalAttributeToken[i+off]) { + switch(ivalues[i]) { + case CGL.kCGLOGLPVersion_3_2_Core: + glp = GLProfile.get(GLProfile.GL3); + break; + case CGL.kCGLOGLPVersion_Legacy: + glp = GLProfile.get(GLProfile.GL2); + break; + default: + throw new RuntimeException("Unhandled OSX OpenGL Profile: 0x"+Integer.toHexString(ivalues[i])); + } + } + } } - for (int i = 0; i < cglInternalAttributeToken.length; i++) { - int attr = cglInternalAttributeToken[i]; + if(null == glp) { + glp = GLProfile.get(GLProfile.GL2); + } + GLCapabilities caps = new GLCapabilities(glp); + for (int i = 0; i < len; i++) { + int attr = cglInternalAttributeToken[i+off]; switch (attr) { case CGL.kCGLPFAColorFloat: caps.setPbufferFloatingPointBuffers(ivalues[i] != 0); diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java index 0d5f5ce8e..08a531200 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java @@ -68,7 +68,7 @@ public class MacOSXExternalCGLContext extends MacOSXCGLContext { getGLStateTracker().setEnabled(false); // external context usage can't track state in Java } - protected static MacOSXExternalCGLContext create(GLDrawableFactory factory, GLProfile glp) { + protected static MacOSXExternalCGLContext create(GLDrawableFactory factory) { long pixelFormat = 0; long currentDrawable = 0; long contextHandle = CGL.getCurrentContext(); // Check: MacOSX 10.3 .. @@ -101,7 +101,7 @@ public class MacOSXExternalCGLContext extends MacOSXCGLContext { if (0 == pixelFormat) { throw new GLException("Error: current pixelformat of current Context 0x"+Long.toHexString(contextHandle)+" is null"); } - GLCapabilitiesImmutable caps = MacOSXCGLGraphicsConfiguration.CGLPixelFormat2GLCapabilities(glp, pixelFormat); + GLCapabilitiesImmutable caps = MacOSXCGLGraphicsConfiguration.CGLPixelFormat2GLCapabilities(pixelFormat); if(DEBUG) { System.err.println("MacOSXExternalCGLContext Create "+caps); } |