diff options
author | Kenneth Russel <[email protected]> | 2008-12-20 08:58:00 +0000 |
---|---|---|
committer | Kenneth Russel <[email protected]> | 2008-12-20 08:58:00 +0000 |
commit | 6eda9476e8168bacdeb1854540d89bd9db0d5029 (patch) | |
tree | 692317f9924638836b16bf83a9cefe0c1047bb66 /src/classes/com/sun/opengl | |
parent | 14a94c810910f88d3b7214ae9be5027dc74df39f (diff) |
Factored out the remaining toolkit, and specifically AWT, dependencies
from GLDrawableFactory implementations into NativeWindowFactory
implementations. These dependencies were the up-front selection of the
GraphicsConfiguration and the locking and unlocking of the toolkit,
which are both currently needed only on X11 platforms due to how
OpenGL and the window system interact there. Added X11GraphicsDevice
and X11GraphicsConfiguration classes which are intended to be used by
Newt or potentially other third-party window toolkits. Unified the
separate NativeWindow and AWT GLDrawableFactory implementations in the
GLDrawableFactory class.
Exposed the toolkit locking mechanism through the NativeWindowFactory
and introduced the concept of a default NativeWindowFactory which is
used by the X11 drawable and context implementations. Removed
unnecessary toolkit locking calls from Mac OS X and Windows drawable
and context implementations.
Added a registration mechanism for new NativeWindowFactories, allowing
third parties to plug in new window toolkits orthogonally to the
OpenGL drawable and context code.
The public APIs for the NativeWindowFactory and the GLDrawableFactory,
in particular how they are fetched, changed as a result of these
refactorings. Updated all uses.
Fixed bug in X11OffscreenGLXDrawable introduced during last set of
changes.
Tested demos on Solaris, Mac OS X and Windows.
git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/branches/JOGL_2_SANDBOX@1824 232f8b59-042b-4e1e-8c03-345bb8c30851
Diffstat (limited to 'src/classes/com/sun/opengl')
17 files changed, 836 insertions, 651 deletions
diff --git a/src/classes/com/sun/opengl/impl/GLDrawableFactoryImpl.java b/src/classes/com/sun/opengl/impl/GLDrawableFactoryImpl.java index 966d8a788..70aef0dc3 100644 --- a/src/classes/com/sun/opengl/impl/GLDrawableFactoryImpl.java +++ b/src/classes/com/sun/opengl/impl/GLDrawableFactoryImpl.java @@ -64,10 +64,6 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory implements super(); } - public static GLDrawableFactoryImpl getFactoryImpl(Class winClazz) { - return (GLDrawableFactoryImpl) getFactory(winClazz); - } - public static GLDrawableFactoryImpl getFactoryImpl() { return (GLDrawableFactoryImpl) getFactory(); } @@ -77,30 +73,21 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory implements // RTLD_LOCAL and we need to call dlsym(RTLD_DEFAULT) public abstract void loadGLULibrary(); - //--------------------------------------------------------------------------- + //---------------------------------------------------------------------- // Support for locking and unlocking the toolkit -- needed only on X11 platforms - protected static boolean lockedToolkit = false; + // - public void lockToolkit() throws GLException { - if(lockedToolkit) { - throw new GLException("Toolkit already locked"); - } - lockedToolkit=true; + public void lockToolkit() { + NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); } public void unlockToolkit() { - if(lockedToolkit) { - lockedToolkit=false; - } - } - - public boolean isToolkitLocked() { - return lockedToolkit; + NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); } //--------------------------------------------------------------------------- // Support for Java2D/JOGL bridge on Mac OS X; the external - // GLDrawable mechanism in the public API is sufficienit to + // GLDrawable mechanism in the public API is sufficient to // implement this functionality on all other platforms // diff --git a/src/classes/com/sun/opengl/impl/NativeWindowFactoryImpl.java b/src/classes/com/sun/opengl/impl/NativeWindowFactoryImpl.java new file mode 100644 index 000000000..97d7c0e30 --- /dev/null +++ b/src/classes/com/sun/opengl/impl/NativeWindowFactoryImpl.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +package com.sun.opengl.impl; + +import java.lang.reflect.*; +import java.security.*; + +import javax.media.opengl.*; + +public class NativeWindowFactoryImpl extends NativeWindowFactory { + protected static final boolean DEBUG = Debug.debug("NativeWindowFactoryImpl"); + + // This subclass of NativeWindowFactory handles the case of + // NativeWindows and AWT Components being passed in + protected NativeWindow getNativeWindowImpl(Object winObj) throws IllegalArgumentException { + if (null==winObj) { + throw new IllegalArgumentException("winObj is null"); + } + if (winObj instanceof NativeWindow) { + NativeWindow nw = (NativeWindow) winObj; + Object wrappedWindow = nw.getWrappedWindow(); + if (wrappedWindow == null) { + // Use the NativeWindow directly + return nw; + } + winObj = wrappedWindow; + } + + if (GLReflection.isAWTComponent(winObj)) { + return getAWTNativeWindow(winObj); + } + + throw new IllegalArgumentException("Target window object type " + + winObj.getClass().getName() + " is unsupported; expected " + + "javax.media.opengl.NativeWindow or java.awt.Component"); + } + + private Constructor nativeWindowConstructor = null; + + private NativeWindow getAWTNativeWindow(Object winObj) { + if (nativeWindowConstructor == null) { + try { + String osName = System.getProperty("os.name"); + String osNameLowerCase = osName.toLowerCase(); + String windowClassName = null; + + // We break compile-time dependencies on the AWT here to + // make it easier to run this code on mobile devices + + if (osNameLowerCase.startsWith("wind")) { + windowClassName = "com.sun.opengl.impl.jawt.windows.WindowsJAWTWindow"; + } else if (osNameLowerCase.startsWith("mac os x")) { + windowClassName = "com.sun.opengl.impl.jawt.macosx.MacOSXJAWTWindow"; + } else { + // Assume Linux, Solaris, etc. Should probably test for these explicitly. + windowClassName = "com.sun.opengl.impl.jawt.x11.X11JAWTWindow"; + } + + if (windowClassName == null) { + throw new IllegalArgumentException("OS " + osName + " not yet supported"); + } + + nativeWindowConstructor = GLReflection.getConstructor(windowClassName, new Class[] { Object.class }); + } catch (Exception e) { + throw (IllegalArgumentException) new IllegalArgumentException().initCause(e); + } + } + + try { + return (NativeWindow) nativeWindowConstructor.newInstance(new Object[] { winObj }); + } catch (Exception ie) { + throw (IllegalArgumentException) new IllegalArgumentException().initCause(ie); + } + } + + // All platforms except for X11 perform the OpenGL pixel format + // selection lazily + public AbstractGraphicsConfiguration chooseGraphicsConfiguration(GLCapabilities capabilities, + GLCapabilitiesChooser chooser, + AbstractGraphicsDevice device) { + return null; + } + + // On most platforms the toolkit lock is a no-op + private ToolkitLock toolkitLock = new ToolkitLock() { + public void lock() { + } + + public void unlock() { + } + }; + + public ToolkitLock getToolkitLock() { + return toolkitLock; + } +} diff --git a/src/classes/com/sun/opengl/impl/awt/Java2D.java b/src/classes/com/sun/opengl/impl/awt/Java2D.java index 0611f799f..a59f5e0cd 100755 --- a/src/classes/com/sun/opengl/impl/awt/Java2D.java +++ b/src/classes/com/sun/opengl/impl/awt/Java2D.java @@ -559,7 +559,7 @@ public class Java2D { } invokeWithOGLSharedContextCurrent(gc, new Runnable() { public void run() { - j2dFBOShareContext = GLDrawableFactory.getFactory(Component.class).createExternalGLContext(); + j2dFBOShareContext = GLDrawableFactory.getFactory().createExternalGLContext(); } }); if (DEBUG) { diff --git a/src/classes/com/sun/opengl/impl/egl/EGLContext.java b/src/classes/com/sun/opengl/impl/egl/EGLContext.java index cf95f3d69..df3bd2a34 100755 --- a/src/classes/com/sun/opengl/impl/egl/EGLContext.java +++ b/src/classes/com/sun/opengl/impl/egl/EGLContext.java @@ -247,10 +247,7 @@ public class EGLContext extends GLContextImpl { } if (eglQueryStringAvailable) { GLDrawableFactoryImpl factory = getDrawableImpl().getFactoryImpl(); - boolean wasLocked = factory.isToolkitLocked(); - if(!wasLocked) { - factory.lockToolkit(); - } + factory.lockToolkit(); try { String ret = EGL.eglQueryString(drawable.getNativeWindow().getDisplayHandle(), EGL.EGL_EXTENSIONS); @@ -259,9 +256,7 @@ public class EGLContext extends GLContextImpl { } return ret; } finally { - if(!wasLocked) { - factory.unlockToolkit(); - } + factory.unlockToolkit(); } } else { return ""; diff --git a/src/classes/com/sun/opengl/impl/egl/awt/EGLAWTDrawableFactory.java b/src/classes/com/sun/opengl/impl/egl/awt/EGLAWTDrawableFactory.java deleted file mode 100644 index 501de1d01..000000000 --- a/src/classes/com/sun/opengl/impl/egl/awt/EGLAWTDrawableFactory.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that this software is not designed or intended for use - * in the design, construction, operation or maintenance of any nuclear - * facility. - */ - -package com.sun.opengl.impl.egl.awt; - -import com.sun.opengl.impl.*; -import com.sun.opengl.impl.egl.*; -import com.sun.opengl.impl.jawt.*; - -public class EGLAWTDrawableFactory extends EGLDrawableFactory { - - public void lockToolkit() { - super.lockToolkit(); - //JAWTUtil.lockToolkit(); - } - - public void unlockToolkit() { - //JAWTUtil.unlockToolkit(); - super.unlockToolkit(); - } - -} diff --git a/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXPbufferCGLDrawable.java b/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXPbufferCGLDrawable.java index dfd970070..81f4abb8f 100644 --- a/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXPbufferCGLDrawable.java +++ b/src/classes/com/sun/opengl/impl/macosx/cgl/MacOSXPbufferCGLDrawable.java @@ -68,17 +68,12 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable { } public void destroy() { - getFactoryImpl().lockToolkit(); - try { - if (this.pBuffer != 0) { - impl.destroy(pBuffer); - this.pBuffer = 0; - if (DEBUG) { - System.err.println("Destroyed pbuffer: " + pBuffer); - } - } - } finally { - getFactoryImpl().unlockToolkit(); + if (this.pBuffer != 0) { + impl.destroy(pBuffer); + this.pBuffer = 0; + if (DEBUG) { + System.err.println("Destroyed pbuffer: " + pBuffer); + } } super.destroy(); } @@ -93,47 +88,42 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable { private void createPbuffer() { NullWindow nw = (NullWindow) getNativeWindow(); - getFactoryImpl().lockToolkit(); - try { - int renderTarget; - GLCapabilities capabilities = getRequestedGLCapabilities(); - if (GLProfile.isGL2() && capabilities.getPbufferRenderToTextureRectangle()) { - renderTarget = GL2.GL_TEXTURE_RECTANGLE; - } else { - int w = getNextPowerOf2(getWidth()); - int h = getNextPowerOf2(getHeight()); - nw.setSize(w, h); - renderTarget = GL.GL_TEXTURE_2D; - } + int renderTarget; + GLCapabilities capabilities = getRequestedGLCapabilities(); + if (GLProfile.isGL2() && capabilities.getPbufferRenderToTextureRectangle()) { + renderTarget = GL2.GL_TEXTURE_RECTANGLE; + } else { + int w = getNextPowerOf2(getWidth()); + int h = getNextPowerOf2(getHeight()); + nw.setSize(w, h); + renderTarget = GL.GL_TEXTURE_2D; + } - int internalFormat = GL.GL_RGBA; - if (capabilities.getPbufferFloatingPointBuffers()) { - // FIXME: want to check availability of GL_APPLE_float_pixels - // extension, but need valid OpenGL context in order to do so -- - // in worst case would need to create dummy window / GLCanvas - // (undesirable) -- could maybe also do this with pbuffers - /* - if (!gl.isExtensionAvailable("GL_APPLE_float_pixels")) { + int internalFormat = GL.GL_RGBA; + if (capabilities.getPbufferFloatingPointBuffers()) { + // FIXME: want to check availability of GL_APPLE_float_pixels + // extension, but need valid OpenGL context in order to do so -- + // in worst case would need to create dummy window / GLCanvas + // (undesirable) -- could maybe also do this with pbuffers + /* + if (!gl.isExtensionAvailable("GL_APPLE_float_pixels")) { throw new GLUnsupportedException("Floating-point support (GL_APPLE_float_pixels) not available"); - } - */ - if(GLProfile.isGL2()) { - switch (capabilities.getRedBits()) { - case 16: internalFormat = GL2.GL_RGBA_FLOAT16_APPLE; break; - case 32: internalFormat = GL2.GL_RGBA_FLOAT32_APPLE; break; - default: throw new GLException("Invalid floating-point bit depth (only 16 and 32 supported)"); - } - } else { - internalFormat = GL.GL_RGBA; - } } - - pBuffer = impl.create(renderTarget, internalFormat, getWidth(), getHeight()); - if (pBuffer == 0) { - throw new GLException("pbuffer creation error: CGL.createPBuffer() failed"); + */ + if(GLProfile.isGL2()) { + switch (capabilities.getRedBits()) { + case 16: internalFormat = GL2.GL_RGBA_FLOAT16_APPLE; break; + case 32: internalFormat = GL2.GL_RGBA_FLOAT32_APPLE; break; + default: throw new GLException("Invalid floating-point bit depth (only 16 and 32 supported)"); } - } finally { - getFactoryImpl().unlockToolkit(); + } else { + internalFormat = GL.GL_RGBA; + } + } + + pBuffer = impl.create(renderTarget, internalFormat, getWidth(), getHeight()); + if (pBuffer == 0) { + throw new GLException("pbuffer creation error: CGL.createPBuffer() failed"); } if (DEBUG) { diff --git a/src/classes/com/sun/opengl/impl/windows/wgl/WindowsOffscreenWGLDrawable.java b/src/classes/com/sun/opengl/impl/windows/wgl/WindowsOffscreenWGLDrawable.java index 38215fd46..724f64b9c 100644 --- a/src/classes/com/sun/opengl/impl/windows/wgl/WindowsOffscreenWGLDrawable.java +++ b/src/classes/com/sun/opengl/impl/windows/wgl/WindowsOffscreenWGLDrawable.java @@ -61,76 +61,66 @@ public class WindowsOffscreenWGLDrawable extends WindowsWGLDrawable { } private void create() { - getFactoryImpl().lockToolkit(); - try { - NullWindow nw = (NullWindow) getNativeWindow(); - GLCapabilities capabilities = getRequestedGLCapabilities(); - int width = getWidth(); - int height = getHeight(); - BITMAPINFO info = BITMAPINFO.create(); - BITMAPINFOHEADER header = info.bmiHeader(); - int bitsPerPixel = (capabilities.getRedBits() + - capabilities.getGreenBits() + - capabilities.getBlueBits()); - header.biSize(header.size()); - header.biWidth(width); - // NOTE: negating the height causes the DIB to be in top-down row - // order rather than bottom-up; ends up being correct during pixel - // readback - header.biHeight(-1 * height); - header.biPlanes((short) 1); - header.biBitCount((short) bitsPerPixel); - header.biXPelsPerMeter(0); - header.biYPelsPerMeter(0); - header.biClrUsed(0); - header.biClrImportant(0); - header.biCompression(WGL.BI_RGB); - header.biSizeImage(width * height * bitsPerPixel / 8); + NullWindow nw = (NullWindow) getNativeWindow(); + GLCapabilities capabilities = getRequestedGLCapabilities(); + int width = getWidth(); + int height = getHeight(); + BITMAPINFO info = BITMAPINFO.create(); + BITMAPINFOHEADER header = info.bmiHeader(); + int bitsPerPixel = (capabilities.getRedBits() + + capabilities.getGreenBits() + + capabilities.getBlueBits()); + header.biSize(header.size()); + header.biWidth(width); + // NOTE: negating the height causes the DIB to be in top-down row + // order rather than bottom-up; ends up being correct during pixel + // readback + header.biHeight(-1 * height); + header.biPlanes((short) 1); + header.biBitCount((short) bitsPerPixel); + header.biXPelsPerMeter(0); + header.biYPelsPerMeter(0); + header.biClrUsed(0); + header.biClrImportant(0); + header.biCompression(WGL.BI_RGB); + header.biSizeImage(width * height * bitsPerPixel / 8); - long hdc = WGL.CreateCompatibleDC(0); - if (hdc == 0) { - System.out.println("LastError: " + WGL.GetLastError()); - throw new GLException("Error creating device context for offscreen OpenGL context"); - } - nw.setSurfaceHandle(hdc); + long hdc = WGL.CreateCompatibleDC(0); + if (hdc == 0) { + System.out.println("LastError: " + WGL.GetLastError()); + throw new GLException("Error creating device context for offscreen OpenGL context"); + } + nw.setSurfaceHandle(hdc); - hbitmap = WGL.CreateDIBSection(hdc, info, WGL.DIB_RGB_COLORS, 0, 0, 0); - if (hbitmap == 0) { - WGL.DeleteDC(hdc); - hdc = 0; - throw new GLException("Error creating offscreen bitmap of width " + width + - ", height " + height); - } - if ((origbitmap = WGL.SelectObject(hdc, hbitmap)) == 0) { - WGL.DeleteObject(hbitmap); - hbitmap = 0; - WGL.DeleteDC(hdc); - hdc = 0; - throw new GLException("Error selecting bitmap into new device context"); - } - - choosePixelFormat(false); - } finally { - getFactoryImpl().unlockToolkit(); + hbitmap = WGL.CreateDIBSection(hdc, info, WGL.DIB_RGB_COLORS, 0, 0, 0); + if (hbitmap == 0) { + WGL.DeleteDC(hdc); + hdc = 0; + throw new GLException("Error creating offscreen bitmap of width " + width + + ", height " + height); } + if ((origbitmap = WGL.SelectObject(hdc, hbitmap)) == 0) { + WGL.DeleteObject(hbitmap); + hbitmap = 0; + WGL.DeleteDC(hdc); + hdc = 0; + throw new GLException("Error selecting bitmap into new device context"); + } + + choosePixelFormat(false); } public void destroy() { - getFactoryImpl().lockToolkit(); - try { - NullWindow nw = (NullWindow) getNativeWindow(); - if (nw.getSurfaceHandle() != 0) { - // Must destroy bitmap and device context - WGL.SelectObject(nw.getSurfaceHandle(), origbitmap); - WGL.DeleteObject(hbitmap); - WGL.DeleteDC(nw.getSurfaceHandle()); - origbitmap = 0; - hbitmap = 0; - nw.setSurfaceHandle(0); - setChosenGLCapabilities(null); - } - } finally { - getFactoryImpl().unlockToolkit(); + NullWindow nw = (NullWindow) getNativeWindow(); + if (nw.getSurfaceHandle() != 0) { + // Must destroy bitmap and device context + WGL.SelectObject(nw.getSurfaceHandle(), origbitmap); + WGL.DeleteObject(hbitmap); + WGL.DeleteDC(nw.getSurfaceHandle()); + origbitmap = 0; + hbitmap = 0; + nw.setSurfaceHandle(0); + setChosenGLCapabilities(null); } super.destroy(); } diff --git a/src/classes/com/sun/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java b/src/classes/com/sun/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java index f82653bcd..a13592d62 100644 --- a/src/classes/com/sun/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java +++ b/src/classes/com/sun/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java @@ -79,27 +79,22 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { } public void destroy() { - getFactoryImpl().lockToolkit(); - try { - NullWindow nw = (NullWindow) getNativeWindow(); - if (nw.getSurfaceHandle() != 0) { - // Must release DC and pbuffer - // NOTE that since the context is not current, glGetError() can - // not be called here, so we skip the use of any composable - // pipelines (see WindowsOnscreenWGLContext.makeCurrentImpl) - WGLExt wglExt = cachedWGLExt; - if (wglExt.wglReleasePbufferDC(buffer, nw.getSurfaceHandle()) == 0) { - throw new GLException("Error releasing pbuffer device context: error code " + WGL.GetLastError()); - } - nw.setSurfaceHandle(0); - if (!wglExt.wglDestroyPbuffer(buffer)) { - throw new GLException("Error destroying pbuffer: error code " + WGL.GetLastError()); - } - buffer = 0; - setChosenGLCapabilities(null); - } - } finally { - getFactoryImpl().unlockToolkit(); + NullWindow nw = (NullWindow) getNativeWindow(); + if (nw.getSurfaceHandle() != 0) { + // Must release DC and pbuffer + // NOTE that since the context is not current, glGetError() can + // not be called here, so we skip the use of any composable + // pipelines (see WindowsOnscreenWGLContext.makeCurrentImpl) + WGLExt wglExt = cachedWGLExt; + if (wglExt.wglReleasePbufferDC(buffer, nw.getSurfaceHandle()) == 0) { + throw new GLException("Error releasing pbuffer device context: error code " + WGL.GetLastError()); + } + nw.setSurfaceHandle(0); + if (!wglExt.wglDestroyPbuffer(buffer)) { + throw new GLException("Error destroying pbuffer: error code " + WGL.GetLastError()); + } + buffer = 0; + setChosenGLCapabilities(null); } super.destroy(); } @@ -151,185 +146,180 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable { (capabilities.getPbufferFloatingPointBuffers() ? " [float]" : "")); } - getFactoryImpl().lockToolkit(); - try { - if (!glCapabilities2iattributes(capabilities, - iattributes, - wglExt, - true, - floatModeTmp)) { - throw new GLException("Pbuffer-related extensions not supported"); - } + if (!glCapabilities2iattributes(capabilities, + iattributes, + wglExt, + true, + floatModeTmp)) { + throw new GLException("Pbuffer-related extensions not supported"); + } - floatMode = floatModeTmp[0]; - boolean rtt = capabilities.getPbufferRenderToTexture(); - boolean rect = capabilities.getPbufferRenderToTextureRectangle(); - boolean useFloat = capabilities.getPbufferFloatingPointBuffers(); - boolean ati = false; + floatMode = floatModeTmp[0]; + boolean rtt = capabilities.getPbufferRenderToTexture(); + boolean rect = capabilities.getPbufferRenderToTextureRectangle(); + boolean useFloat = capabilities.getPbufferFloatingPointBuffers(); + boolean ati = false; - if (useFloat) { - ati = (floatMode == GLPbuffer.ATI_FLOAT); - } + if (useFloat) { + ati = (floatMode == GLPbuffer.ATI_FLOAT); + } - int[] pformats = new int[MAX_PFORMATS]; - int nformats; - int[] nformatsTmp = new int[1]; - if (!wglExt.wglChoosePixelFormat(parentHdc, - iattributes, 0, - fattributes, 0, - MAX_PFORMATS, - pformats, 0, - nformatsTmp, 0)) { - throw new GLException("pbuffer creation error: wglChoosePixelFormat() failed"); + int[] pformats = new int[MAX_PFORMATS]; + int nformats; + int[] nformatsTmp = new int[1]; + if (!wglExt.wglChoosePixelFormat(parentHdc, + iattributes, 0, + fattributes, 0, + MAX_PFORMATS, + pformats, 0, + nformatsTmp, 0)) { + throw new GLException("pbuffer creation error: wglChoosePixelFormat() failed"); + } + nformats = nformatsTmp[0]; + if (nformats <= 0) { + throw new GLException("pbuffer creation error: Couldn't find a suitable pixel format"); + } + + boolean haveMultisample = wglExt.isExtensionAvailable("WGL_ARB_multisample"); + + if (DEBUG) { + System.err.println("" + nformats + " suitable pixel formats found"); + // query pixel format + iattributes[0] = WGLExt.WGL_RED_BITS; + iattributes[1] = WGLExt.WGL_GREEN_BITS; + iattributes[2] = WGLExt.WGL_BLUE_BITS; + iattributes[3] = WGLExt.WGL_ALPHA_BITS; + iattributes[4] = WGLExt.WGL_DEPTH_BITS; + iattributes[5] = (useFloat ? (ati ? WGLExt.WGL_PIXEL_TYPE: WGLExt.WGL_FLOAT_COMPONENTS_NV) : WGLExt.WGL_RED_BITS); + iattributes[6] = (haveMultisample ? WGLExt.WGL_SAMPLE_BUFFERS: WGLExt.WGL_RED_BITS); + iattributes[7] = (haveMultisample ? WGLExt.WGL_SAMPLES: WGLExt.WGL_RED_BITS); + iattributes[8] = WGLExt.WGL_DRAW_TO_PBUFFER; + int[] ivalues = new int[9]; + for (int i = 0; i < nformats; i++) { + if (!wglExt.wglGetPixelFormatAttribiv(parentHdc, pformats[i], 0, 9, iattributes, 0, ivalues, 0)) { + throw new GLException("Error while querying pixel format " + pformats[i] + + "'s (index " + i + "'s) capabilities for debugging"); } - nformats = nformatsTmp[0]; - if (nformats <= 0) { - throw new GLException("pbuffer creation error: Couldn't find a suitable pixel format"); + System.err.print("pixel format " + pformats[i] + " (index " + i + "): "); + System.err.print( "r: " + ivalues[0]); + System.err.print(" g: " + ivalues[1]); + System.err.print(" b: " + ivalues[2]); + System.err.print(" a: " + ivalues[3]); + System.err.print(" depth: " + ivalues[4]); + if (haveMultisample) { + System.err.print(" multisample: " + ivalues[6]); } - - boolean haveMultisample = wglExt.isExtensionAvailable("WGL_ARB_multisample"); - - if (DEBUG) { - System.err.println("" + nformats + " suitable pixel formats found"); - // query pixel format - iattributes[0] = WGLExt.WGL_RED_BITS; - iattributes[1] = WGLExt.WGL_GREEN_BITS; - iattributes[2] = WGLExt.WGL_BLUE_BITS; - iattributes[3] = WGLExt.WGL_ALPHA_BITS; - iattributes[4] = WGLExt.WGL_DEPTH_BITS; - iattributes[5] = (useFloat ? (ati ? WGLExt.WGL_PIXEL_TYPE: WGLExt.WGL_FLOAT_COMPONENTS_NV) : WGLExt.WGL_RED_BITS); - iattributes[6] = (haveMultisample ? WGLExt.WGL_SAMPLE_BUFFERS: WGLExt.WGL_RED_BITS); - iattributes[7] = (haveMultisample ? WGLExt.WGL_SAMPLES: WGLExt.WGL_RED_BITS); - iattributes[8] = WGLExt.WGL_DRAW_TO_PBUFFER; - int[] ivalues = new int[9]; - for (int i = 0; i < nformats; i++) { - if (!wglExt.wglGetPixelFormatAttribiv(parentHdc, pformats[i], 0, 9, iattributes, 0, ivalues, 0)) { - throw new GLException("Error while querying pixel format " + pformats[i] + - "'s (index " + i + "'s) capabilities for debugging"); - } - System.err.print("pixel format " + pformats[i] + " (index " + i + "): "); - System.err.print( "r: " + ivalues[0]); - System.err.print(" g: " + ivalues[1]); - System.err.print(" b: " + ivalues[2]); - System.err.print(" a: " + ivalues[3]); - System.err.print(" depth: " + ivalues[4]); - if (haveMultisample) { - System.err.print(" multisample: " + ivalues[6]); - } - System.err.print(" samples: " + ivalues[7]); - if (useFloat) { - if (ati) { - if (ivalues[5] == WGLExt.WGL_TYPE_RGBA_FLOAT) { - System.err.print(" [ati float]"); - } else if (ivalues[5] != WGLExt.WGL_TYPE_RGBA) { - System.err.print(" [unknown pixel type " + ivalues[5] + "]"); - } - } else { - if (ivalues[5] != 0) { - System.err.print(" [float]"); - } - } + System.err.print(" samples: " + ivalues[7]); + if (useFloat) { + if (ati) { + if (ivalues[5] == WGLExt.WGL_TYPE_RGBA_FLOAT) { + System.err.print(" [ati float]"); + } else if (ivalues[5] != WGLExt.WGL_TYPE_RGBA) { + System.err.print(" [unknown pixel type " + ivalues[5] + "]"); } - - if (ivalues[8] != 0) { - System.err.print(" [pbuffer]"); + } else { + if (ivalues[5] != 0) { + System.err.print(" [float]"); } - System.err.println(); } } - long tmpBuffer = 0; - int whichFormat = -1; - // Loop is a workaround for bugs in NVidia's recent drivers - for (whichFormat = 0; whichFormat < nformats; whichFormat++) { - int format = pformats[whichFormat]; - - // Create the p-buffer. - niattribs = 0; - - if (rtt) { - iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FORMAT; - if (useFloat) { - iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FLOAT_RGB_NV; - } else { - iattributes[niattribs++] = WGLExt.WGL_TEXTURE_RGBA; - } + if (ivalues[8] != 0) { + System.err.print(" [pbuffer]"); + } + System.err.println(); + } + } - iattributes[niattribs++] = WGLExt.WGL_TEXTURE_TARGET; - iattributes[niattribs++] = rect ? WGLExt.WGL_TEXTURE_RECTANGLE_NV : WGLExt.WGL_TEXTURE_2D; + long tmpBuffer = 0; + int whichFormat = -1; + // Loop is a workaround for bugs in NVidia's recent drivers + for (whichFormat = 0; whichFormat < nformats; whichFormat++) { + int format = pformats[whichFormat]; - iattributes[niattribs++] = WGLExt.WGL_MIPMAP_TEXTURE; - iattributes[niattribs++] = GL.GL_FALSE; + // Create the p-buffer. + niattribs = 0; - iattributes[niattribs++] = WGLExt.WGL_PBUFFER_LARGEST; - iattributes[niattribs++] = GL.GL_FALSE; - } + if (rtt) { + iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FORMAT; + if (useFloat) { + iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FLOAT_RGB_NV; + } else { + iattributes[niattribs++] = WGLExt.WGL_TEXTURE_RGBA; + } - iattributes[niattribs++] = 0; + iattributes[niattribs++] = WGLExt.WGL_TEXTURE_TARGET; + iattributes[niattribs++] = rect ? WGLExt.WGL_TEXTURE_RECTANGLE_NV : WGLExt.WGL_TEXTURE_2D; - tmpBuffer = wglExt.wglCreatePbuffer(parentHdc, format, getWidth(), getHeight(), iattributes, 0); - if (tmpBuffer != 0) { - // Done - break; - } - } + iattributes[niattribs++] = WGLExt.WGL_MIPMAP_TEXTURE; + iattributes[niattribs++] = GL.GL_FALSE; - if (tmpBuffer == 0) { - throw new GLException("pbuffer creation error: wglCreatePbuffer() failed: tried " + nformats + - " pixel formats, last error was: " + wglGetLastError()); - } + iattributes[niattribs++] = WGLExt.WGL_PBUFFER_LARGEST; + iattributes[niattribs++] = GL.GL_FALSE; + } - // Get the device context. - long tmpHdc = wglExt.wglGetPbufferDC(tmpBuffer); - if (tmpHdc == 0) { - throw new GLException("pbuffer creation error: wglGetPbufferDC() failed"); - } + iattributes[niattribs++] = 0; - NullWindow nw = (NullWindow) getNativeWindow(); - // Set up instance variables - buffer = tmpBuffer; - nw.setSurfaceHandle(tmpHdc); - cachedWGLExt = wglExt; - cachedParentHdc = parentHdc; - - // Re-query chosen pixel format - { - niattribs = 0; - iattributes[niattribs++] = WGLExt.WGL_ACCELERATION; - iattributes[niattribs++] = WGLExt.WGL_RED_BITS; - iattributes[niattribs++] = WGLExt.WGL_GREEN_BITS; - iattributes[niattribs++] = WGLExt.WGL_BLUE_BITS; - iattributes[niattribs++] = WGLExt.WGL_ALPHA_BITS; - iattributes[niattribs++] = WGLExt.WGL_DEPTH_BITS; - iattributes[niattribs++] = WGLExt.WGL_STENCIL_BITS; - iattributes[niattribs++] = WGLExt.WGL_DOUBLE_BUFFER; - iattributes[niattribs++] = WGLExt.WGL_STEREO; - iattributes[niattribs++] = WGLExt.WGL_ACCUM_RED_BITS; - iattributes[niattribs++] = WGLExt.WGL_ACCUM_GREEN_BITS; - iattributes[niattribs++] = WGLExt.WGL_ACCUM_BLUE_BITS; - iattributes[niattribs++] = WGLExt.WGL_ACCUM_ALPHA_BITS; - iattributes[niattribs++] = (useFloat ? (ati ? WGLExt.WGL_PIXEL_TYPE: WGLExt.WGL_FLOAT_COMPONENTS_NV) : WGLExt.WGL_RED_BITS); - iattributes[niattribs++] = (haveMultisample ? WGLExt.WGL_SAMPLE_BUFFERS: WGLExt.WGL_RED_BITS); - iattributes[niattribs++] = (haveMultisample ? WGLExt.WGL_SAMPLES: WGLExt.WGL_RED_BITS); - iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_PBUFFER; - int[] ivalues = new int[niattribs]; - // FIXME: usually prefer to throw exceptions, but failure here is not critical - if (wglExt.wglGetPixelFormatAttribiv(parentHdc, pformats[whichFormat], 0, niattribs, iattributes, 0, ivalues, 0)) { - setChosenGLCapabilities(iattributes2GLCapabilities(iattributes, niattribs, ivalues, false)); - } - } + tmpBuffer = wglExt.wglCreatePbuffer(parentHdc, format, getWidth(), getHeight(), iattributes, 0); + if (tmpBuffer != 0) { + // Done + break; + } + } - // Determine the actual width and height we were able to create. - int[] tmp = new int[1]; - wglExt.wglQueryPbuffer( buffer, WGLExt.WGL_PBUFFER_WIDTH, tmp, 0 ); - width = tmp[0]; - wglExt.wglQueryPbuffer( buffer, WGLExt.WGL_PBUFFER_HEIGHT, tmp, 0 ); - height = tmp[0]; - nw.setSize(width, height); - } finally { - getFactoryImpl().unlockToolkit(); + if (tmpBuffer == 0) { + throw new GLException("pbuffer creation error: wglCreatePbuffer() failed: tried " + nformats + + " pixel formats, last error was: " + wglGetLastError()); } + // Get the device context. + long tmpHdc = wglExt.wglGetPbufferDC(tmpBuffer); + if (tmpHdc == 0) { + throw new GLException("pbuffer creation error: wglGetPbufferDC() failed"); + } + + NullWindow nw = (NullWindow) getNativeWindow(); + // Set up instance variables + buffer = tmpBuffer; + nw.setSurfaceHandle(tmpHdc); + cachedWGLExt = wglExt; + cachedParentHdc = parentHdc; + + // Re-query chosen pixel format + { + niattribs = 0; + iattributes[niattribs++] = WGLExt.WGL_ACCELERATION; + iattributes[niattribs++] = WGLExt.WGL_RED_BITS; + iattributes[niattribs++] = WGLExt.WGL_GREEN_BITS; + iattributes[niattribs++] = WGLExt.WGL_BLUE_BITS; + iattributes[niattribs++] = WGLExt.WGL_ALPHA_BITS; + iattributes[niattribs++] = WGLExt.WGL_DEPTH_BITS; + iattributes[niattribs++] = WGLExt.WGL_STENCIL_BITS; + iattributes[niattribs++] = WGLExt.WGL_DOUBLE_BUFFER; + iattributes[niattribs++] = WGLExt.WGL_STEREO; + iattributes[niattribs++] = WGLExt.WGL_ACCUM_RED_BITS; + iattributes[niattribs++] = WGLExt.WGL_ACCUM_GREEN_BITS; + iattributes[niattribs++] = WGLExt.WGL_ACCUM_BLUE_BITS; + iattributes[niattribs++] = WGLExt.WGL_ACCUM_ALPHA_BITS; + iattributes[niattribs++] = (useFloat ? (ati ? WGLExt.WGL_PIXEL_TYPE: WGLExt.WGL_FLOAT_COMPONENTS_NV) : WGLExt.WGL_RED_BITS); + iattributes[niattribs++] = (haveMultisample ? WGLExt.WGL_SAMPLE_BUFFERS: WGLExt.WGL_RED_BITS); + iattributes[niattribs++] = (haveMultisample ? WGLExt.WGL_SAMPLES: WGLExt.WGL_RED_BITS); + iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_PBUFFER; + int[] ivalues = new int[niattribs]; + // FIXME: usually prefer to throw exceptions, but failure here is not critical + if (wglExt.wglGetPixelFormatAttribiv(parentHdc, pformats[whichFormat], 0, niattribs, iattributes, 0, ivalues, 0)) { + setChosenGLCapabilities(iattributes2GLCapabilities(iattributes, niattribs, ivalues, false)); + } + } + + // Determine the actual width and height we were able to create. + int[] tmp = new int[1]; + wglExt.wglQueryPbuffer( buffer, WGLExt.WGL_PBUFFER_WIDTH, tmp, 0 ); + width = tmp[0]; + wglExt.wglQueryPbuffer( buffer, WGLExt.WGL_PBUFFER_HEIGHT, tmp, 0 ); + height = tmp[0]; + nw.setSize(width, height); + if (DEBUG) { System.err.println("Created pbuffer " + width + " x " + height); } diff --git a/src/classes/com/sun/opengl/impl/x11/glx/X11GLXContext.java b/src/classes/com/sun/opengl/impl/x11/glx/X11GLXContext.java index b18cc6623..88f11d259 100644 --- a/src/classes/com/sun/opengl/impl/x11/glx/X11GLXContext.java +++ b/src/classes/com/sun/opengl/impl/x11/glx/X11GLXContext.java @@ -250,10 +250,7 @@ public abstract class X11GLXContext extends GLContextImpl { } if (glXQueryExtensionsStringAvailable) { GLDrawableFactoryImpl factory = getDrawableImpl().getFactoryImpl(); - boolean wasLocked = factory.isToolkitLocked(); - if(!wasLocked) { - factory.lockToolkit(); - } + factory.lockToolkit(); try { String ret = GLX.glXQueryExtensionsString(drawable.getNativeWindow().getDisplayHandle(), drawable.getNativeWindow().getScreenIndex()); @@ -262,9 +259,7 @@ public abstract class X11GLXContext extends GLContextImpl { } return ret; } finally { - if(!wasLocked) { - factory.unlockToolkit(); - } + factory.unlockToolkit(); } } else { return ""; @@ -339,7 +334,7 @@ public abstract class X11GLXContext extends GLContextImpl { public boolean isOptimizable() { return (super.isOptimizable() && - !((X11GLXDrawableFactory)getGLDrawable().getFactory()).isVendorATI()); + !X11Util.isVendorATI()); } //---------------------------------------------------------------------- diff --git a/src/classes/com/sun/opengl/impl/x11/glx/X11GLXDrawable.java b/src/classes/com/sun/opengl/impl/x11/glx/X11GLXDrawable.java index cf34d9492..96e2d897f 100644 --- a/src/classes/com/sun/opengl/impl/x11/glx/X11GLXDrawable.java +++ b/src/classes/com/sun/opengl/impl/x11/glx/X11GLXDrawable.java @@ -105,11 +105,7 @@ public abstract class X11GLXDrawable extends GLDrawableImpl { template.screen(screen); XVisualInfo[] infos = null; GLCapabilities[] caps = null; - boolean didLock = false; - if (!getFactoryImpl().isToolkitLocked()) { - getFactoryImpl().lockToolkit(); - didLock = true; - } + getFactoryImpl().lockToolkit(); try { infos = X11Lib.XGetVisualInfo(display, X11Lib.VisualScreenMask, template, count, 0); if (infos == null) { @@ -120,9 +116,7 @@ public abstract class X11GLXDrawable extends GLDrawableImpl { caps[i] = ((X11GLXDrawableFactory)getFactory()).xvi2GLCapabilities(display, infos[i]); } } finally { - if (didLock) { - getFactoryImpl().unlockToolkit(); - } + getFactoryImpl().unlockToolkit(); } GLCapabilities capabilities = getRequestedGLCapabilities(); int chosen = chooser.chooseCapabilities(capabilities, caps, -1); diff --git a/src/classes/com/sun/opengl/impl/x11/glx/X11GLXDrawableFactory.java b/src/classes/com/sun/opengl/impl/x11/glx/X11GLXDrawableFactory.java index 75011ec88..d99b237e5 100644 --- a/src/classes/com/sun/opengl/impl/x11/glx/X11GLXDrawableFactory.java +++ b/src/classes/com/sun/opengl/impl/x11/glx/X11GLXDrawableFactory.java @@ -48,14 +48,11 @@ import com.sun.opengl.impl.x11.*; public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { protected static final boolean DEBUG = Debug.debug("X11GLXDrawableFactory"); - // ATI's proprietary drivers apparently send GLX tokens even for - // direct contexts, so we need to disable the context optimizations - // in this case - private static boolean isVendorATI; - // Map for rediscovering the GLCapabilities associated with a // particular screen and visualID after the fact protected static Map visualToGLCapsMap = Collections.synchronizedMap(new HashMap()); + // The screens for which we've already initialized it + protected static Set/*<Integer>*/ initializedScreenSet = Collections.synchronizedSet(new HashSet()); public static class ScreenAndVisualIDKey { private int screen; @@ -110,6 +107,21 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { return new X11OnscreenGLXDrawable(this, target); } + public void initializeVisualToGLCapabilitiesMap(int screen, + XVisualInfo[] infos, + GLCapabilities[] caps) { + Integer key = new Integer(screen); + if (!initializedScreenSet.contains(key)) { + for (int i = 0; i < infos.length; i++) { + if (caps[i] != null) { + visualToGLCapsMap.put(new ScreenAndVisualIDKey(screen, infos[i].visualid()), + caps[i].clone()); + } + } + initializedScreenSet.add(key); + } + } + public GLCapabilities lookupCapabilitiesByScreenAndVisualID(int screenIndex, long visualID) { return (GLCapabilities) visualToGLCapsMap.get(new ScreenAndVisualIDKey(screenIndex, visualID)); @@ -128,7 +140,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { if (!pbufferSupportInitialized) { Runnable r = new Runnable() { public void run() { - long display = getDisplayConnection(); + long display = X11Util.getDisplayConnection(); lockToolkit(); try { int[] major = new int[1]; @@ -245,7 +257,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { res.setAccumGreenBits(glXGetConfig(display, info, GLX.GLX_ACCUM_GREEN_SIZE, tmp, 0)); res.setAccumBlueBits (glXGetConfig(display, info, GLX.GLX_ACCUM_BLUE_SIZE, tmp, 0)); res.setAccumAlphaBits(glXGetConfig(display, info, GLX.GLX_ACCUM_ALPHA_SIZE, tmp, 0)); - if (isMultisampleAvailable()) { + if (X11Util.isMultisampleAvailable()) { res.setSampleBuffers(glXGetConfig(display, info, GLX.GLX_SAMPLE_BUFFERS, tmp, 0) != 0); res.setNumSamples (glXGetConfig(display, info, GLX.GLX_SAMPLES, tmp, 0)); } @@ -419,63 +431,6 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { return caps; } - // Display connection for use by visual selection algorithm and by all offscreen surfaces - private static long staticDisplay=0; - private static boolean xineramaEnabled=false; - private static boolean multisampleAvailable=false; - public static long getDisplayConnection() { - if (staticDisplay == 0) { - // FIXME: lockToolkit(); - try { - staticDisplay = X11Lib.XOpenDisplay(null); - if (DEBUG && (staticDisplay != 0)) { - long display = staticDisplay; - int screen = X11Lib.DefaultScreen(display); - System.err.println("!!! GLX server vendor : " + - GLX.glXQueryServerString(display, screen, GLX.GLX_VENDOR)); - System.err.println("!!! GLX server version: " + - GLX.glXQueryServerString(display, screen, GLX.GLX_VERSION)); - System.err.println("!!! GLX client vendor : " + - GLX.glXGetClientString(display, GLX.GLX_VENDOR)); - System.err.println("!!! GLX client version: " + - GLX.glXGetClientString(display, GLX.GLX_VERSION)); - } - - if (staticDisplay != 0) { - String vendor = GLX.glXGetClientString(staticDisplay, GLX.GLX_VENDOR); - if (vendor != null && vendor.startsWith("ATI")) { - isVendorATI = true; - } - xineramaEnabled = X11Lib.XineramaEnabled(staticDisplay); - String exts = GLX.glXGetClientString(staticDisplay, GLX.GLX_EXTENSIONS); - if (exts != null) { - multisampleAvailable = (exts.indexOf("GLX_ARB_multisample") >= 0); - } - } - } finally { - // FIXME: unlockToolkit(); - } - if (staticDisplay == 0) { - throw new GLException("Unable to open default display, needed for visual selection and offscreen surface handling"); - } - } - return staticDisplay; - } - - public boolean isXineramaEnabled() { - if (staticDisplay == 0) { - getDisplayConnection(); // will set xineramaEnabled - } - return xineramaEnabled; - } - - public boolean isMultisampleAvailable() { - if (staticDisplay == 0) { - getDisplayConnection(); // will set multisampleAvailable - } - return multisampleAvailable; - } - private static String glXGetConfigErrorCode(int err) { switch (err) { case GLX.GLX_NO_EXTENSION: return "GLX_NO_EXTENSION"; @@ -497,12 +452,6 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { return tmp[tmp_offset]; } - /** Workaround for apparent issue with ATI's proprietary drivers - where direct contexts still send GLX tokens for GL calls */ - public static boolean isVendorATI() { - return isVendorATI; - } - private void maybeDoSingleThreadedWorkaround(Runnable action) { if (Threading.isSingleThreaded() && !Threading.isOpenGLThread()) { @@ -534,7 +483,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { int[] size = new int[1]; lockToolkit(); - long display = getDisplayConnection(); + long display = X11Util.getDisplayConnection(); boolean res = X11Lib.XF86VidModeGetGammaRampSize(display, X11Lib.DefaultScreen(display), size, 0); @@ -554,7 +503,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { } lockToolkit(); - long display = getDisplayConnection(); + long display = X11Util.getDisplayConnection(); boolean res = X11Lib.XF86VidModeSetGammaRamp(display, X11Lib.DefaultScreen(display), rampData.length, @@ -578,7 +527,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { rampData.limit(3 * size); ShortBuffer blueRampData = rampData.slice(); lockToolkit(); - long display = getDisplayConnection(); + long display = X11Util.getDisplayConnection(); boolean res = X11Lib.XF86VidModeGetGammaRamp(display, X11Lib.DefaultScreen(display), size, @@ -610,7 +559,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { rampData.limit(3 * size); ShortBuffer blueRampData = rampData.slice(); lockToolkit(); - long display = getDisplayConnection(); + long display = X11Util.getDisplayConnection(); X11Lib.XF86VidModeSetGammaRamp(display, X11Lib.DefaultScreen(display), size, diff --git a/src/classes/com/sun/opengl/impl/x11/glx/X11GLXNativeWindowFactory.java b/src/classes/com/sun/opengl/impl/x11/glx/X11GLXNativeWindowFactory.java new file mode 100644 index 000000000..98ade1c06 --- /dev/null +++ b/src/classes/com/sun/opengl/impl/x11/glx/X11GLXNativeWindowFactory.java @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +package com.sun.opengl.impl.x11.glx; + +import javax.media.opengl.*; + +import com.sun.opengl.impl.*; +import com.sun.opengl.impl.x11.*; + +/** Subclass of NativeWindowFactory used when non-AWT tookits are used + on X11 platforms. Toolkits will likely need to subclass this one + to add synchronization in certain places and change the accepted + and returned types of the GraphicsDevice and GraphicsConfiguration + abstractions. */ + +public class X11GLXNativeWindowFactory extends NativeWindowFactoryImpl { + public AbstractGraphicsConfiguration chooseGraphicsConfiguration(GLCapabilities capabilities, + GLCapabilitiesChooser chooser, + AbstractGraphicsDevice absDevice) { + if (absDevice != null && + !(absDevice instanceof X11GraphicsDevice)) { + throw new IllegalArgumentException("This NativeWindowFactory accepts only X11GraphicsDevice objects"); + } + + int screen = 0; + if (absDevice != null) { + screen = ((X11GraphicsDevice) absDevice).getScreen(); + } + + long visualID = chooseGraphicsConfigurationImpl(capabilities, chooser, screen); + return new X11GraphicsConfiguration(visualID); + } + + /** Returns the visual ID of the chosen GraphicsConfiguration. */ + protected long chooseGraphicsConfigurationImpl(GLCapabilities capabilities, + GLCapabilitiesChooser chooser, + int screen) { + if (capabilities == null) { + capabilities = new GLCapabilities(); + } + if (chooser == null) { + chooser = new DefaultGLCapabilitiesChooser(); + } + + if (X11Util.isXineramaEnabled()) { + screen = 0; + } + + // Until we have a rock-solid visual selection algorithm written + // in pure Java, we're going to provide the underlying window + // system's selection to the chooser as a hint + + int[] attribs = X11GLXDrawableFactory.glCapabilities2AttribList(capabilities, X11Util.isMultisampleAvailable(), false, 0, 0); + XVisualInfo[] infos = null; + GLCapabilities[] caps = null; + int recommendedIndex = -1; + getDefaultFactory().getToolkitLock().lock(); + try { + long display = X11Util.getDisplayConnection(); + XVisualInfo recommendedVis = GLX.glXChooseVisual(display, screen, attribs, 0); + if (DEBUG) { + System.err.print("!!! glXChooseVisual recommended "); + if (recommendedVis == null) { + System.err.println("null visual"); + } else { + System.err.println("visual id 0x" + Long.toHexString(recommendedVis.visualid())); + } + } + int[] count = new int[1]; + XVisualInfo template = XVisualInfo.create(); + template.screen(screen); + infos = X11Lib.XGetVisualInfo(display, X11Lib.VisualScreenMask, template, count, 0); + if (infos == null) { + throw new GLException("Error while enumerating available XVisualInfos"); + } + caps = new GLCapabilities[infos.length]; + for (int i = 0; i < infos.length; i++) { + caps[i] = ((X11GLXDrawableFactory) GLDrawableFactory.getFactory()).xvi2GLCapabilities(display, infos[i]); + // Attempt to find the visual chosen by glXChooseVisual + if (recommendedVis != null && recommendedVis.visualid() == infos[i].visualid()) { + recommendedIndex = i; + } + } + } finally { + getDefaultFactory().getToolkitLock().unlock(); + } + // Store these away for later + ((X11GLXDrawableFactory) GLDrawableFactory.getFactory()). + initializeVisualToGLCapabilitiesMap(screen, infos, caps); + int chosen = chooser.chooseCapabilities(capabilities, caps, recommendedIndex); + if (chosen < 0 || chosen >= caps.length) { + throw new GLException("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ")"); + } + XVisualInfo vis = infos[chosen]; + if (vis == null) { + throw new GLException("GLCapabilitiesChooser chose an invalid visual"); + } + return vis.visualid(); + } + + // On X11 platforms we need to do some locking; this basic + // implementation should suffice for some simple window toolkits + private ToolkitLock toolkitLock = new ToolkitLock() { + private Thread owner; + private int recursionCount; + + public synchronized void lock() { + Thread cur = Thread.currentThread(); + if (owner == cur) { + ++recursionCount; + return; + } + while (owner != null) { + try { + wait(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + owner = cur; + } + + public synchronized void unlock() { + if (owner != Thread.currentThread()) { + throw new RuntimeException("Not owner"); + } + if (recursionCount > 0) { + --recursionCount; + return; + } + owner = null; + } + }; + + public ToolkitLock getToolkitLock() { + return toolkitLock; + } +} diff --git a/src/classes/com/sun/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java b/src/classes/com/sun/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java index bd2eb9921..035b86708 100644 --- a/src/classes/com/sun/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java +++ b/src/classes/com/sun/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java @@ -54,6 +54,7 @@ public class X11OffscreenGLXDrawable extends X11GLXDrawable { int height) { super(factory, new NullWindow(), true, requestedCapabilities, chooser); ((NullWindow) getNativeWindow()).setSize(width, height); + create(); } public GLContext createContext(GLContext shareWith) { @@ -62,7 +63,7 @@ public class X11OffscreenGLXDrawable extends X11GLXDrawable { private void create() { NullWindow nw = (NullWindow) getNativeWindow(); - long dpy = X11GLXDrawableFactory.getDisplayConnection(); + long dpy = X11Util.getDisplayConnection(); nw.setDisplayHandle(dpy); XVisualInfo vis = chooseVisual(false); int bitsPerPixel = vis.depth(); diff --git a/src/classes/com/sun/opengl/impl/x11/glx/X11PbufferGLXDrawable.java b/src/classes/com/sun/opengl/impl/x11/glx/X11PbufferGLXDrawable.java index 3df6d486a..aa84b034a 100644 --- a/src/classes/com/sun/opengl/impl/x11/glx/X11PbufferGLXDrawable.java +++ b/src/classes/com/sun/opengl/impl/x11/glx/X11PbufferGLXDrawable.java @@ -70,7 +70,7 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable { (requestedCapabilities.getPbufferFloatingPointBuffers() ? " [float]" : "")); } - nw.setDisplayHandle(X11GLXDrawableFactory.getDisplayConnection()); + nw.setDisplayHandle(X11Util.getDisplayConnection()); createPbuffer(); } @@ -115,7 +115,7 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable { } int[] iattributes = X11GLXDrawableFactory.glCapabilities2AttribList(capabilities, - ((X11GLXDrawableFactory)getFactory()).isMultisampleAvailable(), + X11Util.isMultisampleAvailable(), true, display, screen); int[] nelementsTmp = new int[1]; @@ -165,8 +165,8 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable { this.fbConfig = fbConfig; // Pick innocent query values if multisampling or floating point buffers not available - int sbAttrib = ((X11GLXDrawableFactory)getFactory()).isMultisampleAvailable() ? GLXExt.GLX_SAMPLE_BUFFERS: GLX.GLX_RED_SIZE; - int samplesAttrib = ((X11GLXDrawableFactory)getFactory()).isMultisampleAvailable() ? GLXExt.GLX_SAMPLES: GLX.GLX_RED_SIZE; + int sbAttrib = X11Util.isMultisampleAvailable() ? GLXExt.GLX_SAMPLE_BUFFERS: GLX.GLX_RED_SIZE; + int samplesAttrib = X11Util.isMultisampleAvailable() ? GLXExt.GLX_SAMPLES: GLX.GLX_RED_SIZE; int floatNV = capabilities.getPbufferFloatingPointBuffers() ? GLXExt.GLX_FLOAT_COMPONENTS_NV : GLX.GLX_RED_SIZE; // Query the fbconfig to determine its GLCapabilities diff --git a/src/classes/com/sun/opengl/impl/x11/glx/X11Util.java b/src/classes/com/sun/opengl/impl/x11/glx/X11Util.java new file mode 100644 index 000000000..480c607a4 --- /dev/null +++ b/src/classes/com/sun/opengl/impl/x11/glx/X11Util.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +package com.sun.opengl.impl.x11.glx; + +import javax.media.opengl.*; + +import com.sun.opengl.impl.*; +import com.sun.opengl.impl.x11.*; + +public class X11Util { + private static final boolean DEBUG = Debug.debug("X11Util"); + + private X11Util() {} + + // ATI's proprietary drivers apparently send GLX tokens even for + // direct contexts, so we need to disable the context optimizations + // in this case + private static boolean isVendorATI; + + // Display connection for use by visual selection algorithm and by all offscreen surfaces + private static long staticDisplay=0; + private static boolean xineramaEnabled=false; + private static boolean multisampleAvailable=false; + public static long getDisplayConnection() { + if (staticDisplay == 0) { + NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); + try { + staticDisplay = X11Lib.XOpenDisplay(null); + if (DEBUG && (staticDisplay != 0)) { + long display = staticDisplay; + int screen = X11Lib.DefaultScreen(display); + System.err.println("!!! GLX server vendor : " + + GLX.glXQueryServerString(display, screen, GLX.GLX_VENDOR)); + System.err.println("!!! GLX server version: " + + GLX.glXQueryServerString(display, screen, GLX.GLX_VERSION)); + System.err.println("!!! GLX client vendor : " + + GLX.glXGetClientString(display, GLX.GLX_VENDOR)); + System.err.println("!!! GLX client version: " + + GLX.glXGetClientString(display, GLX.GLX_VERSION)); + } + + if (staticDisplay != 0) { + String vendor = GLX.glXGetClientString(staticDisplay, GLX.GLX_VENDOR); + if (vendor != null && vendor.startsWith("ATI")) { + isVendorATI = true; + } + xineramaEnabled = X11Lib.XineramaEnabled(staticDisplay); + String exts = GLX.glXGetClientString(staticDisplay, GLX.GLX_EXTENSIONS); + if (exts != null) { + multisampleAvailable = (exts.indexOf("GLX_ARB_multisample") >= 0); + } + } + } finally { + NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); + } + if (staticDisplay == 0) { + throw new GLException("Unable to open default display, needed for visual selection and offscreen surface handling"); + } + } + return staticDisplay; + } + + public static boolean isXineramaEnabled() { + if (staticDisplay == 0) { + getDisplayConnection(); // will set xineramaEnabled + } + return xineramaEnabled; + } + + public static boolean isMultisampleAvailable() { + if (staticDisplay == 0) { + getDisplayConnection(); // will set multisampleAvailable + } + return multisampleAvailable; + } + + /** Workaround for apparent issue with ATI's proprietary drivers + where direct contexts still send GLX tokens for GL calls */ + public static boolean isVendorATI() { + return isVendorATI; + } +} diff --git a/src/classes/com/sun/opengl/impl/x11/glx/awt/X11AWTGLXDrawableFactory.java b/src/classes/com/sun/opengl/impl/x11/glx/awt/X11AWTGLXDrawableFactory.java deleted file mode 100644 index a5ec4c46c..000000000 --- a/src/classes/com/sun/opengl/impl/x11/glx/awt/X11AWTGLXDrawableFactory.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Neither the name of Sun Microsystems, Inc. or the names of - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, - * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN - * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR - * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR - * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE - * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, - * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF - * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that this software is not designed or intended for use - * in the design, construction, operation or maintenance of any nuclear - * facility. - */ - -package com.sun.opengl.impl.x11.glx.awt; - -import com.sun.opengl.impl.*; -import com.sun.opengl.impl.x11.*; -import com.sun.opengl.impl.x11.glx.*; -import com.sun.opengl.impl.jawt.*; -import com.sun.opengl.impl.jawt.x11.*; -import java.awt.Graphics; -import java.awt.GraphicsConfiguration; -import java.awt.GraphicsDevice; -import java.awt.GraphicsEnvironment; -import java.nio.*; -import java.security.*; -import java.util.*; -import javax.media.opengl.*; -import javax.media.opengl.awt.*; -import com.sun.gluegen.runtime.*; - -public class X11AWTGLXDrawableFactory extends X11GLXDrawableFactory { - - static { - // See DRIHack.java for an explanation of why this is necessary - DRIHack.begin(); - - com.sun.opengl.impl.NativeLibLoader.loadGL2(); - - DRIHack.end(); - } - - public AbstractGraphicsConfiguration chooseGraphicsConfiguration(GLCapabilities capabilities, - GLCapabilitiesChooser chooser, - AbstractGraphicsDevice absDevice) { - if (capabilities == null) { - capabilities = new GLCapabilities(); - } - if (chooser == null) { - chooser = new DefaultGLCapabilitiesChooser(); - } - GraphicsDevice device = null; - if (absDevice != null && - !(absDevice instanceof AWTGraphicsDevice)) { - throw new IllegalArgumentException("This GLDrawableFactory accepts only AWTGraphicsDevice objects"); - } - - if ((absDevice == null) || - (((AWTGraphicsDevice) absDevice).getGraphicsDevice() == null)) { - device = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); - } else { - device = ((AWTGraphicsDevice) absDevice).getGraphicsDevice(); - } - - int screen; - if (isXineramaEnabled()) { - screen = 0; - } else { - screen = X11SunJDKReflection.graphicsDeviceGetScreen(device); - } - - // Until we have a rock-solid visual selection algorithm written - // in pure Java, we're going to provide the underlying window - // system's selection to the chooser as a hint - - int[] attribs = glCapabilities2AttribList(capabilities, isMultisampleAvailable(), false, 0, 0); - XVisualInfo[] infos = null; - GLCapabilities[] caps = null; - int recommendedIndex = -1; - lockToolkit(); - try { - long display = getDisplayConnection(); - XVisualInfo recommendedVis = GLX.glXChooseVisual(display, screen, attribs, 0); - if (DEBUG) { - System.err.print("!!! glXChooseVisual recommended "); - if (recommendedVis == null) { - System.err.println("null visual"); - } else { - System.err.println("visual id 0x" + Long.toHexString(recommendedVis.visualid())); - } - } - int[] count = new int[1]; - XVisualInfo template = XVisualInfo.create(); - template.screen(screen); - infos = X11Lib.XGetVisualInfo(display, X11Lib.VisualScreenMask, template, count, 0); - if (infos == null) { - throw new GLException("Error while enumerating available XVisualInfos"); - } - caps = new GLCapabilities[infos.length]; - for (int i = 0; i < infos.length; i++) { - caps[i] = xvi2GLCapabilities(display, infos[i]); - // Attempt to find the visual chosen by glXChooseVisual - if (recommendedVis != null && recommendedVis.visualid() == infos[i].visualid()) { - recommendedIndex = i; - } - } - } finally { - unlockToolkit(); - } - // Store these away for later - for (int i = 0; i < infos.length; i++) { - if (caps[i] != null) { - visualToGLCapsMap.put(new ScreenAndVisualIDKey(screen, infos[i].visualid()), - caps[i].clone()); - } - } - int chosen = chooser.chooseCapabilities(capabilities, caps, recommendedIndex); - if (chosen < 0 || chosen >= caps.length) { - throw new GLException("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ")"); - } - XVisualInfo vis = infos[chosen]; - if (vis == null) { - throw new GLException("GLCapabilitiesChooser chose an invalid visual"); - } - // FIXME: need to look at glue code and see type of this field - long visualID = vis.visualid(); - // FIXME: the storage for the infos array, as well as that for the - // recommended visual, is leaked; should free them here with XFree() - - // Now figure out which GraphicsConfiguration corresponds to this - // visual by matching the visual ID - GraphicsConfiguration[] configs = device.getConfigurations(); - for (int i = 0; i < configs.length; i++) { - GraphicsConfiguration config = configs[i]; - if (config != null) { - if (X11SunJDKReflection.graphicsConfigurationGetVisualID(config) == visualID) { - return new AWTGraphicsConfiguration(config); - } - } - } - - // Either we weren't able to reflectively introspect on the - // X11GraphicsConfig or something went wrong in the steps above; - // we're going to return null without signaling an error condition - // in this case (although we should distinguish between the two - // and possibly report more of an error in the latter case) - return null; - } - - public void lockToolkit() { - super.lockToolkit(); - JAWTUtil.lockToolkit(); - } - - public void unlockToolkit() { - JAWTUtil.unlockToolkit(); - super.unlockToolkit(); - } - -} diff --git a/src/classes/com/sun/opengl/impl/x11/glx/awt/X11AWTGLXNativeWindowFactory.java b/src/classes/com/sun/opengl/impl/x11/glx/awt/X11AWTGLXNativeWindowFactory.java new file mode 100644 index 000000000..11da7af05 --- /dev/null +++ b/src/classes/com/sun/opengl/impl/x11/glx/awt/X11AWTGLXNativeWindowFactory.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +package com.sun.opengl.impl.x11.glx.awt; + +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import javax.media.opengl.*; +import javax.media.opengl.awt.*; + +import com.sun.opengl.impl.*; +import com.sun.opengl.impl.jawt.*; +import com.sun.opengl.impl.jawt.x11.*; +import com.sun.opengl.impl.x11.*; +import com.sun.opengl.impl.x11.glx.*; + +public class X11AWTGLXNativeWindowFactory extends X11GLXNativeWindowFactory { + public AbstractGraphicsConfiguration chooseGraphicsConfiguration(GLCapabilities capabilities, + GLCapabilitiesChooser chooser, + AbstractGraphicsDevice absDevice) { + GraphicsDevice device = null; + if (absDevice != null && + !(absDevice instanceof AWTGraphicsDevice)) { + throw new IllegalArgumentException("This NativeWindowFactory accepts only AWTGraphicsDevice objects"); + } + + if ((absDevice == null) || + (((AWTGraphicsDevice) absDevice).getGraphicsDevice() == null)) { + device = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); + } else { + device = ((AWTGraphicsDevice) absDevice).getGraphicsDevice(); + } + + long visualID = chooseGraphicsConfigurationImpl(capabilities, chooser, + X11SunJDKReflection.graphicsDeviceGetScreen(device)); + + // Now figure out which GraphicsConfiguration corresponds to this + // visual by matching the visual ID + GraphicsConfiguration[] configs = device.getConfigurations(); + for (int i = 0; i < configs.length; i++) { + GraphicsConfiguration config = configs[i]; + if (config != null) { + if (X11SunJDKReflection.graphicsConfigurationGetVisualID(config) == visualID) { + return new AWTGraphicsConfiguration(config); + } + } + } + + // Either we weren't able to reflectively introspect on the + // X11GraphicsConfig or something went wrong in the steps above; + // we're going to return null without signaling an error condition + // in this case (although we should distinguish between the two + // and possibly report more of an error in the latter case) + return null; + } + + // When running the AWT on X11 platforms, we use the AWT native + // interface (JAWT) to lock and unlock the toolkit + private ToolkitLock toolkitLock = new ToolkitLock() { + private Thread owner; + private int recursionCount; + + public synchronized void lock() { + Thread cur = Thread.currentThread(); + if (owner == cur) { + ++recursionCount; + return; + } + while (owner != null) { + try { + wait(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + owner = cur; + JAWTUtil.lockToolkit(); + } + + public synchronized void unlock() { + if (owner != Thread.currentThread()) { + throw new RuntimeException("Not owner"); + } + if (recursionCount > 0) { + --recursionCount; + return; + } + owner = null; + JAWTUtil.unlockToolkit(); + } + }; + + public ToolkitLock getToolkitLock() { + return toolkitLock; + } +} |