diff options
author | sg215889 <[email protected]> | 2009-07-24 07:29:28 -0700 |
---|---|---|
committer | sg215889 <[email protected]> | 2009-07-24 07:29:28 -0700 |
commit | 0906140a18690a9dced8dec12dfdd8cf4c95a4df (patch) | |
tree | 52f67514b575a61aeba975fad00fd5ab60a52435 /src/jogl/classes | |
parent | 1f65dedf406455731fb682404a01c96aa85d5ae1 (diff) |
Add: Extended support for CVM crosscompile:
- Clean up X11 dependency
- NativeWindow:
- Seperate X11 out of core.
- Add nativewindow.x11.jar and nativewindow.x11.cdc.jar
- Newt:
- Seperate X11,win,osx out of core.
- Add newt.x11.jar, newt.win.jar, newt.osx.jar and the CDC variants
Fix: External Context & Drawable (X11 and Windows)
- Properly fetch current context values (ctx, display, drawable, ..)
- Create GraphicsConfiguration based on the given pixelformat/FBConfig
Fix: Java2D OpenGL Usage
- Using the external context as shared for the external drawable
- JAWTUtil: Skip locking in case of OGL-Flush-Queue
- TODO: Windows FBO still does not work .. (X11 is fine)
Diffstat (limited to 'src/jogl/classes')
27 files changed, 778 insertions, 684 deletions
diff --git a/src/jogl/classes/com/sun/opengl/impl/awt/AWTUtil.java b/src/jogl/classes/com/sun/opengl/impl/awt/AWTUtil.java index 11575ab65..f4c8944df 100644 --- a/src/jogl/classes/com/sun/opengl/impl/awt/AWTUtil.java +++ b/src/jogl/classes/com/sun/opengl/impl/awt/AWTUtil.java @@ -56,12 +56,14 @@ public class AWTUtil { static { lockedToolkit = false; headlessMode = GraphicsEnvironment.isHeadless(); - try { - j2dClazz = Class.forName("com.sun.opengl.impl.awt.Java2D"); - isOGLPipelineActive = j2dClazz.getMethod("isOGLPipelineActive", null); - isQueueFlusherThread = j2dClazz.getMethod("isQueueFlusherThread", null); - j2dOk = true; - } catch (Exception e) {} + if(!headlessMode) { + try { + j2dClazz = Class.forName("com.sun.opengl.impl.awt.Java2D"); + isOGLPipelineActive = j2dClazz.getMethod("isOGLPipelineActive", null); + isQueueFlusherThread = j2dClazz.getMethod("isQueueFlusherThread", null); + j2dOk = true; + } catch (Exception e) {} + } } private static boolean lockedToolkit; @@ -117,7 +119,7 @@ public class AWTUtil { } public static boolean isToolkitLocked() { - return lockedToolkit; + return JAWTUtil.isToolkitLocked(); } } diff --git a/src/jogl/classes/com/sun/opengl/impl/awt/Java2D.java b/src/jogl/classes/com/sun/opengl/impl/awt/Java2D.java index 328771a3b..098ec8529 100755 --- a/src/jogl/classes/com/sun/opengl/impl/awt/Java2D.java +++ b/src/jogl/classes/com/sun/opengl/impl/awt/Java2D.java @@ -558,8 +558,7 @@ public class Java2D { } invokeWithOGLSharedContextCurrent(device.getDefaultConfiguration(), new Runnable() { public void run() { - // AbstractGraphicsScreen awtscreen = AWTGraphicsScreen.createScreenDevice(device); - j2dFBOShareContext = GLDrawableFactory.getFactory(GLProfile.getDefault()).createExternalGLContext(/*awtscreen*/); + j2dFBOShareContext = GLDrawableFactory.getFactory(GLProfile.getDefault()).createExternalGLContext(); } }); if (DEBUG) { diff --git a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java index 62388173c..f1e9483cd 100644 --- a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java +++ b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java @@ -47,7 +47,7 @@ public class WindowsDummyWGLDrawable extends WindowsWGLDrawable { private long hwnd, hdc; public WindowsDummyWGLDrawable(GLDrawableFactory factory) { - super(factory, new NullWindow(WindowsWGLGraphicsConfigurationFactory.createDefaultGraphicsConfiguration(null, false)), true); + super(factory, new NullWindow(WindowsWGLGraphicsConfigurationFactory.createDefaultGraphicsConfiguration(null, true, true)), true); // All entries to CreateDummyWindow must synchronize on one object // to avoid accidentally registering the dummy window class twice synchronized (WindowsDummyWGLDrawable.class) { @@ -59,7 +59,7 @@ public class WindowsDummyWGLDrawable extends WindowsWGLDrawable { // Choose a (hopefully hardware-accelerated) OpenGL pixel format for this device context GLCapabilities caps = new GLCapabilities(null); caps.setDepthBits(16); - PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(caps, true); + PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(caps); int pixelFormat = WGL.ChoosePixelFormat(hdc, pfd); if ((pixelFormat == 0) || (!WGL.SetPixelFormat(hdc, pixelFormat, pfd))) { diff --git a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsExternalWGLContext.java b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsExternalWGLContext.java index b42a54104..b9fc80156 100755 --- a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsExternalWGLContext.java +++ b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsExternalWGLContext.java @@ -44,19 +44,16 @@ import java.util.*; import javax.media.opengl.*; import javax.media.nativewindow.*; import com.sun.opengl.impl.*; +import com.sun.nativewindow.impl.NullWindow; public class WindowsExternalWGLContext extends WindowsWGLContext { private boolean firstMakeCurrent = true; private boolean created = true; private GLContext lastContext; - public WindowsExternalWGLContext(AbstractGraphicsScreen absScreen) { - // FIXME: figure out how to hook back in the Java 2D / JOGL bridge - super(null, null); - hglrc = WGL.wglGetCurrentContext(); - if (hglrc == 0) { - throw new GLException("Error: attempted to make an external GLContext without a drawable/context current"); - } + private WindowsExternalWGLContext(Drawable drawable, long hglrc) { + super(drawable, null); + this.hglrc = hglrc; if (DEBUG) { System.err.println(getThreadName() + ": !!! Created external OpenGL context " + toHexString(hglrc) + " for " + this); } @@ -64,6 +61,29 @@ public class WindowsExternalWGLContext extends WindowsWGLContext { setGLFunctionAvailability(false); } + protected static WindowsExternalWGLContext create(GLDrawableFactory factory, GLProfile glp) { + long hdc = WGL.wglGetCurrentDC(); + if (0==hdc) { + throw new GLException("Error: attempted to make an external GLDrawable without a drawable current"); + } + long hglrc = WGL.wglGetCurrentContext(); + if (hglrc == 0) { + throw new GLException("Error: attempted to make an external GLContext without a context current"); + } + int pfdID = WGL.GetPixelFormat(hdc); + if (pfdID == 0) { + throw new GLException("Error: attempted to make an external GLContext without a valid pixelformat"); + } + + AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(); + WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfiguration.create(glp, aScreen, hdc, pfdID, true, true); + + NullWindow nw = new NullWindow(cfg); + nw.setSurfaceHandle(hdc); + + return new WindowsExternalWGLContext(new Drawable(factory, nw), hglrc); + } + public int makeCurrent() throws GLException { // Save last context if necessary to allow external GLContexts to // talk to other GLContexts created by this library @@ -100,4 +120,27 @@ public class WindowsExternalWGLContext extends WindowsWGLContext { public boolean isCreated() { return created; } + + // Need to provide the display connection to extension querying APIs + static class Drawable extends WindowsWGLDrawable { + Drawable(GLDrawableFactory factory, NativeWindow comp) { + super(factory, comp, true); + } + + 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"); + } + } } diff --git a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java index 164216c2d..706675893 100755 --- a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java +++ b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java @@ -46,20 +46,32 @@ import com.sun.nativewindow.impl.NullWindow; public class WindowsExternalWGLDrawable extends WindowsWGLDrawable { - public WindowsExternalWGLDrawable(GLDrawableFactory factory, NativeWindow component) { + private WindowsExternalWGLDrawable(GLDrawableFactory factory, NativeWindow component) { super(factory, component, true); } - public static WindowsExternalWGLDrawable create(GLDrawableFactory factory, AbstractGraphicsScreen absScreen) { + protected static WindowsExternalWGLDrawable create(GLDrawableFactory factory, GLProfile glp) { long hdc = WGL.wglGetCurrentDC(); - NullWindow nw = new NullWindow(WindowsWGLGraphicsConfigurationFactory.createDefaultGraphicsConfiguration(absScreen, false)); - nw.setSurfaceHandle(hdc); - if (nw.getSurfaceHandle() == 0) { - throw new GLException("Error: attempted to make an external GLDrawable without a drawable/context current"); + if (0==hdc) { + throw new GLException("Error: attempted to make an external GLDrawable without a drawable current"); + } + int pfdID = WGL.GetPixelFormat(hdc); + if (pfdID == 0) { + throw new GLException("Error: attempted to make an external GLContext without a valid pixelformat"); } + + AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(); + WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfiguration.create(glp, aScreen, hdc, pfdID, true, true); + + NullWindow nw = new NullWindow(cfg); + nw.setSurfaceHandle(hdc); + + // cfg.updateGraphicsConfiguration(factory, nw); + return new WindowsExternalWGLDrawable(factory, nw); } + public GLContext createContext(GLContext shareWith) { return new WindowsWGLContext(this, shareWith); } diff --git a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsOffscreenWGLDrawable.java b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsOffscreenWGLDrawable.java index dc9d66073..ecd4e1685 100644 --- a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsOffscreenWGLDrawable.java +++ b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsOffscreenWGLDrawable.java @@ -54,7 +54,7 @@ public class WindowsOffscreenWGLDrawable extends WindowsWGLDrawable { GLCapabilitiesChooser chooser, int width, int height) { - super(factory, new NullWindow(WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(requestedCapabilities, chooser, absScreen, true)), true); + super(factory, new NullWindow(WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(requestedCapabilities, chooser, absScreen, false, false)), true); ((NullWindow) getNativeWindow()).setSize(width, height); create(); } @@ -111,7 +111,7 @@ public class WindowsOffscreenWGLDrawable extends WindowsWGLDrawable { throw new GLException("Error selecting bitmap into new device context"); } - config.updateGraphicsConfiguration(getFactory(), nw, true); + config.updateGraphicsConfiguration(getFactory(), nw); } public void destroy() { @@ -126,4 +126,8 @@ public class WindowsOffscreenWGLDrawable extends WindowsWGLDrawable { nw.setSurfaceHandle(0); } } + + public void swapBuffers() throws GLException { + } + } diff --git a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsOnscreenWGLDrawable.java b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsOnscreenWGLDrawable.java index 31925589b..395ccf7d2 100644 --- a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsOnscreenWGLDrawable.java +++ b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsOnscreenWGLDrawable.java @@ -44,15 +44,6 @@ import javax.media.opengl.*; import com.sun.opengl.impl.*; public class WindowsOnscreenWGLDrawable extends WindowsWGLDrawable { - private static final boolean PROFILING = Debug.debug("WindowsOnscreenWGLDrawable.profiling"); - private static final int PROFILING_TICKS = 200; - private int profilingLockSurfaceTicks; - private long profilingLockSurfaceTime; - private int profilingUnlockSurfaceTicks; - private long profilingUnlockSurfaceTime; - private int profilingSwapBuffersTicks; - private long profilingSwapBuffersTime; - protected WindowsOnscreenWGLDrawable(GLDrawableFactory factory, NativeWindow component) { super(factory, component, false); } @@ -69,43 +60,4 @@ public class WindowsOnscreenWGLDrawable extends WindowsWGLDrawable { return component.getHeight(); } - public void swapBuffers() throws GLException { - boolean didLock = false; - - try { - if ( !isSurfaceLocked() ) { - // Usually the surface shall be locked within [makeCurrent .. swap .. release] - if (lockSurface() == NativeWindow.LOCK_SURFACE_NOT_READY) { - return; - } - didLock = true; - } - - long startTime = 0; - if (PROFILING) { - startTime = System.currentTimeMillis(); - } - - if (!WGL.SwapBuffers(getNativeWindow().getSurfaceHandle()) && (WGL.GetLastError() != 0)) { - throw new GLException("Error swapping buffers"); - } - - if (PROFILING) { - long endTime = System.currentTimeMillis(); - profilingSwapBuffersTime += (endTime - startTime); - int ticks = PROFILING_TICKS; - if (++profilingSwapBuffersTicks == ticks) { - System.err.println("SwapBuffers calls: " + profilingSwapBuffersTime + " ms / " + ticks + " calls (" + - ((float) profilingSwapBuffersTime / (float) ticks) + " ms/call)"); - profilingSwapBuffersTime = 0; - profilingSwapBuffersTicks = 0; - } - } - } finally { - if (didLock) { - unlockSurface(); - } - } - } - } diff --git a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java index 2d996ca40..6a03406f9 100644 --- a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java +++ b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java @@ -61,7 +61,7 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { WindowsWGLDrawable dummyDrawable, WGLExt wglExt) { super(factory, new NullWindow(WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic( - requestedCapabilities, chooser, absScreen, true) ), true); + requestedCapabilities, chooser, absScreen, false, true) ), true); if (width <= 0 || height <= 0) { throw new GLException("Width and height of pbuffer must be positive (were (" + width + ", " + height + "))"); @@ -108,20 +108,6 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { } public void swapBuffers() throws GLException { - // FIXME: this doesn't make sense any more because we don't have - // access to our OpenGL context here - /* - // FIXME: do we need to do anything if the pbuffer is double-buffered? - // For now, just grab the pixels for the render-to-texture support. - if (rtt && !hasRTT) { - if (DEBUG) { - System.err.println("Copying pbuffer data to GL_TEXTURE_2D state"); - } - - GL gl = getGL(); - gl.glCopyTexSubImage2D(textureTarget, 0, 0, 0, 0, 0, width, height); - } - */ } private void createPbuffer(long parentHdc, WGLExt wglExt) { @@ -301,18 +287,24 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB; int[] ivalues = new int[niattribs]; if (wglExt.wglGetPixelFormatAttribivARB(parentHdc, pformats[whichFormat], 0, niattribs, iattributes, 0, ivalues, 0)) { - GLCapabilities newCaps = WindowsWGLGraphicsConfiguration.AttribList2GLCapabilities(glProfile, iattributes, niattribs, ivalues, false); + GLCapabilities newCaps = WindowsWGLGraphicsConfiguration.AttribList2GLCapabilities(glProfile, iattributes, niattribs, ivalues, true, false, true); PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor(); if (WGL.DescribePixelFormat(parentHdc, pformats[whichFormat], pfd.size(), pfd) == 0) { throw new GLException("Unable to describe pixel format " + pformats[whichFormat]); } + if(newCaps.isOnscreen()) { + throw new GLException("Error: Selected Onscreen Caps for PBuffer: "+newCaps); + } config.setCapsPFD(newCaps, pfd, pformats[whichFormat]); } else { PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor(); if (WGL.DescribePixelFormat(parentHdc, pformats[whichFormat], pfd.size(), pfd) == 0) { throw new GLException("Unable to describe pixel format " + pformats[whichFormat]); } - GLCapabilities newCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, pfd); + GLCapabilities newCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, pfd, false, true); + if(newCaps.isOnscreen()) { + throw new GLException("Error: Selected Onscreen Caps for PBuffer: "+newCaps); + } config.setCapsPFD(newCaps, pfd, pformats[whichFormat]); } } diff --git a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLDrawable.java b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLDrawable.java index 464cfbcc2..3017d258b 100644 --- a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLDrawable.java +++ b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLDrawable.java @@ -46,6 +46,15 @@ import com.sun.gluegen.runtime.DynamicLookupHelper; public abstract class WindowsWGLDrawable extends GLDrawableImpl { private static final int MAX_SET_PIXEL_FORMAT_FAIL_COUNT = 5; + private static final boolean PROFILING = Debug.debug("WindowsWGLDrawable.profiling"); + private static final int PROFILING_TICKS = 200; + private int profilingLockSurfaceTicks; + private long profilingLockSurfaceTime; + private int profilingUnlockSurfaceTicks; + private long profilingUnlockSurfaceTime; + private int profilingSwapBuffersTicks; + private long profilingSwapBuffersTime; + public WindowsWGLDrawable(GLDrawableFactory factory, NativeWindow comp, boolean realized) { super(factory, comp, realized); @@ -64,7 +73,7 @@ public abstract class WindowsWGLDrawable extends GLDrawableImpl { try { NativeWindow nativeWindow = getNativeWindow(); WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)nativeWindow.getGraphicsConfiguration().getNativeGraphicsConfiguration(); - config.updateGraphicsConfiguration(getFactory(), nativeWindow, false); + config.updateGraphicsConfiguration(getFactory(), nativeWindow); if (DEBUG) { System.err.println("!!! WindowsWGLDrawable.setRealized(true): "+config); } @@ -73,6 +82,48 @@ public abstract class WindowsWGLDrawable extends GLDrawableImpl { } } + public void swapBuffers() throws GLException { + GLCapabilities caps = (GLCapabilities)getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities(); + if (caps.getDoubleBuffered()) { + boolean didLock = false; + + try { + if ( !isSurfaceLocked() ) { + // Usually the surface shall be locked within [makeCurrent .. swap .. release] + if (lockSurface() == NativeWindow.LOCK_SURFACE_NOT_READY) { + return; + } + didLock = true; + } + + long startTime = 0; + if (PROFILING) { + startTime = System.currentTimeMillis(); + } + + if (!WGL.SwapBuffers(getNativeWindow().getSurfaceHandle()) && (WGL.GetLastError() != 0)) { + throw new GLException("Error swapping buffers"); + } + + if (PROFILING) { + long endTime = System.currentTimeMillis(); + profilingSwapBuffersTime += (endTime - startTime); + int ticks = PROFILING_TICKS; + if (++profilingSwapBuffersTicks == ticks) { + System.err.println("SwapBuffers calls: " + profilingSwapBuffersTime + " ms / " + ticks + " calls (" + + ((float) profilingSwapBuffersTime / (float) ticks) + " ms/call)"); + profilingSwapBuffersTime = 0; + profilingSwapBuffersTicks = 0; + } + } + } finally { + if (didLock) { + unlockSurface(); + } + } + } + } + public DynamicLookupHelper getDynamicLookupHelper() { return (WindowsWGLDrawableFactory) getFactoryImpl() ; } diff --git a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java index 1c5c54b14..4d965e52b 100644 --- a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java +++ b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java @@ -166,8 +166,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl implements } public GLContext createExternalGLContext() { - AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(); - return new WindowsExternalWGLContext(aScreen); + return WindowsExternalWGLContext.create(this, null); } public boolean canCreateExternalGLDrawable() { @@ -175,8 +174,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl implements } public GLDrawable createExternalGLDrawable() { - AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(); - return WindowsExternalWGLDrawable.create(this, aScreen); + return WindowsExternalWGLDrawable.create(this, null); } public void loadOpenGL32Library() { diff --git a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java index 8b721824e..1a8d45465 100644 --- a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java +++ b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java @@ -58,12 +58,27 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio this.pixelfmtID = pixelfmtID; } + public static WindowsWGLGraphicsConfiguration create(GLProfile glp, AbstractGraphicsScreen screen, long hdc, int pfdID, boolean onscreen, boolean usePBuffer) { + PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(); + if (WGL.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) { + throw new GLException("Unable to describe pixel format " + pfdID); + } + if(null==glp) { + glp = GLProfile.getDefault(); + } + GLCapabilities caps = PFD2GLCapabilities(glp, pfd, onscreen, usePBuffer); + WindowsWGLGraphicsConfiguration cfg = new WindowsWGLGraphicsConfiguration(screen, caps, caps, pfd, pfdID, new DefaultGLCapabilitiesChooser()); + cfg.setCapsPFD(caps, pfd, pfdID); + + return cfg; + } + public Object clone() { return super.clone(); } - protected void updateGraphicsConfiguration(GLDrawableFactory factory, NativeWindow nativeWindow, boolean useOffScreen) { - WindowsWGLGraphicsConfigurationFactory.updateGraphicsConfiguration(chooser, factory, nativeWindow, useOffScreen); + protected void updateGraphicsConfiguration(GLDrawableFactory factory, NativeWindow nativeWindow) { + WindowsWGLGraphicsConfigurationFactory.updateGraphicsConfiguration(chooser, factory, nativeWindow); } protected void setCapsPFD(GLCapabilities caps, PIXELFORMATDESCRIPTOR pfd, int pfdID) { // FIXME: setScreen ( .. ) @@ -236,20 +251,67 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio return true; } + public static final int WINDOW_BIT = 1 << 0 ; + public static final int BITMAP_BIT = 1 << 1 ; + public static final int PBUFFER_BIT = 1 << 2 ; + + public static int WGLConfig2DrawableTypeBits(int[] iattribs, + int niattribs, + int[] iresults) { + int val = 0; + + for (int i = 0; i < niattribs; i++) { + int attr = iattribs[i]; + switch (attr) { + case WGLExt.WGL_DRAW_TO_WINDOW_ARB: + if(iresults[i] == GL.GL_TRUE) val |= WINDOW_BIT; + break; + case WGLExt.WGL_DRAW_TO_BITMAP_ARB: + if(iresults[i] == GL.GL_TRUE) val |= BITMAP_BIT; + break; + case WGLExt.WGL_DRAW_TO_PBUFFER_ARB: + if(iresults[i] == GL.GL_TRUE) val |= PBUFFER_BIT; + break; + } + } + return val; + } + + public static boolean WGLConfigDrawableTypeVerify(int val, boolean onscreen, boolean usePBuffer) { + boolean res; + + if ( onscreen ) { + res = ( 0 != (val & WINDOW_BIT) ) ; + } else { + res = ( 0 != (val & BITMAP_BIT) ) || usePBuffer ; + } + if ( usePBuffer ) { + res = res && ( 0 != (val & PBUFFER_BIT) ) ; + } + + return res; + } public static GLCapabilities AttribList2GLCapabilities(GLProfile glp, int[] iattribs, int niattribs, int[] iresults, - boolean requireRenderToWindow) { + boolean relaxed, boolean onscreen, boolean usePBuffer) { GLCapabilities res = new GLCapabilities(glp); + int drawableTypeBits = WGLConfig2DrawableTypeBits(iattribs, niattribs, iresults); + if(WGLConfigDrawableTypeVerify(drawableTypeBits, onscreen, usePBuffer)) { + res.setOnscreen(onscreen); + res.setPBuffer(usePBuffer); + } else if(relaxed) { + res.setOnscreen( 0 != (drawableTypeBits & WINDOW_BIT) ); + res.setPBuffer ( 0 != (drawableTypeBits & PBUFFER_BIT) ); + } else { + return null; + } + for (int i = 0; i < niattribs; i++) { int attr = iattribs[i]; switch (attr) { case WGLExt.WGL_DRAW_TO_WINDOW_ARB: - if (requireRenderToWindow && iresults[i] != GL.GL_TRUE) { - return null; - } - break; - + case WGLExt.WGL_DRAW_TO_BITMAP_ARB: case WGLExt.WGL_DRAW_TO_PBUFFER_ARB: break; @@ -342,7 +404,7 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio // PIXELFORMAT - public static GLCapabilities PFD2GLCapabilities(GLProfile glp, PIXELFORMATDESCRIPTOR pfd) { + public static GLCapabilities PFD2GLCapabilities(GLProfile glp, PIXELFORMATDESCRIPTOR pfd, boolean onscreen, boolean usePBuffer) { if ((pfd.dwFlags() & WGL.PFD_SUPPORT_OPENGL) == 0) { return null; } @@ -359,8 +421,10 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio res.setStencilBits (pfd.cStencilBits()); res.setDoubleBuffered((pfd.dwFlags() & WGL.PFD_DOUBLEBUFFER) != 0); res.setStereo ((pfd.dwFlags() & WGL.PFD_STEREO) != 0); - res.setHardwareAccelerated(((pfd.dwFlags() & WGL.PFD_GENERIC_FORMAT) == 0) || - ((pfd.dwFlags() & WGL.PFD_GENERIC_ACCELERATED) != 0)); + res.setHardwareAccelerated( ((pfd.dwFlags() & WGL.PFD_GENERIC_FORMAT) == 0) || + ((pfd.dwFlags() & WGL.PFD_GENERIC_ACCELERATED) != 0) ); + res.setOnscreen ( onscreen && ((pfd.dwFlags() & WGL.PFD_DRAW_TO_WINDOW) != 0) ); + res.setPBuffer ( usePBuffer ); /* FIXME: Missing ?? if (GLXUtil.isMultisampleAvailable()) { res.setSampleBuffers(glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLE_BUFFERS, tmp, 0) != 0); @@ -374,7 +438,7 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio return res; } - public static PIXELFORMATDESCRIPTOR GLCapabilities2PFD(GLCapabilities caps, boolean offscreen) { + public static PIXELFORMATDESCRIPTOR GLCapabilities2PFD(GLCapabilities caps) { int colorDepth = (caps.getRedBits() + caps.getGreenBits() + caps.getBlueBits()); @@ -387,10 +451,10 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio if (caps.getDoubleBuffered()) { pfdFlags |= WGL.PFD_DOUBLEBUFFER; } - if (offscreen) { - pfdFlags |= WGL.PFD_DRAW_TO_BITMAP; - } else { + if (caps.isOnscreen()) { pfdFlags |= WGL.PFD_DRAW_TO_WINDOW; + } else { + pfdFlags |= WGL.PFD_DRAW_TO_BITMAP; } if (caps.getStereo()) { pfdFlags |= WGL.PFD_STEREO; diff --git a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java index df8081f05..f5974dc61 100644 --- a/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/sun/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java @@ -54,29 +54,42 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio public AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities, CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) { - return chooseGraphicsConfigurationStatic((GLCapabilities)capabilities, chooser, absScreen, false); + GLCapabilities caps = (GLCapabilities)capabilities; + return chooseGraphicsConfigurationStatic(caps, chooser, absScreen, caps.isOnscreen(), caps.isPBuffer()); } - protected static WindowsWGLGraphicsConfiguration createDefaultGraphicsConfiguration(AbstractGraphicsScreen absScreen, boolean useOffScreen) { + protected static WindowsWGLGraphicsConfiguration createDefaultGraphicsConfiguration(AbstractGraphicsScreen absScreen, boolean onscreen, boolean usePBuffer) { GLCapabilities caps = new GLCapabilities(null); + caps.setOnscreen (onscreen); + caps.setPBuffer (usePBuffer); + if(!onscreen) { + caps.setDoubleBuffered(false); + } + if(null==absScreen) { absScreen = DefaultGraphicsScreen.createScreenDevice(0); } - return new WindowsWGLGraphicsConfiguration(absScreen, caps, caps, WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(caps, useOffScreen), -1, null); + return new WindowsWGLGraphicsConfiguration(absScreen, caps, caps, WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(caps), -1, null); } protected static WindowsWGLGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilities caps, CapabilitiesChooser chooser, - AbstractGraphicsScreen absScreen, boolean useOffScreen) { + AbstractGraphicsScreen absScreen, + boolean onscreen, boolean usePBuffer) { if(null==absScreen) { absScreen = DefaultGraphicsScreen.createScreenDevice(0); } - return new WindowsWGLGraphicsConfiguration(absScreen, caps, caps, WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(caps, useOffScreen), -1, + caps.setOnscreen (onscreen); + caps.setPBuffer (usePBuffer); + if(!onscreen) { + caps.setDoubleBuffered(false); + } + return new WindowsWGLGraphicsConfiguration(absScreen, caps, caps, WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(caps), -1, (GLCapabilitiesChooser)chooser); } protected static void updateGraphicsConfiguration(CapabilitiesChooser chooser, - GLDrawableFactory factory, NativeWindow nativeWindow, boolean useOffScreen) { + GLDrawableFactory factory, NativeWindow nativeWindow) { if (nativeWindow == null) { throw new IllegalArgumentException("NativeWindow is null"); } @@ -88,6 +101,8 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration) nativeWindow.getGraphicsConfiguration().getNativeGraphicsConfiguration(); GLCapabilities capabilities = (GLCapabilities) config.getRequestedCapabilities(); + boolean onscreen = capabilities.isOnscreen(); + boolean usePBuffer = capabilities.isPBuffer(); GLProfile glProfile = capabilities.getGLProfile(); long hdc = nativeWindow.getSurfaceHandle(); @@ -98,10 +113,11 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio } PIXELFORMATDESCRIPTOR pfd = null; - int pixelFormat = 0; + int pixelFormat = -1; + boolean pixelFormatSet = false; GLCapabilities chosenCaps = null; - if (!useOffScreen) { + if (onscreen) { if ((pixelFormat = WGL.GetPixelFormat(hdc)) != 0) { // Pixelformat already set by either // - a previous updateGraphicsConfiguration() call on the same HDC, @@ -111,14 +127,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio System.err.println("!!!! NOTE: pixel format already chosen for HDC: 0x" + Long.toHexString(hdc)+ ", pixelformat "+WGL.GetPixelFormat(hdc)); } - pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor(); - if (WGL.DescribePixelFormat(hdc, pixelFormat, pfd.size(), pfd) == 0) { - // FIXME: should this just be a warning? Not really critical... - throw new GLException("Unable to describe pixel format " + pixelFormat + - " of window set by Java2D/OpenGL pipeline"); - } - config.setCapsPFD(WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, pfd), pfd, pixelFormat); - return; + pixelFormatSet = true; } GLCapabilities[] availableCaps = null; @@ -129,15 +138,13 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio WindowsWGLDrawable dummyDrawable = null; GLContextImpl dummyContext = null; WGLExt dummyWGLExt = null; - if (capabilities.getSampleBuffers()) { - dummyDrawable = new WindowsDummyWGLDrawable(factory); - dummyContext = (GLContextImpl) dummyDrawable.createContext(null); - if (dummyContext != null) { - dummyContext.makeCurrent(); - dummyWGLExt = (WGLExt) dummyContext.getPlatformGLExtensions(); - } + dummyDrawable = new WindowsDummyWGLDrawable(factory); + dummyContext = (GLContextImpl) dummyDrawable.createContext(null); + if (dummyContext != null) { + dummyContext.makeCurrent(); + dummyWGLExt = (WGLExt) dummyContext.getPlatformGLExtensions(); } - int recommendedPixelFormat = -1; + int recommendedPixelFormat = pixelFormat - 1; boolean haveWGLChoosePixelFormatARB = false; boolean haveWGLARBMultisample = false; boolean gotAvailableCaps = false; @@ -151,100 +158,103 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio int[] iresults = new int [2*WindowsWGLGraphicsConfiguration.MAX_ATTRIBS]; float[] fattributes = new float[1]; - if(WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList(capabilities, - iattributes, - dummyWGLExt, - false, - null)) { - int[] pformats = new int[WindowsWGLGraphicsConfiguration.MAX_PFORMATS]; - int[] numFormatsTmp = new int[1]; - if (dummyWGLExt.wglChoosePixelFormatARB(hdc, - iattributes, 0, - fattributes, 0, - WindowsWGLGraphicsConfiguration.MAX_PFORMATS, - pformats, 0, - numFormatsTmp, 0)) { - numFormats = numFormatsTmp[0]; - if (numFormats > 0) { - // Remove one-basing of pixel format (added on later) - recommendedPixelFormat = pformats[0] - 1; + if(pixelFormat<=0) { + if(WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList(capabilities, + iattributes, + dummyWGLExt, + false, + null)) { + int[] pformats = new int[WindowsWGLGraphicsConfiguration.MAX_PFORMATS]; + int[] numFormatsTmp = new int[1]; + if (dummyWGLExt.wglChoosePixelFormatARB(hdc, + iattributes, 0, + fattributes, 0, + WindowsWGLGraphicsConfiguration.MAX_PFORMATS, + pformats, 0, + numFormatsTmp, 0)) { + numFormats = numFormatsTmp[0]; + if (recommendedPixelFormat<=0 && numFormats > 0) { + // Remove one-basing of pixel format (added on later) + recommendedPixelFormat = pformats[0] - 1; + if (DEBUG) { + System.err.println(getThreadName() + ": Used wglChoosePixelFormatARB to recommend pixel format " + recommendedPixelFormat); + } + } + } else { if (DEBUG) { - System.err.println(getThreadName() + ": Used wglChoosePixelFormatARB to recommend pixel format " + recommendedPixelFormat); + System.err.println(getThreadName() + ": wglChoosePixelFormatARB failed: " + WGL.GetLastError() ); + Thread.dumpStack(); } } - } else { if (DEBUG) { - System.err.println(getThreadName() + ": wglChoosePixelFormatARB failed: " + WGL.GetLastError() ); - Thread.dumpStack(); - } - } - if (DEBUG) { - if (recommendedPixelFormat < 0) { - System.err.print(getThreadName() + ": wglChoosePixelFormatARB didn't recommend a pixel format"); - if (capabilities.getSampleBuffers()) { - System.err.print(" for multisampled GLCapabilities"); + if (recommendedPixelFormat < 0) { + System.err.print(getThreadName() + ": wglChoosePixelFormatARB didn't recommend a pixel format"); + if (capabilities.getSampleBuffers()) { + System.err.print(" for multisampled GLCapabilities"); + } + System.err.println(); } - System.err.println(); } } + } - // Produce a list of GLCapabilities to give to the - // GLCapabilitiesChooser. - // Use wglGetPixelFormatAttribivARB instead of - // DescribePixelFormat to get higher-precision information - // about the pixel format (should make the GLCapabilities - // more precise as well...i.e., remove the - // "HardwareAccelerated" bit, which is basically - // meaningless, and put in whether it can render to a - // window, to a pbuffer, or to a pixmap) - int niattribs = 0; - iattributes[0] = WGLExt.WGL_NUMBER_PIXEL_FORMATS_ARB; - if (dummyWGLExt.wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, iattributes, 0, iresults, 0)) { - numFormats = iresults[0]; + // Produce a list of GLCapabilities to give to the + // GLCapabilitiesChooser. + // Use wglGetPixelFormatAttribivARB instead of + // DescribePixelFormat to get higher-precision information + // about the pixel format (should make the GLCapabilities + // more precise as well...i.e., remove the + // "HardwareAccelerated" bit, which is basically + // meaningless, and put in whether it can render to a + // window, to a pbuffer, or to a pixmap) + int niattribs = 0; + iattributes[0] = WGLExt.WGL_NUMBER_PIXEL_FORMATS_ARB; + if (dummyWGLExt.wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, iattributes, 0, iresults, 0)) { + numFormats = iresults[0]; - if (DEBUG) { - System.err.println("wglGetPixelFormatAttribivARB reported WGL_NUMBER_PIXEL_FORMATS = " + numFormats); - } + if (DEBUG) { + System.err.println("wglGetPixelFormatAttribivARB reported WGL_NUMBER_PIXEL_FORMATS = " + numFormats); + } - // Should we be filtering out the pixel formats which aren't - // applicable, as we are doing here? - // We don't have enough information in the GLCapabilities to - // represent those that aren't... - iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_WINDOW_ARB; - iattributes[niattribs++] = WGLExt.WGL_ACCELERATION_ARB; - iattributes[niattribs++] = WGLExt.WGL_SUPPORT_OPENGL_ARB; - iattributes[niattribs++] = WGLExt.WGL_DEPTH_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_STENCIL_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_DOUBLE_BUFFER_ARB; - iattributes[niattribs++] = WGLExt.WGL_STEREO_ARB; - iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB; - iattributes[niattribs++] = WGLExt.WGL_RED_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_GREEN_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_BLUE_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_ALPHA_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_ACCUM_RED_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_ACCUM_GREEN_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_ACCUM_BLUE_BITS_ARB; - iattributes[niattribs++] = WGLExt.WGL_ACCUM_ALPHA_BITS_ARB; - if (haveWGLARBMultisample) { - iattributes[niattribs++] = WGLExt.WGL_SAMPLE_BUFFERS_ARB; - iattributes[niattribs++] = WGLExt.WGL_SAMPLES_ARB; - } + // Should we be filtering out the pixel formats which aren't + // applicable, as we are doing here? + // We don't have enough information in the GLCapabilities to + // represent those that aren't... + iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_WINDOW_ARB; + iattributes[niattribs++] = WGLExt.WGL_ACCELERATION_ARB; + iattributes[niattribs++] = WGLExt.WGL_SUPPORT_OPENGL_ARB; + iattributes[niattribs++] = WGLExt.WGL_DEPTH_BITS_ARB; + iattributes[niattribs++] = WGLExt.WGL_STENCIL_BITS_ARB; + iattributes[niattribs++] = WGLExt.WGL_DOUBLE_BUFFER_ARB; + iattributes[niattribs++] = WGLExt.WGL_STEREO_ARB; + iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB; + iattributes[niattribs++] = WGLExt.WGL_RED_BITS_ARB; + iattributes[niattribs++] = WGLExt.WGL_GREEN_BITS_ARB; + iattributes[niattribs++] = WGLExt.WGL_BLUE_BITS_ARB; + iattributes[niattribs++] = WGLExt.WGL_ALPHA_BITS_ARB; + iattributes[niattribs++] = WGLExt.WGL_ACCUM_RED_BITS_ARB; + iattributes[niattribs++] = WGLExt.WGL_ACCUM_GREEN_BITS_ARB; + iattributes[niattribs++] = WGLExt.WGL_ACCUM_BLUE_BITS_ARB; + iattributes[niattribs++] = WGLExt.WGL_ACCUM_ALPHA_BITS_ARB; + if (haveWGLARBMultisample) { + iattributes[niattribs++] = WGLExt.WGL_SAMPLE_BUFFERS_ARB; + iattributes[niattribs++] = WGLExt.WGL_SAMPLES_ARB; + } - availableCaps = new GLCapabilities[numFormats]; - for (int i = 0; i < numFormats; i++) { - if (!dummyWGLExt.wglGetPixelFormatAttribivARB(hdc, i+1, 0, niattribs, iattributes, 0, iresults, 0)) { - throw new GLException("Error getting pixel format attributes for pixel format " + (i + 1) + " of device context"); - } - availableCaps[i] = WindowsWGLGraphicsConfiguration.AttribList2GLCapabilities(glProfile, iattributes, niattribs, iresults, true); - } - gotAvailableCaps = true; - } else { - long lastErr = WGL.GetLastError(); - // Intel Extreme graphics fails with a zero error code - if (lastErr != 0) { - throw new GLException("Unable to enumerate pixel formats of window using wglGetPixelFormatAttribivARB: error code " + WGL.GetLastError()); + availableCaps = new GLCapabilities[numFormats]; + for (int i = 0; i < numFormats; i++) { + if (!dummyWGLExt.wglGetPixelFormatAttribivARB(hdc, i+1, 0, niattribs, iattributes, 0, iresults, 0)) { + throw new GLException("Error getting pixel format attributes for pixel format " + (i + 1) + " of device context"); } + availableCaps[i] = WindowsWGLGraphicsConfiguration.AttribList2GLCapabilities(glProfile, iattributes, niattribs, iresults, + pixelFormatSet, onscreen, usePBuffer); + } + gotAvailableCaps = true; + } else { + long lastErr = WGL.GetLastError(); + // Intel Extreme graphics fails with a zero error code + if (lastErr != 0) { + throw new GLException("Unable to enumerate pixel formats of window using wglGetPixelFormatAttribivARB: error code " + WGL.GetLastError()); } } } @@ -264,7 +274,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio System.err.println(getThreadName() + ": Using ChoosePixelFormat because no wglChoosePixelFormatARB"); } } - pfd = WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(capabilities, !useOffScreen); + pfd = WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(capabilities); recommendedPixelFormat = WGL.ChoosePixelFormat(hdc, pfd); if (DEBUG) { System.err.println(getThreadName() + ": Recommended pixel format = " + recommendedPixelFormat); @@ -282,7 +292,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio if (WGL.DescribePixelFormat(hdc, 1 + i, pfd.size(), pfd) == 0) { throw new GLException("Error describing pixel format " + (1 + i) + " of device context"); } - availableCaps[i] = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, pfd); + availableCaps[i] = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, pfd, onscreen, usePBuffer); } } @@ -291,22 +301,24 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio // chooseCapabilities call, but for the time being, assume they // won't be changed - if(null!=chooser) { - // Supply information to chooser - try { - pixelFormat = chooser.chooseCapabilities(capabilities, availableCaps, recommendedPixelFormat); - } catch (NativeWindowException e) { - throw new GLException(e); + if(pixelFormat<=0) { + if(null!=chooser) { + // Supply information to chooser + try { + pixelFormat = chooser.chooseCapabilities(capabilities, availableCaps, recommendedPixelFormat); + } catch (NativeWindowException e) { + throw new GLException(e); + } + } else { + pixelFormat = recommendedPixelFormat; } - } else { - pixelFormat = recommendedPixelFormat; - } - if ((pixelFormat < 0) || (pixelFormat >= numFormats)) { - throw new GLException("Invalid result " + pixelFormat + - " from GLCapabilitiesChooser (should be between 0 and " + - (numFormats - 1) + ")"); + if ((pixelFormat < 0) || (pixelFormat >= numFormats)) { + throw new GLException("Invalid result " + pixelFormat + + " from GLCapabilitiesChooser (should be between 0 and " + + (numFormats - 1) + ")"); + } + pixelFormat += 1; // one-base the index } - pixelFormat += 1; // one-base the index chosenCaps = availableCaps[pixelFormat-1]; if (DEBUG) { System.err.println(getThreadName() + ": Chosen pixel format (" + pixelFormat + "):"); @@ -319,17 +331,20 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio // For now, use ChoosePixelFormat for offscreen surfaces until // we figure out how to properly choose an offscreen- // compatible pixel format - pfd = WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(capabilities, !useOffScreen); + pfd = WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(capabilities); pixelFormat = WGL.ChoosePixelFormat(hdc, pfd); } - if (!WGL.SetPixelFormat(hdc, pixelFormat, pfd)) { - long lastError = WGL.GetLastError(); - if (DEBUG) { - System.err.println(getThreadName() + ": SetPixelFormat failed: current context = " + WGL.wglGetCurrentContext() + - ", current DC = " + WGL.wglGetCurrentDC()); - System.err.println(getThreadName() + ": GetPixelFormat(hdc " + toHexString(hdc) + ") returns " + WGL.GetPixelFormat(hdc)); - } - throw new GLException("Unable to set pixel format " + pixelFormat + " for device context " + toHexString(hdc) + ": error code " + lastError); + if(!pixelFormatSet) { + if (!WGL.SetPixelFormat(hdc, pixelFormat, pfd)) { + long lastError = WGL.GetLastError(); + if (DEBUG) { + System.err.println(getThreadName() + ": SetPixelFormat failed: current context = " + WGL.wglGetCurrentContext() + + ", current DC = " + WGL.wglGetCurrentDC()); + System.err.println(getThreadName() + ": GetPixelFormat(hdc " + toHexString(hdc) + ") returns " + WGL.GetPixelFormat(hdc)); + } + throw new GLException("Unable to set pixel format " + pixelFormat + " for device context " + toHexString(hdc) + ": error code " + lastError); + } + pixelFormatSet=true; } // Reuse the previously-constructed GLCapabilities because it // turns out that using DescribePixelFormat on some pixel formats @@ -338,7 +353,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio if (chosenCaps != null) { capabilities = chosenCaps; } else { - capabilities = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, pfd); + capabilities = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, pfd, onscreen, usePBuffer); } config.setCapsPFD(capabilities, pfd, pixelFormat); } 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 6491c33da..0603f1cf0 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 @@ -40,6 +40,7 @@ package com.sun.opengl.impl.x11.glx; import javax.media.nativewindow.*; +import javax.media.nativewindow.x11.*; import javax.media.opengl.*; import com.sun.opengl.impl.*; import com.sun.nativewindow.impl.NullWindow; @@ -50,21 +51,42 @@ public class X11ExternalGLXContext extends X11GLXContext { private boolean created = true; private GLContext lastContext; - public X11ExternalGLXContext(AbstractGraphicsScreen screen) { - super(null, null); - getDrawableImpl().getFactoryImpl().lockToolkit(); + private X11ExternalGLXContext(Drawable drawable, long context) { + super(drawable, null); + this.drawable = drawable; + this.context = context; + GLContextShareSet.contextCreated(this); + setGLFunctionAvailability(false); + } + + protected static X11ExternalGLXContext create(GLDrawableFactory factory, GLProfile glp) { + ((GLDrawableFactoryImpl)factory).lockToolkit(); try { - context = GLX.glXGetCurrentContext(); - if (context == 0) { - throw new GLException("Error: attempted to make an external GLContext without a drawable/context current"); - } - NullWindow nw = new NullWindow(X11GLXGraphicsConfigurationFactory.createDefaultGraphicsConfiguration(screen, false)); - drawable = new Drawable(getGLDrawable().getFactory(), nw); + long context = GLX.glXGetCurrentContext(); + if (context == 0) { + throw new GLException("Error: current context null"); + } + long display = GLX.glXGetCurrentDisplay(); + if (display == 0) { + throw new GLException("Error: current display null"); + } + long drawable = GLX.glXGetCurrentDrawable(); + if (drawable == 0) { + throw new GLException("Error: attempted to make an external GLDrawable without a drawable/context current"); + } + int[] val = new int[1]; + GLX.glXQueryContext(display, context, GLX.GLX_SCREEN, val, 0); + X11GraphicsScreen x11Screen = (X11GraphicsScreen) X11GraphicsScreen.createScreenDevice(display, val[0]); + + GLX.glXQueryContext(display, context, GLX.GLX_FBCONFIG_ID, val, 0); + X11GLXGraphicsConfiguration cfg = X11GLXGraphicsConfiguration.create(glp, x11Screen, val[0]); + + NullWindow nw = new NullWindow(cfg); + nw.setSurfaceHandle(drawable); + return new X11ExternalGLXContext(new Drawable(factory, nw), context); } finally { - getDrawableImpl().getFactoryImpl().unlockToolkit(); + ((GLDrawableFactoryImpl)factory).unlockToolkit(); } - GLContextShareSet.contextCreated(this); - setGLFunctionAvailability(false); } protected void create() { @@ -108,7 +130,7 @@ public class X11ExternalGLXContext extends X11GLXContext { } // Need to provide the display connection to extension querying APIs - class Drawable extends X11GLXDrawable { + static class Drawable extends X11GLXDrawable { Drawable(GLDrawableFactory factory, NativeWindow comp) { super(factory, comp, true); } diff --git a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11ExternalGLXDrawable.java b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11ExternalGLXDrawable.java index 9a5e42382..75a6b221a 100755 --- a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11ExternalGLXDrawable.java +++ b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11ExternalGLXDrawable.java @@ -40,6 +40,7 @@ package com.sun.opengl.impl.x11.glx; import javax.media.nativewindow.*; +import javax.media.nativewindow.x11.*; import javax.media.opengl.*; import com.sun.opengl.impl.*; import com.sun.nativewindow.impl.NullWindow; @@ -50,54 +51,58 @@ import com.sun.gluegen.runtime.PointerBuffer; public class X11ExternalGLXDrawable extends X11GLXDrawable { private int fbConfigID; private int renderType; - private long readDrawable; - private X11ExternalGLXDrawable(GLDrawableFactory factory, NativeWindow component) { + private X11ExternalGLXDrawable(GLDrawableFactory factory, NativeWindow component, int renderType) { super(factory, component, true); - readDrawable = GLX.glXGetCurrentReadDrawable(); + this.renderType = renderType; // Need GLXFBConfig ID in order to properly create new contexts // on this drawable - long display = getNativeWindow().getDisplayHandle(); - long context = GLX.glXGetCurrentContext(); - int[] val = new int[1]; - GLX.glXQueryContext(display, context, GLX.GLX_FBCONFIG_ID, val, 0); - fbConfigID = val[0]; - renderType = GLX.GLX_RGBA_TYPE; - GLX.glXQueryContext(display, context, GLX.GLX_RENDER_TYPE, val, 0); - if ((val[0] & GLX.GLX_RGBA_BIT) == 0) { - if (DEBUG) { - System.err.println("X11ExternalGLXDrawable: WARNING: forcing GLX_RGBA_TYPE for newly created contexts"); - } - } + X11GLXGraphicsConfiguration cfg = (X11GLXGraphicsConfiguration) component.getGraphicsConfiguration(); + fbConfigID = cfg.getFBConfigID(); } - protected static X11ExternalGLXDrawable create(GLDrawableFactory factory, AbstractGraphicsScreen aScreen) { - ((GLDrawableFactoryImpl) factory).lockToolkit(); + protected static X11ExternalGLXDrawable create(GLDrawableFactory factory, GLProfile glp) { + ((GLDrawableFactoryImpl)factory).lockToolkit(); try { - long display = GLX.glXGetCurrentDisplay(); - long context = GLX.glXGetCurrentContext(); - int[] val = new int[1]; - GLX.glXQueryContext(display, context, GLX.GLX_SCREEN, val, 0); - int screen = val[0]; - long drawable = GLX.glXGetCurrentDrawable(); - if (drawable == 0) { - throw new GLException("Error: attempted to make an external GLDrawable without a drawable/context current"); - } - - if(screen!=aScreen.getIndex()) { - throw new GLException("Error: Passed AbstractGraphicsScreen's index is not current: "+aScreen+", GLX-screen "+screen); - } - if(display!=aScreen.getDevice().getHandle()) { - throw new GLException("Error: Passed AbstractGraphicsScreen's display is not current: "+aScreen+", GLX-display 0x"+Long.toHexString(display)); - } - - NullWindow nw = new NullWindow(X11GLXGraphicsConfigurationFactory.createDefaultGraphicsConfiguration(aScreen, false)); - nw.setSurfaceHandle(drawable); - return new X11ExternalGLXDrawable(factory, nw); + long context = GLX.glXGetCurrentContext(); + if (context == 0) { + throw new GLException("Error: current context null"); + } + long display = GLX.glXGetCurrentDisplay(); + if (display == 0) { + throw new GLException("Error: current display null"); + } + long drawable = GLX.glXGetCurrentDrawable(); + if (drawable == 0) { + throw new GLException("Error: attempted to make an external GLDrawable without a drawable current"); + } + int[] val = new int[1]; + GLX.glXQueryContext(display, context, GLX.GLX_SCREEN, val, 0); + X11GraphicsScreen x11Screen = (X11GraphicsScreen) X11GraphicsScreen.createScreenDevice(display, val[0]); + + GLX.glXQueryContext(display, context, GLX.GLX_FBCONFIG_ID, val, 0); + X11GLXGraphicsConfiguration cfg = X11GLXGraphicsConfiguration.create(glp, x11Screen, val[0]); + + int w, h; + GLX.glXQueryDrawable(display, drawable, GLX.GLX_WIDTH, val, 0); + w=val[0]; + GLX.glXQueryDrawable(display, drawable, GLX.GLX_HEIGHT, val, 0); + h=val[0]; + + GLX.glXQueryContext(display, context, GLX.GLX_RENDER_TYPE, val, 0); + if ((val[0] & GLX.GLX_RGBA_TYPE) == 0) { + if (DEBUG) { + System.err.println("X11ExternalGLXDrawable: WARNING: forcing GLX_RGBA_TYPE for newly created contexts (current 0x"+Integer.toHexString(val[0])+")"); + } + } + NullWindow nw = new NullWindow(cfg); + nw.setSurfaceHandle(drawable); + nw.setSize(w, h); + return new X11ExternalGLXDrawable(factory, nw, GLX.GLX_RGBA_TYPE); } finally { - ((GLDrawableFactoryImpl) factory).unlockToolkit(); + ((GLDrawableFactoryImpl)factory).unlockToolkit(); } } @@ -110,11 +115,11 @@ public class X11ExternalGLXDrawable extends X11GLXDrawable { } public int getWidth() { - throw new GLException("Should not call this"); + return getNativeWindow().getWidth(); } public int getHeight() { - throw new GLException("Should not call this"); + return getNativeWindow().getHeight(); } class Context extends X11GLXContext { @@ -122,113 +127,8 @@ public class X11ExternalGLXDrawable extends X11GLXDrawable { super(drawable, shareWith); } - protected int makeCurrentImpl() throws GLException { - if (drawable.getNativeWindow().getSurfaceHandle() == 0) { - // parent drawable not properly initialized - // FIXME: signal error? - if (DEBUG) { - System.err.println("parent drawable not properly initialized"); - } - return CONTEXT_NOT_CURRENT; - } - - // Note that we have to completely override makeCurrentImpl - // because the underlying makeCurrent call differs from the norm - getFactoryImpl().lockToolkit(); - try { - boolean created = false; - if (context == 0) { - create(); - if (DEBUG) { - System.err.println(getThreadName() + ": !!! Created GL context for " + getClass().getName()); - } - created = true; - } - - if (!GLX.glXMakeContextCurrent(drawable.getNativeWindow().getDisplayHandle(), - drawable.getNativeWindow().getSurfaceHandle(), - readDrawable, - context)) { - throw new GLException("Error making context current"); - } else { - if (DEBUG && VERBOSE) { - System.err.println(getThreadName() + ": glXMakeCurrent(display " + toHexString(drawable.getNativeWindow().getDisplayHandle()) + - ", drawable " + toHexString(drawable.getNativeWindow().getSurfaceHandle()) + - ", context " + toHexString(context) + ") succeeded"); - } - } - - if (created) { - setGLFunctionAvailability(false); - return CONTEXT_CURRENT_NEW; - } - return CONTEXT_CURRENT; - } finally { - getFactoryImpl().unlockToolkit(); - } - } - - protected void releaseImpl() throws GLException { - getFactoryImpl().lockToolkit(); - try { - if (!GLX.glXMakeContextCurrent(drawable.getNativeWindow().getDisplayHandle(), 0, 0, 0)) { - throw new GLException("Error freeing OpenGL context"); - } - } finally { - getFactoryImpl().unlockToolkit(); - } - } - protected void create() { - long display = getNativeWindow().getDisplayHandle(); - int screen = getNativeWindow().getScreenIndex(); - // We already have the GLXFBConfig ID for the context. All we - // need to do is use it to choose the GLXFBConfig and then - // create a context with it. - int[] iattributes = new int[] { - GLX.GLX_FBCONFIG_ID, - fbConfigID, - 0, - 0 - }; - float[] fattributes = new float[0]; - int[] nelementsTmp = new int[1]; - PointerBuffer fbConfigs = GLX.glXChooseFBConfigCopied(display, screen, iattributes, 0, nelementsTmp, 0); - int nelements = nelementsTmp[0]; - if (nelements <= 0) { - throw new GLException("context creation error: couldn't find a suitable frame buffer configuration"); - } - if (nelements != 1) { - throw new GLException("context creation error: shouldn't get more than one GLXFBConfig"); - } - // Note that we currently don't allow selection of anything but - // the first GLXFBConfig in the returned list (there should be only one) - long fbConfig = fbConfigs.get(0); - // Create a gl context for the drawable - X11GLXContext other = (X11GLXContext) GLContextShareSet.getShareContext(this); - long share = 0; - if (other != null) { - share = other.getContext(); - if (share == 0) { - throw new GLException("GLContextShareSet returned an invalid OpenGL context"); - } - } - // FIXME: how to determine "direct" bit? - context = GLX.glXCreateNewContext(display, fbConfig, renderType, share, true); - if (context == 0) { - String detail = " display=" + toHexString(display) + - " fbconfig=" + fbConfig + - " fbconfigID=" + toHexString(fbConfigID) + - " renderType=" + toHexString(renderType) + - " share=" + toHexString(share); - throw new GLException("context creation error: glXCreateNewContext() failed: " + detail); - } - GLContextShareSet.contextCreated(this); - - if (DEBUG) { - System.err.println("Created context " + toHexString(context) + - " for GLXDrawable " + toHexString(drawable.getNativeWindow().getSurfaceHandle())); - } + createContext(true); } } } diff --git a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXContext.java b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXContext.java index 7029b81b0..57abcf588 100644 --- a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXContext.java +++ b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXContext.java @@ -117,8 +117,15 @@ public abstract class X11GLXContext extends GLContextImpl { /** * Creates and initializes an appropriate OpenGL context. Should only be * called by {@link create()}. + * Note: The direct parameter may be overwritten by the direct state of a shared context. */ - protected void createContext(boolean onscreen) { + protected void createContext(boolean direct) { + X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + if(DEBUG) { + System.err.println("X11GLXContext.createContext got "+config); + } + long display = config.getScreen().getDevice().getHandle(); + X11GLXContext other = (X11GLXContext) GLContextShareSet.getShareContext(this); long share = 0; if (other != null) { @@ -126,14 +133,10 @@ public abstract class X11GLXContext extends GLContextImpl { if (share == 0) { throw new GLException("GLContextShareSet returned an invalid OpenGL context"); } + direct = GLX.glXIsDirect(display, share); } - X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); - if(DEBUG) { - System.err.println("X11GLXContext.createContext got "+config); - } GLCapabilities glCaps = (GLCapabilities) config.getChosenCapabilities(); - long display = config.getScreen().getDevice().getHandle(); isVendorATI = GLXUtil.isVendorATI(display); if(config.getFBConfigID()<0) { @@ -141,7 +144,7 @@ public abstract class X11GLXContext extends GLContextImpl { if(glCaps.getGLProfile().isGL3()) { throw new GLException("Unable to create OpenGL 3.1 context"); } - context = GLX.glXCreateContext(display, config.getXVisualInfo(), share, onscreen); + context = GLX.glXCreateContext(display, config.getXVisualInfo(), share, direct); if (context == 0) { throw new GLException("Unable to create OpenGL context"); } @@ -160,7 +163,7 @@ public abstract class X11GLXContext extends GLContextImpl { // To use GLX_ARB_create_context, we have to make a temp context current, // so we are able to use GetProcAddress - long temp_context = GLX.glXCreateNewContext(display, config.getFBConfig(), GLX.GLX_RGBA_TYPE, share, onscreen); + long temp_context = GLX.glXCreateNewContext(display, config.getFBConfig(), GLX.GLX_RGBA_TYPE, share, direct); if (temp_context == 0) { throw new GLException("Unable to create temp OpenGL context"); } else { @@ -205,7 +208,7 @@ public abstract class X11GLXContext extends GLContextImpl { attribs[5] |= GLX.GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB /* | GLX.GLX_CONTEXT_DEBUG_BIT_ARB */; } - context = glXExt.glXCreateContextAttribsARB(display, config.getFBConfig(), share, onscreen, attribs, 0); + context = glXExt.glXCreateContextAttribsARB(display, config.getFBConfig(), share, direct, attribs, 0); if(0==context) { if(glCaps.getGLProfile().isGL3()) { if (!GLX.glXMakeContextCurrent(display, 0, 0, 0)) { @@ -245,41 +248,46 @@ public abstract class X11GLXContext extends GLContextImpl { } protected int makeCurrentImpl() throws GLException { - if (drawable.getNativeWindow().getSurfaceHandle() == 0) { - if (DEBUG) { - System.err.println("drawable not properly initialized"); + getDrawableImpl().getFactoryImpl().lockToolkit(); + try { + if (drawable.getNativeWindow().getSurfaceHandle() == 0) { + if (DEBUG) { + System.err.println("drawable not properly initialized"); + } + return CONTEXT_NOT_CURRENT; } - return CONTEXT_NOT_CURRENT; - } - boolean created = false; - if (context == 0) { - create(); - if (DEBUG) { - System.err.println(getThreadName() + ": !!! Created GL context for " + getClass().getName()); - } - created = true; - } - - if (GLX.glXGetCurrentContext() != context) { - if (!GLX.glXMakeContextCurrent(drawable.getNativeWindow().getDisplayHandle(), - drawable.getNativeWindow().getSurfaceHandle(), - drawable.getNativeWindow().getSurfaceHandle(), - context)) { - throw new GLException("Error making context current"); + boolean created = false; + if (context == 0) { + create(); + if (DEBUG) { + System.err.println(getThreadName() + ": !!! Created GL context for " + getClass().getName()); + } + created = true; } - if (DEBUG && (VERBOSE || created)) { - System.err.println(getThreadName() + ": glXMakeCurrent(display " + - toHexString(drawable.getNativeWindow().getDisplayHandle()) + - ", drawable " + toHexString(drawable.getNativeWindow().getSurfaceHandle()) + - ", context " + toHexString(context) + ") succeeded"); + + if (GLX.glXGetCurrentContext() != context) { + if (!GLX.glXMakeContextCurrent(drawable.getNativeWindow().getDisplayHandle(), + drawable.getNativeWindow().getSurfaceHandle(), + drawable.getNativeWindow().getSurfaceHandle(), + context)) { + throw new GLException("Error making context current"); + } + if (DEBUG && (VERBOSE || created)) { + System.err.println(getThreadName() + ": glXMakeCurrent(display " + + toHexString(drawable.getNativeWindow().getDisplayHandle()) + + ", drawable " + toHexString(drawable.getNativeWindow().getSurfaceHandle()) + + ", context " + toHexString(context) + ") succeeded"); + } } - } - if (created) { - setGLFunctionAvailability(false); - return CONTEXT_CURRENT_NEW; + if (created) { + setGLFunctionAvailability(false); + return CONTEXT_CURRENT_NEW; + } + return CONTEXT_CURRENT; + } finally { + getDrawableImpl().getFactoryImpl().unlockToolkit(); } - return CONTEXT_CURRENT; } protected void releaseImpl() throws GLException { @@ -386,14 +394,23 @@ public abstract class X11GLXContext extends GLContextImpl { } + private int hasSwapIntervalSGI = 0; + public void setSwapInterval(int interval) { getDrawableImpl().getFactoryImpl().lockToolkit(); try { // FIXME: make the context current first? Currently assumes that // will not be necessary. Make the caller do this? GLXExt glXExt = getGLXExt(); - if (glXExt.isExtensionAvailable("GLX_SGI_swap_control")) { - glXExt.glXSwapIntervalSGI(interval); + if(0==hasSwapIntervalSGI) { + try { + hasSwapIntervalSGI = glXExt.isExtensionAvailable("GLX_SGI_swap_control")?1:-1; + } catch (Throwable t) { hasSwapIntervalSGI=1; } + } + if (hasSwapIntervalSGI>0) { + try { + glXExt.glXSwapIntervalSGI(interval); + } catch (Throwable t) { hasSwapIntervalSGI=-1; } } } finally { getDrawableImpl().getFactoryImpl().unlockToolkit(); diff --git a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXDrawable.java b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXDrawable.java index a454cc429..738714ecb 100644 --- a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXDrawable.java +++ b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXDrawable.java @@ -67,6 +67,7 @@ public abstract class X11GLXDrawable extends GLDrawableImpl { try { X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); config.updateGraphicsConfiguration(); + if (DEBUG) { System.err.println("!!! X11GLXDrawable.setRealized(true): "+config); } @@ -75,6 +76,29 @@ public abstract class X11GLXDrawable extends GLDrawableImpl { } } + public void swapBuffers() throws GLException { + GLCapabilities caps = (GLCapabilities)getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities(); + if (caps.getDoubleBuffered()) { + boolean didLock = false; + try { + if ( !isSurfaceLocked() ) { + // Usually the surface shall be locked within [makeCurrent .. swap .. release] + if (lockSurface() == NativeWindow.LOCK_SURFACE_NOT_READY) { + return; + } + didLock=true; + } + + GLX.glXSwapBuffers(component.getDisplayHandle(), component.getSurfaceHandle()); + + } finally { + if(didLock) { + unlockSurface(); + } + } + } + } + //--------------------------------------------------------------------------- // Internals only below this point // diff --git a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXDrawableFactory.java index de211af79..acca5fe81 100644 --- a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXDrawableFactory.java +++ b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXDrawableFactory.java @@ -140,8 +140,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements Dyna } public GLContext createExternalGLContext() { - AbstractGraphicsScreen screen = X11GraphicsScreen.createDefault(); - return new X11ExternalGLXContext(screen); + return X11ExternalGLXContext.create(this, null); } public boolean canCreateExternalGLDrawable() { @@ -149,8 +148,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements Dyna } public GLDrawable createExternalGLDrawable() { - AbstractGraphicsScreen screen = X11GraphicsScreen.createDefault(); - return X11ExternalGLXDrawable.create(this, screen); + return X11ExternalGLXDrawable.create(this, null); } public void loadGLULibrary() { diff --git a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java index 7b59a8d56..4cd174bec 100644 --- a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java +++ b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java @@ -38,6 +38,7 @@ import javax.media.nativewindow.x11.*; import javax.media.opengl.*; import com.sun.opengl.impl.*; import com.sun.gluegen.runtime.NativeLibrary; +import com.sun.gluegen.runtime.PointerBuffer; import com.sun.nativewindow.impl.x11.*; public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implements Cloneable { @@ -57,6 +58,30 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem fbConfigID = fbcfgID; } + public static X11GLXGraphicsConfiguration create(GLProfile glp, X11GraphicsScreen x11Screen, int fbcfgID) { + long display = x11Screen.getDevice().getHandle(); + if(0==display) { + throw new GLException("Display null of "+x11Screen); + } + int screen = x11Screen.getIndex(); + long fbcfg = glXFBConfigID2FBConfig(display, screen, fbcfgID); + if(0==fbcfg) { + throw new GLException("FBConfig null of 0x"+Integer.toHexString(fbcfgID)); + } + if(null==glp) { + glp = GLProfile.getDefault(); + } + GLCapabilities caps = GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, GLXUtil.isMultisampleAvailable(display)); + if(null==caps) { + throw new GLException("GLCapabilities null of 0x"+Long.toHexString(fbcfg)); + } + XVisualInfo xvi = GLX.glXGetVisualFromFBConfigCopied(display, fbcfg); + if(null==xvi) { + throw new GLException("XVisualInfo null of 0x"+Long.toHexString(fbcfg)); + } + return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser(), xvi, fbcfg, fbcfgID); + } + public Object clone() { return super.clone(); } @@ -84,7 +109,6 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem public static int[] GLCapabilities2AttribList(GLCapabilities caps, boolean forFBAttr, boolean isMultisampleAvailable, - boolean usePBuffer, long display, int screen) { @@ -99,7 +123,7 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem if (forFBAttr) { res[idx++] = GLX.GLX_DRAWABLE_TYPE; - res[idx++] = usePBuffer?GLX.GLX_PBUFFER_BIT:GLX.GLX_WINDOW_BIT; + res[idx++] = caps.isOnscreen() ? ( GLX.GLX_WINDOW_BIT ) : ( caps.isPBuffer() ? GLX.GLX_PBUFFER_BIT : GLX.GLX_PIXMAP_BIT ) ; } if (forFBAttr) { @@ -169,7 +193,7 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem res[idx++] = GLX.GLX_SAMPLES; res[idx++] = caps.getNumSamples(); } - if (usePBuffer) { + if (caps.isPBuffer()) { if (caps.getPbufferFloatingPointBuffers()) { String glXExtensions = GLX.glXQueryExtensionsString(display, screen); if (glXExtensions == null || @@ -184,111 +208,33 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem return res; } - public static GLCapabilities AttribList2GLCapabilities(GLProfile glp, - int[] iattribs, - int niattribs, - int[] ivalues, - boolean usePBuffer) { - GLCapabilities caps = new GLCapabilities(glp); - - for (int i = 0; i < niattribs; i++) { - int attr = iattribs[i]; - switch (attr) { - case GLX.GLX_DOUBLEBUFFER: - caps.setDoubleBuffered(ivalues[i] != GL.GL_FALSE); - break; - - case GLX.GLX_STEREO: - caps.setStereo(ivalues[i] != GL.GL_FALSE); - break; - - case GLX.GLX_RED_SIZE: - caps.setRedBits(ivalues[i]); - break; - - case GLX.GLX_GREEN_SIZE: - caps.setGreenBits(ivalues[i]); - break; - - case GLX.GLX_BLUE_SIZE: - caps.setBlueBits(ivalues[i]); - break; - - case GLX.GLX_ALPHA_SIZE: - caps.setAlphaBits(ivalues[i]); - break; - - case GLX.GLX_DEPTH_SIZE: - caps.setDepthBits(ivalues[i]); - break; - - case GLX.GLX_STENCIL_SIZE: - caps.setStencilBits(ivalues[i]); - break; - - case GLX.GLX_ACCUM_RED_SIZE: - caps.setAccumRedBits(ivalues[i]); - break; - - case GLX.GLX_ACCUM_GREEN_SIZE: - caps.setAccumGreenBits(ivalues[i]); - break; - - case GLX.GLX_ACCUM_BLUE_SIZE: - caps.setAccumBlueBits(ivalues[i]); - break; - - case GLX.GLX_ACCUM_ALPHA_SIZE: - caps.setAccumAlphaBits(ivalues[i]); - break; - - case GLX.GLX_SAMPLE_BUFFERS: - caps.setSampleBuffers(ivalues[i] != GL.GL_FALSE); - break; - - case GLX.GLX_SAMPLES: - caps.setNumSamples(ivalues[i]); - break; - - case GLX.GLX_CONFIG_CAVEAT: - caps.setHardwareAccelerated(ivalues[i] != GLX.GLX_SLOW_CONFIG); - break; - - case GLX.GLX_TRANSPARENT_TYPE: - caps.setBackgroundOpaque(ivalues[i] == GLX.GLX_NONE); - break; - - case GLXExt.GLX_FLOAT_COMPONENTS_NV: - caps.setPbufferFloatingPointBuffers(ivalues[i] != GL.GL_FALSE); - break; - - case GLX.GLX_TRANSPARENT_RED_VALUE: - caps.setTransparentRedValue(ivalues[i]); - break; - - case GLX.GLX_TRANSPARENT_GREEN_VALUE: - caps.setTransparentGreenValue(ivalues[i]); - break; - - case GLX.GLX_TRANSPARENT_BLUE_VALUE: - caps.setTransparentBlueValue(ivalues[i]); - break; - - case GLX.GLX_TRANSPARENT_ALPHA_VALUE: - caps.setTransparentAlphaValue(ivalues[i]); - break; - - default: - break; - } - } + // FBConfig - return caps; + public static boolean GLXFBConfigValid(long display, long fbcfg) { + int[] tmp = new int[1]; + if(GLX.GLX_BAD_ATTRIBUTE == GLX.glXGetFBConfigAttrib(display, fbcfg, GLX.GLX_RENDER_TYPE, tmp, 0)) { + return false; + } + return true; } - // FBConfig + public static boolean GLXFBConfigDrawableTypeVerify(int val, boolean onscreen, boolean usePBuffer) { + boolean res; - public static GLCapabilities GLXFBConfig2GLCapabilities(GLProfile glp, long display, long fbcfg, boolean isMultisampleEnabled) { + if ( onscreen ) { + res = ( 0 != (val & GLX.GLX_WINDOW_BIT) ) ; + } else { + res = ( 0 != (val & GLX.GLX_PIXMAP_BIT) ) || usePBuffer ; + } + if ( usePBuffer ) { + res = res && ( 0 != (val & GLX.GLX_PBUFFER_BIT) ) ; + } + + return res; + } + + public static GLCapabilities GLXFBConfig2GLCapabilities(GLProfile glp, long display, long fbcfg, + boolean relaxed, boolean onscreen, boolean usePBuffer, boolean isMultisampleEnabled) { int[] tmp = new int[1]; int val; val = glXGetFBConfig(display, fbcfg, GLX.GLX_RENDER_TYPE, tmp, 0); @@ -296,6 +242,17 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem throw new GLException("Visual does not support RGBA"); } GLCapabilities res = new GLCapabilities(glp); + + val = glXGetFBConfig(display, fbcfg, GLX.GLX_DRAWABLE_TYPE, tmp, 0); + if(GLXFBConfigDrawableTypeVerify(val, onscreen, usePBuffer)) { + res.setOnscreen(onscreen); + res.setPBuffer(usePBuffer); + } else if(relaxed) { + res.setOnscreen( 0 != (val & GLX.GLX_WINDOW_BIT) ); + res.setPBuffer ( 0 != (val & GLX.GLX_PBUFFER_BIT) ); + } else { + return null; + } res.setDoubleBuffered(glXGetFBConfig(display, fbcfg, GLX.GLX_DOUBLEBUFFER, tmp, 0) != 0); res.setStereo (glXGetFBConfig(display, fbcfg, GLX.GLX_STEREO, tmp, 0) != 0); res.setHardwareAccelerated(glXGetFBConfig(display, fbcfg, GLX.GLX_CONFIG_CAVEAT, tmp, 0) != GLX.GLX_SLOW_CONFIG); @@ -352,6 +309,21 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem return tmp[tmp_offset]; } + public static int glXFBConfig2FBConfigID(long display, long cfg) { + int[] tmpID = new int[1]; + return glXGetFBConfig(display, cfg, GLX.GLX_FBCONFIG_ID, tmpID, 0); + } + + public static long glXFBConfigID2FBConfig(long display, int screen, int id) { + int[] attribs = new int[] { GLX.GLX_FBCONFIG_ID, id, 0 }; + int[] count = { -1 }; + PointerBuffer fbcfgsL = GLX.glXChooseFBConfigCopied(display, screen, attribs, 0, count, 0); + if (fbcfgsL == null || fbcfgsL.limit()<1) { + return 0; + } + return fbcfgsL.get(0); + } + // Visual Info public static XVisualInfo XVisualID2XVisualInfo(long display, long visualID) { @@ -376,7 +348,7 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem return res; } - public static GLCapabilities XVisualInfo2GLCapabilities(GLProfile glp, long display, XVisualInfo info, boolean isMultisampleEnabled) { + public static GLCapabilities XVisualInfo2GLCapabilities(GLProfile glp, long display, XVisualInfo info, boolean onscreen, boolean usePBuffer, boolean isMultisampleEnabled) { int[] tmp = new int[1]; int val = glXGetConfig(display, info, GLX.GLX_USE_GL, tmp, 0); if (val == 0) { @@ -387,6 +359,8 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem throw new GLException("Visual does not support RGBA"); } GLCapabilities res = new GLCapabilities(glp); + res.setOnscreen (onscreen); + res.setPBuffer (usePBuffer); res.setDoubleBuffered(glXGetConfig(display, info, GLX.GLX_DOUBLEBUFFER, tmp, 0) != 0); res.setStereo (glXGetConfig(display, info, GLX.GLX_STEREO, tmp, 0) != 0); // Note: use of hardware acceleration is determined by diff --git a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java index 0fcb9b3ff..9cb7eac08 100644 --- a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java +++ b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java @@ -58,10 +58,10 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac public AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities, CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) { - return chooseGraphicsConfigurationStatic(capabilities, chooser, absScreen, false); + return chooseGraphicsConfigurationStatic(capabilities, chooser, absScreen, capabilities.isOnscreen(), false); } - protected static X11GLXGraphicsConfiguration createDefaultGraphicsConfiguration(AbstractGraphicsScreen absScreen, boolean usePBuffer) { + protected static X11GLXGraphicsConfiguration createDefaultGraphicsConfiguration(AbstractGraphicsScreen absScreen, boolean onscreen, boolean usePBuffer) { if (absScreen == null) { throw new IllegalArgumentException("AbstractGraphicsScreen is null"); } @@ -87,19 +87,18 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac long visID = X11Lib.DefaultVisualID(display, x11Screen.getIndex()); xvis = X11GLXGraphicsConfiguration.XVisualID2XVisualInfo(display, visID); - caps = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(glProfile, display, xvis, isMultisampleAvailable); + caps = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(glProfile, display, xvis, onscreen, usePBuffer, isMultisampleAvailable); - int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(caps, true, isMultisampleAvailable, usePBuffer, 0, 0); + int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(caps, true, isMultisampleAvailable, 0, 0); int[] count = { -1 }; PointerBuffer fbcfgsL = GLX.glXChooseFBConfigCopied(display, screen, attribs, 0, count, 0); if (fbcfgsL == null || fbcfgsL.limit()<1) { throw new Exception("Could not fetch FBConfig for "+caps); } fbcfg = fbcfgsL.get(0); - capsFB = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfg, isMultisampleAvailable); + capsFB = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfg, true, onscreen, usePBuffer, isMultisampleAvailable); - int[] tmpID = new int[1]; - fbid = X11GLXGraphicsConfiguration.glXGetFBConfig(display, fbcfg, GLX.GLX_FBCONFIG_ID, tmpID, 0); + fbid = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfg); xvis = GLX.glXGetVisualFromFBConfigCopied(display, fbcfg); if (xvis==null) { @@ -110,13 +109,13 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); } - return new X11GLXGraphicsConfiguration(x11Screen, (null!=capsFB)?capsFB:caps, caps, null, xvis, fbcfg, fbid); + return new X11GLXGraphicsConfiguration(x11Screen, (null!=capsFB)?capsFB:caps, caps, null, xvis, fbcfg, fbid); } protected static X11GLXGraphicsConfiguration chooseGraphicsConfigurationStatic(Capabilities capabilities, CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen, - boolean usePBuffer) { + boolean onscreen, boolean usePBuffer) { if (absScreen == null) { throw new IllegalArgumentException("AbstractGraphicsScreen is null"); } @@ -139,12 +138,16 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac if (capabilities == null) { capabilities = new GLCapabilities(null); } - + capabilities.setOnscreen (onscreen); + ((GLCapabilities)capabilities).setPBuffer (usePBuffer); + if(!onscreen) { + ((GLCapabilities)capabilities).setDoubleBuffered(false); + } X11GLXGraphicsConfiguration res; res = chooseGraphicsConfigurationFBConfig((GLCapabilities) capabilities, (GLCapabilitiesChooser) chooser, - x11Screen, usePBuffer); + x11Screen); if(null==res) { if(usePBuffer) { throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig"); @@ -164,8 +167,7 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac protected static X11GLXGraphicsConfiguration chooseGraphicsConfigurationFBConfig(GLCapabilities capabilities, GLCapabilitiesChooser chooser, - X11GraphicsScreen x11Screen, - boolean usePBuffer) { + X11GraphicsScreen x11Screen) { int recommendedIndex = -1; GLCapabilities[] caps = null; PointerBuffer fbcfgsL = null; @@ -173,6 +175,8 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac int retFBID=-1; XVisualInfo retXVisualInfo = null; GLProfile glProfile = capabilities.getGLProfile(); + boolean onscreen = capabilities.isOnscreen(); + boolean usePBuffer = capabilities.isPBuffer(); // Utilizing FBConfig // @@ -182,7 +186,7 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac AbstractGraphicsDevice absDevice = x11Screen.getDevice(); long display = absDevice.getHandle(); boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); - int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capabilities, true, isMultisampleAvailable, usePBuffer, 0, 0); + int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capabilities, true, isMultisampleAvailable, 0, 0); int[] count = { -1 }; fbcfgsL = GLX.glXChooseFBConfigCopied(display, screen, attribs, 0, count, 0); @@ -192,10 +196,17 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac } return null; } + if( !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfgsL.get(0) ) ) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: GLX FBConfig invalid: ("+x11Screen+","+capabilities+"): "+fbcfgsL+", fbcfg: 0x"+Long.toHexString(fbcfgsL.get(0))); + } + return null; + } recommendedIndex = 0; // 1st match is always recommended .. caps = new GLCapabilities[fbcfgsL.limit()]; for (int i = 0; i < fbcfgsL.limit(); i++) { - caps[i] = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfgsL.get(i), isMultisampleAvailable); + caps[i] = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfgsL.get(i), + false, onscreen, usePBuffer, isMultisampleAvailable); } if(null==chooser) { @@ -212,8 +223,7 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac throw new GLException("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ")"); } - int[] tmpID = new int[1]; - retFBID = X11GLXGraphicsConfiguration.glXGetFBConfig(display, fbcfgsL.get(chosen), GLX.GLX_FBCONFIG_ID, tmpID, 0); + retFBID = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfgsL.get(chosen)); retXVisualInfo = GLX.glXGetVisualFromFBConfigCopied(display, fbcfgsL.get(chosen)); if (retXVisualInfo==null) { @@ -241,6 +251,7 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac // system's selection to the chooser as a hint GLProfile glProfile = capabilities.getGLProfile(); + boolean onscreen = capabilities.isOnscreen(); GLCapabilities[] caps = null; int recommendedIndex = -1; XVisualInfo retXVisualInfo = null; @@ -252,7 +263,7 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac AbstractGraphicsDevice absDevice = x11Screen.getDevice(); long display = absDevice.getHandle(); boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); - int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capabilities, false, isMultisampleAvailable, false, 0, 0); + int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capabilities, false, isMultisampleAvailable, 0, 0); XVisualInfo[] infos = null; XVisualInfo recommendedVis = GLX.glXChooseVisualCopied(display, screen, attribs, 0); @@ -273,7 +284,7 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac } caps = new GLCapabilities[infos.length]; for (int i = 0; i < infos.length; i++) { - caps[i] = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(glProfile, display, infos[i], isMultisampleAvailable); + caps[i] = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(glProfile, display, infos[i], onscreen, false, isMultisampleAvailable); // Attempt to find the visual chosen by glXChooseVisual if (recommendedVis != null && recommendedVis.visualid() == infos[i].visualid()) { recommendedIndex = i; diff --git a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11OffscreenGLXContext.java b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11OffscreenGLXContext.java index c6d787f2b..7a38f0ce1 100644 --- a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11OffscreenGLXContext.java +++ b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11OffscreenGLXContext.java @@ -58,7 +58,8 @@ public class X11OffscreenGLXContext extends X11GLXContext { } public int getOffscreenContextReadBuffer() { - if (drawable.isDoubleBuffered()) { + GLCapabilities caps = (GLCapabilities)drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities(); + if (caps.getDoubleBuffered()) { return GL.GL_BACK; } return GL.GL_FRONT; @@ -70,15 +71,6 @@ public class X11OffscreenGLXContext extends X11GLXContext { return true; } - protected int makeCurrentImpl() throws GLException { - getDrawableImpl().getFactoryImpl().lockToolkit(); - try { - return super.makeCurrentImpl(); - } finally { - getDrawableImpl().getFactoryImpl().unlockToolkit(); - } - } - protected void create() { createContext(false); } diff --git a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java index 69ecc34d2..51938df5f 100644 --- a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java +++ b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java @@ -47,14 +47,13 @@ import com.sun.nativewindow.impl.x11.*; public class X11OffscreenGLXDrawable extends X11GLXDrawable { private long pixmap; - private boolean isDoubleBuffered; protected X11OffscreenGLXDrawable(GLDrawableFactory factory, AbstractGraphicsScreen screen, GLCapabilities caps, GLCapabilitiesChooser chooser, int width, int height) { - super(factory, new NullWindow(X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(caps, chooser, screen, false)), true); + super(factory, new NullWindow(X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(caps, chooser, screen, false, false)), true); ((NullWindow) getNativeWindow()).setSize(width, height); create(); } @@ -87,7 +86,6 @@ public class X11OffscreenGLXDrawable extends X11GLXDrawable { throw new GLException("glXCreateGLXPixmap failed"); } nw.setSurfaceHandle(drawable); - isDoubleBuffered = (X11GLXGraphicsConfiguration.glXGetConfig(dpy, vis, GLX.GLX_DOUBLEBUFFER, new int[1], 0) != 0); if (DEBUG) { System.err.println("Created pixmap " + toHexString(pixmap) + ", GLXPixmap " + toHexString(drawable) + @@ -135,8 +133,6 @@ public class X11OffscreenGLXDrawable extends X11GLXDrawable { getFactoryImpl().unlockToolkit(); } } - - public boolean isDoubleBuffered() { - return isDoubleBuffered; + public void swapBuffers() throws GLException { } } diff --git a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11OnscreenGLXDrawable.java b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11OnscreenGLXDrawable.java index d80a833f5..4a81448fd 100644 --- a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11OnscreenGLXDrawable.java +++ b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11OnscreenGLXDrawable.java @@ -61,23 +61,4 @@ public class X11OnscreenGLXDrawable extends X11GLXDrawable { return component.getHeight(); } - public void swapBuffers() throws GLException { - boolean didLock = false; - try { - if ( !isSurfaceLocked() ) { - // Usually the surface shall be locked within [makeCurrent .. swap .. release] - if (lockSurface() == NativeWindow.LOCK_SURFACE_NOT_READY) { - return; - } - didLock=true; - } - - GLX.glXSwapBuffers(component.getDisplayHandle(), component.getSurfaceHandle()); - - } finally { - if(didLock) { - unlockSurface(); - } - } - } } diff --git a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11PbufferGLXDrawable.java b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11PbufferGLXDrawable.java index 753e9d884..eecd92a53 100644 --- a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11PbufferGLXDrawable.java +++ b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11PbufferGLXDrawable.java @@ -51,7 +51,7 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable { GLCapabilities caps, GLCapabilitiesChooser chooser, int width, int height) { - super(factory, new NullWindow(X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(caps, chooser, screen, true)), true); + super(factory, new NullWindow(X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(caps, chooser, screen, false, true)), true); if (width <= 0 || height <= 0) { throw new GLException("Width and height of pbuffer must be positive (were (" + width + ", " + height + "))"); @@ -147,4 +147,7 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable { // Floating-point pbuffers currently require NVidia hardware on X11 return GLPbuffer.NV_FLOAT; } + + public void swapBuffers() throws GLException { + } } diff --git a/src/jogl/classes/com/sun/opengl/util/FBObject.java b/src/jogl/classes/com/sun/opengl/util/FBObject.java index c308f430f..84b79dff4 100755 --- a/src/jogl/classes/com/sun/opengl/util/FBObject.java +++ b/src/jogl/classes/com/sun/opengl/util/FBObject.java @@ -50,15 +50,8 @@ public class FBObject { } - public boolean validateStatus(GL gl) - { - if(!gl.glIsFramebuffer(fb)) { - vStatus=-1; - return false; - } - vStatus=gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER); - //vStatus=gl.glCheckFramebufferStatus(fb); - + public boolean validateStatus(GL gl) { + vStatus = getStatus(gl, fb); switch(vStatus) { case GL.GL_FRAMEBUFFER_COMPLETE: return true; @@ -76,9 +69,20 @@ public class FBObject { } } - public String getStatusString() - { - switch(vStatus) { + public static int getStatus(GL gl, int fb) { + if(!gl.glIsFramebuffer(fb)) { + return -1; + } + return gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER); + //return gl.glCheckFramebufferStatus(fb); + } + + public String getStatusString() { + return getStatusString(vStatus); + } + + public static String getStatusString(int fbStatus) { + switch(fbStatus) { case -1: return "NOT A FBO"; case GL.GL_FRAMEBUFFER_COMPLETE: diff --git a/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java b/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java index 782d041a5..cc7afaa95 100644 --- a/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java +++ b/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java @@ -81,7 +81,7 @@ import javax.media.nativewindow.NativeWindowException; */ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser { - private static final boolean DEBUG = false; // FIXME: Debug.debug("DefaultGLCapabilitiesChooser"); + private static final boolean DEBUG = true; // FIXME: Debug.debug("DefaultGLCapabilitiesChooser"); public int chooseCapabilities(Capabilities desired, Capabilities[] available, @@ -128,6 +128,9 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser { if (cur == null) { continue; } + if (_desired.isOnscreen() != cur.isOnscreen()) { + continue; + } if (_desired.getStereo() != cur.getStereo()) { continue; } diff --git a/src/jogl/classes/javax/media/opengl/GLCapabilities.java b/src/jogl/classes/javax/media/opengl/GLCapabilities.java index 37e35d4f0..530078ec0 100644 --- a/src/jogl/classes/javax/media/opengl/GLCapabilities.java +++ b/src/jogl/classes/javax/media/opengl/GLCapabilities.java @@ -54,6 +54,7 @@ import javax.media.nativewindow.Capabilities; configuration on all supported window systems. */ public class GLCapabilities extends Capabilities implements Cloneable { private GLProfile glProfile = null; + private boolean pbuffer = false; private boolean doubleBuffered = true; private boolean stereo = false; private boolean hardwareAccelerated = true; @@ -97,7 +98,7 @@ public class GLCapabilities extends Capabilities implements Cloneable { GLCapabilities other = (GLCapabilities)obj; boolean res = super.equals(obj) && other.getGLProfile()==glProfile && - other.getDoubleBuffered()==doubleBuffered && + other.isPBuffer()==pbuffer && other.getStereo()==stereo && other.getHardwareAccelerated()==hardwareAccelerated && other.getDepthBits()==depthBits && @@ -126,6 +127,16 @@ public class GLCapabilities extends Capabilities implements Cloneable { glProfile=profile; } + /** Indicates whether pbuffer is used/requested. */ + public boolean isPBuffer() { + return pbuffer; + } + + /** Enables or disables pbuffer usage. */ + public void setPBuffer(boolean onOrOff) { + pbuffer = onOrOff; + } + /** Indicates whether double-buffering is enabled. */ public boolean getDoubleBuffered() { return doubleBuffered; @@ -310,6 +321,7 @@ public class GLCapabilities extends Capabilities implements Cloneable { msg.append("GLCapabilities["); msg.append(super.toString()); msg.append(", GL profile: " + glProfile + + ", PBuffer: " + pbuffer + ", DoubleBuffered: " + doubleBuffered + ", Stereo: " + stereo + ", HardwareAccelerated: " + hardwareAccelerated + diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java index 74da59cd3..dd2a487e7 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java @@ -52,6 +52,7 @@ import java.nio.*; import java.security.*; import javax.swing.JComponent; import javax.swing.JPanel; +import com.sun.opengl.util.FBObject; import com.sun.opengl.impl.*; import com.sun.opengl.impl.awt.*; @@ -173,6 +174,9 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { textures, display lists and other OpenGL state, and may be null if sharing is not desired. See the note in the overview documentation on <a href="../../../overview-summary.html#SHARING">context sharing</a>. + <P> + Note: Sharing cannot be enabled using J2D OpenGL FBO sharing, + since J2D GL Context must be shared and we can only share one context. */ public GLJPanel(GLCapabilities capabilities, GLCapabilitiesChooser chooser, GLContext shareWith) { super(); @@ -561,8 +565,8 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { return; } if (sendReshape) { - if (DEBUG) { - System.err.println("glViewport(" + viewportX + ", " + viewportY + ", " + panelWidth + ", " + panelHeight + ")"); + if (DEBUG||VERBOSE) { + System.err.println("display: glViewport(" + viewportX + "," + viewportY + " " + panelWidth + "x" + panelHeight + ")"); } getGL().getGL2().glViewport(viewportX, viewportY, panelWidth, panelHeight); drawableHelper.reshape(GLJPanel.this, viewportX, viewportY, panelWidth, panelHeight); @@ -1268,9 +1272,6 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { // allow us to bind to this object since it's in our namespace. if (Java2D.isFBOEnabled() && Java2D.getOGLSurfaceType(g) == Java2D.FBOBJECT) { - if (DEBUG && VERBOSE) { - System.err.println("GLJPanel: Binding to framebuffer object " + frameBuffer[0]); - } // The texture target for Java2D's OpenGL pipeline when using FBOs // -- either GL_TEXTURE_2D or GL_TEXTURE_RECTANGLE_ARB @@ -1280,17 +1281,21 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { checkedForFBObjectWorkarounds = true; gl.glBindTexture(fboTextureTarget, 0); gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, frameBuffer[0]); - if (gl.glCheckFramebufferStatus(GL2.GL_FRAMEBUFFER) != - GL2.GL_FRAMEBUFFER_COMPLETE) { - // Need to do workarounds - fbObjectWorkarounds = true; - createNewDepthBuffer = true; - if (DEBUG) { - System.err.println("-- GLJPanel: discovered frame_buffer_object workarounds to be necessary"); - } + int status = gl.glCheckFramebufferStatus(GL.GL_FRAMEBUFFER); + if (status != GL.GL_FRAMEBUFFER_COMPLETE) { + // Need to do workarounds + fbObjectWorkarounds = true; + createNewDepthBuffer = true; + if (DEBUG || VERBOSE) { + System.err.println("GLJPanel: ERR GL_FRAMEBUFFER_BINDING: Discovered Invalid J2D FBO("+frameBuffer[0]+"): "+FBObject.getStatusString(status) + + ", frame_buffer_object workarounds to be necessary"); + } } else { // Don't need the frameBufferTexture temporary any more frameBufferTexture = null; + if (DEBUG || VERBOSE) { + System.err.println("GLJPanel: OK GL_FRAMEBUFFER_BINDING: "+frameBuffer[0]); + } } } @@ -1330,23 +1335,23 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { if (fbObjectWorkarounds) { // Hook up the color and depth buffer attachment points for this framebuffer - gl.glFramebufferTexture2D(GL2.GL_FRAMEBUFFER, - GL2.GL_COLOR_ATTACHMENT0, + gl.glFramebufferTexture2D(GL.GL_FRAMEBUFFER, + GL.GL_COLOR_ATTACHMENT0, fboTextureTarget, frameBufferTexture[0], 0); if (DEBUG && VERBOSE) { System.err.println("GLJPanel: frameBufferDepthBuffer: " + frameBufferDepthBuffer[0]); } - gl.glFramebufferRenderbuffer(GL2.GL_FRAMEBUFFER, - GL2.GL_DEPTH_ATTACHMENT, - GL2.GL_RENDERBUFFER, + gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, + GL.GL_DEPTH_ATTACHMENT, + GL.GL_RENDERBUFFER, frameBufferDepthBuffer[0]); } if (DEBUG) { - int status = gl.glCheckFramebufferStatus(GL2.GL_FRAMEBUFFER); - if (status != GL2.GL_FRAMEBUFFER_COMPLETE) { + int status = gl.glCheckFramebufferStatus(GL.GL_FRAMEBUFFER); + if (status != GL.GL_FRAMEBUFFER_COMPLETE) { throw new GLException("Error: framebuffer was incomplete: status = 0x" + Integer.toHexString(status)); } @@ -1417,6 +1422,9 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { // Create no-op context representing Java2D context if (j2dContext == null) { j2dContext = factory.createExternalGLContext(); + if (DEBUG||VERBOSE) { + System.err.println("-- Created External Context: "+j2dContext); + } if (DEBUG) { j2dContext.setGL(new DebugGL2(j2dContext.getGL().getGL2())); } @@ -1474,20 +1482,50 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { joglContext = null; joglDrawable = null; sendReshape = true; - if (DEBUG) { + if (DEBUG||VERBOSE) { System.err.println("Sending reshape because surface changed"); System.err.println("New surface = " + curSurface); } } j2dSurface = curSurface; + if (DEBUG || VERBOSE) { + System.err.print("-- Surface type: "); + int surfaceType = Java2D.getOGLSurfaceType(g); + if (surfaceType == Java2D.UNDEFINED) { + System.err.println("UNDEFINED"); + } else if (surfaceType == Java2D.WINDOW) { + System.err.println("WINDOW"); + } else if (surfaceType == Java2D.PBUFFER) { + System.err.println("PBUFFER"); + } else if (surfaceType == Java2D.TEXTURE) { + System.err.println("TEXTURE"); + } else if (surfaceType == Java2D.FLIP_BACKBUFFER) { + System.err.println("FLIP_BACKBUFFER"); + } else if (surfaceType == Java2D.FBOBJECT) { + System.err.println("FBOBJECT"); + } else { + System.err.println("(Unknown surface type " + surfaceType + ")"); + } + } } if (joglContext == null) { if (factory.canCreateExternalGLDrawable()) { joglDrawable = factory.createExternalGLDrawable(); - joglContext = joglDrawable.createContext(shareWith); + // FIXME: Need to share with j2d context, due to FBO resource .. + // - ORIG: joglContext = joglDrawable.createContext(shareWith); + joglContext = joglDrawable.createContext(j2dContext); + if (DEBUG||VERBOSE) { + System.err.println("-- Created External Drawable: "+joglDrawable); + System.err.println("-- Created Context: "+joglContext); + } } else if (factory.canCreateContextOnJava2DSurface()) { // Mac OS X code path - joglContext = factory.createContextOnJava2DSurface(g, shareWith); + // FIXME: Need to share with j2d context, due to FBO resource .. + // - ORIG: joglContext = factory.createContextOnJava2DSurface(g, shareWith); + joglContext = factory.createContextOnJava2DSurface(g, j2dContext); + if (DEBUG||VERBOSE) { + System.err.println("-- Created Context: "+joglContext); + } } if (DEBUG) { joglContext.setGL(new DebugGL2(joglContext.getGL().getGL2())); @@ -1504,26 +1542,6 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { ((Java2DGLContext) joglContext).setGraphics(g); } - if (DEBUG && VERBOSE && Java2D.isFBOEnabled()) { - System.err.print("-- Surface type: "); - int surfaceType = Java2D.getOGLSurfaceType(g); - if (surfaceType == Java2D.UNDEFINED) { - System.err.println("UNDEFINED"); - } else if (surfaceType == Java2D.WINDOW) { - System.err.println("WINDOW"); - } else if (surfaceType == Java2D.PBUFFER) { - System.err.println("PBUFFER"); - } else if (surfaceType == Java2D.TEXTURE) { - System.err.println("TEXTURE"); - } else if (surfaceType == Java2D.FLIP_BACKBUFFER) { - System.err.println("FLIP_BACKBUFFER"); - } else if (surfaceType == Java2D.FBOBJECT) { - System.err.println("FBOBJECT"); - } else { - System.err.println("(Unknown surface type " + surfaceType + ")"); - } - } - drawableHelper.invokeGL(joglDrawable, joglContext, displayAction, initAction); } } finally { @@ -1538,26 +1556,33 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { gl.glGetIntegerv(GL2.GL_READ_BUFFER, readBuffer, 0); if (Java2D.isFBOEnabled() && Java2D.getOGLSurfaceType(g) == Java2D.FBOBJECT) { - if (DEBUG && VERBOSE) { - System.err.println("GLJPanel: Fetching GL_FRAMEBUFFER_BINDING_EXT"); - } - gl.glGetIntegerv(GL2.GL_FRAMEBUFFER_BINDING, frameBuffer, 0); - - if (fbObjectWorkarounds || - !checkedForFBObjectWorkarounds) { - // See above for description of what we are doing here - if (frameBufferTexture == null) - frameBufferTexture = new int[1]; - - // Query the framebuffer for its color buffer so we can hook - // it back up in our context (should not be necessary) - gl.glGetFramebufferAttachmentParameteriv(GL2.GL_FRAMEBUFFER, - GL2.GL_COLOR_ATTACHMENT0, - GL2.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, - frameBufferTexture, 0); - if (DEBUG && VERBOSE) { - System.err.println("GLJPanel: FBO COLOR_ATTACHMENT0: " + frameBufferTexture[0]); + gl.glGetIntegerv(GL.GL_FRAMEBUFFER_BINDING, frameBuffer, 0); + if(!gl.glIsFramebuffer(frameBuffer[0])) { + checkedForFBObjectWorkarounds=true; + fbObjectWorkarounds = true; + createNewDepthBuffer = true; + if (DEBUG || VERBOSE) { + System.err.println("GLJPanel: Fetched ERR GL_FRAMEBUFFER_BINDING: "+frameBuffer[0]+" - NOT A FBO"+ + ", frame_buffer_object workarounds to be necessary"); } + } else if (DEBUG) { + System.err.println("GLJPanel: Fetched OK GL_FRAMEBUFFER_BINDING: "+frameBuffer[0]); + } + + if(fbObjectWorkarounds || !checkedForFBObjectWorkarounds) { + // See above for description of what we are doing here + if (frameBufferTexture == null) + frameBufferTexture = new int[1]; + + // Query the framebuffer for its color buffer so we can hook + // it back up in our context (should not be necessary) + gl.glGetFramebufferAttachmentParameteriv(GL.GL_FRAMEBUFFER, + GL.GL_COLOR_ATTACHMENT0, + GL.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, + frameBufferTexture, 0); + if (DEBUG && VERBOSE) { + System.err.println("GLJPanel: FBO COLOR_ATTACHMENT0: " + frameBufferTexture[0]); + } } if (!checkedGLVendor) { @@ -1576,7 +1601,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { // simultaneously bound to more than one context. Java2D will // re-bind the FBO during the next validation of its context. // Note: this breaks rendering at least on NVidia hardware - gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, 0); + gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0); } } } |