diff options
author | JOGAMP DEV TEAM <[email protected]> | 2010-04-22 21:12:36 -0400 |
---|---|---|
committer | JOGAMP DEV TEAM <[email protected]> | 2010-04-22 21:12:36 -0400 |
commit | 1d889ddc4728d1534e310b44fad74a2932d22d39 (patch) | |
tree | 4ad0c3eeb3ef728522ac9459eb12c667301a0c32 /src/jogl/classes/com/jogamp/opengl/impl/x11/glx | |
parent | 8790075f074013aa3c71b96993838cf1117275f1 (diff) | |
parent | a588326d206ff32e5ff5db97560851cb9b826022 (diff) |
Merge branch 'master' of github.com:sgothel/jogl
Diffstat (limited to 'src/jogl/classes/com/jogamp/opengl/impl/x11/glx')
16 files changed, 3145 insertions, 0 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/GLXUtil.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/GLXUtil.java new file mode 100644 index 000000000..ec0eaf94f --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/GLXUtil.java @@ -0,0 +1,106 @@ +/* + * 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.jogamp.opengl.impl.x11.glx; + +import javax.media.opengl.*; + +import com.jogamp.nativewindow.impl.x11.*; + +public class GLXUtil { + public static boolean isMultisampleAvailable(long display) { + X11Lib.XLockDisplay(display); + try { + String exts = GLX.glXGetClientString(display, GLX.GLX_EXTENSIONS); + if (exts != null) { + return (exts.indexOf("GLX_ARB_multisample") >= 0); + } + return false; + } finally { + X11Lib.XUnlockDisplay(display); + } + } + + /** Workaround for apparent issue with ATI's proprietary drivers + where direct contexts still send GLX tokens for GL calls */ + public static String getVendorName(long display) { + X11Lib.XLockDisplay(display); + try { + return GLX.glXGetClientString(display, GLX.GLX_VENDOR); + } finally { + X11Lib.XUnlockDisplay(display); + } + } + + public static boolean isVendorNVIDIA(String vendor) { + return vendor != null && vendor.startsWith("NVIDIA") ; + } + + public static boolean isVendorATI(String vendor) { + return vendor != null && vendor.startsWith("ATI") ; + } + + public static boolean isVendorATI(long display) { + return isVendorATI(getVendorName(display)); + } + + public static boolean isVendorNVIDIA(long display) { + return isVendorNVIDIA(getVendorName(display)); + } + + public static void getGLXVersion(long display, int major[], int minor[]) { + if(0 == display) { + throw new GLException("null display handle"); + } + if(major.length<1||minor.length<1) { + throw new GLException("passed int arrays size is not >= 1"); + } + + if (!GLX.glXQueryVersion(display, major, 0, minor, 0)) { + throw new GLException("glXQueryVersion failed"); + } + + // Work around bugs in ATI's Linux drivers where they report they + // only implement GLX version 1.2 on the server side + if (major[0] == 1 && minor[0] == 2) { + String str = GLX.glXGetClientString(display, GLX.GLX_VERSION); + try { + // e.g. "1.3" + major[0] = Integer.valueOf(str.substring(0, 1)).intValue(); + minor[0] = Integer.valueOf(str.substring(2, 3)).intValue(); + } catch (Exception e) { + major[0] = 1; + minor[0] = 2; + } + } + } +} diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java new file mode 100644 index 000000000..1f148bead --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2010 Sven Gothel. 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 Sven Gothel 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 + * SVEN GOTHEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +package com.jogamp.opengl.impl.x11.glx; + +import javax.media.opengl.*; +import com.jogamp.opengl.impl.*; + +import javax.media.nativewindow.*; +import javax.media.nativewindow.x11.*; +import com.jogamp.nativewindow.impl.*; +import com.jogamp.nativewindow.impl.x11.*; + +public class X11DummyGLXDrawable extends X11OnscreenGLXDrawable { + + private long dummyWindow = 0; + + /** + * Due to the ATI Bug https://bugzilla.mozilla.org/show_bug.cgi?id=486277, + * we cannot switch the Display as we please, + * hence we reuse the target's screen configuration. + */ + public X11DummyGLXDrawable(X11GraphicsScreen screen, GLDrawableFactory factory, GLProfile glp) { + super(factory, + new NullWindow(X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic( + new GLCapabilities(glp), null, screen))); + this.realized = true; + + NullWindow nw = (NullWindow) getNativeWindow(); + X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)nw.getGraphicsConfiguration().getNativeGraphicsConfiguration(); + GLCapabilities caps = (GLCapabilities) config.getChosenCapabilities(); + + X11GraphicsDevice device = (X11GraphicsDevice) screen.getDevice(); + long dpy = device.getHandle(); + int scrn = screen.getIndex(); + long visualID = config.getVisualID(); + + X11Lib.XLockDisplay(dpy); + try{ + dummyWindow = X11Lib.CreateDummyWindow(dpy, scrn, visualID); + } finally { + X11Lib.XUnlockDisplay(dpy); + } + nw.setSurfaceHandle( dummyWindow ); + } + + public void setSize(int width, int height) { + } + + public int getWidth() { + return 1; + } + + public int getHeight() { + return 1; + } + + public void destroy() { + if(0!=dummyWindow) { + X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + long dpy = config.getScreen().getDevice().getHandle(); + X11Lib.DestroyDummyWindow(dpy, dummyWindow); + } + } +} diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXContext.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXContext.java new file mode 100755 index 000000000..139c0deed --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXContext.java @@ -0,0 +1,154 @@ +/* + * 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. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package com.jogamp.opengl.impl.x11.glx; + +import javax.media.nativewindow.*; +import javax.media.nativewindow.x11.*; +import javax.media.opengl.*; +import com.jogamp.opengl.impl.*; +import com.jogamp.nativewindow.impl.NullWindow; +import com.jogamp.nativewindow.impl.x11.*; + +public class X11ExternalGLXContext extends X11GLXContext { + private boolean firstMakeCurrent = true; + private boolean created = true; + private GLContext lastContext; + + private X11ExternalGLXContext(Drawable drawable, long context) { + super(drawable, null); + this.context = context; + GLContextShareSet.contextCreated(this); + setGLFunctionAvailability(false, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); + getGLStateTracker().setEnabled(false); // external context usage can't track state in Java + } + + protected static X11ExternalGLXContext create(GLDrawableFactory factory, GLProfile glp) { + ((GLDrawableFactoryImpl)factory).lockToolkit(); + try { + long context = GLX.glXGetCurrentContext(); + if (context == 0) { + throw new GLException("Error: current context null"); + } + long display = GLX.glXGetCurrentDisplay(); + if (display == 0) { + throw new GLException("Error: current display null"); + } + long drawable = GLX.glXGetCurrentDrawable(); + if (drawable == 0) { + throw new GLException("Error: attempted to make an external GLDrawable without a drawable/context current"); + } + int[] val = new int[1]; + GLX.glXQueryContext(display, context, GLX.GLX_SCREEN, val, 0); + X11GraphicsScreen x11Screen = (X11GraphicsScreen) X11GraphicsScreen.createScreenDevice(display, val[0]); + + GLX.glXQueryContext(display, context, GLX.GLX_FBCONFIG_ID, val, 0); + X11GLXGraphicsConfiguration cfg = X11GLXGraphicsConfiguration.create(glp, x11Screen, val[0]); + + NullWindow nw = new NullWindow(cfg); + nw.setSurfaceHandle(drawable); + return new X11ExternalGLXContext(new Drawable(factory, nw), context); + } finally { + ((GLDrawableFactoryImpl)factory).unlockToolkit(); + } + } + + protected void create() { + } + + public int makeCurrent() throws GLException { + // Save last context if necessary to allow external GLContexts to + // talk to other GLContexts created by this library + GLContext cur = getCurrent(); + if (cur != null && cur != this) { + lastContext = cur; + setCurrent(null); + } + return super.makeCurrent(); + } + + public void release() throws GLException { + super.release(); + setCurrent(lastContext); + lastContext = null; + } + + protected int makeCurrentImpl() throws GLException { + if (firstMakeCurrent) { + firstMakeCurrent = false; + return CONTEXT_CURRENT_NEW; + } + return CONTEXT_CURRENT; + } + + protected void releaseImpl() throws GLException { + } + + protected void destroyImpl() throws GLException { + created = false; + GLContextShareSet.contextDestroyed(this); + } + + public boolean isCreated() { + return created; + } + + // Need to provide the display connection to extension querying APIs + static class Drawable extends X11GLXDrawable { + Drawable(GLDrawableFactory factory, NativeWindow comp) { + super(factory, comp, true); + } + + public GLContext createContext(GLContext shareWith) { + throw new GLException("Should not call this"); + } + + public int getWidth() { + throw new GLException("Should not call this"); + } + + public int getHeight() { + throw new GLException("Should not call this"); + } + + public void setSize(int width, int height) { + throw new GLException("Should not call this"); + } + } +} diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXDrawable.java new file mode 100755 index 000000000..f10bd38c6 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11ExternalGLXDrawable.java @@ -0,0 +1,132 @@ +/* + * 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. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package com.jogamp.opengl.impl.x11.glx; + +import javax.media.nativewindow.*; +import javax.media.nativewindow.x11.*; +import javax.media.opengl.*; +import com.jogamp.opengl.impl.*; +import com.jogamp.nativewindow.impl.NullWindow; + + +public class X11ExternalGLXDrawable extends X11GLXDrawable { + private int fbConfigID; + private int renderType; + + private X11ExternalGLXDrawable(GLDrawableFactory factory, NativeWindow component, int renderType) { + super(factory, component, true); + + this.renderType = renderType; + + // Need GLXFBConfig ID in order to properly create new contexts + // on this drawable + X11GLXGraphicsConfiguration cfg = (X11GLXGraphicsConfiguration) component.getGraphicsConfiguration(); + fbConfigID = cfg.getFBConfigID(); + } + + protected static X11ExternalGLXDrawable create(GLDrawableFactory factory, GLProfile glp) { + ((GLDrawableFactoryImpl)factory).lockToolkit(); + try { + long context = GLX.glXGetCurrentContext(); + if (context == 0) { + throw new GLException("Error: current context null"); + } + long display = GLX.glXGetCurrentDisplay(); + if (display == 0) { + throw new GLException("Error: current display null"); + } + long drawable = GLX.glXGetCurrentDrawable(); + if (drawable == 0) { + throw new GLException("Error: attempted to make an external GLDrawable without a drawable current"); + } + int[] val = new int[1]; + GLX.glXQueryContext(display, context, GLX.GLX_SCREEN, val, 0); + X11GraphicsScreen x11Screen = (X11GraphicsScreen) X11GraphicsScreen.createScreenDevice(display, val[0]); + + GLX.glXQueryContext(display, context, GLX.GLX_FBCONFIG_ID, val, 0); + X11GLXGraphicsConfiguration cfg = X11GLXGraphicsConfiguration.create(glp, x11Screen, val[0]); + + int w, h; + GLX.glXQueryDrawable(display, drawable, GLX.GLX_WIDTH, val, 0); + w=val[0]; + GLX.glXQueryDrawable(display, drawable, GLX.GLX_HEIGHT, val, 0); + h=val[0]; + + GLX.glXQueryContext(display, context, GLX.GLX_RENDER_TYPE, val, 0); + if ((val[0] & GLX.GLX_RGBA_TYPE) == 0) { + if (DEBUG) { + System.err.println("X11ExternalGLXDrawable: WARNING: forcing GLX_RGBA_TYPE for newly created contexts (current 0x"+Integer.toHexString(val[0])+")"); + } + } + NullWindow nw = new NullWindow(cfg); + nw.setSurfaceHandle(drawable); + nw.setSize(w, h); + return new X11ExternalGLXDrawable(factory, nw, GLX.GLX_RGBA_TYPE); + } finally { + ((GLDrawableFactoryImpl)factory).unlockToolkit(); + } + } + + public GLContext createContext(GLContext shareWith) { + return new Context(this, shareWith); + } + + public void setSize(int newWidth, int newHeight) { + throw new GLException("Should not call this"); + } + + public int getWidth() { + return getNativeWindow().getWidth(); + } + + public int getHeight() { + return getNativeWindow().getHeight(); + } + + class Context extends X11GLXContext { + Context(X11GLXDrawable drawable, GLContext shareWith) { + super(drawable, shareWith); + } + + protected void create() { + createContext(true); + } + } +} diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java new file mode 100644 index 000000000..dce25978c --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java @@ -0,0 +1,582 @@ +/* + * 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. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package com.jogamp.opengl.impl.x11.glx; + +import java.nio.*; +import java.util.*; +import javax.media.opengl.*; +import javax.media.nativewindow.*; +import javax.media.nativewindow.x11.*; +import com.jogamp.opengl.impl.*; +import com.jogamp.opengl.impl.x11.glx.*; +import com.jogamp.nativewindow.impl.x11.*; +import com.jogamp.gluegen.runtime.ProcAddressTable; + +public abstract class X11GLXContext extends GLContextImpl { + protected long context; + private boolean glXQueryExtensionsStringInitialized; + private boolean glXQueryExtensionsStringAvailable; + private static final Map/*<String, String>*/ functionNameMap; + private static final Map/*<String, String>*/ extensionNameMap; + private GLXExt glXExt; + // Table that holds the addresses of the native C-language entry points for + // GLX extension functions. + private GLXExtProcAddressTable glXExtProcAddressTable; + + static { + functionNameMap = new HashMap(); + functionNameMap.put("glAllocateMemoryNV", "glXAllocateMemoryNV"); + functionNameMap.put("glFreeMemoryNV", "glXFreeMemoryNV"); + + extensionNameMap = new HashMap(); + extensionNameMap.put("GL_ARB_pbuffer", "GLX_SGIX_pbuffer"); + extensionNameMap.put("GL_ARB_pixel_format", "GLX_SGIX_pbuffer"); // good enough + } + + public X11GLXContext(GLDrawableImpl drawable, GLDrawableImpl drawableRead, + GLContext shareWith) { + super(drawable, drawableRead, shareWith); + } + + public X11GLXContext(GLDrawableImpl drawable, + GLContext shareWith) { + this(drawable, null, shareWith); + } + + public final ProcAddressTable getPlatformExtProcAddressTable() { + return getGLXExtProcAddressTable(); + } + + public final GLXExtProcAddressTable getGLXExtProcAddressTable() { + return glXExtProcAddressTable; + } + + public Object getPlatformGLExtensions() { + return getGLXExt(); + } + + public GLXExt getGLXExt() { + if (glXExt == null) { + glXExt = new GLXExtImpl(this); + } + return glXExt; + } + + protected Map/*<String, String>*/ getFunctionNameMap() { return functionNameMap; } + + protected Map/*<String, String>*/ getExtensionNameMap() { return extensionNameMap; } + + protected boolean glXMakeContextCurrent(long dpy, long writeDrawable, long readDrawable, long ctx) { + boolean res = false; + + try { + res = GLX.glXMakeContextCurrent(dpy, writeDrawable, readDrawable, ctx); + } catch (RuntimeException re) { + if(DEBUG) { + System.err.println("X11GLXContext.glXMakeContextCurrent failed: "+re+", with "+ + "dpy "+toHexString(dpy)+ + ", write "+toHexString(writeDrawable)+ + ", read "+toHexString(readDrawable)+ + ", ctx "+toHexString(ctx)); + re.printStackTrace(); + } + } + return res; + } + + protected void destroyContextARBImpl(long _context) { + X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + long display = config.getScreen().getDevice().getHandle(); + + glXMakeContextCurrent(display, 0, 0, 0); + GLX.glXDestroyContext(display, _context); + } + + protected long createContextARBImpl(long share, boolean direct, int ctp, int major, int minor) { + X11GLXDrawableFactory factory = (X11GLXDrawableFactory)drawable.getFactoryImpl(); + X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + long display = config.getScreen().getDevice().getHandle(); + + GLXExt glXExt; + if(null==factory.getSharedContext()) { + glXExt = getGLXExt(); + } else { + glXExt = ((X11GLXContext)factory.getSharedContext()).getGLXExt(); + } + + boolean ctBwdCompat = 0 != ( CTX_PROFILE_COMPAT & ctp ) ; + boolean ctFwdCompat = 0 != ( CTX_OPTION_FORWARD & ctp ) ; + boolean ctDebug = 0 != ( CTX_OPTION_DEBUG & ctp ) ; + + long _context=0; + + int attribs[] = { + /* 0 */ GLX.GLX_CONTEXT_MAJOR_VERSION_ARB, major, + /* 2 */ GLX.GLX_CONTEXT_MINOR_VERSION_ARB, minor, + /* 4 */ GLX.GLX_RENDER_TYPE, GLX.GLX_RGBA_TYPE, // default + /* 6 */ GLX.GLX_CONTEXT_FLAGS_ARB, 0, + /* 8 */ 0, 0, + /* 10 */ 0 + }; + + if ( major > 3 || major == 3 && minor >= 2 ) { + // FIXME: Verify with a None drawable binding (default framebuffer) + attribs[8+0] = GLX.GLX_CONTEXT_PROFILE_MASK_ARB; + if( ctBwdCompat ) { + attribs[8+1] = GLX.GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; + } else { + attribs[8+1] = GLX.GLX_CONTEXT_CORE_PROFILE_BIT_ARB; + } + } + + if ( major >= 3 ) { + if( !ctBwdCompat && ctFwdCompat ) { + attribs[6+1] |= GLX.GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; + } + if( ctDebug) { + attribs[6+1] |= GLX.GLX_CONTEXT_DEBUG_BIT_ARB; + } + } + + try { + _context = glXExt.glXCreateContextAttribsARB(display, config.getFBConfig(), share, direct, attribs, 0); + } catch (RuntimeException re) { + if(DEBUG) { + System.err.println("X11GLXContext.createContextARB glXCreateContextAttribsARB failed: "+re+", with "+getGLVersion(null, major, minor, ctp, "@creation")); + re.printStackTrace(); + } + } + if(0==_context) { + if(DEBUG) { + System.err.println("X11GLXContext.createContextARB couldn't create "+getGLVersion(null, major, minor, ctp, "@creation")); + } + } else { + if (!glXMakeContextCurrent(display, + drawable.getNativeWindow().getSurfaceHandle(), + drawableRead.getNativeWindow().getSurfaceHandle(), + _context)) { + if(DEBUG) { + System.err.println("X11GLXContext.createContextARB couldn't make current "+getGLVersion(null, major, minor, ctp, "@creation")); + } + glXMakeContextCurrent(display, 0, 0, 0); + GLX.glXDestroyContext(display, _context); + _context = 0; + } + } + return _context; + } + + /** + * Creates and initializes an appropriate OpenGL context. Should only be + * called by {@link #create()}. + * Note: The direct parameter may be overwritten by the direct state of a shared context. + */ + protected void createContext(boolean direct) { + if(0!=context) { + throw new GLException("context is not null: "+context); + } + X11GLXDrawableFactory factory = (X11GLXDrawableFactory)drawable.getFactoryImpl(); + X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + long display = config.getScreen().getDevice().getHandle(); + + X11GLXContext other = (X11GLXContext) GLContextShareSet.getShareContext(this); + long share = 0; + if (other != null) { + share = other.getContext(); + if (share == 0) { + throw new GLException("GLContextShareSet returned an invalid OpenGL context"); + } + direct = GLX.glXIsDirect(display, share); + } + + GLCapabilities glCaps = (GLCapabilities) config.getChosenCapabilities(); + GLProfile glp = glCaps.getGLProfile(); + isVendorATI = factory.isVendorATI(); + + if(config.getFBConfigID()<0) { + // not able to use FBConfig + if(glp.isGL3()) { + throw new GLException("Unable to create OpenGL >= 3.1 context"); + } + context = GLX.glXCreateContext(display, config.getXVisualInfo(), share, direct); + if (context == 0) { + throw new GLException("Unable to create context(0)"); + } + if (!glXMakeContextCurrent(display, + drawable.getNativeWindow().getSurfaceHandle(), + drawableRead.getNativeWindow().getSurfaceHandle(), + context)) { + throw new GLException("Error making temp context(0) current: display "+toHexString(display)+", context "+toHexString(context)+", drawable "+drawable); + } + setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); // use GL_VERSION + return; + } + + int minor[] = new int[1]; + int major[] = new int[1]; + int ctp[] = new int[1]; + boolean createContextARBTried = false; + + // utilize the shared context's GLXExt in case it was using the ARB method and it already exists + if(null!=factory.getSharedContext() && factory.getSharedContext().isCreatedWithARBMethod()) { + if(DEBUG) { + System.err.println("X11GLXContext.createContext using shared Context: "+factory.getSharedContext()); + } + context = createContextARB(share, direct, major, minor, ctp); + createContextARBTried = true; + } + + long temp_context = 0; + if(0==context) { + // To use GLX_ARB_create_context, we have to make a temp context current, + // so we are able to use GetProcAddress + temp_context = GLX.glXCreateNewContext(display, config.getFBConfig(), GLX.GLX_RGBA_TYPE, share, direct); + if (temp_context == 0) { + throw new GLException("Unable to create temp OpenGL context(1)"); + } + if (!glXMakeContextCurrent(display, + drawable.getNativeWindow().getSurfaceHandle(), + drawableRead.getNativeWindow().getSurfaceHandle(), + temp_context)) { + throw new GLException("Error making temp context(1) current: display "+toHexString(display)+", context "+toHexString(context)+", drawable "+drawable); + } + setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); // use GL_VERSION + + if( createContextARBTried || + !isFunctionAvailable("glXCreateContextAttribsARB") || + !isExtensionAvailable("GLX_ARB_create_context") ) { + if(glp.isGL3()) { + glXMakeContextCurrent(display, 0, 0, 0); + GLX.glXDestroyContext(display, temp_context); + throw new GLException("Unable to create OpenGL >= 3.1 context (failed GLX_ARB_create_context), GLProfile "+glp+", Drawable "+drawable); + } + + // continue with temp context for GL < 3.0 + context = temp_context; + return; + } + context = createContextARB(share, direct, major, minor, ctp); + createContextARBTried=true; + } + + if(0!=context) { + if(0!=temp_context) { + glXMakeContextCurrent(display, 0, 0, 0); + GLX.glXDestroyContext(display, temp_context); + if (!glXMakeContextCurrent(display, + drawable.getNativeWindow().getSurfaceHandle(), + drawableRead.getNativeWindow().getSurfaceHandle(), + context)) { + throw new GLException("Cannot make previous verified context current"); + } + } + } else { + if(glp.isGL3()) { + glXMakeContextCurrent(display, 0, 0, 0); + GLX.glXDestroyContext(display, temp_context); + throw new GLException("X11GLXContext.createContext failed, but context > GL2 requested "+getGLVersion(null, major[0], minor[0], ctp[0], "@creation")+", "); + } + if(DEBUG) { + System.err.println("X11GLXContext.createContext failed, fall back to !ARB context "+getGLVersion(null, major[0], minor[0], ctp[0], "@creation")); + } + + // continue with temp context for GL <= 3.0 + context = temp_context; + if (!glXMakeContextCurrent(display, + drawable.getNativeWindow().getSurfaceHandle(), + drawableRead.getNativeWindow().getSurfaceHandle(), + context)) { + glXMakeContextCurrent(display, 0, 0, 0); + GLX.glXDestroyContext(display, temp_context); + throw new GLException("Error making context(1) current: display "+toHexString(display)+", context "+toHexString(context)+", drawable "+drawable); + } + } + } + + // Note: Usually the surface shall be locked within [makeCurrent .. swap .. release] + protected int makeCurrentImpl() throws GLException { + int lockRes = drawable.lockSurface(); + boolean exceptionOccurred = false; + try { + if (lockRes == NativeWindow.LOCK_SURFACE_NOT_READY) { + return CONTEXT_NOT_CURRENT; + } + return makeCurrentImplAfterLock(); + } catch (RuntimeException e) { + exceptionOccurred = true; + throw e; + } finally { + if (exceptionOccurred || + (isOptimizable() && lockRes != NativeWindow.LOCK_SURFACE_NOT_READY) && drawable.isSurfaceLocked()) { + drawable.unlockSurface(); + } + } + } + + // Note: Usually the surface shall be locked within [makeCurrent .. swap .. release] + protected void releaseImpl() throws GLException { + try { + releaseImplAfterLock(); + } finally { + if (!isOptimizable() && drawable.isSurfaceLocked()) { + drawable.unlockSurface(); + } + } + } + + protected int makeCurrentImplAfterLock() throws GLException { + long dpy = drawable.getNativeWindow().getDisplayHandle(); + + getDrawableImpl().getFactoryImpl().lockToolkit(); + try { + if (drawable.getNativeWindow().getSurfaceHandle() == 0) { + throw new GLException("drawable not properly initialized: "+drawable); + } + boolean created = false; + if (context == 0) { + create(); + created = true; + GLContextShareSet.contextCreated(this); + if (DEBUG) { + System.err.println(getThreadName() + ": !!! Created GL context for " + getClass().getName()); + } + } + + if (GLX.glXGetCurrentContext() != context) { + + if (!glXMakeContextCurrent(dpy, + drawable.getNativeWindow().getSurfaceHandle(), + drawableRead.getNativeWindow().getSurfaceHandle(), + context)) { + throw new GLException("Error making context current: "+this); + } + if (DEBUG && (VERBOSE || created)) { + System.err.println(getThreadName() + ": glXMakeCurrent(display " + + toHexString(dpy)+ + ", drawable " + toHexString(drawable.getNativeWindow().getSurfaceHandle()) + + ", drawableRead " + toHexString(drawableRead.getNativeWindow().getSurfaceHandle()) + + ", context " + toHexString(context) + ") succeeded"); + } + } + + if (created) { + setGLFunctionAvailability(false, -1, -1, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); + return CONTEXT_CURRENT_NEW; + } + return CONTEXT_CURRENT; + } finally { + getDrawableImpl().getFactoryImpl().unlockToolkit(); + } + } + + protected void releaseImplAfterLock() throws GLException { + getDrawableImpl().getFactoryImpl().lockToolkit(); + try { + if (!glXMakeContextCurrent(drawable.getNativeWindow().getDisplayHandle(), 0, 0, 0)) { + throw new GLException("Error freeing OpenGL context"); + } + } finally { + getDrawableImpl().getFactoryImpl().unlockToolkit(); + } + } + + protected void destroyImpl() throws GLException { + getDrawableImpl().getFactoryImpl().lockToolkit(); + try { + if (context != 0) { + if (DEBUG) { + System.err.println("glXDestroyContext(" + + toHexString(drawable.getNativeWindow().getDisplayHandle()) + + ", " + + toHexString(context) + ")"); + } + GLX.glXDestroyContext(drawable.getNativeWindow().getDisplayHandle(), context); + if (DEBUG) { + System.err.println("!!! Destroyed OpenGL context " + context); + } + context = 0; + GLContextShareSet.contextDestroyed(this); + } + } finally { + getDrawableImpl().getFactoryImpl().unlockToolkit(); + } + } + + public boolean isCreated() { + return (context != 0); + } + + public void copy(GLContext source, int mask) throws GLException { + long dst = getContext(); + long src = ((X11GLXContext) source).getContext(); + if (src == 0) { + throw new GLException("Source OpenGL context has not been created"); + } + if (dst == 0) { + throw new GLException("Destination OpenGL context has not been created"); + } + if (drawable.getNativeWindow().getDisplayHandle() == 0) { + throw new GLException("Connection to X display not yet set up"); + } + getDrawableImpl().getFactoryImpl().lockToolkit(); + try { + GLX.glXCopyContext(drawable.getNativeWindow().getDisplayHandle(), src, dst, mask); + // Should check for X errors and raise GLException + } finally { + getDrawableImpl().getFactoryImpl().unlockToolkit(); + } + } + + protected void updateGLProcAddressTable(int major, int minor, int ctp) { + if (DEBUG) { + System.err.println(getThreadName() + ": !!! Initializing GLX extension address table"); + } + glXQueryExtensionsStringInitialized = false; + glXQueryExtensionsStringAvailable = false; + + if (glXExtProcAddressTable == null) { + // FIXME: cache ProcAddressTables by capability bits so we can + // share them among contexts with the same capabilities + glXExtProcAddressTable = new GLXExtProcAddressTable(); + } + resetProcAddressTable(getGLXExtProcAddressTable()); + super.updateGLProcAddressTable(major, minor, ctp); + } + + public synchronized String getPlatformExtensionsString() { + if (!glXQueryExtensionsStringInitialized) { + glXQueryExtensionsStringAvailable = + getDrawableImpl().getDynamicLookupHelper().dynamicLookupFunction("glXQueryExtensionsString") != 0; + glXQueryExtensionsStringInitialized = true; + } + if (glXQueryExtensionsStringAvailable) { + GLDrawableFactoryImpl factory = getDrawableImpl().getFactoryImpl(); + factory.lockToolkit(); + try { + String ret = GLX.glXQueryExtensionsString(drawable.getNativeWindow().getDisplayHandle(), + drawable.getNativeWindow().getScreenIndex()); + if (DEBUG) { + System.err.println("!!! GLX extensions: " + ret); + } + return ret; + } finally { + factory.unlockToolkit(); + } + } else { + return ""; + } + } + + public boolean isExtensionAvailable(String glExtensionName) { + if (glExtensionName.equals("GL_ARB_pbuffer") || + glExtensionName.equals("GL_ARB_pixel_format")) { + return getGLDrawable().getFactory().canCreateGLPbuffer( + drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice() ); + } + return super.isExtensionAvailable(glExtensionName); + } + + + private int hasSwapIntervalSGI = 0; + + protected void setSwapIntervalImpl(int interval) { + X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + GLCapabilities glCaps = (GLCapabilities) config.getChosenCapabilities(); + if(!glCaps.isOnscreen()) return; + + getDrawableImpl().getFactoryImpl().lockToolkit(); + try { + GLXExt glXExt = getGLXExt(); + if(0==hasSwapIntervalSGI) { + try { + hasSwapIntervalSGI = glXExt.isExtensionAvailable("GLX_SGI_swap_control")?1:-1; + } catch (Throwable t) { hasSwapIntervalSGI=1; } + } + if (hasSwapIntervalSGI>0) { + try { + if( 0 == glXExt.glXSwapIntervalSGI(interval) ) { + currentSwapInterval = interval; + } + } catch (Throwable t) { hasSwapIntervalSGI=-1; } + } + } finally { + getDrawableImpl().getFactoryImpl().unlockToolkit(); + } + } + + public ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3) { + return getGLXExt().glXAllocateMemoryNV(arg0, arg1, arg2, arg3); + } + + public int getOffscreenContextPixelDataType() { + throw new GLException("Should not call this"); + } + + public int getOffscreenContextReadBuffer() { + throw new GLException("Should not call this"); + } + + public boolean offscreenImageNeedsVerticalFlip() { + throw new GLException("Should not call this"); + } + + public void bindPbufferToTexture() { + throw new GLException("Should not call this"); + } + + public void releasePbufferFromTexture() { + throw new GLException("Should not call this"); + } + + public boolean isOptimizable() { + return (super.isOptimizable() && !isVendorATI); + } + + //---------------------------------------------------------------------- + // Internals only below this point + // + + public long getContext() { + return context; + } + + private boolean isVendorATI = false; + +} diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawable.java new file mode 100644 index 000000000..95dfc0a1c --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawable.java @@ -0,0 +1,97 @@ +/* + * 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. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package com.jogamp.opengl.impl.x11.glx; + +import javax.media.nativewindow.*; +import javax.media.opengl.*; +import com.jogamp.opengl.impl.*; +import com.jogamp.common.os.DynamicLookupHelper; + +public abstract class X11GLXDrawable extends GLDrawableImpl { + protected X11GLXDrawable(GLDrawableFactory factory, NativeWindow comp, boolean realized) { + super(factory, comp, realized); + } + + public DynamicLookupHelper getDynamicLookupHelper() { + return (X11GLXDrawableFactory) getFactoryImpl() ; + } + + protected void setRealizedImpl() { + if(!realized) { + return; // nothing to do + } + + if(NativeWindow.LOCK_SURFACE_NOT_READY == lockSurface()) { + throw new GLException("X11GLXDrawable.setRealized(true): lockSurface - surface not ready"); + } + try { + X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + config.updateGraphicsConfiguration(); + + if (DEBUG) { + System.err.println("!!! X11GLXDrawable.setRealized(true): "+config); + } + } finally { + unlockSurface(); + } + } + + protected void swapBuffersImpl() { + boolean didLock = false; + if (!isSurfaceLocked()) { + // Usually the surface shall be locked within [makeCurrent .. swap .. release] + if (lockSurface() == NativeWindow.LOCK_SURFACE_NOT_READY) { + return; + } + didLock = true; + } + try { + GLX.glXSwapBuffers(component.getDisplayHandle(), component.getSurfaceHandle()); + } finally { + if (didLock) { + unlockSurface(); + } + } + } + + //--------------------------------------------------------------------------- + // Internals only below this point + // +} diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java new file mode 100644 index 000000000..d8e5f7646 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java @@ -0,0 +1,398 @@ +/* + * 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.jogamp.opengl.impl.x11.glx; + +import com.jogamp.common.os.DynamicLookupHelper; +import java.nio.*; +import javax.media.nativewindow.*; +import javax.media.nativewindow.x11.*; +import javax.media.opengl.*; +import com.jogamp.gluegen.runtime.opengl.*; +import com.jogamp.opengl.impl.*; +import com.jogamp.common.JogampRuntimeException; +import com.jogamp.common.util.*; +import com.jogamp.nativewindow.impl.NullWindow; +import com.jogamp.nativewindow.impl.x11.*; + +public class X11GLXDrawableFactory extends GLDrawableFactoryImpl implements DynamicLookupHelper { + + public X11GLXDrawableFactory() { + super(); + // Must initialize GLX support eagerly in case a pbuffer is the + // first thing instantiated + GLProcAddressHelper.resetProcAddressTable(GLX.getGLXProcAddressTable(), this); + // Register our GraphicsConfigurationFactory implementations + // The act of constructing them causes them to be registered + new X11GLXGraphicsConfigurationFactory(); + try { + ReflectionUtil.createInstance("com.jogamp.opengl.impl.x11.glx.awt.X11AWTGLXGraphicsConfigurationFactory", + new Object[] {}); + } catch (JogampRuntimeException jre) { /* n/a .. */ } + + X11GraphicsDevice sharedDevice = new X11GraphicsDevice(X11Util.createThreadLocalDisplay(null)); + vendorName = GLXUtil.getVendorName(sharedDevice.getHandle()); + isVendorATI = GLXUtil.isVendorATI(vendorName); + isVendorNVIDIA = GLXUtil.isVendorNVIDIA(vendorName); + if( isVendorATI() ) { + X11Util.markGlobalDisplayUndeletable(sharedDevice.getHandle()); // ATI hack .. + } + sharedScreen = new X11GraphicsScreen(sharedDevice, 0); + X11Lib.XLockDisplay(sharedScreen.getDevice().getHandle()); + try{ + sharedDrawable = new X11DummyGLXDrawable(sharedScreen, this, null); + X11GLXContext ctx = (X11GLXContext) sharedDrawable.createContext(null); + ctx.makeCurrent(); + ctx.release(); + sharedContext = ctx; + }finally{ + X11Lib.XUnlockDisplay(sharedScreen.getDevice().getHandle()); + } + if(null==sharedContext) { + throw new GLException("Couldn't init shared resources"); + } + if (DEBUG) { + System.err.println("!!! Vendor: "+vendorName+", ATI: "+isVendorATI+", NV: "+isVendorNVIDIA); + System.err.println("!!! SharedScreen: "+sharedScreen); + System.err.println("!!! SharedContext: "+sharedContext); + } + } + + private X11GraphicsScreen sharedScreen; + private String vendorName; + private boolean isVendorATI; + private boolean isVendorNVIDIA; + + public String getVendorName() { return vendorName; } + public boolean isVendorATI() { return isVendorATI; } + public boolean isVendorNVIDIA() { return isVendorNVIDIA; } + + private X11DummyGLXDrawable sharedDrawable=null; + private X11GLXContext sharedContext=null; + + protected final GLDrawableImpl getSharedDrawable() { + validate(); + return sharedDrawable; + } + + protected final GLContextImpl getSharedContext() { + validate(); + return sharedContext; + } + + public void shutdown() { + super.shutdown(); + if (DEBUG) { + System.err.println("!!! Shutdown Shared:"); + System.err.println("!!! CTX : "+sharedContext); + System.err.println("!!! Drawable: "+sharedDrawable); + System.err.println("!!! Screen : "+sharedScreen); + Exception e = new Exception("Debug"); + e.printStackTrace(); + } + if(null!=sharedContext) { + sharedContext.destroy(); // implies release, if current + } + if(null!=sharedDrawable) { + sharedDrawable.destroy(); + } + if(null!=sharedScreen) { + X11GraphicsDevice sharedDevice = (X11GraphicsDevice) sharedScreen.getDevice(); + if(null!=sharedDevice) { + X11Util.closeThreadLocalDisplay(null); + } + sharedScreen = null; + } + X11Util.shutdown( !isVendorATI(), DEBUG ); + } + + public GLDrawableImpl createOnscreenDrawable(NativeWindow target) { + validate(); + if (target == null) { + throw new IllegalArgumentException("Null target"); + } + if( isVendorATI() ) { + X11Util.markGlobalDisplayUndeletable(target.getDisplayHandle()); // ATI hack .. + } + return new X11OnscreenGLXDrawable(this, target); + } + + protected GLDrawableImpl createOffscreenDrawable(NativeWindow target) { + validate(); + if (target == null) { + throw new IllegalArgumentException("Null target"); + } + if( isVendorATI() ) { + X11Util.markGlobalDisplayUndeletable(target.getDisplayHandle()); // ATI hack .. + } + return new X11OffscreenGLXDrawable(this, target); + } + + public boolean canCreateGLPbuffer(AbstractGraphicsDevice device) { + validate(); + return glxVersionGreaterEqualThan(device, 1, 3); + } + + private boolean glxVersionsQueried = false; + private int glxVersionMajor=0, glxVersionMinor=0; + public boolean glxVersionGreaterEqualThan(AbstractGraphicsDevice device, int majorReq, int minorReq) { + validate(); + if (!glxVersionsQueried) { + if(null == device) { + device = (X11GraphicsDevice) sharedScreen.getDevice(); + } + if(null == device) { + throw new GLException("FIXME: No AbstractGraphicsDevice (passed or shared-device"); + } + long display = device.getHandle(); + int[] major = new int[1]; + int[] minor = new int[1]; + + GLXUtil.getGLXVersion(display, major, minor); + if (DEBUG) { + System.err.println("!!! GLX version: major " + major[0] + + ", minor " + minor[0]); + } + + glxVersionMajor = major[0]; + glxVersionMinor = minor[0]; + glxVersionsQueried = true; + } + return ( glxVersionMajor > majorReq ) || ( glxVersionMajor == majorReq && glxVersionMinor >= minorReq ) ; + } + + protected GLDrawableImpl createGLPbufferDrawableImpl(final NativeWindow target) { + validate(); + if (target == null) { + throw new IllegalArgumentException("Null target"); + } + + GLDrawableImpl pbufferDrawable; + + /** + * Due to the ATI Bug https://bugzilla.mozilla.org/show_bug.cgi?id=486277, + * we need to have a context current on the same Display to create a PBuffer. + * The dummy context shall also use the same Display, + * since switching Display in this regard is another ATI bug. + */ + boolean usedSharedContext=false; + if( isVendorATI() && null == GLContext.getCurrent() ) { + sharedContext.makeCurrent(); + usedSharedContext=true; + } + if( isVendorATI() ) { + X11Util.markGlobalDisplayUndeletable(target.getDisplayHandle()); // ATI hack .. + } + try { + pbufferDrawable = new X11PbufferGLXDrawable(this, target); + } finally { + if(usedSharedContext) { + sharedContext.release(); + } + } + return pbufferDrawable; + } + + + protected NativeWindow createOffscreenWindow(GLCapabilities capabilities, GLCapabilitiesChooser chooser, int width, int height) { + validate(); + NullWindow nw = null; + X11Lib.XLockDisplay(sharedScreen.getDevice().getHandle()); + try{ + nw = new NullWindow(X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capabilities, chooser, sharedScreen)); + }finally{ + X11Lib.XUnlockDisplay(sharedScreen.getDevice().getHandle()); + } + if(nw != null) { + nw.setSize(width, height); + } + return nw; + } + + public GLContext createExternalGLContext() { + validate(); + return X11ExternalGLXContext.create(this, null); + } + + public boolean canCreateExternalGLDrawable(AbstractGraphicsDevice device) { + validate(); + return canCreateGLPbuffer(device); + } + + public GLDrawable createExternalGLDrawable() { + validate(); + return X11ExternalGLXDrawable.create(this, null); + } + + public void loadGLULibrary() { + validate(); + X11Lib.dlopen("/usr/lib/libGLU.so"); + } + + public long dynamicLookupFunction(String glFuncName) { + long res = 0; + res = GLX.glXGetProcAddressARB(glFuncName); + if (res == 0) { + // GLU routines aren't known to the OpenGL function lookup + res = X11Lib.dlsym(glFuncName); + } + return res; + } + + public boolean canCreateContextOnJava2DSurface(AbstractGraphicsDevice device) { + validate(); + return false; + } + + public GLContext createContextOnJava2DSurface(Object graphics, GLContext shareWith) + throws GLException { + throw new GLException("Unimplemented on this platform"); + } + + //---------------------------------------------------------------------- + // Gamma-related functionality + // + + private boolean gotGammaRampLength; + private int gammaRampLength; + protected synchronized int getGammaRampLength() { + if (gotGammaRampLength) { + return gammaRampLength; + } + + long display = sharedScreen.getDevice().getHandle(); + + X11Lib.XLockDisplay(display); + try { + int[] size = new int[1]; + boolean res = X11Lib.XF86VidModeGetGammaRampSize(display, + X11Lib.DefaultScreen(display), + size, 0); + if (!res) { + return 0; + } + gotGammaRampLength = true; + gammaRampLength = size[0]; + return gammaRampLength; + } finally { + X11Lib.XUnlockDisplay(display); + } + } + + protected boolean setGammaRamp(float[] ramp) { + int len = ramp.length; + short[] rampData = new short[len]; + for (int i = 0; i < len; i++) { + rampData[i] = (short) (ramp[i] * 65535); + } + + long display = sharedScreen.getDevice().getHandle(); + X11Lib.XLockDisplay(display); + try { + boolean res = X11Lib.XF86VidModeSetGammaRamp(display, + X11Lib.DefaultScreen(display), + rampData.length, + rampData, 0, + rampData, 0, + rampData, 0); + return res; + } finally { + X11Lib.XUnlockDisplay(display); + } + } + + protected Buffer getGammaRamp() { + int size = getGammaRampLength(); + ShortBuffer rampData = ShortBuffer.wrap(new short[3 * size]); + rampData.position(0); + rampData.limit(size); + ShortBuffer redRampData = rampData.slice(); + rampData.position(size); + rampData.limit(2 * size); + ShortBuffer greenRampData = rampData.slice(); + rampData.position(2 * size); + rampData.limit(3 * size); + ShortBuffer blueRampData = rampData.slice(); + long display = sharedScreen.getDevice().getHandle(); + X11Lib.XLockDisplay(display); + try { + boolean res = X11Lib.XF86VidModeGetGammaRamp(display, + X11Lib.DefaultScreen(display), + size, + redRampData, + greenRampData, + blueRampData); + if (!res) { + return null; + } + return rampData; + } finally { + X11Lib.XUnlockDisplay(display); + } + } + + protected void resetGammaRamp(Buffer originalGammaRamp) { + if (originalGammaRamp == null) + return; // getGammaRamp failed originally + ShortBuffer rampData = (ShortBuffer) originalGammaRamp; + int capacity = rampData.capacity(); + if ((capacity % 3) != 0) { + throw new IllegalArgumentException("Must not be the original gamma ramp"); + } + int size = capacity / 3; + rampData.position(0); + rampData.limit(size); + ShortBuffer redRampData = rampData.slice(); + rampData.position(size); + rampData.limit(2 * size); + ShortBuffer greenRampData = rampData.slice(); + rampData.position(2 * size); + rampData.limit(3 * size); + ShortBuffer blueRampData = rampData.slice(); + long display = sharedScreen.getDevice().getHandle(); + X11Lib.XLockDisplay(display); + try { + X11Lib.XF86VidModeSetGammaRamp(display, + X11Lib.DefaultScreen(display), + size, + redRampData, + greenRampData, + blueRampData); + } finally { + X11Lib.XUnlockDisplay(display); + } + } +} diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java new file mode 100644 index 000000000..35daf0ae0 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java @@ -0,0 +1,439 @@ +/* + * 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.jogamp.opengl.impl.x11.glx; + +import com.jogamp.common.nio.PointerBuffer; +import javax.media.nativewindow.*; +import javax.media.nativewindow.x11.*; +import javax.media.opengl.*; +import com.jogamp.opengl.impl.*; +import com.jogamp.nativewindow.impl.x11.*; + +public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implements Cloneable { + protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration"); + + public static final int MAX_ATTRIBS = 128; + private long fbConfig; + private int fbConfigID; + private GLCapabilitiesChooser chooser; + + public X11GLXGraphicsConfiguration(X11GraphicsScreen screen, + GLCapabilities capsChosen, GLCapabilities capsRequested, GLCapabilitiesChooser chooser, + XVisualInfo info, long fbcfg, int fbcfgID) { + super(screen, capsChosen, capsRequested, info); + this.chooser=chooser; + fbConfig = fbcfg; + fbConfigID = fbcfgID; + } + + public static X11GLXGraphicsConfiguration create(GLProfile glp, X11GraphicsScreen x11Screen, int fbcfgID) { + long display = x11Screen.getDevice().getHandle(); + if(0==display) { + throw new GLException("Display null of "+x11Screen); + } + int screen = x11Screen.getIndex(); + long fbcfg = glXFBConfigID2FBConfig(display, screen, fbcfgID); + if(0==fbcfg) { + throw new GLException("FBConfig null of "+toHexString(fbcfgID)); + } + if(null==glp) { + glp = GLProfile.getDefault(); + } + GLCapabilities caps = GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, GLXUtil.isMultisampleAvailable(display)); + if(null==caps) { + throw new GLException("GLCapabilities null of "+toHexString(fbcfg)); + } + XVisualInfo xvi = GLX.glXGetVisualFromFBConfigCopied(display, fbcfg); + if(null==xvi) { + throw new GLException("XVisualInfo null of "+toHexString(fbcfg)); + } + return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser(), xvi, fbcfg, fbcfgID); + } + + public Object clone() { + return super.clone(); + } + + public long getFBConfig() { return fbConfig; } + public int getFBConfigID() { return fbConfigID; } + + protected void updateGraphicsConfiguration() { + X11GLXGraphicsConfiguration newConfig = (X11GLXGraphicsConfiguration) + GraphicsConfigurationFactory.getFactory(getScreen().getDevice()).chooseGraphicsConfiguration(getRequestedCapabilities(), + chooser, + getScreen()); + if(null!=newConfig) { + // FIXME: setScreen( ... ); + setXVisualInfo(newConfig.getXVisualInfo()); + setChosenCapabilities(newConfig.getChosenCapabilities()); + fbConfig = newConfig.getFBConfig(); + fbConfigID = newConfig.getFBConfigID(); + if(DEBUG) { + System.err.println("!!! updateGraphicsConfiguration: "+this); + } + } + } + + private static int nonZeroOrDontCare(int value) { + return value != 0 ? value : (int)GLX.GLX_DONT_CARE ; + } + + public static int[] GLCapabilities2AttribList(GLCapabilities caps, + boolean forFBAttr, + boolean isMultisampleAvailable, + long display, + int screen) + { + int colorDepth = (caps.getRedBits() + + caps.getGreenBits() + + caps.getBlueBits()); + if (colorDepth < 15) { + throw new GLException("Bit depths < 15 (i.e., non-true-color) not supported"); + } + int[] res = new int[MAX_ATTRIBS]; + int idx = 0; + + if (forFBAttr) { + res[idx++] = GLX.GLX_DRAWABLE_TYPE; + res[idx++] = caps.isOnscreen() ? ( GLX.GLX_WINDOW_BIT ) : ( caps.isPBuffer() ? GLX.GLX_PBUFFER_BIT : GLX.GLX_PIXMAP_BIT ) ; + } + + if (forFBAttr) { + res[idx++] = GLX.GLX_RENDER_TYPE; + res[idx++] = GLX.GLX_RGBA_BIT; + } else { + res[idx++] = GLX.GLX_RGBA; + } + + // FIXME: Still a bug is Mesa: PBUFFER && GLX_STEREO==GL_FALSE ? + if (forFBAttr) { + res[idx++] = GLX.GLX_DOUBLEBUFFER; + res[idx++] = caps.getDoubleBuffered()?GL.GL_TRUE:GL.GL_FALSE; + res[idx++] = GLX.GLX_STEREO; + res[idx++] = caps.getStereo()?GL.GL_TRUE:GL.GL_FALSE; + res[idx++] = GLX.GLX_TRANSPARENT_TYPE; + res[idx++] = caps.isBackgroundOpaque()?GLX.GLX_NONE:GLX.GLX_TRANSPARENT_RGB; + if(!caps.isBackgroundOpaque()) { + res[idx++] = GLX.GLX_TRANSPARENT_RED_VALUE; + res[idx++] = caps.getTransparentRedValue()>=0?caps.getTransparentRedValue():(int)GLX.GLX_DONT_CARE; + res[idx++] = GLX.GLX_TRANSPARENT_GREEN_VALUE; + res[idx++] = caps.getTransparentGreenValue()>=0?caps.getTransparentGreenValue():(int)GLX.GLX_DONT_CARE; + res[idx++] = GLX.GLX_TRANSPARENT_BLUE_VALUE; + res[idx++] = caps.getTransparentBlueValue()>=0?caps.getTransparentBlueValue():(int)GLX.GLX_DONT_CARE; + res[idx++] = GLX.GLX_TRANSPARENT_ALPHA_VALUE; + res[idx++] = caps.getTransparentAlphaValue()>=0?caps.getTransparentAlphaValue():(int)GLX.GLX_DONT_CARE; + } + } else { + if (caps.getDoubleBuffered()) { + res[idx++] = GLX.GLX_DOUBLEBUFFER; + } + if (caps.getStereo()) { + res[idx++] = GLX.GLX_STEREO; + } + } + + res[idx++] = GLX.GLX_RED_SIZE; + res[idx++] = caps.getRedBits(); + res[idx++] = GLX.GLX_GREEN_SIZE; + res[idx++] = caps.getGreenBits(); + res[idx++] = GLX.GLX_BLUE_SIZE; + res[idx++] = caps.getBlueBits(); + res[idx++] = GLX.GLX_ALPHA_SIZE; + res[idx++] = caps.getAlphaBits(); + res[idx++] = GLX.GLX_DEPTH_SIZE; + res[idx++] = caps.getDepthBits(); + if (caps.getStencilBits() > 0) { + res[idx++] = GLX.GLX_STENCIL_SIZE; + res[idx++] = caps.getStencilBits(); + } + if (caps.getAccumRedBits() > 0 || + caps.getAccumGreenBits() > 0 || + caps.getAccumBlueBits() > 0 || + caps.getAccumAlphaBits() > 0) { + res[idx++] = GLX.GLX_ACCUM_RED_SIZE; + res[idx++] = caps.getAccumRedBits(); + res[idx++] = GLX.GLX_ACCUM_GREEN_SIZE; + res[idx++] = caps.getAccumGreenBits(); + res[idx++] = GLX.GLX_ACCUM_BLUE_SIZE; + res[idx++] = caps.getAccumBlueBits(); + res[idx++] = GLX.GLX_ACCUM_ALPHA_SIZE; + res[idx++] = caps.getAccumAlphaBits(); + } + if (isMultisampleAvailable && caps.getSampleBuffers()) { + res[idx++] = GLX.GLX_SAMPLE_BUFFERS; + res[idx++] = GL.GL_TRUE; + res[idx++] = GLX.GLX_SAMPLES; + res[idx++] = caps.getNumSamples(); + } + if (caps.isPBuffer()) { + if (caps.getPbufferFloatingPointBuffers()) { + String glXExtensions = GLX.glXQueryExtensionsString(display, screen); + if (glXExtensions == null || + glXExtensions.indexOf("GLX_NV_float_buffer") < 0) { + throw new GLException("Floating-point pbuffers on X11 currently require NVidia hardware: "+glXExtensions); + } + res[idx++] = GLXExt.GLX_FLOAT_COMPONENTS_NV; + res[idx++] = GL.GL_TRUE; + } + } + res[idx++] = 0; + return res; + } + + // FBConfig + + public static boolean GLXFBConfigValid(long display, long fbcfg) { + int[] tmp = new int[1]; + if(GLX.GLX_BAD_ATTRIBUTE == GLX.glXGetFBConfigAttrib(display, fbcfg, GLX.GLX_RENDER_TYPE, tmp, 0)) { + return false; + } + return true; + } + + public static boolean GLXFBConfigDrawableTypeVerify(int val, boolean onscreen, boolean usePBuffer) { + boolean res; + + if ( onscreen ) { + res = ( 0 != (val & GLX.GLX_WINDOW_BIT) ) ; + } else { + if ( usePBuffer ) { + res = ( 0 != (val & GLX.GLX_PBUFFER_BIT) ) ; + } else { + res = ( 0 != (val & GLX.GLX_PIXMAP_BIT) ) ; + } + } + + return res; + } + + public static GLCapabilities GLXFBConfig2GLCapabilities(GLProfile glp, long display, long fbcfg, + boolean relaxed, boolean onscreen, boolean usePBuffer, boolean isMultisampleEnabled) { + int[] tmp = new int[1]; + int val; + val = glXGetFBConfig(display, fbcfg, GLX.GLX_RENDER_TYPE, tmp, 0); + if (val != GLX.GLX_RGBA_BIT) { + if(DEBUG) { + System.err.println("FBConfig ("+toHexString(fbcfg)+") does not support RGBA: "+toHexString(val)); + } + return null; + } + GLCapabilities res = new GLCapabilities(glp); + + val = glXGetFBConfig(display, fbcfg, GLX.GLX_DRAWABLE_TYPE, tmp, 0); + if(GLXFBConfigDrawableTypeVerify(val, onscreen, usePBuffer)) { + res.setOnscreen(onscreen); + res.setPBuffer(usePBuffer); + } else if(relaxed) { + res.setOnscreen( 0 != (val & GLX.GLX_WINDOW_BIT) ); + res.setPBuffer ( 0 != (val & GLX.GLX_PBUFFER_BIT) ); + } else { + if(DEBUG) { + System.err.println("FBConfig ("+toHexString(fbcfg)+") GLX_DRAWABLE_TYPE does not match: req(onscrn "+onscreen+", pbuffer "+usePBuffer+"), got(onscreen "+( 0 != (val & GLX.GLX_WINDOW_BIT) )+", pbuffer "+( 0 != (val & GLX.GLX_PBUFFER_BIT) )+", pixmap "+( 0 != (val & GLX.GLX_PIXMAP_BIT) )+")"); + } + return null; + } + res.setDoubleBuffered(glXGetFBConfig(display, fbcfg, GLX.GLX_DOUBLEBUFFER, tmp, 0) != 0); + res.setStereo (glXGetFBConfig(display, fbcfg, GLX.GLX_STEREO, tmp, 0) != 0); + res.setHardwareAccelerated(glXGetFBConfig(display, fbcfg, GLX.GLX_CONFIG_CAVEAT, tmp, 0) != GLX.GLX_SLOW_CONFIG); + res.setDepthBits (glXGetFBConfig(display, fbcfg, GLX.GLX_DEPTH_SIZE, tmp, 0)); + res.setStencilBits (glXGetFBConfig(display, fbcfg, GLX.GLX_STENCIL_SIZE, tmp, 0)); + res.setRedBits (glXGetFBConfig(display, fbcfg, GLX.GLX_RED_SIZE, tmp, 0)); + res.setGreenBits (glXGetFBConfig(display, fbcfg, GLX.GLX_GREEN_SIZE, tmp, 0)); + res.setBlueBits (glXGetFBConfig(display, fbcfg, GLX.GLX_BLUE_SIZE, tmp, 0)); + res.setAlphaBits (glXGetFBConfig(display, fbcfg, GLX.GLX_ALPHA_SIZE, tmp, 0)); + res.setAccumRedBits (glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_RED_SIZE, tmp, 0)); + res.setAccumGreenBits(glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_GREEN_SIZE, tmp, 0)); + res.setAccumBlueBits (glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_BLUE_SIZE, tmp, 0)); + res.setAccumAlphaBits(glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_ALPHA_SIZE, tmp, 0)); + if (isMultisampleEnabled) { + res.setSampleBuffers(glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLE_BUFFERS, tmp, 0) != 0); + res.setNumSamples (glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLES, tmp, 0)); + } + res.setBackgroundOpaque(glXGetFBConfig(display, fbcfg, GLX.GLX_TRANSPARENT_TYPE, tmp, 0) == GLX.GLX_NONE); + if(!res.isBackgroundOpaque()) { + glXGetFBConfig(display, fbcfg, GLX.GLX_TRANSPARENT_RED_VALUE, tmp, 0); + res.setTransparentRedValue(tmp[0]==GLX.GLX_DONT_CARE?-1:tmp[0]); + + glXGetFBConfig(display, fbcfg, GLX.GLX_TRANSPARENT_GREEN_VALUE, tmp, 0); + res.setTransparentGreenValue(tmp[0]==GLX.GLX_DONT_CARE?-1:tmp[0]); + + glXGetFBConfig(display, fbcfg, GLX.GLX_TRANSPARENT_BLUE_VALUE, tmp, 0); + res.setTransparentBlueValue(tmp[0]==GLX.GLX_DONT_CARE?-1:tmp[0]); + + glXGetFBConfig(display, fbcfg, GLX.GLX_TRANSPARENT_ALPHA_VALUE, tmp, 0); + res.setTransparentAlphaValue(tmp[0]==GLX.GLX_DONT_CARE?-1:tmp[0]); + } + try { + res.setPbufferFloatingPointBuffers(glXGetFBConfig(display, fbcfg, GLXExt.GLX_FLOAT_COMPONENTS_NV, tmp, 0) != GL.GL_FALSE); + } catch (Exception e) {} + return res; + } + + private static String glXGetFBConfigErrorCode(int err) { + switch (err) { + case GLX.GLX_NO_EXTENSION: return "GLX_NO_EXTENSION"; + case GLX.GLX_BAD_ATTRIBUTE: return "GLX_BAD_ATTRIBUTE"; + default: return "Unknown error code " + err; + } + } + + public static int glXGetFBConfig(long display, long cfg, int attrib, int[] tmp, int tmp_offset) { + if (display == 0) { + throw new GLException("No display connection"); + } + int res = GLX.glXGetFBConfigAttrib(display, cfg, attrib, tmp, tmp_offset); + if (res != 0) { + throw new GLException("glXGetFBConfig("+toHexString(attrib)+") failed: error code " + glXGetFBConfigErrorCode(res)); + } + return tmp[tmp_offset]; + } + + public static int glXFBConfig2FBConfigID(long display, long cfg) { + int[] tmpID = new int[1]; + return glXGetFBConfig(display, cfg, GLX.GLX_FBCONFIG_ID, tmpID, 0); + } + + public static long glXFBConfigID2FBConfig(long display, int screen, int id) { + int[] attribs = new int[] { GLX.GLX_FBCONFIG_ID, id, 0 }; + int[] count = { -1 }; + PointerBuffer fbcfgsL = GLX.glXChooseFBConfigCopied(display, screen, attribs, 0, count, 0); + if (fbcfgsL == null || fbcfgsL.limit()<1) { + return 0; + } + return fbcfgsL.get(0); + } + + // Visual Info + + public static XVisualInfo XVisualID2XVisualInfo(long display, long visualID) { + XVisualInfo res = null; + NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); + try{ + int[] count = new int[1]; + XVisualInfo template = XVisualInfo.create(); + template.setVisualid(visualID); + XVisualInfo[] infos = X11Lib.XGetVisualInfoCopied(display, X11Lib.VisualIDMask, template, count, 0); + if (infos == null || infos.length == 0) { + return null; + } + res = XVisualInfo.create(infos[0]); + } finally { + NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); + } + if (DEBUG) { + System.err.println("!!! Fetched XVisualInfo for visual ID " + toHexString(visualID)); + System.err.println("!!! Resulting XVisualInfo: visualid = " + toHexString(res.getVisualid())); + } + return res; + } + + public static GLCapabilities XVisualInfo2GLCapabilities(GLProfile glp, long display, XVisualInfo info, boolean onscreen, boolean usePBuffer, boolean isMultisampleEnabled) { + int[] tmp = new int[1]; + int val = glXGetConfig(display, info, GLX.GLX_USE_GL, tmp, 0); + if (val == 0) { + if(DEBUG) { + System.err.println("Visual ("+toHexString(info.getVisualid())+") does not support OpenGL"); + } + return null; + } + val = glXGetConfig(display, info, GLX.GLX_RGBA, tmp, 0); + if (val == 0) { + if(DEBUG) { + System.err.println("Visual ("+toHexString(info.getVisualid())+") does not support RGBA"); + } + return null; + } + GLCapabilities res = new GLCapabilities(glp); + res.setOnscreen (onscreen); + res.setPBuffer (usePBuffer); + res.setDoubleBuffered(glXGetConfig(display, info, GLX.GLX_DOUBLEBUFFER, tmp, 0) != 0); + res.setStereo (glXGetConfig(display, info, GLX.GLX_STEREO, tmp, 0) != 0); + // Note: use of hardware acceleration is determined by + // glXCreateContext, not by the XVisualInfo. Optimistically claim + // that all GLCapabilities have the capability to be hardware + // accelerated. + res.setHardwareAccelerated(true); + res.setDepthBits (glXGetConfig(display, info, GLX.GLX_DEPTH_SIZE, tmp, 0)); + res.setStencilBits (glXGetConfig(display, info, GLX.GLX_STENCIL_SIZE, tmp, 0)); + res.setRedBits (glXGetConfig(display, info, GLX.GLX_RED_SIZE, tmp, 0)); + res.setGreenBits (glXGetConfig(display, info, GLX.GLX_GREEN_SIZE, tmp, 0)); + res.setBlueBits (glXGetConfig(display, info, GLX.GLX_BLUE_SIZE, tmp, 0)); + res.setAlphaBits (glXGetConfig(display, info, GLX.GLX_ALPHA_SIZE, tmp, 0)); + res.setAccumRedBits (glXGetConfig(display, info, GLX.GLX_ACCUM_RED_SIZE, tmp, 0)); + 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 (isMultisampleEnabled) { + res.setSampleBuffers(glXGetConfig(display, info, GLX.GLX_SAMPLE_BUFFERS, tmp, 0) != 0); + res.setNumSamples (glXGetConfig(display, info, GLX.GLX_SAMPLES, tmp, 0)); + } + return res; + } + + private static String glXGetConfigErrorCode(int err) { + switch (err) { + case GLX.GLX_NO_EXTENSION: return "GLX_NO_EXTENSION"; + case GLX.GLX_BAD_SCREEN: return "GLX_BAD_SCREEN"; + case GLX.GLX_BAD_ATTRIBUTE: return "GLX_BAD_ATTRIBUTE"; + case GLX.GLX_BAD_VISUAL: return "GLX_BAD_VISUAL"; + default: return "Unknown error code " + err; + } + } + + public static int glXGetConfig(long display, XVisualInfo info, int attrib, int[] tmp, int tmp_offset) { + if (display == 0) { + throw new GLException("No display connection"); + } + int res = GLX.glXGetConfig(display, info, attrib, tmp, tmp_offset); + if (res != 0) { + throw new GLException("glXGetConfig("+toHexString(attrib)+") failed: error code " + glXGetConfigErrorCode(res)); + } + return tmp[tmp_offset]; + } + + public static String toHexString(int val) { + return "0x"+Integer.toHexString(val); + } + + public static String toHexString(long val) { + return "0x"+Long.toHexString(val); + } + + public String toString() { + return "X11GLXGraphicsConfiguration["+getScreen()+", visualID " + toHexString(getVisualID()) + ", fbConfigID " + toHexString(fbConfigID) + + ",\n\trequested " + getRequestedCapabilities()+ + ",\n\tchosen " + getChosenCapabilities()+ + "]"; + } +} + diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java new file mode 100644 index 000000000..e65fb5e90 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java @@ -0,0 +1,397 @@ +/* + * 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.jogamp.opengl.impl.x11.glx; + +import com.jogamp.common.nio.PointerBuffer; +import javax.media.nativewindow.*; +import javax.media.nativewindow.x11.*; +import com.jogamp.nativewindow.impl.x11.*; + +import javax.media.opengl.*; +import com.jogamp.opengl.impl.*; + + +/** Subclass of GraphicsConfigurationFactory used when non-AWT tookits + are used on X11 platforms. Toolkits will likely need to delegate + to this one to change the accepted and returned types of the + GraphicsDevice and GraphicsConfiguration abstractions. */ + +public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFactory { + protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration"); + + public X11GLXGraphicsConfigurationFactory() { + GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.x11.X11GraphicsDevice.class, this); + } + + public AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities, + CapabilitiesChooser chooser, + AbstractGraphicsScreen absScreen) { + return chooseGraphicsConfigurationStatic(capabilities, chooser, absScreen); + } + + /** + protected static X11GLXGraphicsConfiguration createDefaultGraphicsConfigurationFBConfig(AbstractGraphicsScreen absScreen, boolean onscreen, boolean usePBuffer) { + if (absScreen == null) { + throw new IllegalArgumentException("AbstractGraphicsScreen is null"); + } + if (!(absScreen instanceof X11GraphicsScreen)) { + throw new IllegalArgumentException("Only X11GraphicsScreen are allowed here"); + } + X11GraphicsScreen x11Screen = (X11GraphicsScreen)absScreen; + + GLProfile glProfile = GLProfile.getDefault(); + GLCapabilities caps=null; + XVisualInfo xvis=null; + long fbcfg = 0; + int fbid = -1; + + // Utilizing FBConfig + // + GLCapabilities capsFB = null; + long display = x11Screen.getDevice().getHandle(); + + NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); + X11Lib.XLockDisplay(display); + try { + int screen = x11Screen.getIndex(); + boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); + + long visID = X11Lib.DefaultVisualID(display, x11Screen.getIndex()); + xvis = X11GLXGraphicsConfiguration.XVisualID2XVisualInfo(display, visID); + caps = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(glProfile, display, xvis, onscreen, usePBuffer, isMultisampleAvailable); + + int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(caps, true, isMultisampleAvailable, display, screen); + int[] count = { -1 }; + PointerBuffer fbcfgsL = GLX.glXChooseFBConfigCopied(display, screen, attribs, 0, count, 0); + if (fbcfgsL == null || fbcfgsL.limit()<1) { + throw new Exception("Could not fetch FBConfig for "+caps); + } + fbcfg = fbcfgsL.get(0); + capsFB = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfg, true, onscreen, usePBuffer, isMultisampleAvailable); + + fbid = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfg); + + xvis = GLX.glXGetVisualFromFBConfigCopied(display, fbcfg); + if (xvis==null) { + throw new GLException("Error: Choosen FBConfig has no visual"); + } + } catch (Throwable t) { + } finally { + X11Lib.XUnlockDisplay(display); + NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); + } + + return new X11GLXGraphicsConfiguration(x11Screen, (null!=capsFB)?capsFB:caps, caps, null, xvis, fbcfg, fbid); + } */ + + protected static X11GLXGraphicsConfiguration chooseGraphicsConfigurationStatic(Capabilities capabilities, + CapabilitiesChooser chooser, + AbstractGraphicsScreen absScreen) { + if (absScreen == null) { + throw new IllegalArgumentException("AbstractGraphicsScreen is null"); + } + if (!(absScreen instanceof X11GraphicsScreen)) { + throw new IllegalArgumentException("Only X11GraphicsScreen are allowed here"); + } + X11GraphicsScreen x11Screen = (X11GraphicsScreen)absScreen; + + + if (capabilities != null && + !(capabilities instanceof GLCapabilities)) { + throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilities objects"); + } + + if (chooser != null && + !(chooser instanceof GLCapabilitiesChooser)) { + throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects"); + } + + if (capabilities == null) { + capabilities = new GLCapabilities(null); + } + + boolean onscreen = capabilities.isOnscreen(); + boolean usePBuffer = ((GLCapabilities)capabilities).isPBuffer(); + + GLCapabilities caps2 = (GLCapabilities) capabilities.clone(); + if(!caps2.isOnscreen()) { + // OFFSCREEN !DOUBLE_BUFFER // FIXME DBLBUFOFFSCRN + caps2.setDoubleBuffered(false); + } + + X11GLXGraphicsConfiguration res; + res = chooseGraphicsConfigurationFBConfig((GLCapabilities) caps2, + (GLCapabilitiesChooser) chooser, + x11Screen); + if(null==res) { + if(usePBuffer) { + throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig for "+caps2); + } + res = chooseGraphicsConfigurationXVisual((GLCapabilities) caps2, + (GLCapabilitiesChooser) chooser, + x11Screen); + } + if(null==res) { + throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig and XVisual for "+caps2); + } + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationStatic("+x11Screen+","+caps2+"): "+res); + } + return res; + } + + protected static X11GLXGraphicsConfiguration chooseGraphicsConfigurationFBConfig(GLCapabilities capabilities, + GLCapabilitiesChooser chooser, + X11GraphicsScreen x11Screen) { + long recommendedFBConfig = 0; + int recommendedIndex = -1; + GLCapabilities[] caps = null; + PointerBuffer fbcfgsL = null; + int chosen=-1; + int retFBID=-1; + XVisualInfo retXVisualInfo = null; + GLProfile glProfile = capabilities.getGLProfile(); + boolean onscreen = capabilities.isOnscreen(); + boolean usePBuffer = capabilities.isPBuffer(); + + // Utilizing FBConfig + // + AbstractGraphicsDevice absDevice = x11Screen.getDevice(); + long display = absDevice.getHandle(); + + NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); + try { + X11Lib.XLockDisplay(display); + try{ + int screen = x11Screen.getIndex(); + boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); + int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capabilities, true, isMultisampleAvailable, display, screen); + int[] count = { -1 }; + + // determine the recommended FBConfig .. + fbcfgsL = GLX.glXChooseFBConfigCopied(display, screen, attribs, 0, count, 0); + if (fbcfgsL == null || fbcfgsL.limit()<1) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXChooseFBConfig ("+x11Screen+","+capabilities+"): "+fbcfgsL+", "+count[0]); + } + } else if( !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfgsL.get(0) ) ) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed - GLX FBConfig invalid: ("+x11Screen+","+capabilities+"): "+fbcfgsL+", fbcfg: "+toHexString(fbcfgsL.get(0))); + } + } else { + recommendedFBConfig = fbcfgsL.get(0); + } + + // get all, glXChooseFBConfig(.. attribs==null ..) == glXGetFBConfig(..) + fbcfgsL = GLX.glXChooseFBConfigCopied(display, screen, null, 0, count, 0); + if (fbcfgsL == null || fbcfgsL.limit()<1) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXGetFBConfig ("+x11Screen+"): "+fbcfgsL+", "+count[0]); + } + return null; + } + + // make GLCapabilities and seek the recommendedIndex + caps = new GLCapabilities[fbcfgsL.limit()]; + for (int i = 0; i < fbcfgsL.limit(); i++) { + if( !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfgsL.get(i) ) ) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid: ("+x11Screen+","+capabilities+"): fbcfg: "+toHexString(fbcfgsL.get(i))); + } + } else { + caps[i] = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfgsL.get(i), + false, onscreen, usePBuffer, isMultisampleAvailable); + if(caps[i]!=null && recommendedFBConfig==fbcfgsL.get(i)) { + recommendedIndex=i; + if (DEBUG) { + System.err.println("!!! glXChooseFBConfig recommended "+i+", "+caps[i]); + } + } + } + } + + if(null==chooser) { + chosen = recommendedIndex; // may still be -1 in case nothing was recommended (-1) + } + + if (chosen < 0) { + if(null==chooser) { + // nothing recommended .. so use our default implementation + chooser = new DefaultGLCapabilitiesChooser(); + } + try { + chosen = chooser.chooseCapabilities(capabilities, caps, recommendedIndex); + } catch (NativeWindowException e) { + if(DEBUG) { + e.printStackTrace(); + } + chosen = -1; + } + } + if (chosen < 0) { + // keep on going .. + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig Failed .. unable to choose config, using first"); + } + // seek first available one .. + for(chosen = 0; chosen < caps.length && caps[chosen]==null; chosen++) ; + if(chosen==caps.length) { + // give up .. + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig Failed .. nothing available, bail out"); + } + return null; + } + } else if (chosen >= caps.length) { + if(DEBUG) { + System.err.println("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ", got "+chosen+")"); + } + return null; + } + + retFBID = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfgsL.get(chosen)); + + retXVisualInfo = GLX.glXGetVisualFromFBConfigCopied(display, fbcfgsL.get(chosen)); + if (retXVisualInfo==null) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXGetVisualFromFBConfig ("+x11Screen+", "+fbcfgsL.get(chosen) +" (Continue: "+(false==caps[chosen].isOnscreen())+"):\n\t"+caps[chosen]); + } + if(caps[chosen].isOnscreen()) { + // Onscreen drawables shall have a XVisual .. + return null; + } + } + }finally{ + X11Lib.XUnlockDisplay(display); + } + } finally { + NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); + } + + return new X11GLXGraphicsConfiguration(x11Screen, caps[chosen], capabilities, chooser, retXVisualInfo, fbcfgsL.get(chosen), retFBID); + } + + protected static X11GLXGraphicsConfiguration chooseGraphicsConfigurationXVisual(GLCapabilities capabilities, + GLCapabilitiesChooser chooser, + X11GraphicsScreen x11Screen) { + if (chooser == null) { + chooser = new DefaultGLCapabilitiesChooser(); + } + + // 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 + + GLProfile glProfile = capabilities.getGLProfile(); + boolean onscreen = capabilities.isOnscreen(); + GLCapabilities[] caps = null; + int recommendedIndex = -1; + XVisualInfo retXVisualInfo = null; + int chosen=-1; + + AbstractGraphicsDevice absDevice = x11Screen.getDevice(); + long display = absDevice.getHandle(); + + NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); + try { + X11Lib.XLockDisplay(display); + try{ + int screen = x11Screen.getIndex(); + boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); + int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capabilities, false, isMultisampleAvailable, display, screen); + XVisualInfo[] infos = null; + + XVisualInfo recommendedVis = GLX.glXChooseVisualCopied(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 " + toHexString(recommendedVis.getVisualid())); + } + } + int[] count = new int[1]; + XVisualInfo template = XVisualInfo.create(); + template.setScreen(screen); + infos = X11Lib.XGetVisualInfoCopied(display, X11Lib.VisualScreenMask, template, count, 0); + if (infos == null || infos.length<1) { + throw new GLException("Error while enumerating available XVisualInfos"); + } + caps = new GLCapabilities[infos.length]; + for (int i = 0; i < infos.length; i++) { + caps[i] = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(glProfile, display, infos[i], onscreen, false, isMultisampleAvailable); + // Attempt to find the visual chosen by glXChooseVisual + if (recommendedVis != null && recommendedVis.getVisualid() == infos[i].getVisualid()) { + recommendedIndex = i; + } + } + try { + chosen = chooser.chooseCapabilities(capabilities, caps, recommendedIndex); + } catch (NativeWindowException e) { + if(DEBUG) { + e.printStackTrace(); + } + chosen = -1; + } + if (chosen < 0) { + // keep on going .. + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationXVisual Failed .. unable to choose config, using first"); + } + chosen = 0; // default .. + } else if (chosen >= caps.length) { + throw new GLException("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ")"); + } + if (infos[chosen] == null) { + throw new GLException("GLCapabilitiesChooser chose an invalid visual for "+caps[chosen]); + } + retXVisualInfo = XVisualInfo.create(infos[chosen]); + }finally{ + X11Lib.XUnlockDisplay(display); + } + } finally { + NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); + } + return new X11GLXGraphicsConfiguration(x11Screen, caps[chosen], capabilities, chooser, retXVisualInfo, 0, -1); + } + + public static String toHexString(int val) { + return "0x"+Integer.toHexString(val); + } + + public static String toHexString(long val) { + return "0x"+Long.toHexString(val); + } + +} + diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXContext.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXContext.java new file mode 100644 index 000000000..bea953ee9 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXContext.java @@ -0,0 +1,77 @@ +/* + * 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. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package com.jogamp.opengl.impl.x11.glx; + +import javax.media.opengl.*; +import com.jogamp.opengl.impl.*; +import com.jogamp.opengl.impl.x11.*; + +public class X11OffscreenGLXContext extends X11GLXContext { + private X11OffscreenGLXDrawable drawable; + + public X11OffscreenGLXContext(X11OffscreenGLXDrawable drawable, + GLContext shareWith) { + super(drawable, shareWith); + this.drawable = drawable; + } + + public int getOffscreenContextPixelDataType() { + GL gl = getGL(); + return gl.isGL2GL3()?GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV:GL.GL_UNSIGNED_SHORT_5_5_5_1; + } + + public int getOffscreenContextReadBuffer() { + GLCapabilities caps = (GLCapabilities)drawable.getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities(); + if (caps.getDoubleBuffered()) { + return GL.GL_BACK; + } + return GL.GL_FRONT; + } + + public boolean offscreenImageNeedsVerticalFlip() { + // There doesn't seem to be a way to do this in the construction + // of the Pixmap or GLXPixmap + return true; + } + + protected void create() { + createContext(false); + } +} diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java new file mode 100644 index 000000000..14d07e74f --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OffscreenGLXDrawable.java @@ -0,0 +1,157 @@ +/* + * 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. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package com.jogamp.opengl.impl.x11.glx; + +import javax.media.nativewindow.*; +import javax.media.opengl.*; +import com.jogamp.nativewindow.impl.x11.*; + +public class X11OffscreenGLXDrawable extends X11GLXDrawable { + private long pixmap; + + protected X11OffscreenGLXDrawable(GLDrawableFactory factory, NativeWindow target) { + super(factory, target, true); + create(); + } + + protected void setRealizedImpl() { + if(realized) { + create(); + } else { + destroy(); + } + } + + public GLContext createContext(GLContext shareWith) { + return new X11OffscreenGLXContext(this, shareWith); + } + + private void create() { + NativeWindow nw = getNativeWindow(); + X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration) nw.getGraphicsConfiguration().getNativeGraphicsConfiguration(); + XVisualInfo vis = config.getXVisualInfo(); + int bitsPerPixel = vis.getDepth(); + AbstractGraphicsScreen aScreen = config.getScreen(); + AbstractGraphicsDevice aDevice = aScreen.getDevice(); + long dpy = aDevice.getHandle(); + int screen = aScreen.getIndex(); + + getFactoryImpl().lockToolkit(); + try { + X11Lib.XLockDisplay(dpy); + try{ + + pixmap = X11Lib.XCreatePixmap(dpy, X11Lib.RootWindow(dpy, screen), + component.getWidth(), component.getHeight(), bitsPerPixel); + if (pixmap == 0) { + throw new GLException("XCreatePixmap failed"); + } + long drawable = GLX.glXCreateGLXPixmap(dpy, vis, pixmap); + if (drawable == 0) { + X11Lib.XFreePixmap(dpy, pixmap); + pixmap = 0; + throw new GLException("glXCreateGLXPixmap failed"); + } + ((SurfaceChangeable)nw).setSurfaceHandle(drawable); + if (DEBUG) { + System.err.println("Created pixmap " + toHexString(pixmap) + + ", GLXPixmap " + toHexString(drawable) + + ", display " + toHexString(dpy)); + } + }finally{ + X11Lib.XUnlockDisplay(dpy); + } + } finally { + getFactoryImpl().unlockToolkit(); + } + } + + public void destroy() { + if (pixmap == 0) return; + + NativeWindow nw = getNativeWindow(); + long display = nw.getDisplayHandle(); + + getFactoryImpl().lockToolkit(); + try { + X11Lib.XLockDisplay(display); + try{ + long drawable = nw.getSurfaceHandle(); + if (DEBUG) { + System.err.println("Destroying pixmap " + toHexString(pixmap) + + ", GLXPixmap " + toHexString(drawable) + + ", display " + toHexString(display)); + } + + // Must destroy pixmap and GLXPixmap + + if (DEBUG) { + long cur = GLX.glXGetCurrentContext(); + if (cur != 0) { + System.err.println("WARNING: found context " + toHexString(cur) + " current during pixmap destruction"); + } + } + + // FIXME: workaround for crashes on NVidia hardware when + // destroying pixmap (no context is current at the point of the + // crash, at least from the point of view of + // glXGetCurrentContext) + GLX.glXMakeCurrent(display, 0, 0); + + GLX.glXDestroyGLXPixmap(display, drawable); + X11Lib.XFreePixmap(display, pixmap); + drawable = 0; + pixmap = 0; + ((SurfaceChangeable)nw).setSurfaceHandle(0); + + }finally{ + X11Lib.XUnlockDisplay(display); + } + } finally { + getFactoryImpl().unlockToolkit(); + display = 0; + } + } + protected void swapBuffersImpl() { + if(DEBUG) { + System.err.println("unhandled swapBuffersImpl() called for: "+this); + } + } +} diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OnscreenGLXContext.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OnscreenGLXContext.java new file mode 100644 index 000000000..c89a5efd5 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OnscreenGLXContext.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * 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. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package com.jogamp.opengl.impl.x11.glx; + +import java.util.*; + +import javax.media.nativewindow.*; +import javax.media.opengl.*; +import com.jogamp.opengl.impl.*; +import com.jogamp.opengl.impl.x11.*; + +public class X11OnscreenGLXContext extends X11GLXContext { + // This indicates whether the context we have created is indirect + // and therefore requires the toolkit to be locked around all GL + // calls rather than just all GLX calls + protected boolean isIndirect; + + public X11OnscreenGLXContext(X11OnscreenGLXDrawable drawable, + GLContext shareWith) { + super(drawable, shareWith); + } + + public boolean isOptimizable() { + return super.isOptimizable() && !isIndirect; + } + + protected void create() { + createContext(true); + isIndirect = !GLX.glXIsDirect(drawable.getNativeWindow().getDisplayHandle(), context); + } +} diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OnscreenGLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OnscreenGLXDrawable.java new file mode 100644 index 000000000..43468b858 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11OnscreenGLXDrawable.java @@ -0,0 +1,64 @@ +/* + * 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. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package com.jogamp.opengl.impl.x11.glx; + +import javax.media.nativewindow.*; +import javax.media.opengl.*; +import com.jogamp.opengl.impl.*; +import com.jogamp.opengl.impl.x11.*; + +public class X11OnscreenGLXDrawable extends X11GLXDrawable { + protected X11OnscreenGLXDrawable(GLDrawableFactory factory, NativeWindow component) { + super(factory, component, false); + } + + public GLContext createContext(GLContext shareWith) { + return new X11OnscreenGLXContext(this, shareWith); + } + + public int getWidth() { + return component.getWidth(); + } + + public int getHeight() { + return component.getHeight(); + } + +} diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXContext.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXContext.java new file mode 100644 index 000000000..1b70adf6b --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXContext.java @@ -0,0 +1,73 @@ +/* + * 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. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package com.jogamp.opengl.impl.x11.glx; + +import javax.media.opengl.*; +import com.jogamp.opengl.impl.*; +import com.jogamp.opengl.impl.x11.*; + +public class X11PbufferGLXContext extends X11GLXContext { + private X11PbufferGLXDrawable drawable; + + public X11PbufferGLXContext(X11PbufferGLXDrawable drawable, + GLContext shareWith) { + super(drawable, shareWith); + this.drawable = drawable; + } + + public void bindPbufferToTexture() { + // FIXME: figure out how to implement this + throw new GLException("Not yet implemented"); + } + + public void releasePbufferFromTexture() { + // FIXME: figure out how to implement this + throw new GLException("Not yet implemented"); + } + + + public int getFloatingPointMode() { + return drawable.getFloatingPointMode(); + } + + protected void create() { + createContext(true); + } +} diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXDrawable.java new file mode 100644 index 000000000..50b32b9ec --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11PbufferGLXDrawable.java @@ -0,0 +1,157 @@ +/* + * 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. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package com.jogamp.opengl.impl.x11.glx; + +import javax.media.opengl.*; +import javax.media.nativewindow.*; +import com.jogamp.opengl.impl.*; +import com.jogamp.opengl.impl.x11.glx.*; +import com.jogamp.nativewindow.impl.x11.*; + +public class X11PbufferGLXDrawable extends X11GLXDrawable { + protected X11PbufferGLXDrawable(GLDrawableFactory factory, NativeWindow target) { + /* GLCapabilities caps, + GLCapabilitiesChooser chooser, + int width, int height */ + super(factory, target, true); + + if (DEBUG) { + System.out.println("Pbuffer config: " + getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration()); + } + + createPbuffer(); + + if (DEBUG) { + System.err.println("Created pbuffer " + this); + } + } + + protected void setRealizedImpl() { + if(realized) { + createPbuffer(); + } else { + destroy(); + } + } + + public GLContext createContext(GLContext shareWith) { + return new X11PbufferGLXContext(this, shareWith); + } + + public void destroy() { + getFactoryImpl().lockToolkit(); + try { + NativeWindow nw = getNativeWindow(); + if (nw.getSurfaceHandle() != 0) { + GLX.glXDestroyPbuffer(nw.getDisplayHandle(), nw.getSurfaceHandle()); + } + ((SurfaceChangeable)nw).setSurfaceHandle(0); + } finally { + getFactoryImpl().unlockToolkit(); + } + } + + private void createPbuffer() { + getFactoryImpl().lockToolkit(); + try { + X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration) getNativeWindow().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + AbstractGraphicsScreen aScreen = config.getScreen(); + AbstractGraphicsDevice aDevice = aScreen.getDevice(); + long display = aDevice.getHandle(); + int screen = aScreen.getIndex(); + + if (display==0) { + throw new GLException("Null display"); + } + + NativeWindow nw = getNativeWindow(); + + GLCapabilities capabilities = (GLCapabilities)config.getChosenCapabilities(); + + if (capabilities.getPbufferRenderToTexture()) { + throw new GLException("Render-to-texture pbuffers not supported yet on X11"); + } + + if (capabilities.getPbufferRenderToTextureRectangle()) { + throw new GLException("Render-to-texture-rectangle pbuffers not supported yet on X11"); + } + + // Create the p-buffer. + int niattribs = 0; + int[] iattributes = new int[5]; + + iattributes[niattribs++] = GLX.GLX_PBUFFER_WIDTH; + iattributes[niattribs++] = nw.getWidth(); + iattributes[niattribs++] = GLX.GLX_PBUFFER_HEIGHT; + iattributes[niattribs++] = nw.getHeight(); + iattributes[niattribs++] = 0; + + long pbuffer = GLX.glXCreatePbuffer(display, config.getFBConfig(), iattributes, 0); + if (pbuffer == 0) { + // FIXME: query X error code for detail error message + throw new GLException("pbuffer creation error: glXCreatePbuffer() failed"); + } + + // Set up instance variables + ((SurfaceChangeable)nw).setSurfaceHandle(pbuffer); + + // Determine the actual width and height we were able to create. + int[] tmp = new int[1]; + GLX.glXQueryDrawable(display, pbuffer, GLX.GLX_WIDTH, tmp, 0); + int width = tmp[0]; + GLX.glXQueryDrawable(display, pbuffer, GLX.GLX_HEIGHT, tmp, 0); + int height = tmp[0]; + ((SurfaceChangeable)nw).setSize(width, height); + } finally { + getFactoryImpl().unlockToolkit(); + } + } + + public int getFloatingPointMode() { + // Floating-point pbuffers currently require NVidia hardware on X11 + return GLPbuffer.NV_FLOAT; + } + + protected void swapBuffersImpl() { + if(DEBUG) { + System.err.println("unhandled swapBuffersImpl() called for: "+this); + } + } +} diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java new file mode 100644 index 000000000..dc6c60664 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java @@ -0,0 +1,150 @@ +/* + * 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.jogamp.opengl.impl.x11.glx.awt; + +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import javax.media.nativewindow.*; +import javax.media.nativewindow.x11.*; +import javax.media.nativewindow.awt.*; +import javax.media.opengl.*; +import javax.media.opengl.awt.*; + +import com.jogamp.opengl.impl.*; +import com.jogamp.nativewindow.impl.jawt.*; +import com.jogamp.nativewindow.impl.jawt.x11.*; +import com.jogamp.nativewindow.impl.x11.*; +import com.jogamp.opengl.impl.x11.*; +import com.jogamp.opengl.impl.x11.glx.*; + +public class X11AWTGLXGraphicsConfigurationFactory extends GraphicsConfigurationFactory { + protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration"); + + public X11AWTGLXGraphicsConfigurationFactory() { + GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.awt.AWTGraphicsDevice.class, this); + } + + public AbstractGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities, + CapabilitiesChooser chooser, + AbstractGraphicsScreen absScreen) { + GraphicsDevice device = null; + if (absScreen != null && + !(absScreen instanceof AWTGraphicsScreen)) { + throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only AWTGraphicsScreen objects"); + } + + if(null==absScreen) { + absScreen = AWTGraphicsScreen.createScreenDevice(-1); + } + AWTGraphicsScreen awtScreen = (AWTGraphicsScreen) absScreen; + device = ((AWTGraphicsDevice)awtScreen.getDevice()).getGraphicsDevice(); + + if (capabilities != null && + !(capabilities instanceof GLCapabilities)) { + throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only GLCapabilities objects"); + } + + if (chooser != null && + !(chooser instanceof GLCapabilitiesChooser)) { + throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only GLCapabilitiesChooser objects"); + } + + if(DEBUG) { + System.err.println("X11AWTGLXGraphicsConfigurationFactory: got "+absScreen); + } + + GraphicsConfiguration gc; + X11GraphicsConfiguration x11Config; + + // Need the lock here, since it could be an AWT owned display connection + NativeWindowFactory.getDefaultFactory().getToolkitLock().lock(); + try { + long displayHandle = X11SunJDKReflection.graphicsDeviceGetDisplay(device); + if(0==displayHandle) { + displayHandle = X11Util.createThreadLocalDefaultDisplay(); + if(DEBUG) { + System.err.println("X11AWTGLXGraphicsConfigurationFactory: using a thread local X11 display"); + } + } else { + if(DEBUG) { + System.err.println("X11AWTGLXGraphicsConfigurationFactory: using AWT X11 display 0x"+Long.toHexString(displayHandle)); + } + } + ((AWTGraphicsDevice)awtScreen.getDevice()).setHandle(displayHandle); + X11GraphicsDevice x11Device = new X11GraphicsDevice(displayHandle); + + X11GraphicsScreen x11Screen = new X11GraphicsScreen(x11Device, awtScreen.getIndex()); + if(DEBUG) { + System.err.println("X11AWTGLXGraphicsConfigurationFactory: made "+x11Screen); + } + + gc = device.getDefaultConfiguration(); + AWTGraphicsConfiguration.setupCapabilitiesRGBABits(capabilities, gc); + if(DEBUG) { + System.err.println("AWT Colormodel compatible: "+capabilities); + } + + x11Config = (X11GraphicsConfiguration) + GraphicsConfigurationFactory.getFactory(x11Device).chooseGraphicsConfiguration(capabilities, + chooser, + x11Screen); + if (x11Config == null) { + throw new GLException("Unable to choose a GraphicsConfiguration: "+capabilities+",\n\t"+chooser+"\n\t"+x11Screen); + } + + long visualID = x11Config.getVisualID(); + // 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(awtScreen, x11Config.getChosenCapabilities(), x11Config.getRequestedCapabilities(), + config, x11Config); + } + } + } + } finally { + NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock(); + } + // Either we weren't able to reflectively introspect on the + // X11GraphicsConfig or something went wrong in the steps above; + // Let's take the default configuration as used on Windows and MacOSX then .. + if(DEBUG) { + System.err.println("!!! Using default configuration"); + } + return new AWTGraphicsConfiguration(awtScreen, x11Config.getChosenCapabilities(), x11Config.getRequestedCapabilities(), gc, x11Config); + } +} |