diff options
author | Sven Gothel <[email protected]> | 2009-09-25 12:30:31 -0700 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2009-09-25 12:30:31 -0700 |
commit | 760d6821e09985252c8b439d9a92bead7bcf1193 (patch) | |
tree | 71808409d1b424eb2d24e13942babc219b3bf64d | |
parent | 82ff74cfca31c3c72d9c1de260c17323943fa571 (diff) |
Fix MacOSX External GLContext
11 files changed, 489 insertions, 182 deletions
diff --git a/make/build-jogl.xml b/make/build-jogl.xml index c541748f8..64e5cf93a 100644 --- a/make/build-jogl.xml +++ b/make/build-jogl.xml @@ -1408,6 +1408,7 @@ <condition property="c.compiler.use-debug"><istrue value="${c.compiler.debug}"/></condition> <patternset id="c.src.files.jogl.gl2"> + <include name="${rootrel.src.c}/macosx/MacOSXCustomCGLCode.c" if="isOSX"/> <include name="${rootrel.src.c}/macosx/MacOSXWindowSystemInterface.m" if="isOSX"/> <include name="${rootrel.src.c}/macosx/ContextUpdater.m" if="isOSX"/> <include name="${rootrel.src.c}/GLXGetProcAddressARB.c" if="isX11"/> @@ -1426,6 +1427,7 @@ </patternset> <patternset id="c.src.files.jogl.gl2es12"> + <include name="${rootrel.src.c}/macosx/MacOSXCustomCGLCode.c" if="isOSX"/> <include name="${rootrel.src.c}/macosx/MacOSXWindowSystemInterface.m" if="isOSX"/> <include name="${rootrel.src.c}/macosx/ContextUpdater.m" if="isOSX"/> <include name="${rootrel.src.c}/GLXGetProcAddressARB.c" if="isX11"/> diff --git a/make/stub_includes/macosx/OpenGL/OpenGL.h b/make/stub_includes/macosx/OpenGL/OpenGL.h index 16225b46b..afb11efea 100644 --- a/make/stub_includes/macosx/OpenGL/OpenGL.h +++ b/make/stub_includes/macosx/OpenGL/OpenGL.h @@ -73,18 +73,44 @@ typedef enum _CGLError { kCGLBadConnection = 10017 /* invalid CoreGraphics connection */ } CGLError; +typedef enum _CGLContextParameter { + kCGLCPSwapRectangle = 200, + kCGLCPSwapInterval = 222, + kCGLCPDispatchTableSize = 224, + kCGLCPClientStorage = 226, + kCGLCPSurfaceTexture = 228, + kCGLCPSurfaceOrder = 235, + kCGLCPSurfaceOpacity = 236, + kCGLCPSurfaceBackingSize = 304, + kCGLCPSurfaceSurfaceVolatile = 306, + kCGLCPReclaimResources = 308, + kCGLCPCurrentRendererID = 309, + kCGLCPGPUVertexProcessing = 310, + kCGLCPGPUFragmentProcessing = 311, + kCGLCPHasDrawable = 314, + kCGLCPMPSwapsInFlight = 315, +} CGLContextParameter; + /* Pixel format manipulation */ CGLError CGLChoosePixelFormat(const CGLPixelFormatAttribute *attribs, CGLPixelFormatObj *pix, long *npix); CGLError CGLDestroyPixelFormat(CGLPixelFormatObj pix); +CGLPixelFormatObj CGLGetPixelFormat ( CGLContextObj ctx ); /* Context manipulation */ CGLError CGLCreateContext(CGLPixelFormatObj pix, CGLContextObj share, CGLContextObj* ctx); +void CGLReleaseContext(CGLContextObj ctx); CGLError CGLDestroyContext(CGLContextObj ctx); CGLError CGLSetCurrentContext(CGLContextObj ctx); +CGLContextObj CGLGetCurrentContext (void); +CGLError CGLFlushDrawable ( CGLContextObj ctx); +CGLError CGLSetParameter ( CGLContextObj ctx, CGLContextParameter pname, const int *params ); +CGLError CGLCopyContext ( CGLContextObj src, CGLContextObj dst, int mask ); + + /* PBuffer manipulation */ CGLError CGLCreatePBuffer(long width, diff --git a/make/stub_includes/opengl/macosx-window-system.h b/make/stub_includes/opengl/macosx-window-system.h index f43adb546..7d2704be4 100644 --- a/make/stub_includes/opengl/macosx-window-system.h +++ b/make/stub_includes/opengl/macosx-window-system.h @@ -9,27 +9,36 @@ typedef int Bool; +// CGL .. +void CGLQueryPixelFormat(void* pixelFormat, int* iattrs, int niattrs, int* ivalues); + +// NS .. void* createPixelFormat(int* iattrs, int niattrs, int* ivalues); void queryPixelFormat(void* pixelFormat, int* iattrs, int niattrs, int* ivalues); void deletePixelFormat(void* pixelFormat); +// NS .. +void *getCurrentContext(void); +void *getNSView(void* nsContext); + void* createContext(void* shareContext, void* nsView, void* pixelFormat, int* viewNotReady); +void *getCGLContext(void* nsContext); Bool makeCurrentContext(void* nsContext); -Bool clearCurrentContext(void* nsContext); +Bool clearCurrentContext(void *nsContext); Bool deleteContext(void* nsContext); Bool flushBuffer(void* nsContext); -void setContextOpacity(void* context, int opacity); +void setContextOpacity(void* nsContext, int opacity); void updateContext(void* nsContext); void copyContext(void* destContext, void* srcContext, int mask); void* updateContextRegister(void* nsContext, void* nsView); -void updateContextUnregister(void* nsContext, void* nsView, void* updater); +void updateContextUnregister(void* updater); void* createPBuffer(int renderTarget, int internalFormat, int width, int height); -Bool destroyPBuffer(void* nsContext, void* pBuffer); +Bool destroyPBuffer(void* pBuffer); void setContextPBuffer(void* nsContext, void* pBuffer); void setContextTextureImageToPBuffer(void* nsContext, void* pBuffer, int colorBuffer); diff --git a/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLContext.java index 181efc8bb..111b215e3 100644 --- a/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLContext.java +++ b/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLContext.java @@ -49,7 +49,8 @@ import com.sun.gluegen.runtime.ProcAddressTable; public abstract class MacOSXCGLContext extends GLContextImpl { protected MacOSXCGLDrawable drawable; - protected long nsContext; // NSOpenGLContext + protected long nsContext; // NSOpenGLContext + protected long cglContext; // CGLContextObj private CGLExt cglExt; // Table that holds the addresses of the native C-language entry points for // CGL extension functions. @@ -111,44 +112,23 @@ public abstract class MacOSXCGLContext extends GLContextImpl } } MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); - GLCapabilities capabilities = (GLCapabilities)config.getRequestedCapabilities(); - GLProfile glProfile = capabilities.getGLProfile(); + GLCapabilities capabilitiesRequested = (GLCapabilities)config.getRequestedCapabilities(); + GLProfile glProfile = capabilitiesRequested.getGLProfile(); if(glProfile.isGL3()) { throw new GLException("GL3 profile currently not supported on MacOSX, due to the lack of a OpenGL 3.1 implementation"); } - // FIXME: Shall being moved to MacOSXCGLGraphicsConfiguration ! - int[] viewNotReady = new int[1]; - int[] iattribs = new int[128]; - int[] ivalues = new int[128]; - int idx = 0; - if (pbuffer) { - iattribs[idx] = CGL.NSOpenGLPFAPixelBuffer; ivalues[idx] = 1; idx++; - } - if (floatingPoint) { - iattribs[idx] = CGL.kCGLPFAColorFloat; ivalues[idx] = 1; idx++; - } - iattribs[idx] = CGL.NSOpenGLPFADoubleBuffer; ivalues[idx] = (capabilities.getDoubleBuffered() ? 1 : 0); idx++; - iattribs[idx] = CGL.NSOpenGLPFAStereo; ivalues[idx] = (capabilities.getStereo() ? 1 : 0); idx++; - iattribs[idx] = CGL.NSOpenGLPFAColorSize; ivalues[idx] = (capabilities.getRedBits() + - capabilities.getGreenBits() + - capabilities.getBlueBits()); idx++; - iattribs[idx] = CGL.NSOpenGLPFAAlphaSize; ivalues[idx] = capabilities.getAlphaBits(); idx++; - iattribs[idx] = CGL.NSOpenGLPFADepthSize; ivalues[idx] = capabilities.getDepthBits(); idx++; - iattribs[idx] = CGL.NSOpenGLPFAAccumSize; ivalues[idx] = (capabilities.getAccumRedBits() + - capabilities.getAccumGreenBits() + - capabilities.getAccumBlueBits() + - capabilities.getAccumAlphaBits()); idx++; - iattribs[idx] = CGL.NSOpenGLPFAStencilSize; ivalues[idx] = capabilities.getStencilBits(); idx++; - if (capabilities.getSampleBuffers()) { - iattribs[idx] = CGL.NSOpenGLPFASampleBuffers; ivalues[idx] = 1; idx++; - iattribs[idx] = CGL.NSOpenGLPFASamples; ivalues[idx] = capabilities.getNumSamples(); idx++; - } + // HACK .. bring in OnScreen/PBuffer selection to the DrawableFactory !! + GLCapabilities capabilities = (GLCapabilities) capabilitiesRequested.clone(); + capabilities.setPBuffer(pbuffer); + capabilities.setPbufferFloatingPointBuffers(floatingPoint); - long pixelFormat = CGL.createPixelFormat(iattribs, 0, idx, ivalues, 0); + 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 nsContext = CGL.createContext(share, drawable.getNativeWindow().getSurfaceHandle(), @@ -170,80 +150,8 @@ public abstract class MacOSXCGLContext extends GLContextImpl CGL.setContextOpacity(nsContext, 0); } - // On this platform the pixel format is associated with the - // context and not the drawable. However it's a reasonable - // approximation to just store the chosen pixel format up in the - // NativeWindow's AbstractGraphicsConfiguration, - // since the public API doesn't provide for a different GLCapabilities per context. - // 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(glProfile); - CGL.queryPixelFormat(pixelFormat, iattribs, 0, idx, ivalues, 0); - for (int i = 0; i < idx; i++) { - int attr = iattribs[i]; - switch (attr) { - case CGL.kCGLPFAColorFloat: - caps.setPbufferFloatingPointBuffers(ivalues[i] != 0); - break; - - case CGL.NSOpenGLPFADoubleBuffer: - caps.setDoubleBuffered(ivalues[i] != 0); - break; - - case CGL.NSOpenGLPFAStereo: - caps.setStereo(ivalues[i] != 0); - break; - - case CGL.NSOpenGLPFAColorSize: - { - int bitSize = ivalues[i]; - if (bitSize == 32) - bitSize = 24; - bitSize /= 3; - caps.setRedBits(bitSize); - caps.setGreenBits(bitSize); - caps.setBlueBits(bitSize); - } - break; - - case CGL.NSOpenGLPFAAlphaSize: - caps.setAlphaBits(ivalues[i]); - break; - - case CGL.NSOpenGLPFADepthSize: - caps.setDepthBits(ivalues[i]); - break; - - case CGL.NSOpenGLPFAAccumSize: - { - int bitSize = ivalues[i] / 4; - caps.setAccumRedBits(bitSize); - caps.setAccumGreenBits(bitSize); - caps.setAccumBlueBits(bitSize); - caps.setAccumAlphaBits(bitSize); - } - break; - - case CGL.NSOpenGLPFAStencilSize: - caps.setStencilBits(ivalues[i]); - break; - - case CGL.NSOpenGLPFASampleBuffers: - caps.setSampleBuffers(ivalues[i] != 0); - break; - - case CGL.NSOpenGLPFASamples: - caps.setNumSamples(ivalues[i]); - break; - - default: - break; - } - } - - config.setChosenCapabilities(caps); - } + GLCapabilities caps = MacOSXCGLGraphicsConfiguration.NSPixelFormat2GLCapabilities(glProfile, pixelFormat); + config.setChosenCapabilities(caps); } finally { CGL.deletePixelFormat(pixelFormat); } @@ -256,14 +164,14 @@ public abstract class MacOSXCGLContext extends GLContextImpl } protected int makeCurrentImpl() throws GLException { - if (drawable.getNativeWindow().getSurfaceHandle() == 0) { + if (0 == cglContext && drawable.getNativeWindow().getSurfaceHandle() == 0) { if (DEBUG) { System.err.println("drawable not properly initialized"); } return CONTEXT_NOT_CURRENT; } boolean created = false; - if (nsContext == 0) { + if ( 0 == cglContext && 0 == nsContext) { if (!create()) { return CONTEXT_NOT_CURRENT; } @@ -273,8 +181,14 @@ public abstract class MacOSXCGLContext extends GLContextImpl created = true; } - if (!CGL.makeCurrentContext(nsContext)) { - throw new GLException("Error making nsContext current"); + if ( 0 != cglContext ) { + if (CGL.kCGLNoError != CGL.CGLSetCurrentContext(cglContext)) { + throw new GLException("Error making cglContext current"); + } + } else { + if (!CGL.makeCurrentContext(nsContext)) { + throw new GLException("Error making nsContext current"); + } } if (created) { @@ -285,38 +199,64 @@ public abstract class MacOSXCGLContext extends GLContextImpl } protected void releaseImpl() throws GLException { - if (!CGL.clearCurrentContext(nsContext)) { - throw new GLException("Error freeing OpenGL nsContext"); + if ( 0 != cglContext ) { + CGL.CGLReleaseContext(cglContext); + } else { + if (!CGL.clearCurrentContext(nsContext)) { + throw new GLException("Error freeing OpenGL nsContext"); + } } } protected void destroyImpl() throws GLException { - if (nsContext != 0) { + boolean hadContext = isCreated(); + if ( 0 != cglContext ) { + if (CGL.kCGLNoError != CGL.CGLDestroyContext(cglContext)) { + throw new GLException("Unable to delete OpenGL cglContext"); + } + if (DEBUG) { + System.err.println("!!! Destroyed OpenGL cglContext " + cglContext); + } + cglContext = 0; + GLContextShareSet.contextDestroyed(this); + } else if ( 0 != nsContext ) { if (!CGL.deleteContext(nsContext)) { - throw new GLException("Unable to delete OpenGL context"); + throw new GLException("Unable to delete OpenGL nsContext"); } if (DEBUG) { - System.err.println("!!! Destroyed OpenGL context " + nsContext); + System.err.println("!!! Destroyed OpenGL nsContext " + nsContext); } nsContext = 0; + } + if(hadContext) { GLContextShareSet.contextDestroyed(this); } } public boolean isCreated() { - return (nsContext != 0); + return 0 != cglContext || 0 != nsContext ; } public void copy(GLContext source, int mask) throws GLException { - long dst = getNSContext(); - long src = ((MacOSXCGLContext) source).getNSContext(); - if (src == 0) { - throw new GLException("Source OpenGL context has not been created"); - } - if (dst == 0) { - throw new GLException("Destination OpenGL context has not been created"); + long dst = getCGLContext(); + long src = 0; + if( 0 != dst ) { + src = ((MacOSXCGLContext) source).getCGLContext(); + if (src == 0) { + throw new GLException("Source OpenGL cglContext has not been created ; Destination has a cglContext."); + } + CGL.CGLCopyContext(src, dst, mask); + } else { + dst = getNSContext(); + src = ((MacOSXCGLContext) source).getNSContext(); + if (src == 0) { + throw new GLException("Source OpenGL nsContext has not been created"); + } + if (dst == 0) { + throw new GLException("Destination OpenGL nsContext has not been created"); + } + CGL.copyContext(dst, src, mask); } - CGL.copyContext(dst, src, mask); } protected void updateGLProcAddressTable() { @@ -338,10 +278,14 @@ public abstract class MacOSXCGLContext extends GLContextImpl } protected void setSwapIntervalImpl(int interval) { - if (nsContext == 0) { + if ( 0 != cglContext ) { + int[] lval = new int[] { (int) interval } ; + CGL.CGLSetParameter(cglContext, CGL.kCGLCPSwapInterval, lval, 0); + } else if ( 0 != nsContext ) { + CGL.setSwapInterval(nsContext, interval); + } else { throw new GLException("OpenGL context not current"); } - CGL.setSwapInterval(nsContext, interval); currentSwapInterval = interval ; } @@ -391,6 +335,9 @@ public abstract class MacOSXCGLContext extends GLContextImpl // Internals only below this point // + public long getCGLContext() { + return cglContext; + } public long getNSContext() { return nsContext; } diff --git a/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java index d8c2a016d..7bcc4ca14 100644 --- a/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java +++ b/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java @@ -105,8 +105,7 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl implements D } public GLContext createExternalGLContext() { - AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(); - return new MacOSXExternalCGLContext(aScreen); + return MacOSXExternalCGLContext.create(this, null); } public boolean canCreateExternalGLDrawable() { diff --git a/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java b/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java index b5d2fc38e..c94efc92b 100644 --- a/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java +++ b/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java @@ -42,16 +42,193 @@ import com.sun.opengl.impl.*; import com.sun.gluegen.runtime.NativeLibrary; public class MacOSXCGLGraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable { - public MacOSXCGLGraphicsConfiguration(AbstractGraphicsScreen screen, GLCapabilities capsChosen, GLCapabilities capsRequested) { + long pixelformat; + + public MacOSXCGLGraphicsConfiguration(AbstractGraphicsScreen screen, GLCapabilities capsChosen, GLCapabilities capsRequested, + long pixelformat) { super(screen, capsChosen, capsRequested); + this.pixelformat=pixelformat; } public Object clone() { return super.clone(); } + protected void setChosenPixelFormat(long pixelformat) { + this.pixelformat=pixelformat; + } + protected void setChosenCapabilities(GLCapabilities caps) { super.setChosenCapabilities(caps); } + + protected static final int[] cglInternalAttributeToken = new int[] { + CGL.kCGLPFAColorFloat, + CGL.NSOpenGLPFAPixelBuffer, + CGL.NSOpenGLPFADoubleBuffer, + CGL.NSOpenGLPFAStereo, + CGL.NSOpenGLPFAColorSize, + CGL.NSOpenGLPFAAlphaSize, + CGL.NSOpenGLPFADepthSize, + CGL.NSOpenGLPFAAccumSize, + CGL.NSOpenGLPFAStencilSize, + CGL.NSOpenGLPFASampleBuffers, + CGL.NSOpenGLPFASamples }; + + protected static int[] GLCapabilities2AttribList(GLCapabilities caps) { + int[] ivalues = new int[cglInternalAttributeToken.length]; + + for (int idx = 0; idx < cglInternalAttributeToken.length; idx++) { + int attr = cglInternalAttributeToken[idx]; + switch (attr) { + case CGL.kCGLPFAColorFloat: + ivalues[idx] = caps.getPbufferFloatingPointBuffers() ? 1 : 0; + break; + + case CGL.NSOpenGLPFAPixelBuffer: + ivalues[idx] = caps.isPBuffer() ? 1 : 0; + break; + + case CGL.NSOpenGLPFADoubleBuffer: + ivalues[idx] = (caps.getDoubleBuffered() ? 1 : 0); + break; + + case CGL.NSOpenGLPFAStereo: + ivalues[idx] = (caps.getStereo() ? 1 : 0); + break; + + case CGL.NSOpenGLPFAColorSize: + ivalues[idx] = (caps.getRedBits() + caps.getGreenBits() + caps.getBlueBits()); + break; + + case CGL.NSOpenGLPFAAlphaSize: + ivalues[idx] = caps.getAlphaBits(); + break; + + case CGL.NSOpenGLPFADepthSize: + ivalues[idx] = caps.getDepthBits(); + break; + + case CGL.NSOpenGLPFAAccumSize: + ivalues[idx] = (caps.getAccumRedBits() + caps.getAccumGreenBits() + caps.getAccumBlueBits() + caps.getAccumAlphaBits()); + break; + + case CGL.NSOpenGLPFAStencilSize: + ivalues[idx] = caps.getStencilBits(); + break; + + case CGL.NSOpenGLPFASampleBuffers: + ivalues[idx] = caps.getSampleBuffers() ? 1 : 0; + break; + + case CGL.NSOpenGLPFASamples: + ivalues[idx] = caps.getSampleBuffers() ? ivalues[idx] = caps.getNumSamples() : 0; + break; + + default: + break; + } + } + return ivalues; + } + + protected static long GLCapabilities2NSPixelFormat(GLCapabilities caps) { + int[] ivalues = GLCapabilities2AttribList(caps); + return CGL.createPixelFormat(cglInternalAttributeToken, 0, cglInternalAttributeToken.length, ivalues, 0); + } + + protected static GLCapabilities NSPixelFormat2GLCapabilities(GLProfile glp, long pixelFormat) { + return PixelFormat2GLCapabilities(glp, pixelFormat, true); + } + + protected static GLCapabilities CGLPixelFormat2GLCapabilities(GLProfile glp, long pixelFormat) { + return PixelFormat2GLCapabilities(glp, pixelFormat, false); + } + + private static GLCapabilities PixelFormat2GLCapabilities(GLProfile glp, long pixelFormat, boolean nsUsage) { + int[] ivalues = new int[cglInternalAttributeToken.length]; + + // On this platform the pixel format is associated with the + // context and not the drawable. However it's a reasonable + // approximation to just store the chosen pixel format up in the + // NativeWindow's AbstractGraphicsConfiguration, + // since the public API doesn't provide for a different GLCapabilities per context. + // 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); + } else { + CGL.CGLQueryPixelFormat(pixelFormat, cglInternalAttributeToken, 0, cglInternalAttributeToken.length, ivalues, 0); + } + for (int i = 0; i < cglInternalAttributeToken.length; i++) { + int attr = cglInternalAttributeToken[i]; + switch (attr) { + case CGL.kCGLPFAColorFloat: + caps.setPbufferFloatingPointBuffers(ivalues[i] != 0); + break; + + case CGL.NSOpenGLPFAPixelBuffer: + caps.setPBuffer(ivalues[i] != 0); + break; + + case CGL.NSOpenGLPFADoubleBuffer: + caps.setDoubleBuffered(ivalues[i] != 0); + break; + + case CGL.NSOpenGLPFAStereo: + caps.setStereo(ivalues[i] != 0); + break; + + case CGL.NSOpenGLPFAColorSize: + { + int bitSize = ivalues[i]; + if (bitSize == 32) + bitSize = 24; + bitSize /= 3; + caps.setRedBits(bitSize); + caps.setGreenBits(bitSize); + caps.setBlueBits(bitSize); + } + break; + + case CGL.NSOpenGLPFAAlphaSize: + caps.setAlphaBits(ivalues[i]); + break; + + case CGL.NSOpenGLPFADepthSize: + caps.setDepthBits(ivalues[i]); + break; + + case CGL.NSOpenGLPFAAccumSize: + { + int bitSize = ivalues[i] / 4; + caps.setAccumRedBits(bitSize); + caps.setAccumGreenBits(bitSize); + caps.setAccumBlueBits(bitSize); + caps.setAccumAlphaBits(bitSize); + } + break; + + case CGL.NSOpenGLPFAStencilSize: + caps.setStencilBits(ivalues[i]); + break; + + case CGL.NSOpenGLPFASampleBuffers: + caps.setSampleBuffers(ivalues[i] != 0); + break; + + case CGL.NSOpenGLPFASamples: + caps.setNumSamples(ivalues[i]); + break; + + default: + break; + } + } + + return caps; + } } diff --git a/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java index f59268b5e..7c2c7b751 100644 --- a/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java @@ -78,7 +78,7 @@ public class MacOSXCGLGraphicsConfigurationFactory extends GraphicsConfiguration capabilities = new GLCapabilities(null); } - return new MacOSXCGLGraphicsConfiguration(absScreen, (GLCapabilities)capabilities, (GLCapabilities)capabilities); + return new MacOSXCGLGraphicsConfiguration(absScreen, (GLCapabilities)capabilities, (GLCapabilities)capabilities, 0); } } diff --git a/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXExternalCGLContext.java b/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXExternalCGLContext.java index 7283122f4..03116f6bd 100644 --- a/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXExternalCGLContext.java +++ b/src/jogl/classes/com/sun/opengl/impl/macosx/cgl/MacOSXExternalCGLContext.java @@ -40,38 +40,75 @@ package com.sun.opengl.impl.macosx.cgl; import javax.media.opengl.*; -import javax.media.nativewindow.*; import com.sun.opengl.impl.*; +import javax.media.nativewindow.*; +import com.sun.nativewindow.impl.NullWindow; + public class MacOSXExternalCGLContext extends MacOSXCGLContext { private boolean firstMakeCurrent = true; private boolean created = true; private GLContext lastContext; - public MacOSXExternalCGLContext(AbstractGraphicsScreen absScreen) { - super(null, null); - - // FIXME: we don't have a "current context" primitive implemented - // yet on OS X. In the current implementation this would need to - // return an NSOpenGLContext*, but "external" toolkits are not - // guaranteed to be using the Cocoa OpenGL API. Additionally, if - // we switched this implementation to use the low-level CGL APIs, - // we would lose the ability to share textures and display lists - // between contexts since you need an NSOpenGLContext, not a - // CGLContextObj, in order to share textures and display lists - // between two NSOpenGLContexts. - // - // The ramifications here are that it is not currently possible to - // share textures and display lists between an OpenGL context - // created by JOGL and one created by a third-party library on OS - // X. - - // context = CGL.CGLGetCurrentContext(); - + private MacOSXExternalCGLContext(Drawable drawable, long cglContext, long nsContext) { + super(drawable, null); + drawable.setExternalCGLContext(this); + this.cglContext = cglContext; + this.nsContext = nsContext; GLContextShareSet.contextCreated(this); setGLFunctionAvailability(false); } + protected static MacOSXExternalCGLContext create(GLDrawableFactory factory, GLProfile glp) { + ((GLDrawableFactoryImpl)factory).lockToolkit(); + try { + long pixelFormat = 0; + long currentDrawable = 0; + long cglContext = 0; + long nsContext = CGL.getCurrentContext(); // Check: MacOSX 10.3 .. + if( 0 != nsContext ) { + currentDrawable = CGL.getNSView(nsContext); + long ctx = CGL.getCGLContext(nsContext); + if (ctx == 0) { + throw new GLException("Error: NULL cglContext of nsContext 0x" +Long.toHexString(nsContext)); + } + pixelFormat = CGL.CGLGetPixelFormat(ctx); + if(DEBUG) { + System.err.println("MacOSXExternalCGLContext Create nsContext 0x"+Long.toHexString(nsContext)+ + ", cglContext 0x"+Long.toHexString(ctx)+ + ", pixelFormat 0x"+Long.toHexString(pixelFormat)); + } + } else { + cglContext = CGL.CGLGetCurrentContext(); + if (cglContext == 0) { + throw new GLException("Error: current cglContext null, no nsContext"); + } + pixelFormat = CGL.CGLGetPixelFormat(cglContext); + if(DEBUG) { + System.err.println("MacOSXExternalCGLContext Create cglContext 0x"+Long.toHexString(cglContext)+ + ", pixelFormat 0x"+Long.toHexString(pixelFormat)); + } + } + + if (0 == pixelFormat) { + throw new GLException("Error: current pixelformat of current cglContext 0x"+Long.toHexString(cglContext)+" is null"); + } + GLCapabilities caps = MacOSXCGLGraphicsConfiguration.CGLPixelFormat2GLCapabilities(glp, pixelFormat); + if(DEBUG) { + System.err.println("MacOSXExternalCGLContext Create "+caps); + } + + AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(); + MacOSXCGLGraphicsConfiguration cfg = new MacOSXCGLGraphicsConfiguration(aScreen, caps, caps, pixelFormat); + + NullWindow nw = new NullWindow(cfg); + nw.setSurfaceHandle(currentDrawable); + return new MacOSXExternalCGLContext(new Drawable(factory, nw), cglContext, nsContext); + } finally { + ((GLDrawableFactoryImpl)factory).unlockToolkit(); + } + } + protected boolean create() { return true; } @@ -87,6 +124,16 @@ public class MacOSXExternalCGLContext extends MacOSXCGLContext { return super.makeCurrent(); } + protected void swapBuffers() { + DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + GLCapabilities caps = (GLCapabilities)config.getChosenCapabilities(); + if(caps.isOnscreen()) { + if (CGL.kCGLNoError != CGL.CGLFlushDrawable(cglContext)) { + throw new GLException("Error swapping buffers"); + } + } + } + public void release() throws GLException { super.release(); setCurrent(lastContext); @@ -114,11 +161,55 @@ public class MacOSXExternalCGLContext extends MacOSXCGLContext { } public void setOpenGLMode(int mode) { - if (mode != MacOSXCGLDrawable.NSOPENGL_MODE) + if (mode != MacOSXCGLDrawable.CGL_MODE) throw new GLException("OpenGL mode switching not supported for external GLContexts"); } public int getOpenGLMode() { - return MacOSXCGLDrawable.NSOPENGL_MODE; + return MacOSXCGLDrawable.CGL_MODE; + } + + // Need to provide the display connection to extension querying APIs + static class Drawable extends MacOSXCGLDrawable { + MacOSXExternalCGLContext extCtx; + + Drawable(GLDrawableFactory factory, NativeWindow comp) { + super(factory, comp, true); + } + + void setExternalCGLContext(MacOSXExternalCGLContext externalContext) { + extCtx = externalContext; + } + + public GLContext createContext(GLContext shareWith) { + throw new GLException("Should not call this"); + } + + public int getWidth() { + throw new GLException("Should not call this"); + } + + public int getHeight() { + throw new GLException("Should not call this"); + } + + public void setSize(int width, int height) { + throw new GLException("Should not call this"); + } + + protected void swapBuffersImpl() { + 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/com/sun/opengl/impl/x11/glx/X11ExternalGLXContext.java b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11ExternalGLXContext.java index 0603f1cf0..b509447f7 100755 --- a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11ExternalGLXContext.java +++ b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11ExternalGLXContext.java @@ -53,7 +53,6 @@ public class X11ExternalGLXContext extends X11GLXContext { private X11ExternalGLXContext(Drawable drawable, long context) { super(drawable, null); - this.drawable = drawable; this.context = context; GLContextShareSet.contextCreated(this); setGLFunctionAvailability(false); diff --git a/src/jogl/native/macosx/MacOSXCustomCGLCode.c b/src/jogl/native/macosx/MacOSXCustomCGLCode.c new file mode 100644 index 000000000..c29be889d --- /dev/null +++ b/src/jogl/native/macosx/MacOSXCustomCGLCode.c @@ -0,0 +1,24 @@ +#include <stdlib.h> + +#include <assert.h> + +#include </usr/include/machine/types.h> +#include "macosx-window-system.h" + +void CGLQueryPixelFormat(void* pixelFormat, int* iattrs, int niattrs, int* ivalues) { + CGLPixelFormatObj pix = (CGLPixelFormatObj) pixelFormat; + // FIXME: think about how specifying this might affect the API + int virtualScreen = 0; + + int i; + GLint value; + for (i = 0; i < niattrs && iattrs[i]>0; i++) { + CGLPixelFormatAttribute attr = (CGLPixelFormatAttribute) iattrs[i]; + if ( kCGLNoError == CGLDescribePixelFormat(pix, virtualScreen, attr, &value) ) { + ivalues[i] = value; + } else { + ivalues[i] = 0; + } + } +} + diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface.m index 350f6152f..5405ad4ee 100644 --- a/src/jogl/native/macosx/MacOSXWindowSystemInterface.m +++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface.m @@ -382,7 +382,7 @@ void* createPixelFormat(int* iattrs, int niattrs, int* ivalues) { int idx = 0; int i; - for (i = 0; i < niattrs; i++) { + for (i = 0; i < niattrs && iattrs[i]>0; i++) { int attr = iattrs[i]; switch (attr) { case NSOpenGLPFAPixelBuffer: @@ -451,7 +451,7 @@ void queryPixelFormat(void* pixelFormat, int* iattrs, int niattrs, int* ivalues) int virtualScreen = 0; int i; - for (i = 0; i < niattrs; i++) { + for (i = 0; i < niattrs && iattrs[i]>0; i++) { [fmt getValues: &tmp forAttribute: (NSOpenGLPixelFormatAttribute) iattrs[i] forVirtualScreen: virtualScreen]; @@ -524,8 +524,37 @@ void* createContext(void* shareContext, return nsContext; } -Bool makeCurrentContext(void* context) { - NSOpenGLContext *nsContext = (NSOpenGLContext*)context; +void * getCurrentContext() { + NSOpenGLContext *nsContext = NULL; + + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + nsContext = [NSOpenGLContext currentContext]; + [pool release]; + return nsContext;; +} + +void * getCGLContext(void* nsJContext) { + NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext; + void * cglContext = NULL; + + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + cglContext = [nsContext CGLContextObj]; + [pool release]; + return cglContext; +} + +void * getNSView(void* nsJContext) { + NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext; + void * view = NULL; + + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + view = [nsContext view]; + [pool release]; + return view; +} + +Bool makeCurrentContext(void* nsJContext) { + NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext; NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; [nsContext makeCurrentContext]; @@ -533,15 +562,21 @@ Bool makeCurrentContext(void* context) { return true; } -Bool clearCurrentContext(void* context) { +Bool clearCurrentContext(void* nsJContext) { + NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext; + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSOpenGLContext *currentNSContext = [NSOpenGLContext currentContext]; + if( currentNSContext != nsContext ) { + [nsContext makeCurrentContext]; + } [NSOpenGLContext clearCurrentContext]; [pool release]; return true; } -Bool deleteContext(void* context) { - NSOpenGLContext *nsContext = (NSOpenGLContext*)context; +Bool deleteContext(void* nsJContext) { + NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext; NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; [nsContext clearDrawable]; @@ -550,8 +585,8 @@ Bool deleteContext(void* context) { return true; } -Bool flushBuffer(void* context) { - NSOpenGLContext *nsContext = (NSOpenGLContext*)context; +Bool flushBuffer(void* nsJContext) { + NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext; NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; [nsContext flushBuffer]; @@ -559,14 +594,14 @@ Bool flushBuffer(void* context) { return true; } -void setContextOpacity(void* context, int opacity) { - NSOpenGLContext *nsContext = (NSOpenGLContext*)context; +void setContextOpacity(void* nsJContext, int opacity) { + NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext; [nsContext setValues:&opacity forParameter:NSOpenGLCPSurfaceOpacity]; } -void updateContext(void* context) { - NSOpenGLContext *nsContext = (NSOpenGLContext*)context; +void updateContext(void* nsJContext) { + NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext; NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; [nsContext update]; @@ -579,8 +614,8 @@ void copyContext(void* destContext, void* srcContext, int mask) { [dst copyAttributesFromContext: src withMask: mask]; } -void* updateContextRegister(void* context, void* view) { - NSOpenGLContext *nsContext = (NSOpenGLContext*)context; +void* updateContextRegister(void* nsJContext, void* view) { + NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext; NSView *nsView = (NSView*)view; NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @@ -590,7 +625,7 @@ void* updateContextRegister(void* context, void* view) { return NULL; } -void updateContextUnregister(void* context, void* view, void* updater) { +void updateContextUnregister(void* updater) { ContextUpdater *contextUpdater = (ContextUpdater *)updater; NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @@ -610,10 +645,8 @@ void* createPBuffer(int renderTarget, int internalFormat, int width, int height) return pBuffer; } -Bool destroyPBuffer(void* context, void* buffer) { +Bool destroyPBuffer(void* buffer) { /* FIXME: not clear whether we need to perform the clearDrawable below */ - /* FIXME: remove the context argument -- don't need it any more */ - /* NSOpenGLContext *nsContext = (NSOpenGLContext*)context; */ NSOpenGLPixelBuffer *pBuffer = (NSOpenGLPixelBuffer*)buffer; NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @@ -628,8 +661,8 @@ Bool destroyPBuffer(void* context, void* buffer) { return true; } -void setContextPBuffer(void* context, void* buffer) { - NSOpenGLContext *nsContext = (NSOpenGLContext*)context; +void setContextPBuffer(void* nsJContext, void* buffer) { + NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext; NSOpenGLPixelBuffer *pBuffer = (NSOpenGLPixelBuffer*)buffer; NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @@ -640,8 +673,8 @@ void setContextPBuffer(void* context, void* buffer) { [pool release]; } -void setContextTextureImageToPBuffer(void* context, void* buffer, int colorBuffer) { - NSOpenGLContext *nsContext = (NSOpenGLContext*)context; +void setContextTextureImageToPBuffer(void* nsJContext, void* buffer, int colorBuffer) { + NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext; NSOpenGLPixelBuffer *pBuffer = (NSOpenGLPixelBuffer*)buffer; NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @@ -686,8 +719,8 @@ void* getProcAddress(const char *procname) { return NULL; } -void setSwapInterval(void* context, int interval) { - NSOpenGLContext *nsContext = (NSOpenGLContext*)context; +void setSwapInterval(void* nsJContext, int interval) { + NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext; long swapInterval = interval; [nsContext setValues: &swapInterval forParameter: NSOpenGLCPSwapInterval]; } |