diff options
24 files changed, 1180 insertions, 908 deletions
diff --git a/src/classes/com/sun/javafx/newt/GLWindow.java b/src/classes/com/sun/javafx/newt/GLWindow.java index b48d64ed2..e2fa4c67e 100644 --- a/src/classes/com/sun/javafx/newt/GLWindow.java +++ b/src/classes/com/sun/javafx/newt/GLWindow.java @@ -226,7 +226,7 @@ public class GLWindow extends Window implements GLAutoDrawable { public void setVisible(boolean visible) { window.setVisible(visible); if (visible && context == null) { - factory = GLDrawableFactory.getFactory(window); + factory = GLDrawableFactory.getFactory(); drawable = factory.createGLDrawable(window, window.getChosenCapabilities(), null); window.setVisible(true); drawable.setRealized(true); 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/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; + } +} diff --git a/src/classes/javax/media/opengl/GLDrawableFactory.java b/src/classes/javax/media/opengl/GLDrawableFactory.java index f6ada6c50..677441572 100644 --- a/src/classes/javax/media/opengl/GLDrawableFactory.java +++ b/src/classes/javax/media/opengl/GLDrawableFactory.java @@ -59,7 +59,7 @@ import com.sun.opengl.impl.*; passed GLCapabilitiesChooser will be ignored. </P> <P> Because of the multithreaded nature of the Java platform's - window system toolkit, it is typically not possible to immediately + Abstract Window Toolkit, it is typically not possible to immediately reject a given {@link GLCapabilities} as being unsupportable by either returning <code>null</code> from the creation routines or raising a {@link GLException}. The semantics of the rejection @@ -77,179 +77,67 @@ import com.sun.opengl.impl.*; */ public abstract class GLDrawableFactory { - private static GLDrawableFactory awtFactory; - private static GLDrawableFactory nwFactory; + private static GLDrawableFactory factory; - /** Initializes the sole GLDrawableFactory instance for the given profile. */ - private static void initializeAWTFactory() throws GLException { - if (awtFactory != null) { - return; - } - - // See if the user is requesting one of the embedded profiles, - // and if so, try to instantiate the EGLDrawableFactory - if (GLProfile.isGLES()) { - try { - awtFactory = (GLDrawableFactory) GLReflection.createInstance("com.sun.opengl.impl.egl.awt.EGLAWTDrawableFactory"); - return; - } catch (Exception e) { - e.printStackTrace(); - } - } else if (!GLProfile.isGL2() && !GLProfile.isGL2ES12()) { - // We require that the user passes in one of the known profiles - throw new GLException("Unknown or unsupported profile \"" + GLProfile.getProfile() + "\""); - } - - // Use the desktop OpenGL as the fallback always - try { - String factoryClassName = - (String) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return System.getProperty("opengl.awt.factory.class.name"); - } - }); - String osName = System.getProperty("os.name"); - String osNameLowerCase = osName.toLowerCase(); - - // Because there are some complications with generating all - // platforms' Java glue code on all platforms (among them that we - // would have to include jawt.h and jawt_md.h in the jogl - // sources, which we currently don't have to do) we break the only - // static dependencies with platform-specific code here using reflection. - - if (factoryClassName == null) { - if (osNameLowerCase.startsWith("wind")) { - factoryClassName = "com.sun.opengl.impl.windows.wgl.WindowsWGLDrawableFactory"; - } else if (osNameLowerCase.startsWith("mac os x")) { - factoryClassName = "com.sun.opengl.impl.macosx.cgl.awt.MacOSXAWTCGLDrawableFactory"; - } else { - // Assume Linux, Solaris, etc. Should probably test for these explicitly. - factoryClassName = "com.sun.opengl.impl.x11.glx.awt.X11AWTGLXDrawableFactory"; - } - } - - awtFactory = (GLDrawableFactory) GLReflection.createInstance(factoryClassName); - } catch (Exception e) { - throw new GLException(e); - } - } - - private static GLDrawableFactory getAWTFactory() - throws GLException - { - if(null==GLProfile.getProfile()) { - throw new GLException("No chosen/preset GLProfile"); - } - initializeAWTFactory(); - if(awtFactory == null) { - throw new GLException("Could not determine the AWT-GLDrawableFactory"); - } - return awtFactory; + /** Creates a new GLDrawableFactory instance. End users do not need + to call this method. */ + protected GLDrawableFactory() { } - /** Initializes the sole GLDrawableFactory instance for the given profile. */ - private static void initializeNWFactory() throws GLException { - if (nwFactory != null) { - return; - } + /** Returns the sole GLDrawableFactory instance. The {@link + GLProfile GLProfile} must be configured before calling this + method. */ + public static GLDrawableFactory getFactory() throws GLException { + if (null == factory) { + if (null == GLProfile.getProfile()) { + throw new GLException("GLProfile was not properly initialized"); + } - // See if the user is requesting one of the embedded profiles, - // and if so, try to instantiate the EGLDrawableFactory - if (GLProfile.isGLES()) { - try { - nwFactory = (GLDrawableFactory) GLReflection.createInstance("com.sun.opengl.impl.egl.EGLDrawableFactory"); - return; - } catch (Exception e) { + // See if the user is requesting one of the embedded profiles, + // and if so, try to instantiate the EGLDrawableFactory + if (GLProfile.isGLES()) { + try { + factory = (GLDrawableFactory) GLReflection.createInstance("com.sun.opengl.impl.egl.EGLDrawableFactory"); + } catch (Exception e) { e.printStackTrace(); + } + } else if (!GLProfile.isGL2() && !GLProfile.isGL2ES12()) { + // We require that the user passes in one of the known profiles + throw new GLException("Unknown or unsupported profile \"" + GLProfile.getProfile() + "\""); } - } else if (!GLProfile.isGL2() && !GLProfile.isGL2ES12()) { - // We require that the user passes in one of the known profiles - throw new GLException("Unknown or unsupported profile \"" + GLProfile.getProfile() + "\""); - } - // Use the desktop OpenGL as the fallback always - try { - String factoryClassName = - (String) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return System.getProperty("opengl.factory.class.name"); + if (null == factory) { + // Use the desktop OpenGL as the fallback always + try { + String factoryClassName = + (String) AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + return System.getProperty("opengl.factory.class.name"); + } + }); + String osName = System.getProperty("os.name"); + String osNameLowerCase = osName.toLowerCase(); + + if (factoryClassName == null) { + if (osNameLowerCase.startsWith("windows")) { + factoryClassName = "com.sun.opengl.impl.windows.wgl.WindowsWGLDrawableFactory"; + } else if (osNameLowerCase.startsWith("mac os x")) { + // FIXME: remove this residual dependence on the AWT + factoryClassName = "com.sun.opengl.impl.macosx.cgl.awt.MacOSXAWTCGLDrawableFactory"; + } else { + // Assume Linux, Solaris, etc. Should probably test for these explicitly. + factoryClassName = "com.sun.opengl.impl.x11.glx.X11GLXDrawableFactory"; } - }); - String osName = System.getProperty("os.name"); - String osNameLowerCase = osName.toLowerCase(); - - if (factoryClassName == null) { - if (osNameLowerCase.startsWith("wind")) { - factoryClassName = "com.sun.opengl.impl.windows.wgl.WindowsWGLDrawableFactory"; - } else if (osNameLowerCase.startsWith("mac os x")) { - factoryClassName = "com.sun.opengl.impl.macosx.cgl.MacOSXCGLDrawableFactory"; - } else { - // Assume Linux, Solaris, etc. Should probably test for these explicitly. - factoryClassName = "com.sun.opengl.impl.x11.glx.X11GLXDrawableFactory"; } - } - nwFactory = (GLDrawableFactory) GLReflection.createInstance(factoryClassName); - return; - } catch (Exception e) { - throw new GLException(e); - } - } - - private static GLDrawableFactory getNWFactory() - throws GLException - { - if(null==GLProfile.getProfile()) { - throw new GLException("No chosen/preset GLProfile"); - } - initializeNWFactory(); - if(nwFactory == null) { - throw new GLException("Could not determine the NativeWindow GLDrawableFactory"); - } - return nwFactory; - } - - /** Creates a new GLDrawableFactory instance. End users do not need - to call this method. */ - protected GLDrawableFactory() { - } - - /** Returns a GLDrawableFactory suitable to the passed winObj. - In case winObj is a NativeWindow, the wrapped window object will be used. */ - public static GLDrawableFactory getFactory(Object winObj) - throws GLException - { - if (winObj == null) { - throw new IllegalArgumentException("winObj is null"); - } - if ( winObj instanceof NativeWindow ) { - NativeWindow nw = (NativeWindow)winObj; - if(null!=nw.getWrappedWindow()) { - winObj = nw.getWrappedWindow(); + factory = (GLDrawableFactory) GLReflection.createInstance(factoryClassName); + } catch (Exception e) { + throw new GLException(e); } + } } - return getFactory(winObj.getClass()); - } - - /** Returns a GLDrawableFactory suitable to the passed winClazz. */ - public static GLDrawableFactory getFactory(Class winClazz) - throws GLException - { - if (GLReflection.implementationOf(winClazz, NativeWindow.class.getName())) { - return getNWFactory(); - } else if (GLReflection.isAWTComponent(winClazz)) { - return getAWTFactory(); - } - throw new IllegalArgumentException("Target type is unsupported. Currently supported: \n"+ - "\tjavax.media.opengl.NativeWindow\n"+ - "\tjava.awt.Component\n"); - } - /** Returns the common GLDrawableFactory, suitable for NativeWindow. */ - public static GLDrawableFactory getFactory() - throws GLException - { - return getNWFactory(); + return factory; } /** Shuts down this GLDrawableFactory, releasing resources @@ -261,38 +149,6 @@ public abstract class GLDrawableFactory { } /** - * <P> Selects a graphics configuration on the specified graphics - * device compatible with the supplied GLCapabilities. This method - * is intended to be used by applications which do not use the - * supplied GLCanvas class but instead wrap their own Canvas or - * other window toolkit-specific object with a GLDrawable. Some - * platforms (specifically X11) require the graphics configuration - * to be specified when the window toolkit object is created. This - * method may return null on platforms on which the OpenGL pixel - * format selection process is performed later. </P> - * - * <P> The concrete data type of the passed graphics device and - * returned graphics configuration must be specified in the - * documentation binding this particular API to the underlying - * window toolkit. The Reference Implementation accepts {@link - * AWTGraphicsDevice AWTGraphicsDevice} objects and returns {@link - * AWTGraphicsConfiguration AWTGraphicsConfiguration} objects. </P> - * - * @see java.awt.Canvas#Canvas(java.awt.GraphicsConfiguration) - * - * @throws IllegalArgumentException if the data type of the passed - * AbstractGraphicsDevice is not supported by this - * GLDrawableFactory. - * @throws GLException if any window system-specific errors caused - * the selection of the graphics configuration to fail. - */ - public abstract AbstractGraphicsConfiguration - chooseGraphicsConfiguration(GLCapabilities capabilities, - GLCapabilitiesChooser chooser, - AbstractGraphicsDevice device) - throws IllegalArgumentException, GLException; - - /** * Returns a GLDrawable that wraps a platform-specific window system * object, such as an AWT or LCDUI Canvas. On platforms which * support it, selects a pixel format compatible with the supplied @@ -409,5 +265,4 @@ public abstract class GLDrawableFactory { */ public abstract GLDrawable createExternalGLDrawable() throws GLException; - } diff --git a/src/classes/javax/media/opengl/NativeWindowFactory.java b/src/classes/javax/media/opengl/NativeWindowFactory.java index ee28bfea1..18ce61974 100644 --- a/src/classes/javax/media/opengl/NativeWindowFactory.java +++ b/src/classes/javax/media/opengl/NativeWindowFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * 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 @@ -28,113 +28,191 @@ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - * - * You acknowledge that this software is not designed or intended for use - * in the design, construction, operation or maintenance of any nuclear - * facility. - * - * Sun gratefully acknowledges that this software was originally authored - * and developed by Kenneth Bradley Russell and Christopher John Kline. */ package javax.media.opengl; import java.lang.reflect.*; import java.security.*; +import java.util.*; + import com.sun.opengl.impl.*; -public class NativeWindowFactory { - private static Constructor awtFactory = null; +/** Provides the link between the window toolkit and the Java binding + to the OpenGL API. The NativeWindowFactory, and NativeWindow + instances it creates, encompass all of the toolkit-specific + functionality, leaving the GLDrawableFactory independent of any + particular toolkit. */ + +public abstract class NativeWindowFactory { + private static NativeWindowFactory defaultFactory; + private static HashMap/*<Class, NativeWindowFactory>*/ registeredFactories = + new HashMap(); + private static Class nativeWindowClass; + + /** Creates a new NativeWindowFactory instance. End users do not + need to call this method. */ + protected NativeWindowFactory() { + } + + static { + initialize(); + } + + private static void initialize() { + String osName = System.getProperty("os.name"); + String osNameLowerCase = osName.toLowerCase(); + String factoryClassName = null; - /** Initializes the sole NativeWindowFactory instance . */ - private static void initializeAWTFactory() throws GLException { - if (awtFactory == null) { - // Use the desktop OpenGL as the fallback always + // We break compile-time dependencies on the AWT here to + // make it easier to run this code on mobile devices + + NativeWindowFactory factory = new NativeWindowFactoryImpl(); + nativeWindowClass = javax.media.opengl.NativeWindow.class; + registerFactory(nativeWindowClass, factory); + defaultFactory = factory; + + Class componentClass = null; try { - String osName = System.getProperty("os.name"); - String osNameLowerCase = osName.toLowerCase(); - String factoryClassName = null; - - // Because there are some complications with generating all - // platforms' Java glue code on all platforms (among them that we - // would have to include jawt.h and jawt_md.h in the jogl - // sources, which we currently don't have to do) we break the only - // static dependencies with platform-specific code here using reflection. - - if (osNameLowerCase.startsWith("wind")) { - factoryClassName = "com.sun.opengl.impl.jawt.windows.WindowsJAWTWindow"; - } else if (osNameLowerCase.startsWith("mac os x")) { - factoryClassName = "com.sun.opengl.impl.jawt.macosx.MacOSXJAWTWindow"; - } else { - // Assume Linux, Solaris, etc. Should probably test for these explicitly. - factoryClassName = "com.sun.opengl.impl.jawt.x11.X11JAWTWindow"; - } - - if (factoryClassName == null) { - throw new GLException("OS " + osName + " not yet supported"); - } - - awtFactory = GLReflection.getConstructor(factoryClassName, new Class[] { Object.class }); + componentClass = Class.forName("java.awt.Component"); } catch (Exception e) { - throw new GLException(e); + } + if (componentClass != null) { + if (!osNameLowerCase.startsWith("wind") && + !osNameLowerCase.startsWith("mac os x")) { + // Assume X11 platform -- should probably test for these explicitly + try { + Constructor factoryConstructor = + GLReflection.getConstructor("com.sun.opengl.impl.x11.glx.awt.X11AWTGLXNativeWindowFactory", new Class[] {}); + factory = (NativeWindowFactory) factoryConstructor.newInstance(null); + } catch (Exception e) { + } + } + registerFactory(componentClass, factory); + defaultFactory = factory; } } - } - - /** - * Returns a NativeWindow. - * - * This method digest a window object 'winObj'. - * This can be either itself a NativeWindow, - * or any other Java-level window toolkit window object. - * - * In case 'winObj' is a terminal NativeWindow, where - * {@link NativeWindow#isTerminalObject()} returns true, - * it is passed through directly. - * - * Otherwise either the non NativeWindow object, - * or the wrapped window object within the proxy NativeWindow - * will be used to factor a terminal NativeWindow. - * - * @throws IllegalArgumentException if the passed winObj is null - * @throws NativeWindowException if the passed winObj's is a proxy NativeWindow - * and does not hold a supported wrapped window object, - * or it is not a supported window object. - * @throws GLException if any window system-specific errors caused - * the creation of the GLDrawable to fail. - */ - public static NativeWindow getNativeWindow(Object winObj) - throws IllegalArgumentException, GLException, NativeWindowException - { - if(null==winObj) { - throw new IllegalArgumentException("winObj is null"); + + /** Sets the default NativeWindowFactory. Certain operations on + X11 platforms require synchronization, and the implementation + of this synchronization may be specific to the window toolkit + in use. It is impractical to require that all of the APIs that + might require synchronization receive a {@link ToolkitLock + ToolkitLock} as argument. For this reason the concept of a + default NativeWindowFactory is introduced. The toolkit lock + provided via {@link #getToolkitLock getToolkitLock} from this + default NativeWindowFactory will be used for synchronization + within the Java binding to OpenGL. By default, if the AWT is + available, the default toolkit will support the AWT. */ + public static void setDefaultFactory(NativeWindowFactory factory) { + defaultFactory = factory; } - if(winObj instanceof NativeWindow) { - NativeWindow nw = (NativeWindow) winObj; - if(nw.isTerminalObject()) { - return nw; // use the terminal NativeWindow object directly + + /** Gets the default NativeWindowFactory. Certain operations on + X11 platforms require synchronization, and the implementation + of this synchronization may be specific to the window toolkit + in use. It is impractical to require that all of the APIs that + might require synchronization receive a {@link ToolkitLock + ToolkitLock} as argument. For this reason the concept of a + default NativeWindowFactory is introduced. The toolkit lock + provided via {@link #getToolkitLock getToolkitLock} from this + default NativeWindowFactory will be used for synchronization + within the Java binding to OpenGL. By default, if the AWT is + available, the default toolkit will support the AWT. */ + public static NativeWindowFactory getDefaultFactory() { + return defaultFactory; + } + + /** Returns the appropriate NativeWindowFactory to handle window + objects of the given type. The windowClass might be {@link + NativeWindow NativeWindow}, in which case the client has + already assumed the responsibility of creating a compatible + NativeWindow implementation, or it might be that of a toolkit + class like {@link java.awt.Component Component}. */ + public static NativeWindowFactory getFactory(Class windowClass) throws IllegalArgumentException { + if (nativeWindowClass.isAssignableFrom(windowClass)) { + return (NativeWindowFactory) registeredFactories.get(nativeWindowClass); } - Object wrappedWindow = nw.getWrappedWindow(); - if(null==wrappedWindow) { - throw new NativeWindowException("Proxy NativeWindow holds no wrapped window: "+nw); + Class clazz = windowClass; + while (clazz != null) { + NativeWindowFactory factory = (NativeWindowFactory) registeredFactories.get(clazz); + if (factory != null) { + return factory; + } + clazz = clazz.getSuperclass(); } - winObj = wrappedWindow; + throw new IllegalArgumentException("No registered NativeWindowFactory for class " + windowClass.getName()); } - if (GLReflection.isAWTComponent(winObj)) { - initializeAWTFactory(); - if(awtFactory == null) { - throw new GLException("Could not determine an AWT-NativeWindow constructor"); - } - try { - return (NativeWindow) awtFactory.newInstance(new Object[] { winObj }); - } catch (Exception ie) { - ie.printStackTrace(); - } + /** Registers a NativeWindowFactory handling window objects of the + given class. This does not need to be called by end users, + only implementors of new NativeWindowFactory subclasses.. */ + protected static void registerFactory(Class windowClass, NativeWindowFactory factory) { + registeredFactories.put(windowClass, factory); } - throw new NativeWindowException("Target type is unsupported. Currently supported: \n"+ - "\tjavax.media.opengl.NativeWindow\n"+ - "\tjava.awt.Component\n"); - } -} + /** Converts the given window object into a {@link NativeWindow + NativeWindow} which can be operated upon by the {@link + GLDrawableFactory GLDrawableFactory}. The object may be a + component for a particular window toolkit, such as an AWT + Canvas. It may also be a NativeWindow object, in which no + conversion is necessary. The particular implementation of the + NativeWindowFactory is responsible for handling objects from a + particular window toolkit. The built-in NativeWindowFactory + handles NativeWindow instances as well as AWT Components. + + @throws IllegalArgumentException if the given window object + could not be handled by any of the registered + NativeWindowFactory instances + */ + public static NativeWindow getNativeWindow(Object winObj) throws IllegalArgumentException, NativeWindowException { + if (winObj == null) { + throw new IllegalArgumentException("Null window object"); + } + + return getFactory(winObj.getClass()).getNativeWindowImpl(winObj); + } + + /** + * <P> Selects a graphics configuration on the specified graphics + * device compatible with the supplied GLCapabilities. This method + * is intended to be used by applications which do not use the + * supplied GLCanvas class but instead wrap their own Canvas or + * other window toolkit-specific object with a GLDrawable. Some + * platforms (specifically X11) require the graphics configuration + * to be specified when the window toolkit object is created. This + * method may return null on platforms on which the OpenGL pixel + * format selection process is performed later. </P> + * + * <P> The concrete data type of the passed graphics device and + * returned graphics configuration must be specified in the + * documentation binding this particular API to the underlying + * window toolkit. The Reference Implementation accepts {@link + * AWTGraphicsDevice AWTGraphicsDevice} objects and returns {@link + * AWTGraphicsConfiguration AWTGraphicsConfiguration} objects. </P> + * + * @see java.awt.Canvas#Canvas(java.awt.GraphicsConfiguration) + * + * @throws IllegalArgumentException if the data type of the passed + * AbstractGraphicsDevice is not supported by this + * NativeWindowFactory. + * @throws GLException if any window system-specific errors caused + * the selection of the graphics configuration to fail. + */ + public abstract AbstractGraphicsConfiguration + chooseGraphicsConfiguration(GLCapabilities capabilities, + GLCapabilitiesChooser chooser, + AbstractGraphicsDevice device) + throws IllegalArgumentException, GLException; + + /** Performs the conversion from a toolkit's window object to a + NativeWindow. Implementors of concrete NativeWindowFactory + subclasses should override this method. */ + protected abstract NativeWindow getNativeWindowImpl(Object winObj) throws IllegalArgumentException; + + /** Returns the object which provides support for synchronizing + with the underlying window toolkit. On most platforms the + returned object does nothing; currently it only has effects on + X11 platforms. */ + public abstract ToolkitLock getToolkitLock(); +} diff --git a/src/classes/com/sun/opengl/impl/egl/awt/EGLAWTDrawableFactory.java b/src/classes/javax/media/opengl/ToolkitLock.java index 501de1d01..9574de77c 100644 --- a/src/classes/com/sun/opengl/impl/egl/awt/EGLAWTDrawableFactory.java +++ b/src/classes/javax/media/opengl/ToolkitLock.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * 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 @@ -28,28 +28,21 @@ * 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 { +package javax.media.opengl; - public void lockToolkit() { - super.lockToolkit(); - //JAWTUtil.lockToolkit(); - } +/** Provides an interface for locking and unlocking the underlying + window toolkit, where this is necessary in the OpenGL + implementation. This mechanism is generally only needed on X11 + platforms. Currently it is only used when the AWT is in use. + Implementations of this lock, if they are not no-ops, must support + reentrant locking and unlocking. */ - public void unlockToolkit() { - //JAWTUtil.unlockToolkit(); - super.unlockToolkit(); - } +public interface ToolkitLock { + /** Locks the toolkit. */ + public void lock(); + /** Unlocks the toolkit. */ + public void unlock(); } diff --git a/src/classes/javax/media/opengl/X11GraphicsConfiguration.java b/src/classes/javax/media/opengl/X11GraphicsConfiguration.java new file mode 100644 index 000000000..95127f2c1 --- /dev/null +++ b/src/classes/javax/media/opengl/X11GraphicsConfiguration.java @@ -0,0 +1,53 @@ +/* + * 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 javax.media.opengl; + +/** Encapsulates a graphics configuration, or OpenGL pixel format, on + X11 platforms. Objects of this type are returned from {@link + NativeWindowFactory#chooseGraphicsConfiguration + NativeWindowFactory.chooseGraphicsConfiguration()} on X11 + platforms when toolkits other than the AWT are being used. */ + +public class X11GraphicsConfiguration implements AbstractGraphicsConfiguration { + private long visualID; + + /** Constructs a new X11GraphicsConfiguration corresponding to the given visual ID. */ + public X11GraphicsConfiguration(long visualID) { + this.visualID = visualID; + } + + /** Returns the visual ID that this graphics configuration object represents. */ + public long getVisualID() { + return visualID; + } +} diff --git a/src/classes/javax/media/opengl/X11GraphicsDevice.java b/src/classes/javax/media/opengl/X11GraphicsDevice.java new file mode 100644 index 000000000..1a8900f31 --- /dev/null +++ b/src/classes/javax/media/opengl/X11GraphicsDevice.java @@ -0,0 +1,53 @@ +/* + * 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 javax.media.opengl; + +/** Encapsulates a graphics device, or screen, on X11 + platforms. Objects of this type are passed to {@link + NativeWindowFactory#chooseGraphicsConfiguration + NativeWindowFactory.chooseGraphicsConfiguration()} on X11 + platforms when toolkits other than the AWT are being used. */ + +public class X11GraphicsDevice implements AbstractGraphicsDevice { + private int screen; + + /** Constructs a new X11GraphicsDevice corresponding to the given screen. */ + public X11GraphicsDevice(int screen) { + this.screen = screen; + } + + /** Returns the screen that this graphics device object represents. */ + public int getScreen() { + return screen; + } +} diff --git a/src/classes/javax/media/opengl/awt/GLCanvas.java b/src/classes/javax/media/opengl/awt/GLCanvas.java index 8d4a1df86..9391b566d 100644 --- a/src/classes/javax/media/opengl/awt/GLCanvas.java +++ b/src/classes/javax/media/opengl/awt/GLCanvas.java @@ -149,8 +149,8 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { this.glCaps = capabilities; } if (!Beans.isDesignTime()) { - drawable = GLDrawableFactory.getFactory(this.getClass()).createGLDrawable(NativeWindowFactory.getNativeWindow(this), - capabilities, chooser); + drawable = GLDrawableFactory.getFactory().createGLDrawable(NativeWindowFactory.getFactory(getClass()).getNativeWindow(this), + capabilities, chooser); context = (GLContextImpl) drawable.createContext(shareWith); context.setSynchronized(true); } @@ -553,9 +553,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable { } AWTGraphicsConfiguration config = (AWTGraphicsConfiguration) - GLDrawableFactory.getFactory(Component.class).chooseGraphicsConfiguration(capabilities, - chooser, - new AWTGraphicsDevice(device)); + NativeWindowFactory.getFactory(Component.class).chooseGraphicsConfiguration(capabilities, + chooser, + new AWTGraphicsDevice(device)); if (config == null) { return null; } diff --git a/src/classes/javax/media/opengl/awt/GLJPanel.java b/src/classes/javax/media/opengl/awt/GLJPanel.java index 48a2c7cd9..7c38cefe7 100644 --- a/src/classes/javax/media/opengl/awt/GLJPanel.java +++ b/src/classes/javax/media/opengl/awt/GLJPanel.java @@ -145,7 +145,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable { getDefaultConfiguration()); } GLProfile.setProfile(GLProfile.GL2); - factory = GLDrawableFactoryImpl.getFactoryImpl(Component.class); + factory = GLDrawableFactoryImpl.getFactoryImpl(); } /** Creates a new GLJPanel component with a default set of OpenGL |