diff options
author | Kenneth Russel <[email protected]> | 2003-07-08 09:20:04 +0000 |
---|---|---|
committer | Kenneth Russel <[email protected]> | 2003-07-08 09:20:04 +0000 |
commit | 4f936be964c9e8613a5e43e1d88490ff7f550ec9 (patch) | |
tree | 74a2c01c6093d89ac123d08642b11a2007cc99e2 /src/net/java/games | |
parent | 93d272a0525ec57aa3cd584f15cde6cf2a637e0c (diff) |
Added sharing of display lists and textures among OpenGL contexts
through new methods in GLDrawableFactory; GLContext has not been
exposed in the public API. Tested with new simple TestContextSharing
demonstration on Windows, Linux and Mac OS X.
git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/trunk@18 232f8b59-042b-4e1e-8c03-345bb8c30851
Diffstat (limited to 'src/net/java/games')
23 files changed, 444 insertions, 73 deletions
diff --git a/src/net/java/games/jogl/GLCanvas.java b/src/net/java/games/jogl/GLCanvas.java index adee0315d..474dd238d 100644 --- a/src/net/java/games/jogl/GLCanvas.java +++ b/src/net/java/games/jogl/GLCanvas.java @@ -65,14 +65,21 @@ public final class GLCanvas extends Canvas implements GLDrawable { // This workaround makes things quite a bit slower private static final boolean isOSX = System.getProperty("os.name").equals("Mac OS X"); - GLCanvas(GLCapabilities capabilities, GLCapabilitiesChooser chooser) { + GLCanvas(GLCapabilities capabilities, + GLCapabilitiesChooser chooser, + GLDrawable shareWith) { super(); - context = GLContextFactory.getFactory().createGLContext(this, capabilities, chooser); + context = GLContextFactory.getFactory().createGLContext(this, capabilities, chooser, + GLContextHelper.getContext(shareWith)); } - GLCanvas(GraphicsConfiguration config, GLCapabilities capabilities, GLCapabilitiesChooser chooser) { + GLCanvas(GraphicsConfiguration config, + GLCapabilities capabilities, + GLCapabilitiesChooser chooser, + GLDrawable shareWith) { super(config); - context = GLContextFactory.getFactory().createGLContext(this, capabilities, chooser); + context = GLContextFactory.getFactory().createGLContext(this, capabilities, chooser, + GLContextHelper.getContext(shareWith)); } public void display() { @@ -171,6 +178,10 @@ public final class GLCanvas extends Canvas implements GLDrawable { return new GLPbufferImpl(context.createPbufferContext(capabilities, initialWidth, initialHeight)); } + GLContext getContext() { + return context; + } + //---------------------------------------------------------------------- // Internals only below this point // diff --git a/src/net/java/games/jogl/GLContextHelper.java b/src/net/java/games/jogl/GLContextHelper.java new file mode 100644 index 000000000..d99e17d39 --- /dev/null +++ b/src/net/java/games/jogl/GLContextHelper.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package net.java.games.jogl; + +import net.java.games.jogl.impl.*; + +/** This package-private class helps extract a GLContext from a + GLDrawable. The getContext() method can not be placed in the + public API of GLDrawable without exposing the GLContext class to + the public API, which is not desired. */ + +class GLContextHelper { + static GLContext getContext(GLDrawable drawable) throws GLException { + if (drawable == null) { + return null; + } + + if (drawable instanceof GLCanvas) { + return ((GLCanvas) drawable).getContext(); + } else if (drawable instanceof GLJPanel) { + return ((GLJPanel) drawable).getContext(); + } else if (drawable instanceof GLPbufferImpl) { + return ((GLPbufferImpl) drawable).getContext(); + } else { + throw new GLException( + "Sharing of contexts and display lists not supported among user-defined GLDrawables " + + "(unknown drawable type " + drawable.getClass().getName() + ")" + ); + } + } +} diff --git a/src/net/java/games/jogl/GLDrawableFactory.java b/src/net/java/games/jogl/GLDrawableFactory.java index 17d5779df..79109771c 100644 --- a/src/net/java/games/jogl/GLDrawableFactory.java +++ b/src/net/java/games/jogl/GLDrawableFactory.java @@ -77,13 +77,36 @@ public class GLDrawableFactory { /** Creates a {@link GLCanvas} with the specified capabilities using the default capabilities selection algorithm. */ public GLCanvas createGLCanvas(GLCapabilities capabilities) { - return createGLCanvas(capabilities, null); + return createGLCanvas(capabilities, null, null); + } + + /** Creates a {@link GLCanvas} with the specified capabilities using + the default capabilities selection algorithm. The canvas will + share textures and display lists with the specified {@link + GLDrawable}; the drawable must either be null or have been + fabricated from this factory or by classes in this package. A + null drawable indicates no sharing. */ + public GLCanvas createGLCanvas(GLCapabilities capabilities, GLDrawable shareWith) { + return createGLCanvas(capabilities, null, shareWith); } /** Creates a {@link GLCanvas} with the specified capabilities using the supplied capabilities selection algorithm. A null chooser is equivalent to using the {@link DefaultGLCapabilitiesChooser}. */ public GLCanvas createGLCanvas(GLCapabilities capabilities, GLCapabilitiesChooser chooser) { + return createGLCanvas(capabilities, chooser, null); + } + + /** Creates a {@link GLCanvas} with the specified capabilities using + the supplied capabilities selection algorithm. A null chooser is + equivalent to using the {@link DefaultGLCapabilitiesChooser}. + The canvas will share textures and display lists with the + specified {@link GLDrawable}; the drawable must either be null + or have been fabricated from this factory or by classes in this + package. A null drawable indicates no sharing. */ + public GLCanvas createGLCanvas(GLCapabilities capabilities, + GLCapabilitiesChooser chooser, + GLDrawable shareWith) { // FIXME: do we need to select a GraphicsConfiguration here as in // GL4Java? If so, this class will have to be made abstract and // we'll have to provide hooks into this package to get at the @@ -91,22 +114,45 @@ public class GLDrawableFactory { if (chooser == null) { chooser = new DefaultGLCapabilitiesChooser(); } - return new GLCanvas(capabilities, chooser); + return new GLCanvas(capabilities, chooser, shareWith); } /** Creates a {@link GLJPanel} with the specified capabilities using the default capabilities selection algorithm. */ public GLJPanel createGLJPanel(GLCapabilities capabilities) { - return createGLJPanel(capabilities, null); + return createGLJPanel(capabilities, null, null); + } + + /** Creates a {@link GLJPanel} with the specified capabilities using + the default capabilities selection algorithm. The panel will + share textures and display lists with the specified {@link + GLDrawable}; the drawable must either be null or have been + fabricated from this factory or by classes in this package. A + null drawable indicates no sharing. */ + public GLJPanel createGLJPanel(GLCapabilities capabilities, GLDrawable shareWith) { + return createGLJPanel(capabilities, null, shareWith); } /** Creates a {@link GLJPanel} with the specified capabilities using the supplied capabilities selection algorithm. A null chooser is equivalent to using the {@link DefaultGLCapabilitiesChooser}. */ public GLJPanel createGLJPanel(GLCapabilities capabilities, GLCapabilitiesChooser chooser) { + return createGLJPanel(capabilities, chooser, null); + } + + /** Creates a {@link GLJPanel} with the specified capabilities using + the supplied capabilities selection algorithm. A null chooser is + equivalent to using the {@link DefaultGLCapabilitiesChooser}. + The panel will share textures and display lists with the + specified {@link GLDrawable}; the drawable must either be null + or have been fabricated from this factory or by classes in this + package. A null drawable indicates no sharing. */ + public GLJPanel createGLJPanel(GLCapabilities capabilities, + GLCapabilitiesChooser chooser, + GLDrawable shareWith) { if (chooser == null) { chooser = new DefaultGLCapabilitiesChooser(); } - return new GLJPanel(capabilities, chooser); + return new GLJPanel(capabilities, chooser, shareWith); } } diff --git a/src/net/java/games/jogl/GLJPanel.java b/src/net/java/games/jogl/GLJPanel.java index 787a4a8cc..07952eef3 100644 --- a/src/net/java/games/jogl/GLJPanel.java +++ b/src/net/java/games/jogl/GLJPanel.java @@ -64,8 +64,6 @@ import net.java.games.jogl.impl.*; them. */ public final class GLJPanel extends JPanel implements GLDrawable { - private GLCapabilities capabilities; - private GLCapabilitiesChooser chooser; private GLDrawableHelper drawableHelper = new GLDrawableHelper(); private GLContext context; private BufferedImage offscreenImage; @@ -86,10 +84,10 @@ public final class GLJPanel extends JPanel implements GLDrawable { private int[] skippixels = new int[1]; private int[] alignment = new int[1]; - GLJPanel(GLCapabilities capabilities, GLCapabilitiesChooser chooser) { + GLJPanel(GLCapabilities capabilities, GLCapabilitiesChooser chooser, GLDrawable shareWith) { super(); - this.capabilities = capabilities; - this.chooser = chooser; + context = GLContextFactory.getFactory().createGLContext(null, capabilities, chooser, + GLContextHelper.getContext(shareWith)); } public void display() { @@ -110,7 +108,7 @@ public final class GLJPanel extends JPanel implements GLDrawable { be invoked by applications directly. */ public void paintComponent(Graphics g) { displayAction.setGraphics(g); - getContext().invokeGL(displayAction, false, initAction); + context.invokeGL(displayAction, false, initAction); synchronized(semaphore) { repaintDone = true; semaphore.notifyAll(); @@ -129,8 +127,8 @@ public final class GLJPanel extends JPanel implements GLDrawable { final int fy = 0; final int fwidth = width; final int fheight = height; - getContext().resizeOffscreenContext(width, height); - getContext().invokeGL(new Runnable() { + context.resizeOffscreenContext(width, height); + context.invokeGL(new Runnable() { public void run() { getGL().glViewport(fx, fy, fwidth, fheight); drawableHelper.reshape(GLJPanel.this, fx, fy, fwidth, fheight); @@ -153,23 +151,19 @@ public final class GLJPanel extends JPanel implements GLDrawable { } public GL getGL() { - // must use getContext() because context is created lazily - return getContext().getGL(); + return context.getGL(); } public void setGL(GL gl) { - // must use getContext() because context is created lazily - getContext().setGL(gl); + context.setGL(gl); } public GLU getGLU() { - // must use getContext() because context is created lazily - return getContext().getGLU(); + return context.getGLU(); } public void setGLU(GLU glu) { - // must use getContext() because context is created lazily - getContext().setGLU(glu); + context.setGLU(glu); } public void setRenderingThread(Thread currentThreadOrNull) throws GLException { @@ -178,7 +172,7 @@ public final class GLJPanel extends JPanel implements GLDrawable { } public Thread getRenderingThread() { - return getContext().getRenderingThread(); + return context.getRenderingThread(); } public void setNoAutoRedrawMode(boolean noAutoRedraws) { @@ -201,17 +195,14 @@ public final class GLJPanel extends JPanel implements GLDrawable { throw new GLException("Not supported"); } + GLContext getContext() { + return context; + } + //---------------------------------------------------------------------- // Internals only below this point // - private GLContext getContext() { - if (context == null) { - context = GLContextFactory.getFactory().createGLContext(null, capabilities, chooser); - } - return context; - } - class InitAction implements Runnable { public void run() { drawableHelper.init(GLJPanel.this); @@ -230,7 +221,7 @@ public final class GLJPanel extends JPanel implements GLDrawable { drawableHelper.display(GLJPanel.this); // Must now copy pixels from offscreen context into surface if (offscreenImage == null) { - int awtFormat = getContext().getOffscreenContextBufferedImageType(); + int awtFormat = context.getOffscreenContextBufferedImageType(); offscreenImage = new BufferedImage(getWidth(), getHeight(), awtFormat); switch (awtFormat) { case BufferedImage.TYPE_3BYTE_BGR: diff --git a/src/net/java/games/jogl/impl/GLContext.java b/src/net/java/games/jogl/impl/GLContext.java index eb7d21988..db8842b39 100644 --- a/src/net/java/games/jogl/impl/GLContext.java +++ b/src/net/java/games/jogl/impl/GLContext.java @@ -113,7 +113,10 @@ public abstract class GLContext { // moment in time protected FunctionAvailabilityCache functionAvailability; - public GLContext(Component component, GLCapabilities capabilities, GLCapabilitiesChooser chooser) { + public GLContext(Component component, + GLCapabilities capabilities, + GLCapabilitiesChooser chooser, + GLContext shareWith) { this.component = component; try { this.capabilities = (GLCapabilities) capabilities.clone(); @@ -123,6 +126,9 @@ public abstract class GLContext { this.chooser = chooser; gl = createGL(); functionAvailability = new FunctionAvailabilityCache(this); + if (shareWith != null) { + GLContextShareSet.registerSharing(this, shareWith); + } } /** Runs the given runnable with this OpenGL context valid. */ @@ -434,7 +440,12 @@ public abstract class GLContext { /** Dynamically looks up the given function. */ protected abstract long dynamicLookupFunction(String glFuncName); - + + /** Indicates whether the underlying OpenGL context has been + created. This is used to manage sharing of display lists and + textures between contexts. */ + public abstract boolean isCreated(); + //---------------------------------------------------------------------- // Internals only below this point // diff --git a/src/net/java/games/jogl/impl/GLContextFactory.java b/src/net/java/games/jogl/impl/GLContextFactory.java index a4797c6eb..b686d3543 100644 --- a/src/net/java/games/jogl/impl/GLContextFactory.java +++ b/src/net/java/games/jogl/impl/GLContextFactory.java @@ -86,5 +86,6 @@ public abstract class GLContextFactory { public abstract GLContext createGLContext(Component component, GLCapabilities capabilities, - GLCapabilitiesChooser chooser); + GLCapabilitiesChooser chooser, + GLContext shareWith); } diff --git a/src/net/java/games/jogl/impl/GLContextShareSet.java b/src/net/java/games/jogl/impl/GLContextShareSet.java new file mode 100644 index 000000000..73ee86499 --- /dev/null +++ b/src/net/java/games/jogl/impl/GLContextShareSet.java @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package net.java.games.jogl.impl; + +import java.lang.ref.*; +import java.util.*; + +/** Provides a mechanism by which OpenGL contexts can share textures + and display lists in the face of multithreading and asynchronous + context creation as is inherent in the AWT and Swing. */ + +public class GLContextShareSet { + // This class is implemented with a WeakHashMap that goes from the + // contexts as keys to a complex data structure as value that tracks + // context creation and deletion. + + private static Map/*<GLContext, WeakReference<ShareSet>>*/ shareMap = new WeakHashMap(); + private static Object dummyValue = new Object(); + + private static class ShareSet { + private Map allShares = new WeakHashMap(); + private Map createdShares = new WeakHashMap(); + private Map destroyedShares = new WeakHashMap(); + + public void add(GLContext ctx) { + if (allShares.put(ctx, dummyValue) == null) { + if (ctx.isCreated()) { + createdShares.put(ctx, dummyValue); + } else { + destroyedShares.put(ctx, dummyValue); + } + } + } + + public GLContext getCreatedShare(GLContext ignore) { + for (Iterator iter = createdShares.keySet().iterator(); iter.hasNext(); ) { + GLContext ctx = (GLContext) iter.next(); + if (ctx != ignore) { + return ctx; + } + } + return null; + } + + public void contextCreated(GLContext ctx) { + Object res = destroyedShares.remove(ctx); + assert res != null : "State of ShareSet corrupted; thought context " + + ctx + " should have been in destroyed set but wasn't"; + res = createdShares.put(ctx, dummyValue); + assert res == null : "State of ShareSet corrupted; thought context " + + ctx + " shouldn't have been in created set but was"; + } + + public void contextDestroyed(GLContext ctx) { + Object res = createdShares.remove(ctx); + assert res != null : "State of ShareSet corrupted; thought context " + + ctx + " should have been in created set but wasn't"; + res = destroyedShares.put(ctx, dummyValue); + assert res == null : "State of ShareSet corrupted; thought context " + + ctx + " shouldn't have been in destroyed set but was"; + } + } + + + /** Indicate that contexts <code>share1</code> and + <code>share2</code> will share textures and display lists. */ + public static synchronized void registerSharing(GLContext share1, GLContext share2) { + ShareSet share = entryFor(share1); + if (share == null) { + share = entryFor(share2); + } + if (share == null) { + share = new ShareSet(); + } + share.add(share1); + share.add(share2); + addEntry(share1, share); + addEntry(share2, share); + } + + public static synchronized GLContext getShareContext(GLContext contextToCreate) { + ShareSet share = entryFor(contextToCreate); + if (share == null) { + return null; + } + return share.getCreatedShare(contextToCreate); + } + + public static synchronized void contextCreated(GLContext context) { + ShareSet share = entryFor(context); + if (share != null) { + share.contextCreated(context); + } + } + + public static synchronized void contextDestroyed(GLContext context) { + ShareSet share = entryFor(context); + if (share != null) { + share.contextDestroyed(context); + } + } + + //---------------------------------------------------------------------- + // Internals only below this point + // + + private static ShareSet entryFor(GLContext context) { + return (ShareSet) shareMap.get(context); + } + + private static void addEntry(GLContext context, ShareSet share) { + if (shareMap.get(context) == null) { + shareMap.put(context, share); + } + } +} diff --git a/src/net/java/games/jogl/impl/GLPbufferImpl.java b/src/net/java/games/jogl/impl/GLPbufferImpl.java index d510a9c31..860fc8422 100644 --- a/src/net/java/games/jogl/impl/GLPbufferImpl.java +++ b/src/net/java/games/jogl/impl/GLPbufferImpl.java @@ -143,6 +143,10 @@ public class GLPbufferImpl implements GLPbuffer { context.releasePbufferFromTexture(); } + public GLContext getContext() { + return context; + } + //---------------------------------------------------------------------- // No-ops for ComponentEvents // diff --git a/src/net/java/games/jogl/impl/macosx/MacOSXDummyGLContext.java b/src/net/java/games/jogl/impl/macosx/MacOSXDummyGLContext.java index 05ed7d9dc..02ca808c9 100644 --- a/src/net/java/games/jogl/impl/macosx/MacOSXDummyGLContext.java +++ b/src/net/java/games/jogl/impl/macosx/MacOSXDummyGLContext.java @@ -54,7 +54,7 @@ class MacOSXDummyGLContext extends MacOSXGLContext private MacOSXGLImpl gl; MacOSXDummyGLContext(MacOSXGLImpl gl) { - super(null, null, null); + super(null, null, null, null); this.gl = gl; } diff --git a/src/net/java/games/jogl/impl/macosx/MacOSXGLContext.java b/src/net/java/games/jogl/impl/macosx/MacOSXGLContext.java index d35392ac1..53e5986ec 100644 --- a/src/net/java/games/jogl/impl/macosx/MacOSXGLContext.java +++ b/src/net/java/games/jogl/impl/macosx/MacOSXGLContext.java @@ -53,9 +53,12 @@ public abstract class MacOSXGLContext extends GLContext // OpenGL functions. private GLProcAddressTable glProcAddressTable; - public MacOSXGLContext(Component component, GLCapabilities capabilities, GLCapabilitiesChooser chooser) + public MacOSXGLContext(Component component, + GLCapabilities capabilities, + GLCapabilitiesChooser chooser, + GLContext shareWith) { - super(component, capabilities, chooser); + super(component, capabilities, chooser, shareWith); } protected String mapToRealGLFunctionName(String glFunctionName) @@ -96,6 +99,10 @@ public abstract class MacOSXGLContext extends GLContext protected long dynamicLookupFunction(String glFuncName) { return CGL.getProcAddress(glFuncName); } + + public boolean isCreated() { + return (nsContext != 0); + } protected void resetGLFunctionAvailability() { @@ -125,6 +132,10 @@ public abstract class MacOSXGLContext extends GLContext // Internals only below this point // + protected long getNSContext() { + return nsContext; + } + protected JAWT getJAWT() { if (jawt == null) diff --git a/src/net/java/games/jogl/impl/macosx/MacOSXGLContextFactory.java b/src/net/java/games/jogl/impl/macosx/MacOSXGLContextFactory.java index 323f75480..f3e002c22 100644 --- a/src/net/java/games/jogl/impl/macosx/MacOSXGLContextFactory.java +++ b/src/net/java/games/jogl/impl/macosx/MacOSXGLContextFactory.java @@ -44,11 +44,14 @@ import net.java.games.jogl.*; import net.java.games.jogl.impl.*; public class MacOSXGLContextFactory extends GLContextFactory { - public GLContext createGLContext(Component component, GLCapabilities capabilities, GLCapabilitiesChooser chooser) { + public GLContext createGLContext(Component component, + GLCapabilities capabilities, + GLCapabilitiesChooser chooser, + GLContext shareWith) { if (component != null) { - return new MacOSXOnscreenGLContext(component, capabilities, chooser); + return new MacOSXOnscreenGLContext(component, capabilities, chooser, shareWith); } else { - return new MacOSXOffscreenGLContext(capabilities, chooser); + return new MacOSXOffscreenGLContext(capabilities, chooser, shareWith); } } } diff --git a/src/net/java/games/jogl/impl/macosx/MacOSXOffscreenGLContext.java b/src/net/java/games/jogl/impl/macosx/MacOSXOffscreenGLContext.java index 46d754462..e9f3bed24 100644 --- a/src/net/java/games/jogl/impl/macosx/MacOSXOffscreenGLContext.java +++ b/src/net/java/games/jogl/impl/macosx/MacOSXOffscreenGLContext.java @@ -49,8 +49,10 @@ public class MacOSXOffscreenGLContext extends MacOSXGLContext private int width; private int height; - public MacOSXOffscreenGLContext(GLCapabilities capabilities, GLCapabilitiesChooser chooser) { - super(null, capabilities, chooser); + public MacOSXOffscreenGLContext(GLCapabilities capabilities, + GLCapabilitiesChooser chooser, + GLContext shareWith) { + super(null, capabilities, chooser, shareWith); System.err.println("MacOSXOffscreenGLContext not implemented yet"); } diff --git a/src/net/java/games/jogl/impl/macosx/MacOSXOnscreenGLContext.java b/src/net/java/games/jogl/impl/macosx/MacOSXOnscreenGLContext.java index 5b0df9052..8f75fd561 100644 --- a/src/net/java/games/jogl/impl/macosx/MacOSXOnscreenGLContext.java +++ b/src/net/java/games/jogl/impl/macosx/MacOSXOnscreenGLContext.java @@ -53,8 +53,11 @@ public class MacOSXOnscreenGLContext extends MacOSXGLContext { private long nsView; // NSView private Runnable myDeferredReshapeAction; - public MacOSXOnscreenGLContext(Component component, GLCapabilities capabilities, GLCapabilitiesChooser chooser) { - super(component, capabilities, chooser); + public MacOSXOnscreenGLContext(Component component, + GLCapabilities capabilities, + GLCapabilitiesChooser chooser, + GLContext shareWith) { + super(component, capabilities, chooser, shareWith); } public synchronized void invokeGL(final Runnable runnable, boolean isReshape, Runnable initAction) throws GLException { @@ -121,12 +124,19 @@ public class MacOSXOnscreenGLContext extends MacOSXGLContext { } protected void create() { - nsContext = CGL.createContext(nsView); + MacOSXGLContext other = (MacOSXGLContext) GLContextShareSet.getShareContext(this); + long share = 0; + if (other != null) { + share = other.getNSContext(); + if (share == 0) { + throw new GLException("GLContextShareSet returned an invalid OpenGL context"); + } + } + nsContext = CGL.createContext(nsView, share); if (nsContext == 0) { throw new GLException("Error creating nsContext"); } - // FIXME - //choosePixelFormatAndCreateContext(true); + GLContextShareSet.contextCreated(this); } protected synchronized boolean makeCurrent(Runnable initAction) throws GLException { diff --git a/src/net/java/games/jogl/impl/windows/WindowsGLContext.java b/src/net/java/games/jogl/impl/windows/WindowsGLContext.java index 5a6021acf..44ff97ffc 100644 --- a/src/net/java/games/jogl/impl/windows/WindowsGLContext.java +++ b/src/net/java/games/jogl/impl/windows/WindowsGLContext.java @@ -69,8 +69,11 @@ public abstract class WindowsGLContext extends GLContext { extensionNameMap.put("GL_ARB_pixel_format", "WGL_ARB_pixel_format"); } - public WindowsGLContext(Component component, GLCapabilities capabilities, GLCapabilitiesChooser chooser) { - super(component, capabilities, chooser); + public WindowsGLContext(Component component, + GLCapabilities capabilities, + GLCapabilitiesChooser chooser, + GLContext shareWith) { + super(component, capabilities, chooser, shareWith); } protected GL createGL() @@ -103,7 +106,7 @@ public abstract class WindowsGLContext extends GLContext { public abstract boolean offscreenImageNeedsVerticalFlip(); /** - * Creates and initializes an appropriate OpenGl context. Should only be + * Creates and initializes an appropriate OpenGL context. Should only be * called by {@link makeCurrent(Runnable)}. */ protected abstract void create(); @@ -124,6 +127,20 @@ public abstract class WindowsGLContext extends GLContext { if (created) { resetGLFunctionAvailability(); + // Windows can set up sharing of display lists after creation time + WindowsGLContext other = (WindowsGLContext) GLContextShareSet.getShareContext(this); + if (other != null) { + long hglrc2 = other.getHGLRC(); + if (hglrc2 == 0) { + throw new GLException("GLContextShareSet returned an invalid OpenGL context"); + } + if (!WGL.wglShareLists(hglrc2, hglrc)) { + throw new GLException("wglShareLists(0x" + Long.toHexString(hglrc2) + + ", 0x" + Long.toHexString(hglrc) + ") failed"); + } + } + GLContextShareSet.contextCreated(this); + initAction.run(); } return true; @@ -152,6 +169,10 @@ public abstract class WindowsGLContext extends GLContext { return res; } + public boolean isCreated() { + return (hglrc != 0); + } + protected void resetGLFunctionAvailability() { super.resetGLFunctionAvailability(); if (DEBUG) { @@ -270,6 +291,10 @@ public abstract class WindowsGLContext extends GLContext { } } + protected long getHGLRC() { + return hglrc; + } + static PIXELFORMATDESCRIPTOR glCapabilities2PFD(GLCapabilities caps, boolean onscreen) { int colorDepth = (caps.getRedBits() + caps.getGreenBits() + diff --git a/src/net/java/games/jogl/impl/windows/WindowsGLContextFactory.java b/src/net/java/games/jogl/impl/windows/WindowsGLContextFactory.java index 15e622efb..cfad54025 100644 --- a/src/net/java/games/jogl/impl/windows/WindowsGLContextFactory.java +++ b/src/net/java/games/jogl/impl/windows/WindowsGLContextFactory.java @@ -46,11 +46,12 @@ import net.java.games.jogl.impl.*; public class WindowsGLContextFactory extends GLContextFactory { public GLContext createGLContext(Component component, GLCapabilities capabilities, - GLCapabilitiesChooser chooser) { + GLCapabilitiesChooser chooser, + GLContext shareWith) { if (component != null) { - return new WindowsOnscreenGLContext(component, capabilities, chooser); + return new WindowsOnscreenGLContext(component, capabilities, chooser, shareWith); } else { - return new WindowsOffscreenGLContext(capabilities, chooser); + return new WindowsOffscreenGLContext(capabilities, chooser, shareWith); } } } diff --git a/src/net/java/games/jogl/impl/windows/WindowsOffscreenGLContext.java b/src/net/java/games/jogl/impl/windows/WindowsOffscreenGLContext.java index 727517e63..e26060b65 100644 --- a/src/net/java/games/jogl/impl/windows/WindowsOffscreenGLContext.java +++ b/src/net/java/games/jogl/impl/windows/WindowsOffscreenGLContext.java @@ -50,8 +50,10 @@ public class WindowsOffscreenGLContext extends WindowsGLContext { private int width; private int height; - public WindowsOffscreenGLContext(GLCapabilities capabilities, GLCapabilitiesChooser chooser) { - super(null, capabilities, chooser); + public WindowsOffscreenGLContext(GLCapabilities capabilities, + GLCapabilitiesChooser chooser, + GLContext shareWith) { + super(null, capabilities, chooser, shareWith); } protected GL createGL() @@ -165,5 +167,6 @@ public class WindowsOffscreenGLContext extends WindowsGLContext { origbitmap = 0; hbitmap = 0; hdc = 0; + GLContextShareSet.contextDestroyed(this); } } diff --git a/src/net/java/games/jogl/impl/windows/WindowsOnscreenGLContext.java b/src/net/java/games/jogl/impl/windows/WindowsOnscreenGLContext.java index a5b7519cf..d97cded65 100644 --- a/src/net/java/games/jogl/impl/windows/WindowsOnscreenGLContext.java +++ b/src/net/java/games/jogl/impl/windows/WindowsOnscreenGLContext.java @@ -54,8 +54,11 @@ public class WindowsOnscreenGLContext extends WindowsGLContext { // Variables for pbuffer support List pbuffersToInstantiate = new ArrayList(); - public WindowsOnscreenGLContext(Component component, GLCapabilities capabilities, GLCapabilitiesChooser chooser) { - super(component, capabilities, chooser); + public WindowsOnscreenGLContext(Component component, + GLCapabilities capabilities, + GLCapabilitiesChooser chooser, + GLContext shareWith) { + super(component, capabilities, chooser, shareWith); } protected GL createGL() diff --git a/src/net/java/games/jogl/impl/windows/WindowsPbufferGLContext.java b/src/net/java/games/jogl/impl/windows/WindowsPbufferGLContext.java index 484c8f8af..18e954b2a 100644 --- a/src/net/java/games/jogl/impl/windows/WindowsPbufferGLContext.java +++ b/src/net/java/games/jogl/impl/windows/WindowsPbufferGLContext.java @@ -67,7 +67,7 @@ public class WindowsPbufferGLContext extends WindowsGLContext { private int texture; // actual texture object public WindowsPbufferGLContext(GLCapabilities capabilities, int initialWidth, int initialHeight) { - super(null, capabilities, null); + super(null, capabilities, null, null); this.initWidth = initialWidth; this.initHeight = initialHeight; if (initWidth <= 0 || initHeight <= 0) { diff --git a/src/net/java/games/jogl/impl/x11/X11GLContext.java b/src/net/java/games/jogl/impl/x11/X11GLContext.java index ec430bfe8..3fb142bff 100644 --- a/src/net/java/games/jogl/impl/x11/X11GLContext.java +++ b/src/net/java/games/jogl/impl/x11/X11GLContext.java @@ -65,8 +65,11 @@ public abstract class X11GLContext extends GLContext { functionNameMap.put("glFreeMemoryNV", "glXFreeMemoryNV"); } - public X11GLContext(Component component, GLCapabilities capabilities, GLCapabilitiesChooser chooser) { - super(component, capabilities, chooser); + public X11GLContext(Component component, + GLCapabilities capabilities, + GLCapabilitiesChooser chooser, + GLContext shareWith) { + super(component, capabilities, chooser, shareWith); } protected GL createGL() @@ -162,6 +165,10 @@ public abstract class X11GLContext extends GLContext { return res; } + public boolean isCreated() { + return (context != 0); + } + protected void resetGLFunctionAvailability() { super.resetGLFunctionAvailability(); if (DEBUG) { @@ -287,20 +294,34 @@ public abstract class X11GLContext extends GLContext { } protected long createContext(XVisualInfo vis, boolean onscreen) { - // FIXME: support sharing of display lists between contexts - return GLX.glXCreateContext(display, vis, 0, onscreen); + X11GLContext other = (X11GLContext) GLContextShareSet.getShareContext(this); + long share = 0; + if (other != null) { + share = other.getContext(); + if (share == 0) { + throw new GLException("GLContextShareSet returned an invalid OpenGL context"); + } + } + long res = GLX.glXCreateContext(display, vis, share, onscreen); + if (res != 0) { + GLContextShareSet.contextCreated(this); + } + return res; } // Helper routine for the overridden create() to call protected void chooseVisualAndCreateContext(boolean onscreen) { XVisualInfo vis = chooseVisual(); - // FIXME: support sharing of display lists between contexts context = createContext(vis, onscreen); if (context == 0) { throw new GLException("Unable to create OpenGL context"); } } + protected long getContext() { + return context; + } + protected int[] glCapabilities2AttribList(GLCapabilities caps) { int colorDepth = (caps.getRedBits() + caps.getGreenBits() + diff --git a/src/net/java/games/jogl/impl/x11/X11GLContextFactory.java b/src/net/java/games/jogl/impl/x11/X11GLContextFactory.java index cf1e4be25..5a8298753 100644 --- a/src/net/java/games/jogl/impl/x11/X11GLContextFactory.java +++ b/src/net/java/games/jogl/impl/x11/X11GLContextFactory.java @@ -46,11 +46,12 @@ import net.java.games.jogl.impl.*; public class X11GLContextFactory extends GLContextFactory { public GLContext createGLContext(Component component, GLCapabilities capabilities, - GLCapabilitiesChooser chooser) { + GLCapabilitiesChooser chooser, + GLContext shareWith) { if (component != null) { - return new X11OnscreenGLContext(component, capabilities, chooser); + return new X11OnscreenGLContext(component, capabilities, chooser, shareWith); } else { - return new X11OffscreenGLContext(capabilities, chooser); + return new X11OffscreenGLContext(capabilities, chooser, shareWith); } } } diff --git a/src/net/java/games/jogl/impl/x11/X11OffscreenGLContext.java b/src/net/java/games/jogl/impl/x11/X11OffscreenGLContext.java index 62fd380ee..727c8f23d 100644 --- a/src/net/java/games/jogl/impl/x11/X11OffscreenGLContext.java +++ b/src/net/java/games/jogl/impl/x11/X11OffscreenGLContext.java @@ -53,8 +53,10 @@ public class X11OffscreenGLContext extends X11GLContext { // Display connection for use by all offscreen surfaces private long staticDisplay; - public X11OffscreenGLContext(GLCapabilities capabilities, GLCapabilitiesChooser chooser) { - super(null, capabilities, chooser); + public X11OffscreenGLContext(GLCapabilities capabilities, + GLCapabilitiesChooser chooser, + GLContext shareWith) { + super(null, capabilities, chooser, shareWith); } protected GL createGL() @@ -173,5 +175,6 @@ public class X11OffscreenGLContext extends X11GLContext { context = 0; drawable = 0; pixmap = 0; + GLContextShareSet.contextDestroyed(this); } } diff --git a/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java b/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java index 385874da7..882e9b3f1 100644 --- a/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java +++ b/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java @@ -54,8 +54,11 @@ public class X11OnscreenGLContext extends X11GLContext { // Variables for pbuffer support List pbuffersToInstantiate = new ArrayList(); - public X11OnscreenGLContext(Component component, GLCapabilities capabilities, GLCapabilitiesChooser chooser) { - super(component, capabilities, chooser); + public X11OnscreenGLContext(Component component, + GLCapabilities capabilities, + GLCapabilitiesChooser chooser, + GLContext shareWith) { + super(component, capabilities, chooser, shareWith); } protected GL createGL() diff --git a/src/net/java/games/jogl/impl/x11/X11PbufferGLContext.java b/src/net/java/games/jogl/impl/x11/X11PbufferGLContext.java index 264d60fc7..c92eba96f 100644 --- a/src/net/java/games/jogl/impl/x11/X11PbufferGLContext.java +++ b/src/net/java/games/jogl/impl/x11/X11PbufferGLContext.java @@ -65,7 +65,7 @@ public class X11PbufferGLContext extends X11GLContext { // it looks like floating-point buffers are not) public X11PbufferGLContext(GLCapabilities capabilities, int initialWidth, int initialHeight) { - super(null, capabilities, null); + super(null, capabilities, null, null); this.initWidth = initialWidth; this.initHeight = initialHeight; if (initWidth <= 0 || initHeight <= 0) { |