diff options
Diffstat (limited to 'src/classes/com/sun/opengl/impl')
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; + } +} |