diff options
author | Sven Gothel <[email protected]> | 2011-10-25 06:11:14 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2011-10-25 06:11:14 +0200 |
commit | 4433f2a68fa3ca500e258a6862b0e95461fc5083 (patch) | |
tree | 9d0b33c44218834d403272a0a241f2e55c95a5ed | |
parent | 3b6ef84e25a3fcaa2de381be3758c144ae239b6a (diff) |
MacOSX: Pull down (and fix releaseContext) NSOPENGL/CGL mode/impl, fixes SWT usage and FBOMRT
13 files changed, 515 insertions, 608 deletions
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh index 22cd516ba..492437f38 100755 --- a/make/scripts/tests.sh +++ b/make/scripts/tests.sh @@ -45,6 +45,8 @@ echo MacOsX $MOSX function jrun() { awton=$1 shift + swton=$1 + shift #D_ARGS="-Djogl.debug.ExtensionAvailabilityCache -Djogl.debug=all -Dnativewindow.debug=all -Djogamp.debug.ProcAddressHelper=true -Djogamp.debug.NativeLibrary=true -Djogamp.debug.NativeLibrary.Lookup=true" #D_ARGS="-Djogl.debug=all -Dnativewindow.debug=all" @@ -113,7 +115,9 @@ function jrun() { fi if [ $MOSX_MT -eq 1 ] ; then X_ARGS="-XstartOnFirstThread $X_ARGS" - C_ARG="com.jogamp.newt.util.MainThread" + if [ $swton -eq 0 ] ; then + C_ARG="com.jogamp.newt.util.MainThread" + fi fi echo echo "Test Start: $*" @@ -133,16 +137,16 @@ function jrun() { } function testnoawt() { - jrun 0 $* 2>&1 | tee -a java-run.log + jrun 0 0 $* 2>&1 | tee -a java-run.log } function testawt() { MOSX_MT=0 - jrun 1 $* 2>&1 | tee -a java-run.log + jrun 1 0 $* 2>&1 | tee -a java-run.log } -function testawtmt() { - jrun 1 $* 2>&1 | tee -a java-run.log +function testswt() { + jrun 0 1 $* 2>&1 | tee -a java-run.log } # @@ -185,9 +189,6 @@ function testawtmt() { #testnoawt com.jogamp.opengl.test.junit.newt.ManualScreenMode03NEWT #testnoawt com.jogamp.opengl.test.junit.newt.TestWindowClosingProtocol02NEWT $* #testnoawt -Djava.awt.headless=true com.jogamp.opengl.test.junit.newt.TestGLWindows01NEWT -#testnoawt com.jogamp.opengl.test.junit.jogl.swt.TestSWT01GLn $* -#testnoawt com.jogamp.opengl.test.junit.jogl.swt.TestSWT02GLn $* - # # awt (testawt) @@ -208,6 +209,11 @@ function testawtmt() { #testawt com.jogamp.opengl.test.junit.jogl.swt.TestSWTAWT01GLn $* #testawt com.jogamp.opengl.test.junit.jogl.glu.TestBug463ScaleImageMemoryAWT $* +# +# swt (testswt) +# +#testswt com.jogamp.opengl.test.junit.jogl.swt.TestSWT01GLn $* +#testswt com.jogamp.opengl.test.junit.jogl.swt.TestSWT02GLn $* # # newt.awt (testawt) @@ -242,7 +248,7 @@ function testawtmt() { #testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLShaderState01NEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLShaderState02NEWT $* #testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestRulerNEWT01 $* -#testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestFBOMRTNEWT01 $* +testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestFBOMRTNEWT01 $* #testnoawt com.jogamp.opengl.test.junit.graph.TestRegionRendererNEWT01 $* #testnoawt com.jogamp.opengl.test.junit.graph.TestTextRendererNEWT01 $* @@ -261,11 +267,7 @@ function testawtmt() { # # regressions # -#testnoawt com.jogamp.opengl.test.junit.jogl.swt.TestSWT01GLn $* -#testnoawt com.jogamp.opengl.test.junit.jogl.swt.TestSWT02GLn $* -#testawt com.jogamp.opengl.test.junit.jogl.swt.TestSWTAWT01GLn $* -#testawt com.jogamp.opengl.test.junit.newt.TestFocus01SwingAWTRobot $* -testawt com.jogamp.opengl.test.junit.newt.TestFocus02SwingAWTRobot $* +#testawt com.jogamp.opengl.test.junit.newt.TestFocus02SwingAWTRobot $* $spath/count-edt-start.sh java-run.log diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java index a3aa369dd..60ca7a7f4 100644 --- a/src/jogl/classes/javax/media/opengl/GLContext.java +++ b/src/jogl/classes/javax/media/opengl/GLContext.java @@ -377,7 +377,7 @@ public abstract class GLContext { */ public String toString() { StringBuffer sb = new StringBuffer(); - sb.append(getClass().getName()); + sb.append(getClass().getSimpleName()); sb.append(" ["); this.append(sb); sb.append("] "); diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java index 15db80cc4..58c9aaaa6 100644 --- a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java @@ -195,7 +195,7 @@ public abstract class GLDrawableImpl implements GLDrawable { } public String toString() { - return getClass().getName()+"[Realized "+isRealized()+ + return getClass().getSimpleName()+"[Realized "+isRealized()+ ",\n\tFactory "+getFactory()+ ",\n\thandle "+toHexString(getHandle())+ ",\n\tWindow "+getNativeSurface()+"]"; diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java index 383594d87..45c8b9304 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java @@ -40,19 +40,62 @@ package jogamp.opengl.macosx.cgl; -import java.nio.*; -import java.util.*; +import java.nio.ByteBuffer; +import java.security.AccessController; +import java.util.Map; +import java.util.StringTokenizer; -import javax.media.opengl.*; -import javax.media.nativewindow.*; -import jogamp.opengl.*; +import javax.media.nativewindow.AbstractGraphicsConfiguration; +import javax.media.nativewindow.AbstractGraphicsDevice; +import javax.media.nativewindow.DefaultGraphicsConfiguration; +import javax.media.opengl.GLCapabilitiesImmutable; +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; +import jogamp.opengl.GLGraphicsConfigurationUtil; +import jogamp.opengl.macosx.cgl.MacOSXCGLDrawable.GLBackendType; + +import com.jogamp.common.nio.PointerBuffer; import com.jogamp.gluegen.runtime.ProcAddressTable; import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver; + public abstract class MacOSXCGLContext extends GLContextImpl { - protected boolean isNSContext; + // Abstract interface for implementation of this context (either + // NSOpenGL-based or CGL-based) + protected interface GLBackendImpl { + boolean isNSContext(); + boolean create(long share); + boolean destroy(); + boolean copyImpl(long src, int mask); + boolean makeCurrent(); + boolean release(); + boolean setSwapInterval(int interval); + boolean swapBuffers(boolean isOnscreen); + } + + private static boolean isTigerOrLater; + + 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)); + } + + private boolean haveSetOpenGLMode = false; + private GLBackendType openGLMode = GLBackendType.NSOPENGL; + + // Implementation object (either NSOpenGL-based or CGL-based) + protected GLBackendImpl impl; + private CGLExt _cglExt; // Table that holds the addresses of the native C-language entry points for // CGL extension functions. @@ -61,11 +104,11 @@ public abstract class MacOSXCGLContext extends GLContextImpl protected MacOSXCGLContext(GLDrawableImpl drawable, GLContext shareWith) { super(drawable, shareWith); + initOpenGLImpl(getOpenGLMode()); } @Override protected void resetStates() { - isNSContext = false; // no inner state _cglExt = null; super.resetStates(); } @@ -74,7 +117,9 @@ public abstract class MacOSXCGLContext extends GLContextImpl return getCGLExt(); } - protected boolean isNSContext() { return isNSContext; } + protected boolean isNSContext() { + return (null != impl) ? impl.isNSContext() : this.openGLMode == GLBackendType.NSOPENGL; + } public CGLExt getCGLExt() { if (_cglExt == null) { @@ -107,125 +152,108 @@ public abstract class MacOSXCGLContext extends GLContextImpl return false; } - /** - * Creates and initializes an appropriate OpenGl Context (NS). Should only be - * called by {@link makeCurrentImpl()}. - */ - protected boolean create(boolean pbuffer, boolean floatingPoint) { + protected long createImplPreset() throws GLException { MacOSXCGLContext other = (MacOSXCGLContext) GLContextShareSet.getShareContext(this); long share = 0; if (other != null) { - if (!other.isNSContext()) { - throw new GLException("GLContextShareSet is not a NS Context"); - } + // Change our OpenGL mode to match that of any share context before we create ourselves + setOpenGLMode(other.getOpenGLMode()); share = other.getHandle(); if (share == 0) { throw new GLException("GLContextShareSet returned a NULL OpenGL context"); } } MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); - GLCapabilitiesImmutable capabilitiesRequested = (GLCapabilitiesImmutable) config.getRequestedCapabilities(); - GLProfile glProfile = capabilitiesRequested.getGLProfile(); + GLCapabilitiesImmutable capabilitiesChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities(); + if (capabilitiesChosen.getPbufferFloatingPointBuffers() && + !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"); } - // HACK .. bring in OnScreen/PBuffer selection to the DrawableFactory !! - GLCapabilities capabilities = (GLCapabilities) capabilitiesRequested.cloneMutable(); - capabilities.setPBuffer(pbuffer); - capabilities.setPbufferFloatingPointBuffers(floatingPoint); - - long pixelFormat = MacOSXCGLGraphicsConfiguration.GLCapabilities2NSPixelFormat(capabilities); - if (pixelFormat == 0) { - throw new GLException("Unable to allocate pixel format with requested GLCapabilities"); - } - config.setChosenPixelFormat(pixelFormat); - try { - int[] viewNotReady = new int[1]; - // Try to allocate a context with this - contextHandle = CGL.createContext(share, - drawable.getHandle(), - pixelFormat, - capabilities.isBackgroundOpaque(), - viewNotReady, 0); - if (contextHandle == 0) { - 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; - } - throw new GLException("Error creating NSOpenGLContext with requested pixel format"); - } - - if (!pbuffer && !capabilities.isBackgroundOpaque()) { - // Set the context opacity - CGL.setContextOpacity(contextHandle, 0); - } - - GLCapabilitiesImmutable caps = MacOSXCGLGraphicsConfiguration.NSPixelFormat2GLCapabilities(glProfile, pixelFormat); - caps = GLGraphicsConfigurationUtil.fixOpaqueGLCapabilities(caps, capabilities.isBackgroundOpaque()); - config.setChosenCapabilities(caps); - } finally { - CGL.deletePixelFormat(pixelFormat); + if (DEBUG) { + System.err.println("!!! Share context is " + toHexString(share) + " for " + this); } - if (!CGL.makeCurrentContext(contextHandle)) { - throw new GLException("Error making Context (NS) current"); + return share; + } + + 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"); } - isNSContext = true; setGLFunctionAvailability(true, true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); - GLContextShareSet.contextCreated(this); + if (DEBUG) { + System.err.println("!!! Created " + this); + } return true; } - + protected void makeCurrentImpl(boolean newCreated) throws GLException { - if ( isNSContext ) { - if (!CGL.makeCurrentContext(contextHandle)) { - throw new GLException("Error making Context (NS) current"); - } - } else { - if (CGL.kCGLNoError != CGL.CGLSetCurrentContext(contextHandle)) { - throw new GLException("Error making Context (CGL) current"); - } + if (getOpenGLMode() != ((MacOSXCGLDrawable)drawable).getOpenGLMode()) { + setOpenGLMode(((MacOSXCGLDrawable)drawable).getOpenGLMode()); } + + if (!impl.makeCurrent()) { + throw new GLException("Error making Context current: "+this); + } } protected void releaseImpl() throws GLException { - if ( isNSContext ) { - if (!CGL.clearCurrentContext(contextHandle)) { - throw new GLException("Error freeing OpenGL Context (NS)"); - } - } else { - CGL.CGLReleaseContext(contextHandle); + if (!impl.release()) { + throw new GLException("Error releasing OpenGL Context: "+this); } } - + protected void destroyImpl() throws GLException { - if ( !isNSContext ) { - if (CGL.kCGLNoError != CGL.CGLDestroyContext(contextHandle)) { - throw new GLException("Unable to delete OpenGL Context (CGL)"); - } - } else { - if (!CGL.deleteContext(contextHandle, true)) { - throw new GLException("Unable to delete OpenGL Context (NS) "+toHexString(contextHandle)); - } + if(!impl.destroy()) { + throw new GLException("Error destroying OpenGL Context: "+this); } } protected void copyImpl(GLContext source, int mask) throws GLException { - long dst = getHandle(); - long src = source.getHandle(); - if( !isNSContext() ) { - if ( ((MacOSXCGLContext)source).isNSContext() ) { - throw new GLException("Source OpenGL Context is NS ; Destination Context is CGL."); - } - CGL.CGLCopyContext(src, dst, mask); + if( isNSContext() != ((MacOSXCGLContext)source).isNSContext() ) { + throw new GLException("Source/Destination OpenGL Context tyoe mismatch: source "+source+", dest: "+this); + } + if(!impl.copyImpl(source.getHandle(), mask)) { + throw new GLException("Error copying OpenGL Context: source "+source+", dest: "+this); + } + } + + protected void swapBuffers() { + DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)config.getChosenCapabilities(); + if(!impl.swapBuffers(caps.isOnscreen())) { + throw new GLException("Error swapping buffers: "+this); + } + } + + protected void setSwapIntervalImpl(int interval) { + if( ! isCreated() ) { + throw new GLException("OpenGL context not created"); + } + if(!impl.setSwapInterval(interval)) { + throw new GLException("Error set swap-interval: "+this); + } + if ( isNSContext() ) { + CGL.setSwapInterval(contextHandle, interval); } else { - if ( !((MacOSXCGLContext)source).isNSContext() ) { - throw new GLException("Source OpenGL Context is CGL ; Destination Context is NS."); - } - CGL.copyContext(dst, src, mask); + int[] lval = new int[] { (int) interval } ; + CGL.CGLSetParameter(contextHandle, CGL.kCGLCPSwapInterval, lval, 0); } + currentSwapInterval = interval ; + } + + public ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3) { + // FIXME: apparently the Apple extension doesn't require a custom memory allocator + throw new GLException("Not yet implemented"); } protected final void updateGLXProcAddressTable() { @@ -246,8 +274,6 @@ public abstract class MacOSXCGLContext extends GLContextImpl } } else { if (cglExtProcAddressTable == null) { - // FIXME: cache ProcAddressTables by capability bits so we can - // share them among contexts with the same capabilities cglExtProcAddressTable = new CGLExtProcAddressTable(new GLProcAddressResolver()); } resetProcAddressTable(getCGLExtProcAddressTable()); @@ -264,40 +290,6 @@ public abstract class MacOSXCGLContext extends GLContextImpl return new StringBuffer(); } - protected void swapBuffers() { - DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); - GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)config.getChosenCapabilities(); - if(caps.isOnscreen()) { - if(isNSContext) { - if (!CGL.flushBuffer(contextHandle)) { - throw new GLException("Error swapping buffers (NS)"); - } - } else { - if (CGL.kCGLNoError != CGL.CGLFlushDrawable(contextHandle)) { - throw new GLException("Error swapping buffers (CGL)"); - } - } - } - } - - protected void setSwapIntervalImpl(int interval) { - if( ! isCreated() ) { - throw new GLException("OpenGL context not created"); - } - if ( isNSContext ) { - CGL.setSwapInterval(contextHandle, interval); - } else { - int[] lval = new int[] { (int) interval } ; - CGL.CGLSetParameter(contextHandle, CGL.kCGLCPSwapInterval, lval, 0); - } - currentSwapInterval = interval ; - } - - public ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3) { - // FIXME: apparently the Apple extension doesn't require a custom memory allocator - throw new GLException("Not yet implemented"); - } - public boolean isExtensionAvailable(String glExtensionName) { if (glExtensionName.equals("GL_ARB_pbuffer") || glExtensionName.equals("GL_ARB_pixel_format")) { @@ -327,6 +319,234 @@ public abstract class MacOSXCGLContext extends GLContextImpl } // Support for "mode switching" as described in MacOSXCGLDrawable - public abstract void setOpenGLMode(int mode); - public abstract int getOpenGLMode(); + public void setOpenGLMode(GLBackendType mode) { + if (mode == openGLMode) { + return; + } + if (haveSetOpenGLMode) { + throw new GLException("Can't switch between using NSOpenGLPixelBuffer and CGLPBufferObj more than once"); + } + destroyImpl(); + ((MacOSXCGLDrawable)drawable).setOpenGLMode(mode); + if (DEBUG) { + System.err.println("Switching context mode " + openGLMode + " -> " + mode); + } + initOpenGLImpl(mode); + openGLMode = mode; + haveSetOpenGLMode = true; + } + public final GLBackendType getOpenGLMode() { return openGLMode; } + + protected void initOpenGLImpl(GLBackendType backend) { + switch (backend) { + case NSOPENGL: + impl = new NSOpenGLImpl(); + break; + case CGL: + impl = new CGLImpl(); + break; + default: + throw new InternalError("Illegal implementation mode " + backend); + } + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append(getClass().getSimpleName()); + sb.append(" ["); + super.append(sb); + sb.append(", mode "); + sb.append(openGLMode); + sb.append("] "); + return sb.toString(); + } + + // NSOpenGLContext-based implementation + class NSOpenGLImpl implements GLBackendImpl { + public boolean isNSContext() { return true; } + + public boolean create(long share) { + MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities(); + long pixelFormat = MacOSXCGLGraphicsConfiguration.GLCapabilities2NSPixelFormat(chosenCaps); + if (pixelFormat == 0) { + throw new GLException("Unable to allocate pixel format with requested GLCapabilities"); + } + config.setChosenPixelFormat(pixelFormat); + try { + int[] viewNotReady = new int[1]; + // Try to allocate a context with this + contextHandle = CGL.createContext(share, + drawable.getHandle(), + pixelFormat, + chosenCaps.isBackgroundOpaque(), + viewNotReady, 0); + if (0 == contextHandle) { + 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; + } + throw new GLException("Error creating NSOpenGLContext with requested pixel format"); + } + + if (!chosenCaps.isPBuffer() && !chosenCaps.isBackgroundOpaque()) { + // Set the context opacity + CGL.setContextOpacity(contextHandle, 0); + } + + 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()); + } + } 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; + } + + public boolean destroy() { + return CGL.deleteContext(contextHandle, true); + } + + public boolean copyImpl(long src, int mask) { + CGL.copyContext(contextHandle, src, mask); + return true; + } + + public boolean makeCurrent() { + return CGL.makeCurrentContext(contextHandle); + } + + public boolean release() { + return CGL.clearCurrentContext(contextHandle); + } + + public boolean setSwapInterval(int interval) { + CGL.setSwapInterval(contextHandle, interval); + return true; + } + public boolean swapBuffers(boolean isOnscreen) { + if(isOnscreen) { + return CGL.flushBuffer(contextHandle); + } + return true; + } + } + + class CGLImpl implements GLBackendImpl { + public boolean isNSContext() { return false; } + + public boolean create(long share) { + DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) 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"); + } + try { + // Create new context + PointerBuffer ctx = 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); + 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); + if (res != CGL.kCGLNoError) { + throw new GLException("Error code " + res + " while attaching context to pbuffer"); + } + } + contextHandle = ctx.get(0); + } finally { + CGL.CGLDestroyPixelFormat(fmt.get(0)); + } + return true; + } + + public boolean destroy() { + return CGL.CGLDestroyContext(contextHandle) == CGL.kCGLNoError; + } + + public boolean copyImpl(long src, int mask) { + CGL.CGLCopyContext(src, contextHandle, mask); + return true; + } + + public boolean makeCurrent() { + return CGL.CGLSetCurrentContext(contextHandle) == CGL.kCGLNoError; + } + + public boolean release() { + return (CGL.CGLSetCurrentContext(0) == CGL.kCGLNoError); + } + + public boolean setSwapInterval(int interval) { + int[] lval = new int[] { interval } ; + CGL.CGLSetParameter(contextHandle, CGL.kCGLCPSwapInterval, lval, 0); + return true; + } + public boolean swapBuffers(boolean isOnscreen) { + if(isOnscreen) { + return CGL.kCGLNoError == CGL.CGLFlushDrawable(contextHandle); + } + return true; + } + } } diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java index 10e061d3a..5a35f661d 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java @@ -40,9 +40,12 @@ package jogamp.opengl.macosx.cgl; -import javax.media.nativewindow.*; -import javax.media.opengl.*; -import jogamp.opengl.*; +import javax.media.nativewindow.NativeSurface; +import javax.media.opengl.GLDrawableFactory; +import javax.media.opengl.GLException; + +import jogamp.opengl.GLDrawableImpl; +import jogamp.opengl.GLDynamicLookupHelper; public abstract class MacOSXCGLDrawable extends GLDrawableImpl { // The Java2D/OpenGL pipeline on OS X uses low-level CGLContextObjs @@ -74,12 +77,23 @@ public abstract class MacOSXCGLDrawable extends GLDrawableImpl { // lifetime of a given GLPbuffer. This is not a fully general // solution (for example, you can't share textures among a // GLPbuffer, a GLJPanel and a GLCanvas simultaneously) but should - // be enough to get things off the ground. - public static final int NSOPENGL_MODE = 1; - public static final int CGL_MODE = 2; + // be enough to get things off the ground. + public enum GLBackendType { + NSOPENGL(0), CGL(1); + + public final int id; + + GLBackendType(int id){ + this.id = id; + } + } + private boolean haveSetOpenGLMode = false; + private GLBackendType openGLMode = GLBackendType.NSOPENGL; + public MacOSXCGLDrawable(GLDrawableFactory factory, NativeSurface comp, boolean realized) { super(factory, comp, realized); + initOpenGLImpl(getOpenGLMode()); } protected void setRealizedImpl() { @@ -93,7 +107,25 @@ public abstract class MacOSXCGLDrawable extends GLDrawableImpl { return Thread.currentThread().getName(); } - // Support for "mode switching" as per above - public abstract void setOpenGLMode(int mode); - public abstract int getOpenGLMode(); + // Support for "mode switching" as described in MacOSXCGLDrawable + public void setOpenGLMode(GLBackendType mode) { + if (mode == openGLMode) { + return; + } + if (haveSetOpenGLMode) { + throw new GLException("Can't switch between using NSOpenGLPixelBuffer and CGLPBufferObj more than once"); + } + + destroyImpl(); + if (DEBUG) { + System.err.println("Switching context mode " + openGLMode + " -> " + mode); + } + initOpenGLImpl(mode); + openGLMode = mode; + haveSetOpenGLMode = true; + } + public final GLBackendType getOpenGLMode() { return openGLMode; } + + protected void initOpenGLImpl(GLBackendType backend) { /* nop */ } + } diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java index 47867256d..0d5f5ce8e 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java @@ -40,19 +40,28 @@ package jogamp.opengl.macosx.cgl; -import javax.media.opengl.*; -import jogamp.opengl.*; +import javax.media.nativewindow.AbstractGraphicsScreen; +import javax.media.nativewindow.DefaultGraphicsScreen; +import javax.media.nativewindow.NativeSurface; +import javax.media.nativewindow.NativeWindowFactory; +import javax.media.opengl.GLCapabilitiesImmutable; +import javax.media.opengl.GLContext; +import javax.media.opengl.GLDrawableFactory; +import javax.media.opengl.GLException; +import javax.media.opengl.GLProfile; -import javax.media.nativewindow.*; import jogamp.nativewindow.WrappedSurface; +import jogamp.opengl.GLContextShareSet; +import jogamp.opengl.macosx.cgl.MacOSXCGLDrawable.GLBackendType; + public class MacOSXExternalCGLContext extends MacOSXCGLContext { private GLContext lastContext; private MacOSXExternalCGLContext(Drawable drawable, boolean isNSContext, long handle) { super(drawable, null); + setOpenGLMode(isNSContext ? GLBackendType.NSOPENGL : GLBackendType.CGL ); drawable.setExternalCGLContext(this); - this.isNSContext = isNSContext; this.contextHandle = handle; GLContextShareSet.contextCreated(this); setGLFunctionAvailability(false, true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); @@ -139,15 +148,6 @@ public class MacOSXExternalCGLContext extends MacOSXCGLContext { protected void destroyImpl() throws GLException { } - public void setOpenGLMode(int mode) { - if (mode != MacOSXCGLDrawable.CGL_MODE) - throw new GLException("OpenGL mode switching not supported for external GLContexts"); - } - - public int getOpenGLMode() { - return MacOSXCGLDrawable.CGL_MODE; - } - // Need to provide the display connection to extension querying APIs static class Drawable extends MacOSXCGLDrawable { MacOSXExternalCGLContext extCtx; @@ -180,15 +180,6 @@ public class MacOSXExternalCGLContext extends MacOSXCGLContext { if (extCtx != null) { extCtx.swapBuffers(); } - } - - public void setOpenGLMode(int mode) { - if (mode != CGL_MODE) - throw new GLException("OpenGL mode switching not supported for external GLContext's drawables"); - } - - public int getOpenGLMode() { - return CGL_MODE; - } + } } } diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java index b387c28c8..97d198c92 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java @@ -56,18 +56,6 @@ public class MacOSXOnscreenCGLContext extends MacOSXCGLContext { } @Override - protected void releaseImpl() throws GLException { - super.releaseImpl(); - } - - @Override - protected void swapBuffers() { - if (!CGL.flushBuffer(contextHandle)) { - throw new GLException("Error swapping buffers"); - } - } - - @Override protected void drawableUpdatedNotify() throws GLException { if(0==updateHandle || CGL.updateContextNeedsUpdate(updateHandle)) { if (contextHandle == 0) { @@ -81,11 +69,8 @@ public class MacOSXOnscreenCGLContext extends MacOSXCGLContext { @Override protected boolean createImpl() { - boolean res = create(false, false); - if(!isNSContext) { - throw new InternalError("XXX0"); - } - if(res) { + boolean res = super.createImpl(); + if(res && isNSContext()) { if(0 != updateHandle) { throw new InternalError("XXX1"); } @@ -104,16 +89,5 @@ public class MacOSXOnscreenCGLContext extends MacOSXCGLContext { updateHandle = 0; } super.destroyImpl(); - } - - @Override - public void setOpenGLMode(int mode) { - if (mode != MacOSXCGLDrawable.NSOPENGL_MODE) - throw new GLException("OpenGL mode switching not supported for on-screen GLContexts"); - } - - @Override - public int getOpenGLMode() { - return MacOSXCGLDrawable.NSOPENGL_MODE; - } + } } diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java index 513dc3a04..24276c39e 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java @@ -41,51 +41,43 @@ package jogamp.opengl.macosx.cgl; import java.lang.ref.WeakReference; -import java.util.*; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; -import javax.media.nativewindow.*; -import javax.media.opengl.*; +import javax.media.nativewindow.NativeSurface; +import javax.media.opengl.GLContext; +import javax.media.opengl.GLDrawableFactory; public class MacOSXOnscreenCGLDrawable extends MacOSXCGLDrawable { - private List/*<WeakReference<GLContext>>*/ createdContexts = - new ArrayList(); + private List<WeakReference<MacOSXCGLContext>> createdContexts = new ArrayList<WeakReference<MacOSXCGLContext>>(); protected MacOSXOnscreenCGLDrawable(GLDrawableFactory factory, NativeSurface component) { super(factory, component, false); } public GLContext createContext(GLContext shareWith) { - MacOSXOnscreenCGLContext context = - new MacOSXOnscreenCGLContext(this, shareWith); + MacOSXOnscreenCGLContext ctx= new MacOSXOnscreenCGLContext(this, shareWith); // NOTE: we need to keep track of the created contexts in order to // implement swapBuffers() because of how Mac OS X implements its // OpenGL window interface - synchronized (this) { - List newContexts = new ArrayList(); - newContexts.addAll(createdContexts); - newContexts.add(new WeakReference(context)); - createdContexts = newContexts; + synchronized (createdContexts) { + createdContexts.add(new WeakReference<MacOSXCGLContext>(ctx)); } - return context; + return ctx; } protected void swapBuffersImpl() { - for (Iterator iter = createdContexts.iterator(); iter.hasNext(); ) { - WeakReference ref = (WeakReference) iter.next(); - MacOSXOnscreenCGLContext ctx = (MacOSXOnscreenCGLContext) ref.get(); - // FIXME: clear out unreachable contexts - if (ctx != null) { - ctx.swapBuffers(); - } + synchronized (createdContexts) { + for (Iterator<WeakReference<MacOSXCGLContext>> iter = createdContexts.iterator(); iter.hasNext(); ) { + WeakReference<MacOSXCGLContext> ref = iter.next(); + MacOSXCGLContext ctx = ref.get(); + if (ctx != null) { + ctx.swapBuffers(); + } else { + iter.remove(); + } + } } - } - - public void setOpenGLMode(int mode) { - if (mode != NSOPENGL_MODE) - throw new GLException("OpenGL mode switching not supported for on-screen GLDrawables"); - } - - public int getOpenGLMode() { - return NSOPENGL_MODE; - } + } } diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLContext.java index 267578680..c5743b923 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLContext.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLContext.java @@ -33,13 +33,14 @@ package jogamp.opengl.macosx.cgl; -import com.jogamp.common.nio.PointerBuffer; -import java.security.*; -import java.util.*; +import javax.media.nativewindow.DefaultGraphicsConfiguration; +import javax.media.opengl.GL; +import javax.media.opengl.GL2; +import javax.media.opengl.GLCapabilitiesImmutable; +import javax.media.opengl.GLContext; +import javax.media.opengl.GLException; +import javax.media.opengl.GLPbuffer; -import javax.media.opengl.*; -import javax.media.nativewindow.*; -import jogamp.opengl.*; public class MacOSXPbufferCGLContext extends MacOSXCGLContext { @@ -47,20 +48,9 @@ public class MacOSXPbufferCGLContext extends MacOSXCGLContext { private int textureTarget; // e.g. GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_NV private int texture; // actual texture object - private static boolean isTigerOrLater; - - 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)); - } - public MacOSXPbufferCGLContext(MacOSXPbufferCGLDrawable drawable, GLContext shareWith) { super(drawable, shareWith); - initOpenGLImpl(); } public void bindPbufferToTexture() { @@ -76,14 +66,8 @@ public class MacOSXPbufferCGLContext extends MacOSXCGLContext { } protected void makeCurrentImpl(boolean newCreated) throws GLException { - if (getOpenGLMode() != ((MacOSXPbufferCGLDrawable)drawable).getOpenGLMode()) { - setOpenGLMode(((MacOSXPbufferCGLDrawable)drawable).getOpenGLMode()); - } - - if (!impl.makeCurrent(contextHandle)) { - throw new GLException("Error making Context (NS) current"); - } - + super.makeCurrentImpl(newCreated); + if (newCreated) { // Initialize render-to-texture support if requested DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); @@ -110,254 +94,7 @@ public class MacOSXPbufferCGLContext extends MacOSXCGLContext { } } - protected void releaseImpl() throws GLException { - if (!impl.release(contextHandle)) { - throw new GLException("Error releasing OpenGL Context (NS)"); - } - } - - protected void destroyImpl() throws GLException { - impl.destroy(contextHandle); - } - - protected void setSwapIntervalImpl(int interval) { - impl.setSwapInterval(contextHandle, interval); - currentSwapInterval = impl.getSwapInterval() ; - } - public int getFloatingPointMode() { return GLPbuffer.APPLE_FLOAT; } - - protected boolean createImpl() throws GLException { - DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); - GLCapabilitiesImmutable capabilities = (GLCapabilitiesImmutable)config.getChosenCapabilities(); - if (capabilities.getPbufferFloatingPointBuffers() && - !isTigerOrLater) { - throw new GLException("Floating-point pbuffers supported only on OS X 10.4 or later"); - } - // Change our OpenGL mode to match that of any share context before we create ourselves - MacOSXCGLContext other = (MacOSXCGLContext) GLContextShareSet.getShareContext(this); - if (other != null) { - setOpenGLMode(other.getOpenGLMode()); - } - // Will throw exception upon error - isNSContext = impl.isNSContext(); - contextHandle = impl.create(); - - if (!impl.makeCurrent(contextHandle)) { - throw new GLException("Error making Context (NS:"+isNSContext()+") current"); - } - if(!isNSContext()) { // FIXME: ?? - throw new GLException("Not a NS Context"); - } - setGLFunctionAvailability(true, true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); - return true; - } - - //--------------------------------------------------------------------------- - // OpenGL "mode switching" functionality - // - private boolean haveSetOpenGLMode = false; - // FIXME: should consider switching the default mode based on - // whether the Java2D/JOGL bridge is active -- need to ask ourselves - // whether it's more likely that we will share with a GLCanvas or a - // GLJPanel when the bridge is turned on - private int openGLMode = MacOSXCGLDrawable.NSOPENGL_MODE; - // Implementation object (either NSOpenGL-based or CGL-based) - protected Impl impl; - - public void setOpenGLMode(int mode) { - if (mode == openGLMode) { - return; - } - if (haveSetOpenGLMode) { - throw new GLException("Can't switch between using NSOpenGLPixelBuffer and CGLPBufferObj more than once"); - } - destroyImpl(); - ((MacOSXPbufferCGLDrawable)drawable).setOpenGLMode(mode); - openGLMode = mode; - haveSetOpenGLMode = true; - if (DEBUG) { - System.err.println("Switching PBuffer context mode to " + - ((mode == MacOSXCGLDrawable.NSOPENGL_MODE) ? "NSOPENGL_MODE" : "CGL_MODE")); - } - initOpenGLImpl(); - } - - public int getOpenGLMode() { - return openGLMode; - } - - private void initOpenGLImpl() { - switch (openGLMode) { - case MacOSXCGLDrawable.NSOPENGL_MODE: - impl = new NSOpenGLImpl(); - break; - case MacOSXCGLDrawable.CGL_MODE: - impl = new CGLImpl(); - break; - default: - throw new InternalError("Illegal implementation mode " + openGLMode); - } - } - - // Abstract interface for implementation of this context (either - // NSOpenGL-based or CGL-based) - interface Impl { - public boolean isNSContext(); - public long create(); - public void destroy(long ctx); - public boolean makeCurrent(long ctx); - public boolean release(long ctx); - public void setSwapInterval(long ctx, int interval); - public int getSwapInterval(); - } - - // NSOpenGLContext-based implementation - class NSOpenGLImpl implements Impl { - public boolean isNSContext() { return true; } - public long create() { - DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); - GLCapabilitiesImmutable capabilities = (GLCapabilitiesImmutable)config.getChosenCapabilities(); - if (capabilities.getPbufferFloatingPointBuffers() && - !isTigerOrLater) { - throw new GLException("Floating-point pbuffers supported only on OS X 10.4 or later"); - } - if (!MacOSXPbufferCGLContext.this.create(true, capabilities.getPbufferFloatingPointBuffers())) { - throw new GLException("Error creating context for pbuffer"); - } - // Must now associate the pbuffer with our newly-created context - CGL.setContextPBuffer(contextHandle, drawable.getHandle()); - return contextHandle; - } - - public void destroy(long ctx) { - MacOSXPbufferCGLContext.super.destroyImpl(); - } - - public boolean makeCurrent(long ctx) { - return CGL.makeCurrentContext(ctx); - } - - public boolean release(long ctx) { - return CGL.clearCurrentContext(ctx); - } - - private int currentSwapInterval = 0 ; - - public void setSwapInterval(long ctx, int interval) { - CGL.setSwapInterval(ctx, interval); - currentSwapInterval = interval ; - } - public int getSwapInterval() { - return currentSwapInterval; - } - } - - class CGLImpl implements Impl { - public boolean isNSContext() { return false; } - public long create() { - // Find and configure share context - MacOSXCGLContext other = (MacOSXCGLContext) GLContextShareSet.getShareContext(MacOSXPbufferCGLContext.this); - long share = 0; - if (other != null) { - // Reconfigure pbuffer-based GLContexts - if (other instanceof MacOSXPbufferCGLContext) { - MacOSXPbufferCGLContext ctx = (MacOSXPbufferCGLContext) other; - ctx.setOpenGLMode(MacOSXCGLDrawable.CGL_MODE); - } else { - if (other.isNSContext()) { - throw new GLException("Can't share between NSOpenGLContexts and CGLContextObjs"); - } - } - share = other.getHandle(); - // Note we don't check for a 0 return value, since switching - // the context's mode causes it to be destroyed and not - // re-initialized until the next makeCurrent - } - - // Set up pixel format attributes - // FIXME: shall go into MacOSXCGLGraphicsConfiguration - int[] attrs = new int[256]; - int i = 0; - attrs[i++] = CGL.kCGLPFAPBuffer; - DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); - GLCapabilitiesImmutable capabilities = (GLCapabilitiesImmutable)config.getChosenCapabilities(); - if (capabilities.getPbufferFloatingPointBuffers()) - attrs[i++] = CGL.kCGLPFAColorFloat; - if (capabilities.getDoubleBuffered()) - attrs[i++] = CGL.kCGLPFADoubleBuffer; - if (capabilities.getStereo()) - attrs[i++] = CGL.kCGLPFAStereo; - attrs[i++] = CGL.kCGLPFAColorSize; - attrs[i++] = (capabilities.getRedBits() + - capabilities.getGreenBits() + - capabilities.getBlueBits()); - attrs[i++] = CGL.kCGLPFAAlphaSize; - attrs[i++] = capabilities.getAlphaBits(); - attrs[i++] = CGL.kCGLPFADepthSize; - attrs[i++] = capabilities.getDepthBits(); - // FIXME: should validate stencil size as is done in MacOSXWindowSystemInterface.m - attrs[i++] = CGL.kCGLPFAStencilSize; - attrs[i++] = capabilities.getStencilBits(); - attrs[i++] = CGL.kCGLPFAAccumSize; - attrs[i++] = (capabilities.getAccumRedBits() + - capabilities.getAccumGreenBits() + - capabilities.getAccumBlueBits() + - capabilities.getAccumAlphaBits()); - if (capabilities.getSampleBuffers()) { - attrs[i++] = CGL.kCGLPFASampleBuffers; - attrs[i++] = 1; - attrs[i++] = CGL.kCGLPFASamples; - attrs[i++] = capabilities.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"); - } - - // Create new context - PointerBuffer ctx = 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); - CGL.CGLDestroyPixelFormat(fmt.get(0)); - if (res != CGL.kCGLNoError) { - throw new GLException("Error code " + res + " while creating context"); - } - // Attach newly-created context to the pbuffer - res = CGL.CGLSetPBuffer(ctx.get(0), drawable.getHandle(), 0, 0, 0); - if (res != CGL.kCGLNoError) { - throw new GLException("Error code " + res + " while attaching context to pbuffer"); - } - return ctx.get(0); - } - - public void destroy(long ctx) { - if (CGL.CGLDestroyContext(ctx) != CGL.kCGLNoError) { - throw new GLException("Unable to delete OpenGL context (cgl)"); - } - } - - public boolean makeCurrent(long ctx) { - return CGL.CGLSetCurrentContext(ctx) == CGL.kCGLNoError; - } - - public boolean release(long ctx) { - return (CGL.CGLSetCurrentContext(0) == CGL.kCGLNoError); - } - - public void setSwapInterval(long ctx, int interval) { - // For now not supported (not really relevant for off-screen contexts anyway) - } - public int getSwapInterval() { - return 0; - } - } } diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java index 2554b5f67..fdbfaf6d6 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java @@ -40,20 +40,39 @@ package jogamp.opengl.macosx.cgl; +import javax.media.nativewindow.DefaultGraphicsConfiguration; +import javax.media.nativewindow.NativeSurface; +import javax.media.nativewindow.SurfaceChangeable; +import javax.media.opengl.GL; +import javax.media.opengl.GL2; +import javax.media.opengl.GLCapabilitiesImmutable; +import javax.media.opengl.GLContext; +import javax.media.opengl.GLDrawableFactory; +import javax.media.opengl.GLException; +import javax.media.opengl.GLProfile; + +import jogamp.opengl.Debug; + import com.jogamp.common.nio.PointerBuffer; -import javax.media.opengl.*; -import javax.media.nativewindow.*; -import jogamp.opengl.*; + public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable { private static final boolean DEBUG = Debug.debug("MacOSXPbufferCGLDrawable"); + // Abstract interface for implementation of this drawable (either + // NSOpenGL-based or CGL-based) + interface GLBackendImpl { + public long create(int renderTarget, int internalFormat, int width, int height); + public void destroy(long pbuffer); + } + + // Implementation object (either NSOpenGL-based or CGL-based) + protected GLBackendImpl impl; + // State for render-to-texture and render-to-texture-rectangle support // private int textureTarget; // e.g. GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_NV // private int texture; // actual texture object - // NSOpenGLPbuffer (for normal mode) - // CGLPbufferObj (for CGL_MODE situation, i.e., when Java2D/JOGL bridge is active) // Note that we can not store this in the NativeSurface because the // semantic is that contains an NSView protected long pBuffer; @@ -65,7 +84,6 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable { System.out.println("Pbuffer config: " + getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration()); } - initOpenGLImpl(); createPbuffer(); if (DEBUG) { @@ -163,62 +181,26 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable { return (1<<power); } - //--------------------------------------------------------------------------- - // OpenGL "mode switching" functionality - // - private boolean haveSetOpenGLMode = false; - // FIXME: should consider switching the default mode based on - // whether the Java2D/JOGL bridge is active -- need to ask ourselves - // whether it's more likely that we will share with a GLCanvas or a - // GLJPanel when the bridge is turned on - private int openGLMode = NSOPENGL_MODE; - // Implementation object (either NSOpenGL-based or CGL-based) - protected Impl impl; - - public void setOpenGLMode(int mode) { - if (mode == openGLMode) { - return; - } - if (haveSetOpenGLMode) { - throw new GLException("Can't switch between using NSOpenGLPixelBuffer and CGLPBufferObj more than once"); - } - destroyImpl(); - openGLMode = mode; - haveSetOpenGLMode = true; - if (DEBUG) { - System.err.println("Switching PBuffer drawable mode to " + - ((mode == MacOSXCGLDrawable.NSOPENGL_MODE) ? "NSOPENGL_MODE" : "CGL_MODE")); - } - initOpenGLImpl(); - createPbuffer(); - } - - public int getOpenGLMode() { - return openGLMode; + public void setOpenGLMode(GLBackendType mode) { + super.setOpenGLMode(mode); + createPbuffer(); // recreate } - private void initOpenGLImpl() { - switch (openGLMode) { - case NSOPENGL_MODE: + protected void initOpenGLImpl(GLBackendType backend) { + switch (backend) { + case NSOPENGL: impl = new NSOpenGLImpl(); break; - case CGL_MODE: + case CGL: impl = new CGLImpl(); break; default: - throw new InternalError("Illegal implementation mode " + openGLMode); + throw new InternalError("Illegal implementation mode " + backend); } - } - - // Abstract interface for implementation of this drawable (either - // NSOpenGL-based or CGL-based) - interface Impl { - public long create(int renderTarget, int internalFormat, int width, int height); - public void destroy(long pbuffer); - } - + } + // NSOpenGLPixelBuffer implementation - class NSOpenGLImpl implements Impl { + class NSOpenGLImpl implements GLBackendImpl { public long create(int renderTarget, int internalFormat, int width, int height) { return CGL.createPBuffer(renderTarget, internalFormat, width, height); } @@ -229,7 +211,7 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable { } // CGL implementation - class CGLImpl implements Impl { + class CGLImpl implements GLBackendImpl { public long create(int renderTarget, int internalFormat, int width, int height) { PointerBuffer pbuffer = PointerBuffer.allocateDirect(1); int res = CGL.CGLCreatePBuffer(width, height, renderTarget, internalFormat, 0, pbuffer); @@ -245,5 +227,6 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable { throw new GLException("Error destroying CGL-based pbuffer: error code " + res); } } - } + } + } diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXJava2DCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXJava2DCGLContext.java index 5e661b321..ae58f6811 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXJava2DCGLContext.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXJava2DCGLContext.java @@ -39,12 +39,16 @@ package jogamp.opengl.macosx.cgl.awt; -import jogamp.opengl.macosx.cgl.*; - import java.awt.Graphics; -import javax.media.opengl.*; -import jogamp.opengl.*; -import jogamp.opengl.awt.*; + +import javax.media.opengl.GLContext; +import javax.media.opengl.GLException; + +import jogamp.opengl.awt.Java2D; +import jogamp.opengl.awt.Java2DGLContext; +import jogamp.opengl.macosx.cgl.MacOSXCGLContext; +import jogamp.opengl.macosx.cgl.MacOSXCGLDrawable.GLBackendType; + /** MacOSXCGLContext implementation supporting the Java2D/JOGL bridge * on Mac OS X. The external GLDrawable mechanism does not work on Mac @@ -76,37 +80,14 @@ public class MacOSXJava2DCGLContext extends MacOSXCGLContext implements Java2DGL } protected boolean createImpl() { - // Find and configure share context - MacOSXCGLContext other = (MacOSXCGLContext) GLContextShareSet.getShareContext(this); - long share = 0; - if (other != null) { - // Reconfigure pbuffer-based GLContexts - if (other instanceof MacOSXPbufferCGLContext) { - MacOSXPbufferCGLContext ctx = (MacOSXPbufferCGLContext) other; - ctx.setOpenGLMode(MacOSXCGLDrawable.CGL_MODE); - } else { - if (other.getOpenGLMode() != MacOSXCGLDrawable.CGL_MODE) { - throw new GLException("Can't share between NSOpenGLContexts and CGLContextObjs"); - } - } - share = other.getHandle(); - // Note we don't check for a 0 return value, since switching - // the context's mode causes it to be destroyed and not - // re-initialized until the next makeCurrent - } - - if (DEBUG) { - System.err.println("!!! Share context is " + toHexString(share) + " for " + getClass().getName()); - } - + long share = createImplPreset(); + long ctx = Java2D.createOGLContextOnSurface(graphics, share); if (ctx == 0) { return false; } setGLFunctionAvailability(true, true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); // use GL_VERSION - // FIXME: think about GLContext sharing contextHandle = ctx; - isNSContext = true; return true; } @@ -120,12 +101,10 @@ public class MacOSXJava2DCGLContext extends MacOSXCGLContext implements Java2DGL Java2D.destroyOGLContext(contextHandle); } - public void setOpenGLMode(int mode) { - if (mode != MacOSXCGLDrawable.CGL_MODE) + public void setOpenGLMode(GLBackendType mode) { + if (mode != GLBackendType.CGL) { throw new GLException("OpenGL mode switching not supported for Java2D GLContexts"); - } - - public int getOpenGLMode() { - return MacOSXCGLDrawable.CGL_MODE; + } + super.setOpenGLMode(mode); } } diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java index 769f1bed2..5203d4ab5 100644 --- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java @@ -642,7 +642,7 @@ public abstract class X11GLXContext extends GLContextImpl { public String toString() { StringBuffer sb = new StringBuffer(); - sb.append(getClass().getName()); + sb.append(getClass().getSimpleName()); sb.append(" ["); super.append(sb); sb.append(", direct "); diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestFBOMRTNEWT01.java b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestFBOMRTNEWT01.java index 35eaa956b..50d65e985 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestFBOMRTNEWT01.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestFBOMRTNEWT01.java @@ -63,9 +63,6 @@ public class TestFBOMRTNEWT01 extends UITestCase { @Test public void test01() throws InterruptedException { - if(Platform.getOSType() == Platform.OSType.MACOS) { - throw new RuntimeException("On OSX: Triggers Bus Error (Illegal Memory Access) @ glDrawArrays(..)"); - } // preset .. final NEWTGLContext.WindowContext winctx = NEWTGLContext.createOnscreenWindow(GLProfile.getGL2ES2(), 640, 480, true); final GLDrawable drawable = winctx.context.getGLDrawable(); |