diff options
Diffstat (limited to 'src/jogl/classes/jogamp/opengl/x11/glx')
18 files changed, 3409 insertions, 0 deletions
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/GLXUtil.java b/src/jogl/classes/jogamp/opengl/x11/glx/GLXUtil.java new file mode 100644 index 000000000..46bc9460d --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/x11/glx/GLXUtil.java @@ -0,0 +1,102 @@ +/* + * 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.*; + + +public class GLXUtil { + public static String getExtension(long display) { + return GLX.glXGetClientString(display, GLX.GLX_EXTENSIONS); + } + + public static boolean isMultisampleAvailable(String extensions) { + if (extensions != null) { + return (extensions.indexOf("GLX_ARB_multisample") >= 0); + } + return false; + } + + public static boolean isMultisampleAvailable(long display) { + return isMultisampleAvailable(getExtension(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) { + return GLX.glXGetClientString(display, GLX.GLX_VENDOR); + } + + 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/jogamp/opengl/x11/glx/X11DummyGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11DummyGLXDrawable.java new file mode 100644 index 000000000..1f2bf9344 --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11DummyGLXDrawable.java @@ -0,0 +1,90 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions 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. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.impl.x11.glx; + +import javax.media.opengl.*; + +import javax.media.nativewindow.x11.*; +import com.jogamp.nativewindow.impl.*; +import com.jogamp.nativewindow.impl.x11.*; + +public class X11DummyGLXDrawable extends X11OnscreenGLXDrawable { + private static final int f_dim = 64; + 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, GLCapabilitiesImmutable caps) { + super(factory, + new ProxySurface(X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic( + caps, caps, null, screen))); + this.realized = true; + + ProxySurface ns = (ProxySurface) getNativeSurface(); + X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)ns.getGraphicsConfiguration().getNativeGraphicsConfiguration(); + + X11GraphicsDevice device = (X11GraphicsDevice) screen.getDevice(); + long dpy = device.getHandle(); + int scrn = screen.getIndex(); + long visualID = config.getVisualID(); + + dummyWindow = X11Util.CreateDummyWindow(dpy, scrn, visualID, f_dim, f_dim); + ns.setSurfaceHandle( dummyWindow ); + ns.setSize(f_dim, f_dim); + + updateHandle(); + } + + public static X11DummyGLXDrawable create(X11GraphicsScreen screen, GLDrawableFactory factory, GLProfile glp) { + GLCapabilities caps = new GLCapabilities(glp); + return new X11DummyGLXDrawable(screen, factory, caps); + } + + public void setSize(int width, int height) { + } + + public int getWidth() { + return 1; + } + + public int getHeight() { + return 1; + } + + protected void destroyImpl() { + if(0!=dummyWindow) { + destroyHandle(); + X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + X11Util.DestroyDummyWindow(config.getScreen().getDevice().getHandle(), dummyWindow); + } + } +} diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java new file mode 100644 index 000000000..76f7f6591 --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. 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.ProxySurface; + +public class X11ExternalGLXContext extends X11GLXContext { + private boolean firstMakeCurrent = true; + private GLContext lastContext; + + private X11ExternalGLXContext(Drawable drawable, long ctx) { + super(drawable, null); + this.contextHandle = ctx; + 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) { + long ctx = GLX.glXGetCurrentContext(); + if (ctx == 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, ctx, GLX.GLX_SCREEN, val, 0); + X11GraphicsScreen x11Screen = (X11GraphicsScreen) X11GraphicsScreen.createScreenDevice(display, val[0]); + + GLX.glXQueryContext(display, ctx, GLX.GLX_FBCONFIG_ID, val, 0); + X11GLXGraphicsConfiguration cfg = X11GLXGraphicsConfiguration.create(glp, x11Screen, val[0]); + + ProxySurface ns = new ProxySurface(cfg); + ns.setSurfaceHandle(drawable); + return new X11ExternalGLXContext(new Drawable(factory, ns), ctx); + } + + protected boolean createImpl() { + return true; + } + + 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 void makeCurrentImpl(boolean newCreated) throws GLException { + if (firstMakeCurrent) { + firstMakeCurrent = false; + } + } + + protected void releaseImpl() throws GLException { + } + + protected void destroyImpl() throws GLException { + } + + // Need to provide the display connection to extension querying APIs + static class Drawable extends X11GLXDrawable { + Drawable(GLDrawableFactory factory, NativeSurface 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/jogamp/opengl/x11/glx/X11ExternalGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXDrawable.java new file mode 100644 index 000000000..f0270fd2a --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXDrawable.java @@ -0,0 +1,105 @@ +/* + * 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.nativewindow.impl.ProxySurface; + + +public class X11ExternalGLXDrawable extends X11GLXDrawable { + + private X11ExternalGLXDrawable(GLDrawableFactory factory, NativeSurface surface) { + super(factory, surface, true); + } + + protected static X11ExternalGLXDrawable create(GLDrawableFactory factory, GLProfile glp) { + 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])+")"); + } + } + ProxySurface ns = new ProxySurface(cfg); + ns.setSurfaceHandle(drawable); + ns.setSize(w, h); + return new X11ExternalGLXDrawable(factory, ns); + } + + public GLContext createContext(GLContext shareWith) { + return new Context(this, shareWith); + } + + public void setSize(int newWidth, int newHeight) { + throw new GLException("Should not call this"); + } + + class Context extends X11GLXContext { + Context(X11GLXDrawable drawable, GLContext shareWith) { + super(drawable, shareWith); + } + } +} diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLCapabilities.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLCapabilities.java new file mode 100644 index 000000000..3f9d2baae --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLCapabilities.java @@ -0,0 +1,124 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions 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. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.impl.x11.glx; + +import com.jogamp.nativewindow.impl.x11.XVisualInfo; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLException; +import javax.media.opengl.GLProfile; +import java.util.Comparator; + +public class X11GLCapabilities extends GLCapabilities { + XVisualInfo xVisualInfo; // maybe null if !onscreen + long fbcfg; + int fbcfgid; + + /** Comparing xvisual id only */ + public static class XVisualIDComparator implements Comparator { + + public int compare(Object o1, Object o2) { + if ( ! ( o1 instanceof X11GLCapabilities ) ) { + Class c = (null != o1) ? o1.getClass() : null ; + throw new ClassCastException("arg1 not a X11GLCapabilities object: " + c); + } + if ( ! ( o2 instanceof X11GLCapabilities ) ) { + Class c = (null != o2) ? o2.getClass() : null ; + throw new ClassCastException("arg2 not a X11GLCapabilities object: " + c); + } + + final X11GLCapabilities caps1 = (X11GLCapabilities) o1; + final long id1 = caps1.getXVisualID(); + + final X11GLCapabilities caps2 = (X11GLCapabilities) o2; + final long id2 = caps2.getXVisualID(); + + if(id1 > id2) { + return 1; + } else if(id1 < id2) { + return -1; + } + return 0; + } + } + + public X11GLCapabilities(XVisualInfo xVisualInfo, long fbcfg, int fbcfgid, GLProfile glp) { + super(glp); + this.xVisualInfo = xVisualInfo; + this.fbcfg = fbcfg; + this.fbcfgid = fbcfgid; + } + + public X11GLCapabilities(XVisualInfo xVisualInfo, GLProfile glp) { + super(glp); + this.xVisualInfo = xVisualInfo; + this.fbcfg = 0; + this.fbcfgid = -1; + } + + public Object cloneMutable() { + return clone(); + } + + public Object clone() { + try { + return super.clone(); + } catch (RuntimeException e) { + throw new GLException(e); + } + } + + final public XVisualInfo getXVisualInfo() { return xVisualInfo; } + final public long getXVisualID() { return (null!=xVisualInfo) ? xVisualInfo.getVisualid() : 0; } + final public boolean hasXVisualInfo() { return null!=xVisualInfo; } + + final public long getFBConfig() { return fbcfg; } + final public int getFBConfigID() { return fbcfgid; } + final public boolean hasFBConfig() { return 0!=fbcfg && fbcfgid>0; } + + final static String na_str = "----" ; + + public StringBuffer toString(StringBuffer sink) { + if(null == sink) { + sink = new StringBuffer(); + } + if(hasXVisualInfo()) { + sink.append("0x").append(Long.toHexString(xVisualInfo.getVisualid())); + } else { + sink.append(na_str); + } + sink.append(" "); + if(hasFBConfig()) { + sink.append("0x").append(Integer.toHexString(fbcfgid)); + } else { + sink.append(na_str); + } + sink.append(": "); + return super.toString(sink); + } +}
\ No newline at end of file diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java new file mode 100644 index 000000000..dd25f241e --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java @@ -0,0 +1,587 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. 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.X11GraphicsDevice; + +import com.jogamp.common.util.VersionNumber; +import com.jogamp.opengl.impl.*; +import com.jogamp.gluegen.runtime.ProcAddressTable; +import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver; +import com.jogamp.nativewindow.impl.x11.X11Util; + +public abstract class X11GLXContext extends GLContextImpl { + protected static final boolean TRACE_CONTEXT_CURRENT = false; // true; + + private static final Map/*<String, String>*/ functionNameMap; + private static final Map/*<String, String>*/ extensionNameMap; + private VersionNumber glXVersion; + private boolean glXVersionOneThreeCapable; + private boolean glXQueryExtensionsStringInitialized; + private boolean glXQueryExtensionsStringAvailable; + private GLXExt glXExt; + // Table that holds the addresses of the native C-language entry points for + // GLX extension functions. + private GLXExtProcAddressTable glXExtProcAddressTable; + private int hasSwapIntervalSGI = 0; + + // 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 isDirect; + + 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 + } + + X11GLXContext(GLDrawableImpl drawable, + GLContext shareWith) { + super(drawable, shareWith); + } + + protected void resetState() { + glXVersion = null; + glXVersionOneThreeCapable = false; + glXQueryExtensionsStringInitialized=false; + glXQueryExtensionsStringAvailable=false; + // no inner state glXExt=null; + glXExtProcAddressTable = null; + hasSwapIntervalSGI = 0; + isDirect = false; + } + + 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; } + + public final boolean isGLXVersionGreaterEqualOneThree() { + if(null == glXVersion) { + X11GLXDrawableFactory factory = (X11GLXDrawableFactory)drawable.getFactoryImpl(); + + X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + X11GraphicsDevice device = (X11GraphicsDevice) config.getScreen().getDevice(); + + glXVersion = factory.getGLXVersion(device); + glXVersionOneThreeCapable = ( null != glXVersion ) ? glXVersion.compareTo(X11GLXDrawableFactory.versionOneThree) >= 0 : false ; + } + return glXVersionOneThreeCapable; + } + + public final boolean isGLReadDrawableAvailable() { + return isGLXVersionGreaterEqualOneThree(); + } + + private final boolean glXMakeContextCurrent(long dpy, long writeDrawable, long readDrawable, long ctx) { + boolean res = false; + + try { + if(TRACE_CONTEXT_CURRENT) { + Throwable t = new Throwable(Thread.currentThread()+" - glXMakeContextCurrent("+toHexString(dpy)+", "+ + toHexString(writeDrawable)+", "+toHexString(readDrawable)+", "+toHexString(ctx)+") - GLX >= 1.3 "+ glXVersionOneThreeCapable); + t.printStackTrace(); + } + if ( glXVersionOneThreeCapable ) { + res = GLX.glXMakeContextCurrent(dpy, writeDrawable, readDrawable, ctx); + } else if ( writeDrawable == readDrawable ) { + res = GLX.glXMakeCurrent(dpy, writeDrawable, ctx); + } else { + // should not happen due to 'isGLReadDrawableAvailable()' query in GLContextImpl + throw new InternalError("Given readDrawable but no driver support"); + } + } catch (RuntimeException re) { + if(DEBUG) { + System.err.println("Warning: 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 ctx) { + X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + long display = config.getScreen().getDevice().getHandle(); + + glXMakeContextCurrent(display, 0, 0, 0); + GLX.glXDestroyContext(display, ctx); + } + + protected long createContextARBImpl(long share, boolean direct, int ctp, int major, int minor) { + updateGLXProcAddressTable(); + GLXExt _glXExt = getGLXExt(); + if(DEBUG) { + System.err.println("X11GLXContext.createContextARBImpl: "+getGLVersion(major, minor, ctp, "@creation") + + ", handle "+toHexString(drawable.getHandle()) + ", share "+toHexString(share)+", direct "+direct+ + ", glXCreateContextAttribsARB: "+toHexString(glXExtProcAddressTable._addressof_glXCreateContextAttribsARB)); + Thread.dumpStack(); + } + + boolean ctBwdCompat = 0 != ( CTX_PROFILE_COMPAT & ctp ) ; + boolean ctFwdCompat = 0 != ( CTX_OPTION_FORWARD & ctp ) ; + boolean ctDebug = 0 != ( CTX_OPTION_DEBUG & ctp ) ; + + long ctx=0; + + final int idx_flags = 6; + final int idx_profile = 8; + + 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[idx_profile+0] = GLX.GLX_CONTEXT_PROFILE_MASK_ARB; + if( ctBwdCompat ) { + attribs[idx_profile+1] = GLX.GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; + } else { + attribs[idx_profile+1] = GLX.GLX_CONTEXT_CORE_PROFILE_BIT_ARB; + } + } + + if ( major >= 3 ) { + if( !ctBwdCompat && ctFwdCompat ) { + attribs[idx_flags+1] |= GLX.GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; + } + if( ctDebug) { + attribs[idx_flags+1] |= GLX.GLX_CONTEXT_DEBUG_BIT_ARB; + } + } + + X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + AbstractGraphicsDevice device = config.getScreen().getDevice(); + long display = device.getHandle(); + + try { + // critical path, a remote display might not support this command, + // hence we need to catch the X11 Error within this block. + X11Util.XSync(display, false); + ctx = _glXExt.glXCreateContextAttribsARB(display, config.getFBConfig(), share, direct, attribs, 0); + X11Util.XSync(display, false); + } catch (RuntimeException re) { + if(DEBUG) { + Throwable t = new Throwable("Info: X11GLXContext.createContextARBImpl glXCreateContextAttribsARB failed with "+getGLVersion(major, minor, ctp, "@creation"), re); + t.printStackTrace(); + } + } + if(0!=ctx) { + if (!glXMakeContextCurrent(display, drawable.getHandle(), drawableRead.getHandle(), ctx)) { + if(DEBUG) { + System.err.println("X11GLXContext.createContextARBImpl couldn't make current "+getGLVersion(major, minor, ctp, "@creation")); + } + // release & destroy + glXMakeContextCurrent(display, 0, 0, 0); + GLX.glXDestroyContext(display, ctx); + ctx = 0; + } else { + if (DEBUG) { + System.err.println(getThreadName() + ": createContextARBImpl: OK "+getGLVersion(major, minor, ctp, "@creation")+", share "+share+", direct "+direct); + } + // the following is issued by the caller 'GLContextImpl.createContextARB()' + // setGLFunctionAvailability(true, major, minor, ctp); + } + } else if (DEBUG) { + System.err.println(getThreadName() + ": createContextARBImpl: NO "+getGLVersion(major, minor, ctp, "@creation")); + } + + return ctx; + } + + protected boolean createImpl() { + // covers the whole context creation loop incl createContextARBImpl and destroyContextARBImpl + X11Util.setX11ErrorHandler(true, true); + try { + return createImplRaw(); + } finally { + X11Util.setX11ErrorHandler(false, false); + } + } + + private boolean createImplRaw() { + boolean direct = true; // try direct always + isDirect = false; // fall back + + X11GLXDrawableFactory factory = (X11GLXDrawableFactory)drawable.getFactoryImpl(); + X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + AbstractGraphicsDevice device = config.getScreen().getDevice(); + X11GLXContext sharedContext = (X11GLXContext) factory.getOrCreateSharedContextImpl(device); + long display = device.getHandle(); + + isGLReadDrawableAvailable(); // trigger setup glXVersionOneThreeCapable + + X11GLXContext other = (X11GLXContext) GLContextShareSet.getShareContext(this); + long share = 0; + if (other != null) { + share = other.getHandle(); + if (share == 0) { + throw new GLException("GLContextShareSet returned an invalid OpenGL context"); + } + direct = GLX.glXIsDirect(display, share); + } + + GLCapabilitiesImmutable glCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities(); + GLProfile glp = glCaps.getGLProfile(); + isVendorATI = factory.isGLXVendorATI(device); + + if(config.getFBConfigID()<0) { + // not able to use FBConfig + if(glp.isGL3()) { + throw new GLException("Unable to create OpenGL >= 3.1 context"); + } + contextHandle = GLX.glXCreateContext(display, config.getXVisualInfo(), share, direct); + if (contextHandle == 0) { + throw new GLException("Unable to create context(0)"); + } + if (!glXMakeContextCurrent(display, drawable.getHandle(), drawableRead.getHandle(), contextHandle)) { + throw new GLException("Error making temp context(0) current: display "+toHexString(display)+", context "+toHexString(contextHandle)+", drawable "+drawable); + } + setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); // use GL_VERSION + isDirect = GLX.glXIsDirect(display, contextHandle); + if (DEBUG) { + System.err.println(getThreadName() + ": createContextImpl: OK (old-1) share "+share+", direct "+isDirect+"/"+direct); + } + return true; + } + + 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!=sharedContext && sharedContext.isCreatedWithARBMethod()) { + contextHandle = createContextARB(share, direct, major, minor, ctp); + createContextARBTried = true; + if (DEBUG && 0!=contextHandle) { + System.err.println(getThreadName() + ": createContextImpl: OK (ARB, using sharedContext) share "+share); + } + } + + long temp_ctx = 0; + if(0==contextHandle) { + // To use GLX_ARB_create_context, we have to make a temp context current, + // so we are able to use GetProcAddress + temp_ctx = GLX.glXCreateNewContext(display, config.getFBConfig(), GLX.GLX_RGBA_TYPE, share, direct); + if (temp_ctx == 0) { + throw new GLException("Unable to create temp OpenGL context(1)"); + } + if (!glXMakeContextCurrent(display, drawable.getHandle(), drawableRead.getHandle(), temp_ctx)) { + throw new GLException("Error making temp context(1) current: display "+toHexString(display)+", context "+toHexString(temp_ctx)+", drawable "+drawable); + } + setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); // use GL_VERSION + boolean isCreateContextAttribsARBAvailable = isFunctionAvailable("glXCreateContextAttribsARB"); + glXMakeContextCurrent(display, 0, 0, 0); // release temp context + + if( !createContextARBTried ) { + if ( isCreateContextAttribsARBAvailable && + isExtensionAvailable("GLX_ARB_create_context") ) { + // initial ARB context creation + contextHandle = createContextARB(share, direct, major, minor, ctp); + createContextARBTried=true; + if (DEBUG) { + if(0!=contextHandle) { + System.err.println(getThreadName() + ": createContextImpl: OK (ARB, initial) share "+share); + } else { + System.err.println(getThreadName() + ": createContextImpl: NOT OK (ARB, initial) - creation failed - share "+share); + } + } + } else if (DEBUG) { + System.err.println(getThreadName() + ": createContextImpl: NOT OK (ARB, initial) - extension not available - share "+share); + } + } + } + + if(0!=contextHandle) { + if(0!=temp_ctx) { + glXMakeContextCurrent(display, 0, 0, 0); + GLX.glXDestroyContext(display, temp_ctx); + if (!glXMakeContextCurrent(display, drawable.getHandle(), drawableRead.getHandle(), contextHandle)) { + throw new GLException("Cannot make previous verified context current"); + } + } + } else { + if(glp.isGL3()) { + glXMakeContextCurrent(display, 0, 0, 0); + GLX.glXDestroyContext(display, temp_ctx); + throw new GLException("X11GLXContext.createContextImpl failed, but context > GL2 requested "+getGLVersion(major[0], minor[0], ctp[0], "@creation")+", "); + } + if(DEBUG) { + System.err.println("X11GLXContext.createContextImpl failed, fall back to !ARB context "+getGLVersion(major[0], minor[0], ctp[0], "@creation")); + } + + // continue with temp context for GL <= 3.0 + contextHandle = temp_ctx; + if (!glXMakeContextCurrent(display, drawable.getHandle(), drawableRead.getHandle(), contextHandle)) { + glXMakeContextCurrent(display, 0, 0, 0); + GLX.glXDestroyContext(display, temp_ctx); + throw new GLException("Error making context(1) current: display "+toHexString(display)+", context "+toHexString(contextHandle)+", drawable "+drawable); + } + if (DEBUG) { + System.err.println(getThreadName() + ": createContextImpl: OK (old-2) share "+share); + } + } + isDirect = GLX.glXIsDirect(display, contextHandle); + if (DEBUG) { + System.err.println(getThreadName() + ": createContextImpl: OK direct "+isDirect+"/"+direct); + } + return true; + } + + protected void makeCurrentImpl(boolean newCreated) throws GLException { + long dpy = drawable.getNativeSurface().getDisplayHandle(); + + if (GLX.glXGetCurrentContext() != contextHandle) { + X11Util.setX11ErrorHandler(true, true); + try { + if (!glXMakeContextCurrent(dpy, drawable.getHandle(), drawableRead.getHandle(), contextHandle)) { + throw new GLException("Error making context current: "+this); + } + } finally { + X11Util.setX11ErrorHandler(false, false); + } + if (DEBUG && newCreated) { + System.err.println(getThreadName() + ": glXMakeCurrent(display " + + toHexString(dpy)+ + ", drawable " + toHexString(drawable.getHandle()) + + ", drawableRead " + toHexString(drawableRead.getHandle()) + + ", context " + toHexString(contextHandle) + ") succeeded"); + } + } + } + + protected void releaseImpl() throws GLException { + long display = drawable.getNativeSurface().getDisplayHandle(); + X11Util.setX11ErrorHandler(true, true); + try { + if (!glXMakeContextCurrent(display, 0, 0, 0)) { + throw new GLException("Error freeing OpenGL context"); + } + } finally { + X11Util.setX11ErrorHandler(false, false); + } + } + + protected void destroyImpl() throws GLException { + long display = drawable.getNativeSurface().getDisplayHandle(); + if (DEBUG) { + System.err.println("glXDestroyContext(dpy " + + toHexString(display)+ + ", ctx " + + toHexString(contextHandle) + ")"); + } + GLX.glXDestroyContext(display, contextHandle); + if (DEBUG) { + System.err.println("!!! Destroyed OpenGL context " + contextHandle); + } + } + + protected void copyImpl(GLContext source, int mask) throws GLException { + long dst = getHandle(); + long src = source.getHandle(); + long display = drawable.getNativeSurface().getDisplayHandle(); + if (0 == display) { + throw new GLException("Connection to X display not yet set up"); + } + GLX.glXCopyContext(display, src, dst, mask); + // Should check for X errors and raise GLException + } + + protected final void updateGLXProcAddressTable() { + AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice(); + String key = adevice.getUniqueID(); + if (DEBUG) { + System.err.println(getThreadName() + ": !!! Initializing GLX extension address table: "+key); + } + glXQueryExtensionsStringInitialized = false; + glXQueryExtensionsStringAvailable = false; + + GLXExtProcAddressTable table = null; + synchronized(mappedContextTypeObjectLock) { + table = (GLXExtProcAddressTable) mappedGLXProcAddress.get( key ); + } + if(null != table) { + glXExtProcAddressTable = table; + if(DEBUG) { + System.err.println(getThreadName() + ": !!! GLContext GLX ProcAddressTable reusing key("+key+") -> "+table.hashCode()); + } + } else { + if (glXExtProcAddressTable == null) { + glXExtProcAddressTable = new GLXExtProcAddressTable(new GLProcAddressResolver()); + } + resetProcAddressTable(getGLXExtProcAddressTable()); + synchronized(mappedContextTypeObjectLock) { + mappedGLXProcAddress.put(key, getGLXExtProcAddressTable()); + if(DEBUG) { + System.err.println(getThreadName() + ": !!! GLContext GLX ProcAddressTable mapping key("+key+") -> "+getGLXExtProcAddressTable().hashCode()); + Thread.dumpStack(); + } + } + } + } + + public synchronized String getPlatformExtensionsString() { + if (!glXQueryExtensionsStringInitialized) { + glXQueryExtensionsStringAvailable = + getDrawableImpl().getGLDynamicLookupHelper().dynamicLookupFunction("glXQueryExtensionsString") != 0; + glXQueryExtensionsStringInitialized = true; + } + if (glXQueryExtensionsStringAvailable) { + NativeSurface ns = drawable.getNativeSurface(); + String ret = GLX.glXQueryExtensionsString(ns.getDisplayHandle(), ns.getScreenIndex()); + if (DEBUG) { + System.err.println("!!! GLX extensions: " + ret); + } + return ret; + } else { + return ""; + } + } + + public boolean isExtensionAvailable(String glExtensionName) { + if (glExtensionName.equals("GL_ARB_pbuffer") || + glExtensionName.equals("GL_ARB_pixel_format")) { + return getGLDrawable().getFactory().canCreateGLPbuffer( + drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice() ); + } + return super.isExtensionAvailable(glExtensionName); + } + + protected void setSwapIntervalImpl(int interval) { + X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + GLCapabilitiesImmutable glCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities(); + if(!glCaps.isOnscreen()) return; + + 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; } + } + } + + 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 String toString() { + StringBuffer sb = new StringBuffer(); + sb.append(getClass().getName()); + sb.append(" ["); + super.append(sb); + sb.append(", direct "); + sb.append(isDirect); + sb.append("] "); + return sb.toString(); + } + + //---------------------------------------------------------------------- + // Internals only below this point + // + + private boolean isVendorATI = false; + +} diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawable.java new file mode 100644 index 000000000..9c3737d3d --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawable.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. 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.*; + +public abstract class X11GLXDrawable extends GLDrawableImpl { + protected X11GLXDrawable(GLDrawableFactory factory, NativeSurface comp, boolean realized) { + super(factory, comp, realized); + } + + public GLDynamicLookupHelper getGLDynamicLookupHelper() { + return getFactoryImpl().getGLDynamicLookupHelper(0); + } + + protected void setRealizedImpl() { + if(realized) { + X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + config.updateGraphicsConfiguration(); + + if (DEBUG) { + System.err.println("!!! X11GLXDrawable.setRealized(true): "+config); + } + } + } + + protected void swapBuffersImpl() { + GLX.glXSwapBuffers(getNativeSurface().getDisplayHandle(), getHandle()); + } + + //--------------------------------------------------------------------------- + // Internals only below this point + // +} diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java new file mode 100644 index 000000000..709e2ddab --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java @@ -0,0 +1,542 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. 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 java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.nio.*; + +import javax.media.nativewindow.*; +import javax.media.nativewindow.x11.*; +import javax.media.opengl.*; + +import com.jogamp.opengl.impl.*; +import com.jogamp.common.JogampRuntimeException; +import com.jogamp.common.util.*; +import com.jogamp.nativewindow.impl.ProxySurface; +import com.jogamp.nativewindow.impl.x11.*; + +public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { + + private static final DesktopGLDynamicLookupHelper x11GLXDynamicLookupHelper; + static final VersionNumber versionOneThree = new VersionNumber(1, 3, 0); + + static { + DesktopGLDynamicLookupHelper tmp = null; + try { + tmp = new DesktopGLDynamicLookupHelper(new X11GLXDynamicLibraryBundleInfo()); + } catch (GLException gle) { + if(DEBUG) { + gle.printStackTrace(); + } + } + x11GLXDynamicLookupHelper = tmp; + if(null!=x11GLXDynamicLookupHelper) { + GLX.getGLXProcAddressTable().reset(x11GLXDynamicLookupHelper); + } + } + + public static VersionNumber getGLXVersion(X11GraphicsDevice device) { + int[] major = new int[1]; + int[] minor = new int[1]; + GLXUtil.getGLXVersion(device.getHandle(), major, minor); + return new VersionNumber(major[0], minor[0], 0); + } + + public GLDynamicLookupHelper getGLDynamicLookupHelper(int profile) { + return x11GLXDynamicLookupHelper; + } + + public X11GLXDrawableFactory() { + super(); + // Register our GraphicsConfigurationFactory implementations + // The act of constructing them causes them to be registered + new X11GLXGraphicsConfigurationFactory(); + if(GLProfile.isAWTAvailable()) { + try { + ReflectionUtil.createInstance("com.jogamp.opengl.impl.x11.glx.awt.X11AWTGLXGraphicsConfigurationFactory", + null, getClass().getClassLoader()); + } catch (JogampRuntimeException jre) { /* n/a .. */ } + } + + defaultDevice = new X11GraphicsDevice(X11Util.getNullDisplayName(), AbstractGraphicsDevice.DEFAULT_UNIT); + + // Init shared resources off thread + // Will be released via ShutdownHook + sharedResourceImpl = new SharedResourceImplementation(); + sharedResourceRunner = new SharedResourceRunner(sharedResourceImpl); + sharedResourceThread = new Thread(sharedResourceRunner, Thread.currentThread().getName()+"-SharedResourceRunner"); + sharedResourceThread.setDaemon(true); // Allow JVM to exit, even if this one is running + sharedResourceThread.start(); + } + + X11GraphicsDevice defaultDevice; + SharedResourceImplementation sharedResourceImpl; + SharedResourceRunner sharedResourceRunner; + Thread sharedResourceThread; + HashMap/*<connection, SharedResource>*/ sharedMap = new HashMap(); + + static class SharedResource implements SharedResourceRunner.Resource { + X11GraphicsDevice device; + X11GraphicsScreen screen; + X11DummyGLXDrawable drawable; + X11GLXContext context; + String glXVendorName; + boolean isGLXVendorATI; + boolean isGLXVendorNVIDIA; + VersionNumber glXVersion; + + SharedResource(X11GraphicsDevice dev, X11GraphicsScreen scrn, + X11DummyGLXDrawable draw, X11GLXContext ctx, + VersionNumber glXVer, String glXVendor) { + device = dev; + screen = scrn; + drawable = draw; + context = ctx; + glXVersion = glXVer; + glXVendorName = glXVendor; + isGLXVendorATI = GLXUtil.isVendorATI(glXVendorName); + isGLXVendorNVIDIA = GLXUtil.isVendorNVIDIA(glXVendorName); + } + final public AbstractGraphicsDevice getDevice() { return device; } + final public AbstractGraphicsScreen getScreen() { return screen; } + final public GLDrawableImpl getDrawable() { return drawable; } + final public GLContextImpl getContext() { return context; } + + final String getGLXVendorName() { return glXVendorName; } + final boolean isGLXVendorATI() { return isGLXVendorATI; } + final boolean isGLXVendorNVIDIA() { return isGLXVendorNVIDIA; } + final VersionNumber getGLXVersion() { return glXVersion; } + final boolean isGLXVersionGreaterEqualOneThree() { + return ( null != glXVersion ) ? glXVersion.compareTo(versionOneThree) >= 0 : false ; + } + } + + class SharedResourceImplementation implements SharedResourceRunner.Implementation { + public void clear() { + synchronized(sharedMap) { + sharedMap.clear(); + } + } + public SharedResourceRunner.Resource mapPut(String connection, SharedResourceRunner.Resource resource) { + synchronized(sharedMap) { + return (SharedResourceRunner.Resource) sharedMap.put(connection, resource); + } + } + public SharedResourceRunner.Resource mapGet(String connection) { + synchronized(sharedMap) { + return (SharedResourceRunner.Resource) sharedMap.get(connection); + } + } + public Collection/*<Resource>*/ mapValues() { + synchronized(sharedMap) { + return sharedMap.values(); + } + } + + public SharedResourceRunner.Resource createSharedResource(String connection) { + X11GraphicsDevice sharedDevice = new X11GraphicsDevice(X11Util.createDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT); + sharedDevice.setCloseDisplay(true); + sharedDevice.lock(); + try { + String glXVendorName = GLXUtil.getVendorName(sharedDevice.getHandle()); + X11GraphicsScreen sharedScreen = new X11GraphicsScreen(sharedDevice, 0); + if (null == sharedScreen) { + throw new GLException("Couldn't create shared screen for device: "+sharedDevice+", idx 0"); + } + GLProfile glp = GLProfile.getMinDesktop(sharedDevice); + if (null == glp) { + throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice); + } + X11DummyGLXDrawable sharedDrawable = X11DummyGLXDrawable.create(sharedScreen, X11GLXDrawableFactory.this, glp); + if (null == sharedDrawable) { + throw new GLException("Couldn't create shared drawable for screen: "+sharedScreen+", "+glp); + } + X11GLXContext sharedContext = (X11GLXContext) sharedDrawable.createContext(null); + if (null == sharedContext) { + throw new GLException("Couldn't create shared context for drawable: "+sharedDrawable); + } + sharedContext.setSynchronized(true); + VersionNumber glXVersion = getGLXVersion(sharedDevice); + boolean madeCurrent = false; + sharedContext.makeCurrent(); + try { + madeCurrent = sharedContext.isCurrent(); + } finally { + sharedContext.release(); + } + if (DEBUG) { + System.err.println("!!! SharedDevice: " + sharedDevice); + System.err.println("!!! SharedScreen: " + sharedScreen); + System.err.println("!!! SharedContext: " + sharedContext + ", madeCurrent " + madeCurrent); + System.err.println("!!! GLX Vendor: " + glXVendorName); + System.err.println("!!! GLX Version: " + glXVersion + + " >= 1.3: " + (glXVersion.compareTo(versionOneThree) >= 0)); + } + return new SharedResource(sharedDevice, sharedScreen, sharedDrawable, sharedContext, glXVersion, glXVendorName); + } catch (Throwable t) { + throw new GLException("WindowsWGLDrawableFactory - Could not initialize shared resources for "+connection, t); + } finally { + sharedDevice.unlock(); + } + } + + public void releaseSharedResource(SharedResourceRunner.Resource shared) { + SharedResource sr = (SharedResource) shared; + if (DEBUG) { + System.err.println("!!! Shutdown Shared:"); + System.err.println("!!! Device : " + sr.device); + System.err.println("!!! Screen : " + sr.screen); + System.err.println("!!! Drawable: " + sr.drawable); + System.err.println("!!! CTX : " + sr.context); + } + + if (null != sr.context) { + // may cause JVM SIGSEGV: sharedContext.destroy(); + sr.context = null; + } + + if (null != sr.drawable) { + // may cause JVM SIGSEGV: sharedDrawable.destroy(); + sr.drawable = null; + } + + if (null != sr.screen) { + sr.screen = null; + } + + if (null != sr.device) { + sr.device.close(); + sr.device = null; + } + } + } + + public final AbstractGraphicsDevice getDefaultDevice() { + return defaultDevice; + } + + public final boolean getIsDeviceCompatible(AbstractGraphicsDevice device) { + if(device instanceof X11GraphicsDevice) { + return true; + } + return false; + } + + protected final GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device) { + SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); + if(null!=sr) { + return sr.getContext(); + } + return null; + } + + protected AbstractGraphicsDevice getOrCreateSharedDeviceImpl(AbstractGraphicsDevice device) { + SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); + if(null!=sr) { + return sr.getDevice(); + } + return null; + } + + protected final long getOrCreateSharedDpy(AbstractGraphicsDevice device) { + SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); + if(null!=sr) { + return sr.getDevice().getHandle(); + } + return 0; + } + + SharedResource getOrCreateSharedResource(AbstractGraphicsDevice device) { + return (SharedResource) sharedResourceRunner.getOrCreateShared(device); + } + + public final String getGLXVendorName(AbstractGraphicsDevice device) { + SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); + if(null!=sr) { + return ((SharedResource)sr).getGLXVendorName(); + } + return GLXUtil.getVendorName(device.getHandle()); + } + + public final boolean isGLXVendorATI(AbstractGraphicsDevice device) { + SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); + if(null!=sr) { + return ((SharedResource)sr).isGLXVendorATI(); + } + return GLXUtil.isVendorATI(device.getHandle()); + } + + public final boolean isGLXVendorNVIDIA(AbstractGraphicsDevice device) { + SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); + if(null!=sr) { + return ((SharedResource)sr).isGLXVendorNVIDIA(); + } + return GLXUtil.isVendorNVIDIA(device.getHandle()); + } + + protected final void shutdownInstance() { + sharedResourceRunner.releaseAndWait(); + + // Don't really close pending Display connections, + // since this may trigger a JVM exception + X11Util.shutdown( false, DEBUG ); + } + + protected List/*GLCapabilitiesImmutable*/ getAvailableCapabilitiesImpl(AbstractGraphicsDevice device) { + return X11GLXGraphicsConfigurationFactory.getAvailableCapabilities(this, device); + } + + protected final GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) { + if (target == null) { + throw new IllegalArgumentException("Null target"); + } + return new X11OnscreenGLXDrawable(this, target); + } + + protected final GLDrawableImpl createOffscreenDrawableImpl(NativeSurface target) { + if (target == null) { + throw new IllegalArgumentException("Null target"); + } + AbstractGraphicsConfiguration config = target.getGraphicsConfiguration().getNativeGraphicsConfiguration(); + GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities(); + if(!caps.isPBuffer()) { + return new X11PixmapGLXDrawable(this, target); + } + + // PBuffer GLDrawable Creation + GLDrawableImpl pbufferDrawable; + AbstractGraphicsDevice device = config.getScreen().getDevice(); + + /** + * 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. + */ + SharedResource sr = (SharedResource) sharedResourceRunner.getOrCreateShared(device); + if( null!=sr && sr.isGLXVendorATI() && null == GLContext.getCurrent() ) { + sr.getContext().makeCurrent(); + try { + pbufferDrawable = new X11PbufferGLXDrawable(this, target); + } finally { + sr.getContext().release(); + } + } else { + pbufferDrawable = new X11PbufferGLXDrawable(this, target); + } + return pbufferDrawable; + } + + public final boolean isGLXVersionGreaterEqualOneThree(AbstractGraphicsDevice device) { + SharedResource sr = (SharedResource) sharedResourceRunner.getOrCreateShared(device); + if(null!=sr) { + return sr.isGLXVersionGreaterEqualOneThree(); + } + if( device instanceof X11GraphicsDevice ) { + VersionNumber v = getGLXVersion( (X11GraphicsDevice) device); + return ( null != v ) ? v.compareTo(versionOneThree) >= 0 : false ; + } + return false; + } + + public final boolean canCreateGLPbuffer(AbstractGraphicsDevice device) { + if(null == device) { + SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(defaultDevice); + if(null!=sr) { + device = sr.getDevice(); + } + } + return isGLXVersionGreaterEqualOneThree(device); + } + + protected final NativeSurface createOffscreenSurfaceImpl(AbstractGraphicsDevice device, + GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, + GLCapabilitiesChooser chooser, + int width, int height) { + X11GraphicsScreen screen = null; + SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device); + if(null!=sr) { + screen = (X11GraphicsScreen) sr.getScreen(); + } + if(null==screen) { + return null; + } + + ProxySurface ns = new ProxySurface( + X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen) ); + if(ns != null) { + ns.setSize(width, height); + } + return ns; + } + + protected final GLContext createExternalGLContextImpl() { + return X11ExternalGLXContext.create(this, null); + } + + public final boolean canCreateExternalGLDrawable(AbstractGraphicsDevice device) { + return canCreateGLPbuffer(device); + } + + protected final GLDrawable createExternalGLDrawableImpl() { + return X11ExternalGLXDrawable.create(this, null); + } + + public final boolean canCreateContextOnJava2DSurface(AbstractGraphicsDevice device) { + return false; + } + + public final 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 final synchronized int getGammaRampLength() { + if (gotGammaRampLength) { + return gammaRampLength; + } + + long display = getOrCreateSharedDpy(defaultDevice); + if(0 == display) { + return 0; + } + + int[] size = new int[1]; + boolean res = X11Util.XF86VidModeGetGammaRampSize(display, + X11Util.DefaultScreen(display), + size, 0); + if (!res) { + return 0; + } + gotGammaRampLength = true; + gammaRampLength = size[0]; + return gammaRampLength; + } + + protected final boolean setGammaRamp(float[] ramp) { + long display = getOrCreateSharedDpy(defaultDevice); + if(0 == display) { + return false; + } + + int len = ramp.length; + short[] rampData = new short[len]; + for (int i = 0; i < len; i++) { + rampData[i] = (short) (ramp[i] * 65535); + } + + boolean res = X11Util.XF86VidModeSetGammaRamp(display, + X11Util.DefaultScreen(display), + rampData.length, + rampData, 0, + rampData, 0, + rampData, 0); + return res; + } + + protected final Buffer getGammaRamp() { + long display = getOrCreateSharedDpy(defaultDevice); + if(0 == display) { + return null; + } + + 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(); + + boolean res = X11Util.XF86VidModeGetGammaRamp(display, + X11Util.DefaultScreen(display), + size, + redRampData, + greenRampData, + blueRampData); + if (!res) { + return null; + } + return rampData; + } + + protected final void resetGammaRamp(Buffer originalGammaRamp) { + if (originalGammaRamp == null) { + return; // getGammaRamp failed originally + } + long display = getOrCreateSharedDpy(defaultDevice); + if(0 == display) { + return; + } + + 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(); + + X11Util.XF86VidModeSetGammaRamp(display, + X11Util.DefaultScreen(display), + size, + redRampData, + greenRampData, + blueRampData); + } +} diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDynamicLibraryBundleInfo.java new file mode 100644 index 000000000..d7905aa72 --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDynamicLibraryBundleInfo.java @@ -0,0 +1,84 @@ +/** + * Copyright 2010 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions 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. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ + +package com.jogamp.opengl.impl.x11.glx; + +import com.jogamp.opengl.impl.*; +import java.util.*; + +public class X11GLXDynamicLibraryBundleInfo extends DesktopGLDynamicLibraryBundleInfo { + protected X11GLXDynamicLibraryBundleInfo() { + super(); + } + + public List getToolLibNames() { + List/*<List>*/ libNamesList = new ArrayList(); + + List/*<String>*/ glesLibNames = new ArrayList(); + + // Be aware that on DRI systems, eg ATI fglrx, etc, + // you have to set LIBGL_DRIVERS_PATH env variable. + // Eg on Ubuntu 64bit systems this is: + // export LIBGL_DRIVERS_PATH=/usr/lib/fglrx/dri:/usr/lib32/fglrx/dri + // + + // this is the default GL lib name, according to the spec + glesLibNames.add("libGL.so.1"); + + // try this one as well, if spec fails + glesLibNames.add("libGL.so"); + + // last but not least .. the generic one + glesLibNames.add("GL"); + + libNamesList.add(glesLibNames); + + return libNamesList; + } + + /** + * This respects old DRI requirements:<br> + * <pre> + * http://dri.sourceforge.net/doc/DRIuserguide.html + * </pre> + */ + public boolean shallLinkGlobal() { return true; } + + public final List getToolGetProcAddressFuncNameList() { + List res = new ArrayList(); + res.add("glXGetProcAddressARB"); + res.add("glXGetProcAddress"); + return res; + } + + public final long toolDynamicLookupFunction(long toolGetProcAddressHandle, String funcName) { + return GLX.glXGetProcAddress(toolGetProcAddressHandle, funcName); + } +} + + diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java new file mode 100644 index 000000000..f7779ab28 --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java @@ -0,0 +1,447 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. 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 java.util.ArrayList; + +import javax.media.nativewindow.*; +import javax.media.nativewindow.x11.*; +import javax.media.opengl.*; + +import com.jogamp.common.nio.PointerBuffer; +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 GLCapabilitiesChooser chooser; + + X11GLXGraphicsConfiguration(X11GraphicsScreen screen, + X11GLCapabilities capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) { + super(screen, capsChosen, capsRequested, capsChosen.getXVisualInfo()); + this.chooser=chooser; + } + + 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(x11Screen.getDevice()); + } + X11GLCapabilities caps = GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, GLXUtil.isMultisampleAvailable(display)); + if(null==caps) { + throw new GLException("GLCapabilities null of "+toHexString(fbcfg)); + } + return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser()); + } + + public Object clone() { + return super.clone(); + } + + public final long getFBConfig() { + return ((X11GLCapabilities)capabilitiesChosen).getFBConfig(); + } + public final int getFBConfigID() { + return ((X11GLCapabilities)capabilitiesChosen).getFBConfigID(); + } + + void updateGraphicsConfiguration() { + X11GLXGraphicsConfiguration newConfig = (X11GLXGraphicsConfiguration) + GraphicsConfigurationFactory.getFactory(getScreen().getDevice()).chooseGraphicsConfiguration( + getChosenCapabilities(), getRequestedCapabilities(), chooser, getScreen()); + if(null!=newConfig) { + // FIXME: setScreen( ... ); + setXVisualInfo(newConfig.getXVisualInfo()); + setChosenCapabilities(newConfig.getChosenCapabilities()); + if(DEBUG) { + System.err.println("!!! updateGraphicsConfiguration: "+this); + } + } + } + + private static int nonZeroOrDontCare(int value) { + return value != 0 ? value : (int)GLX.GLX_DONT_CARE ; + } + + static int[] GLCapabilities2AttribList(GLCapabilitiesImmutable 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 + + 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; + } + + static int FBCfgDrawableTypeBits(final long display, final long fbcfg) { + int val = 0; + + int[] tmp = new int[1]; + int fbtype = glXGetFBConfig(display, fbcfg, GLX.GLX_DRAWABLE_TYPE, tmp, 0); + + if ( 0 != ( fbtype & GLX.GLX_WINDOW_BIT ) ) { + val |= GLGraphicsConfigurationUtil.WINDOW_BIT; + } + if ( 0 != ( fbtype & GLX.GLX_PIXMAP_BIT ) ) { + val |= GLGraphicsConfigurationUtil.BITMAP_BIT; + } + if ( 0 != ( fbtype & GLX.GLX_PBUFFER_BIT ) ) { + val |= GLGraphicsConfigurationUtil.PBUFFER_BIT; + } + return val; + } + + static X11GLCapabilities GLXFBConfig2GLCapabilities(GLProfile glp, long display, long fbcfg, + boolean relaxed, boolean onscreen, boolean usePBuffer, + boolean isMultisampleAvailable) { + ArrayList bucket = new ArrayList(); + final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer); + if( GLXFBConfig2GLCapabilities(bucket, glp, display, fbcfg, winattrmask, isMultisampleAvailable) ) { + return (X11GLCapabilities) bucket.get(0); + } else if ( relaxed && GLXFBConfig2GLCapabilities(bucket, glp, display, fbcfg, GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable) ) { + return (X11GLCapabilities) bucket.get(0); + } + return null; + } + + static boolean GLXFBConfig2GLCapabilities(ArrayList capsBucket, + GLProfile glp, long display, long fbcfg, + int winattrmask, boolean isMultisampleAvailable) { + final int allDrawableTypeBits = FBCfgDrawableTypeBits(display, fbcfg); + int drawableTypeBits = winattrmask & allDrawableTypeBits; + + int fbcfgid = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfg); + XVisualInfo visualInfo = GLX.glXGetVisualFromFBConfig(display, fbcfg); + if(null == visualInfo) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities: Null XVisualInfo for FBConfigID 0x" + Integer.toHexString(fbcfgid)); + } + // onscreen must have an XVisualInfo + drawableTypeBits = drawableTypeBits & ~GLGraphicsConfigurationUtil.WINDOW_BIT; + } + + if( 0 == drawableTypeBits ) { + return false; + } + + int[] tmp = new int[1]; + if(GLX.GLX_BAD_ATTRIBUTE == GLX.glXGetFBConfigAttrib(display, fbcfg, GLX.GLX_RENDER_TYPE, tmp, 0)) { + return false; + } + + GLCapabilities res = new X11GLCapabilities(visualInfo, fbcfg, fbcfgid, glp); + 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 (isMultisampleAvailable) { + 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 GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits ); + } + + 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; + } + } + + 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]; + } + + static int glXFBConfig2FBConfigID(long display, long cfg) { + int[] tmpID = new int[1]; + return glXGetFBConfig(display, cfg, GLX.GLX_FBCONFIG_ID, tmpID, 0); + } + + 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.glXChooseFBConfig(display, screen, attribs, 0, count, 0); + if (fbcfgsL == null || fbcfgsL.limit()<1) { + return 0; + } + return fbcfgsL.get(0); + } + + // Visual Info + + static XVisualInfo XVisualID2XVisualInfo(long display, long visualID) { + int[] count = new int[1]; + XVisualInfo template = XVisualInfo.create(); + template.setVisualid(visualID); + XVisualInfo[] infos = X11Util.XGetVisualInfo(display, X11Lib.VisualIDMask, template, count, 0); + if (infos == null || infos.length == 0) { + return null; + } + XVisualInfo res = XVisualInfo.create(infos[0]); + if (DEBUG) { + System.err.println("!!! Fetched XVisualInfo for visual ID " + toHexString(visualID)); + System.err.println("!!! Resulting XVisualInfo: visualid = " + toHexString(res.getVisualid())); + } + return res; + } + + static boolean XVisualInfo2GLCapabilities(ArrayList capsBucket, + GLProfile glp, long display, XVisualInfo info, + final int winattrmask, boolean isMultisampleEnabled) { + final int allDrawableTypeBits = GLGraphicsConfigurationUtil.WINDOW_BIT | GLGraphicsConfigurationUtil.BITMAP_BIT ; + final int drawableTypeBits = winattrmask & allDrawableTypeBits; + + if( 0 == drawableTypeBits ) { + return false; + } + + 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 false; + } + 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 false; + } + + GLCapabilities res = new X11GLCapabilities(info, glp); + + 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 GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits); + } + + 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; + } + } + + 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 String toString() { + return "X11GLXGraphicsConfiguration["+getScreen()+", visualID " + toHexString(getVisualID()) + ", fbConfigID " + toHexString(getFBConfigID()) + + ",\n\trequested " + getRequestedCapabilities()+ + ",\n\tchosen " + getChosenCapabilities()+ + "]"; + } +} + diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java new file mode 100644 index 000000000..b391dc948 --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java @@ -0,0 +1,378 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. 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.nativewindow.AbstractGraphicsConfiguration; +import javax.media.nativewindow.AbstractGraphicsDevice; +import javax.media.nativewindow.AbstractGraphicsScreen; +import javax.media.nativewindow.CapabilitiesChooser; +import javax.media.nativewindow.CapabilitiesImmutable; +import javax.media.nativewindow.GraphicsConfigurationFactory; +import javax.media.nativewindow.x11.X11GraphicsScreen; +import javax.media.nativewindow.x11.X11GraphicsDevice; +import javax.media.opengl.DefaultGLCapabilitiesChooser; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLCapabilitiesChooser; +import javax.media.opengl.GLCapabilitiesImmutable; +import javax.media.opengl.GLDrawableFactory; +import javax.media.opengl.GLException; +import javax.media.opengl.GLProfile; + +import com.jogamp.common.nio.PointerBuffer; +import com.jogamp.nativewindow.impl.x11.X11Lib; +import com.jogamp.nativewindow.impl.x11.X11Util; +import com.jogamp.nativewindow.impl.x11.XVisualInfo; +import com.jogamp.opengl.impl.Debug; +import com.jogamp.opengl.impl.GLGraphicsConfigurationFactory; +import com.jogamp.opengl.impl.GLGraphicsConfigurationUtil; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + + +/** Subclass of GraphicsConfigurationFactory used when non-AWT toolkits + 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 GLGraphicsConfigurationFactory { + protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration"); + static X11GLCapabilities.XVisualIDComparator XVisualIDComparator = new X11GLCapabilities.XVisualIDComparator(); + + X11GLXGraphicsConfigurationFactory() { + GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.x11.X11GraphicsDevice.class, this); + } + + protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl( + CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested, CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) { + if (!(absScreen instanceof X11GraphicsScreen)) { + throw new IllegalArgumentException("Only X11GraphicsScreen are allowed here"); + } + + if ( !(capsChosen instanceof GLCapabilitiesImmutable) ) { + throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilities objects - chosen"); + } + + if ( !(capsRequested instanceof GLCapabilitiesImmutable)) { + throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilities objects - requested"); + } + + if (chooser != null && !(chooser instanceof GLCapabilitiesChooser)) { + throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects"); + } + return chooseGraphicsConfigurationStatic((GLCapabilitiesImmutable)capsChosen, (GLCapabilitiesImmutable)capsRequested, + (GLCapabilitiesChooser)chooser, (X11GraphicsScreen)absScreen); + } + + protected static List/*<X11GLCapabilities>*/ getAvailableCapabilities(X11GLXDrawableFactory factory, AbstractGraphicsDevice device) { + X11GLXDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResource(device); + if(null == sharedResource) { + throw new GLException("Shared resource for device n/a: "+device); + } + X11GraphicsScreen sharedScreen = (X11GraphicsScreen) sharedResource.getScreen(); + X11GLXDrawable sharedDrawable = (X11GLXDrawable) sharedResource.getDrawable(); + GLCapabilitiesImmutable capsChosen = sharedDrawable.getChosenGLCapabilities(); + GLProfile glp = capsChosen.getGLProfile(); + + List/*GLCapabilitiesImmutable*/ availableCaps = null; + + if( sharedResource.isGLXVersionGreaterEqualOneThree() ) { + availableCaps = getAvailableGLCapabilitiesFBConfig(sharedScreen, glp); + } + if( null == availableCaps || 0 == availableCaps.size() ) { + availableCaps = getAvailableGLCapabilitiesXVisual(sharedScreen, glp); + } + if( null != availableCaps ) { + Collections.sort(availableCaps, XVisualIDComparator); + } + return availableCaps; + } + + static List/*<X11GLCapabilities>*/ getAvailableGLCapabilitiesFBConfig(X11GraphicsScreen x11Screen, GLProfile glProfile) { + PointerBuffer fbcfgsL = null; + + // Utilizing FBConfig + // + AbstractGraphicsDevice absDevice = x11Screen.getDevice(); + long display = absDevice.getHandle(); + + int screen = x11Screen.getIndex(); + boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); + int[] count = { -1 }; + ArrayList availableCaps = new ArrayList(); + + fbcfgsL = GLX.glXChooseFBConfig(display, screen, null, 0, count, 0); + if (fbcfgsL == null || fbcfgsL.limit()<=0) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesFBConfig: Failed glXChooseFBConfig ("+x11Screen+"): "+fbcfgsL+", "+count[0]); + } + return null; + } + for (int i = 0; i < fbcfgsL.limit(); i++) { + if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, display, fbcfgsL.get(i), GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable) ) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesFBConfig: FBConfig invalid (2): ("+x11Screen+"): fbcfg: "+toHexString(fbcfgsL.get(i))); + } + } + } + return availableCaps; + } + + static List/*<X11GLCapabilities>*/ getAvailableGLCapabilitiesXVisual(X11GraphicsScreen x11Screen, GLProfile glProfile) { + AbstractGraphicsDevice absDevice = x11Screen.getDevice(); + long display = absDevice.getHandle(); + + int screen = x11Screen.getIndex(); + boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); + + int[] count = new int[1]; + XVisualInfo template = XVisualInfo.create(); + template.setScreen(screen); + XVisualInfo[] infos = X11Util.XGetVisualInfo(display, X11Lib.VisualScreenMask, template, count, 0); + if (infos == null || infos.length<1) { + throw new GLException("Error while enumerating available XVisualInfos"); + } + ArrayList availableCaps = new ArrayList(); + for (int i = 0; i < infos.length; i++) { + if( !X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(availableCaps, glProfile, display, infos[i], GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable) ) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesXVisual: XVisual invalid: ("+x11Screen+"): fbcfg: "+toHexString(infos[i].getVisualid())); + } + } + } + return availableCaps; + } + + + static X11GLXGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilitiesImmutable capsChosen, + GLCapabilitiesImmutable capsReq, + GLCapabilitiesChooser chooser, + X11GraphicsScreen x11Screen) { + if (x11Screen == null) { + throw new IllegalArgumentException("AbstractGraphicsScreen is null"); + } + + if (capsChosen == null) { + capsChosen = new GLCapabilities(null); + } + X11GraphicsDevice x11Device = (X11GraphicsDevice) x11Screen.getDevice(); + X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory(); + + capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, factory.canCreateGLPbuffer(x11Device) ); + boolean usePBuffer = capsChosen.isPBuffer(); + + X11GLXGraphicsConfiguration res = null; + if( factory.isGLXVersionGreaterEqualOneThree(x11Device) ) { + res = chooseGraphicsConfigurationFBConfig(capsChosen, capsReq, chooser, x11Screen); + } + if(null==res) { + if(usePBuffer) { + throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig for "+capsChosen); + } + res = chooseGraphicsConfigurationXVisual(capsChosen, capsReq, chooser, x11Screen); + } + if(null==res) { + throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig and XVisual for "+capsChosen); + } + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationStatic("+x11Screen+","+capsChosen+"): "+res); + } + return res; + } + + static X11GLXGraphicsConfiguration fetchGraphicsConfigurationFBConfig(X11GraphicsScreen x11Screen, int fbID, GLProfile glp) { + AbstractGraphicsDevice absDevice = x11Screen.getDevice(); + long display = absDevice.getHandle(); + int screen = x11Screen.getIndex(); + + long fbcfg = X11GLXGraphicsConfiguration.glXFBConfigID2FBConfig(display, screen, fbID); + if( !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfg ) ) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed - GLX FBConfig invalid: ("+x11Screen+","+toHexString(fbID)+"): fbcfg: "+toHexString(fbcfg)); + } + return null; + } + X11GLCapabilities caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, GLXUtil.isMultisampleAvailable(display)); + return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser()); + } + + private static X11GLXGraphicsConfiguration chooseGraphicsConfigurationFBConfig(GLCapabilitiesImmutable capsChosen, + GLCapabilitiesImmutable capsReq, + GLCapabilitiesChooser chooser, + X11GraphicsScreen x11Screen) { + long recommendedFBConfig = -1; + int recommendedIndex = -1; + PointerBuffer fbcfgsL = null; + GLProfile glProfile = capsChosen.getGLProfile(); + boolean onscreen = capsChosen.isOnscreen(); + boolean usePBuffer = capsChosen.isPBuffer(); + + // Utilizing FBConfig + // + AbstractGraphicsDevice absDevice = x11Screen.getDevice(); + long display = absDevice.getHandle(); + + int screen = x11Screen.getIndex(); + boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); + int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capsChosen, true, isMultisampleAvailable, display, screen); + int[] count = { -1 }; + ArrayList/*<X11GLCapabilities>*/ availableCaps = new ArrayList(); + final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer); + + // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice + fbcfgsL = GLX.glXChooseFBConfig(display, screen, attribs, 0, count, 0); + if (fbcfgsL != null && fbcfgsL.limit()>0) { + for (int i = 0; i < fbcfgsL.limit(); i++) { + if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, display, fbcfgsL.get(i), winattrmask, isMultisampleAvailable) ) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (1): ("+x11Screen+","+capsChosen+"): fbcfg: "+toHexString(fbcfgsL.get(i))); + } + } + } + if(availableCaps.size() > 0) { + recommendedFBConfig = fbcfgsL.get(0); + recommendedIndex=0; + if (DEBUG) { + System.err.println("!!! glXChooseFBConfig recommended fbcfg " + toHexString(recommendedFBConfig) + ", idx " + recommendedIndex); + System.err.println("!!! user caps " + capsChosen); + System.err.println("!!! fbcfg caps " + availableCaps.get(recommendedIndex)); + } + } else if (DEBUG) { + System.err.println("!!! glXChooseFBConfig no caps for recommended fbcfg " + toHexString(fbcfgsL.get(0))); + System.err.println("!!! user caps " + capsChosen); + } + } + + // 2nd choice: get all GLCapabilities available, no preferred recommendedIndex available + if( 0 == availableCaps.size() ) { + // reset .. + recommendedFBConfig = -1; + recommendedIndex = -1; + + fbcfgsL = GLX.glXChooseFBConfig(display, screen, null, 0, count, 0); + if (fbcfgsL == null || fbcfgsL.limit()<=0) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXChooseFBConfig ("+x11Screen+","+capsChosen+"): "+fbcfgsL+", "+count[0]); + } + return null; + } + + for (int i = 0; i < fbcfgsL.limit(); i++) { + if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, display, fbcfgsL.get(i), winattrmask, isMultisampleAvailable) ) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (2): ("+x11Screen+"): fbcfg: "+toHexString(fbcfgsL.get(i))); + } + } + } + } + int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex); + if ( 0 > chosenIndex ) { + if (DEBUG) { + Thread.dumpStack(); + } + return null; + } + X11GLCapabilities chosenCaps = (X11GLCapabilities) availableCaps.get(chosenIndex); + + return new X11GLXGraphicsConfiguration(x11Screen, chosenCaps, capsReq, chooser); + } + + private static X11GLXGraphicsConfiguration chooseGraphicsConfigurationXVisual(GLCapabilitiesImmutable capsChosen, + GLCapabilitiesImmutable capsReq, + GLCapabilitiesChooser chooser, + X11GraphicsScreen x11Screen) { + if (chooser == null) { + chooser = new DefaultGLCapabilitiesChooser(); + } + + GLProfile glProfile = capsChosen.getGLProfile(); + final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(capsChosen.isOnscreen(), false /* pbuffer */); + ArrayList availableCaps = new ArrayList(); + int recommendedIndex = -1; + + AbstractGraphicsDevice absDevice = x11Screen.getDevice(); + long display = absDevice.getHandle(); + + int screen = x11Screen.getIndex(); + boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display); + int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capsChosen, false, isMultisampleAvailable, display, screen); + + // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice + XVisualInfo recommendedVis = GLX.glXChooseVisual(display, screen, attribs, 0); + if (DEBUG) { + System.err.print("!!! glXChooseVisual recommended "); + if (recommendedVis == null) { + System.err.println("null visual"); + } else { + System.err.println("visual id " + toHexString(recommendedVis.getVisualid())); + } + } + + // 2nd choice: get all GLCapabilities available, preferred recommendedIndex might be available if 1st choice was successful + int[] count = new int[1]; + XVisualInfo template = XVisualInfo.create(); + template.setScreen(screen); + XVisualInfo[] infos = X11Util.XGetVisualInfo(display, X11Lib.VisualScreenMask, template, count, 0); + if (infos == null || infos.length<1) { + throw new GLException("Error while enumerating available XVisualInfos"); + } + + for (int i = 0; i < infos.length; i++) { + if( !X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(availableCaps, glProfile, display, infos[i], winattrmask, isMultisampleAvailable) ) { + if(DEBUG) { + System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesXVisual: XVisual invalid: ("+x11Screen+"): fbcfg: "+toHexString(infos[i].getVisualid())); + } + } else { + // Attempt to find the visual chosenIndex by glXChooseVisual + if (recommendedVis != null && recommendedVis.getVisualid() == infos[i].getVisualid()) { + recommendedIndex = availableCaps.size() - 1; + } + } + } + + int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex); + if ( 0 > chosenIndex ) { + if (DEBUG) { + Thread.dumpStack(); + } + return null; + } + X11GLCapabilities chosenCaps = (X11GLCapabilities) availableCaps.get(chosenIndex); + + return new X11GLXGraphicsConfiguration(x11Screen, chosenCaps, capsReq, chooser); + } + +} + diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXContext.java new file mode 100644 index 000000000..ba6a566e6 --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXContext.java @@ -0,0 +1,48 @@ +/* + * 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.*; + +public class X11OnscreenGLXContext extends X11GLXContext { + + public X11OnscreenGLXContext(X11OnscreenGLXDrawable drawable, GLContext shareWith) { + super(drawable, shareWith); + } +} diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java new file mode 100644 index 000000000..5243e8c46 --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. 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.*; + +public class X11OnscreenGLXDrawable extends X11GLXDrawable { + /** GLXWindow can't be made current on AWT with NVidia driver, hence disabled for now */ + public static final boolean USE_GLXWINDOW = false; + long glXWindow; // GLXWindow, a GLXDrawable representation + boolean useGLXWindow; + + protected X11OnscreenGLXDrawable(GLDrawableFactory factory, NativeSurface component) { + super(factory, component, false); + glXWindow=0; + useGLXWindow=false; + } + + public long getHandle() { + if(useGLXWindow) { + return glXWindow; + } + return getNativeSurface().getSurfaceHandle(); + } + + protected void destroyHandle() { + if(0!=glXWindow) { + GLX.glXDestroyWindow(getNativeSurface().getDisplayHandle(), glXWindow); + glXWindow = 0; + useGLXWindow=false; + } + } + + /** must be locked already */ + protected void updateHandle() { + if(USE_GLXWINDOW) { + X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration(); + if(config.getFBConfig()>=0) { + useGLXWindow=true; + long dpy = getNativeSurface().getDisplayHandle(); + if(0!=glXWindow) { + GLX.glXDestroyWindow(dpy, glXWindow); + } + glXWindow = GLX.glXCreateWindow(dpy, config.getFBConfig(), getNativeSurface().getSurfaceHandle(), null, 0); + if (DEBUG) { + System.err.println("!!! X11OnscreenGLXDrawable.setRealized(true): glXWindow: "+toHexString(getNativeSurface().getSurfaceHandle())+" -> "+toHexString(glXWindow)); + } + if(0==glXWindow) { + throw new GLException("X11OnscreenGLXDrawable.setRealized(true): GLX.glXCreateWindow() failed: "+this); + } + } + } + } + + public GLContext createContext(GLContext shareWith) { + return new X11OnscreenGLXContext(this, shareWith); + } +} diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXContext.java new file mode 100644 index 000000000..7ee5d51d4 --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXContext.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.opengl.*; + +public class X11PbufferGLXContext extends X11GLXContext { + + public X11PbufferGLXContext(X11PbufferGLXDrawable drawable, GLContext shareWith) { + super(drawable, shareWith); + } + + 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 ((X11PbufferGLXDrawable)drawable).getFloatingPointMode(); + } +} diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java new file mode 100644 index 000000000..65970dab2 --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. 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.*; + +public class X11PbufferGLXDrawable extends X11GLXDrawable { + protected X11PbufferGLXDrawable(GLDrawableFactory factory, NativeSurface target) { + /* GLCapabilities caps, + GLCapabilitiesChooser chooser, + int width, int height */ + super(factory, target, true); + + if (DEBUG) { + System.out.println("Pbuffer config: " + getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration()); + } + + createPbuffer(); + + if (DEBUG) { + System.err.println("Created pbuffer " + this); + } + } + + protected void setRealizedImpl() { + if(realized) { + createPbuffer(); + } else { + destroyImpl(); + } + } + + public GLContext createContext(GLContext shareWith) { + return new X11PbufferGLXContext(this, shareWith); + } + + protected void destroyImpl() { + NativeSurface ns = getNativeSurface(); + if (ns.getSurfaceHandle() != 0) { + GLX.glXDestroyPbuffer(ns.getDisplayHandle(), ns.getSurfaceHandle()); + } + ((SurfaceChangeable)ns).setSurfaceHandle(0); + } + + private void createPbuffer() { + X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration) getNativeSurface().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"); + } + + NativeSurface ns = getNativeSurface(); + + GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable)config.getChosenCapabilities(); + + if (chosenCaps.getPbufferRenderToTexture()) { + throw new GLException("Render-to-texture pbuffers not supported yet on X11"); + } + + if (chosenCaps.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++] = ns.getWidth(); + iattributes[niattribs++] = GLX.GLX_PBUFFER_HEIGHT; + iattributes[niattribs++] = ns.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)ns).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)ns).setSize(width, height); + } + + 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/jogamp/opengl/x11/glx/X11PixmapGLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXContext.java new file mode 100644 index 000000000..b7b4da75d --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXContext.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. 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.*; + +public class X11PixmapGLXContext extends X11GLXContext { + + public X11PixmapGLXContext(X11PixmapGLXDrawable drawable, + GLContext shareWith) { + super(drawable, shareWith); + } + + 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() { + GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)drawable.getNativeSurface().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; + } +} diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXDrawable.java new file mode 100644 index 000000000..0343ffb02 --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXDrawable.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. 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 X11PixmapGLXDrawable extends X11GLXDrawable { + private long pixmap; + + protected X11PixmapGLXDrawable(GLDrawableFactory factory, NativeSurface target) { + super(factory, target, true); + create(); + } + + protected void setRealizedImpl() { + if(realized) { + create(); + } else { + destroyImpl(); + } + } + + public GLContext createContext(GLContext shareWith) { + return new X11PixmapGLXContext(this, shareWith); + } + + private void create() { + NativeSurface ns = getNativeSurface(); + X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration) ns.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(); + + pixmap = X11Util.XCreatePixmap(dpy, X11Util.RootWindow(dpy, screen), + surface.getWidth(), surface.getHeight(), bitsPerPixel); + if (pixmap == 0) { + throw new GLException("XCreatePixmap failed"); + } + long drawable = GLX.glXCreateGLXPixmap(dpy, vis, pixmap); + if (drawable == 0) { + X11Util.XFreePixmap(dpy, pixmap); + pixmap = 0; + throw new GLException("glXCreateGLXPixmap failed"); + } + ((SurfaceChangeable)ns).setSurfaceHandle(drawable); + if (DEBUG) { + System.err.println("Created pixmap " + toHexString(pixmap) + + ", GLXPixmap " + toHexString(drawable) + + ", display " + toHexString(dpy)); + } + } + + protected void destroyImpl() { + if (pixmap == 0) return; + + NativeSurface ns = getNativeSurface(); + long display = ns.getDisplayHandle(); + + long drawable = ns.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); + X11Util.XFreePixmap(display, pixmap); + drawable = 0; + pixmap = 0; + ((SurfaceChangeable)ns).setSurfaceHandle(0); + display = 0; + } + + protected void swapBuffersImpl() { + if(DEBUG) { + System.err.println("unhandled swapBuffersImpl() called for: "+this); + } + } +} diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java new file mode 100644 index 000000000..898a8a658 --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 2010 JogAmp Community. 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 javax.media.nativewindow.*; +import javax.media.nativewindow.x11.*; +import javax.media.nativewindow.awt.*; +import javax.media.opengl.*; + +import com.jogamp.opengl.impl.*; +import com.jogamp.nativewindow.impl.jawt.x11.*; +import com.jogamp.nativewindow.impl.x11.*; + +public class X11AWTGLXGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory { + protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration"); + + public X11AWTGLXGraphicsConfigurationFactory() { + GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.awt.AWTGraphicsDevice.class, this); + } + + protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl( + CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested, + 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, AbstractGraphicsDevice.DEFAULT_UNIT); + } + AWTGraphicsScreen awtScreen = (AWTGraphicsScreen) absScreen; + device = ((AWTGraphicsDevice)awtScreen.getDevice()).getGraphicsDevice(); + + if ( !(capsChosen instanceof GLCapabilitiesImmutable) ) { + throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only GLCapabilities objects - chosen"); + } + + if ( !(capsRequested instanceof GLCapabilitiesImmutable) ) { + throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only GLCapabilities objects - requested"); + } + + if (chooser != null && + !(chooser instanceof GLCapabilitiesChooser)) { + throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only GLCapabilitiesChooser objects"); + } + + if(DEBUG) { + System.err.println("X11AWTGLXGraphicsConfigurationFactory: got "+absScreen); + } + + long displayHandle = X11SunJDKReflection.graphicsDeviceGetDisplay(device); + boolean owner = false; + if(0==displayHandle) { + displayHandle = X11Util.createDisplay(null); + owner = true; + if(DEBUG) { + System.err.println(Thread.currentThread().getName() + " - X11AWTGLXGraphicsConfigurationFactory: using a thread local X11 display"); + } + } else { + if(DEBUG) { + System.err.println(Thread.currentThread().getName() + " - X11AWTGLXGraphicsConfigurationFactory: using AWT X11 display 0x"+Long.toHexString(displayHandle)); + } + /** + * May cause an exception on NVidia X11 Display destruction, + * when destruction happen immediately after construction, around 10ms. + * However, the own Display handle is required for AMD gpus. + */ + String name = X11Util.XDisplayString(displayHandle); + displayHandle = X11Util.createDisplay(name); + owner = true; + } + ((AWTGraphicsDevice)awtScreen.getDevice()).setSubType(NativeWindowFactory.TYPE_X11, displayHandle); + X11GraphicsDevice x11Device = new X11GraphicsDevice(displayHandle, AbstractGraphicsDevice.DEFAULT_UNIT); + x11Device.setCloseDisplay(owner); + X11GraphicsScreen x11Screen = new X11GraphicsScreen(x11Device, awtScreen.getIndex()); + if(DEBUG) { + System.err.println("X11AWTGLXGraphicsConfigurationFactory: made "+x11Screen); + } + GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(x11Device); + GraphicsConfiguration[] configs = device.getConfigurations(); + + // + // Match the X11/GL Visual with AWT: + // - choose a config AWT agnostic and then + // - try to find the visual within the GraphicsConfiguration + // + // The resulting GraphicsConfiguration has to be 'forced' on the AWT native peer, + // ie. returned by GLCanvas's getGraphicsConfiguration() befor call by super.addNotify(). + // + X11GraphicsConfiguration x11Config = (X11GraphicsConfiguration) factory.chooseGraphicsConfiguration(capsChosen, capsRequested, chooser, x11Screen); + if (x11Config == null) { + throw new GLException("Unable to choose a GraphicsConfiguration (1): "+capsChosen+",\n\t"+chooser+"\n\t"+x11Screen); + } + long visualID = x11Config.getVisualID(); + for (int i = 0; i < configs.length; i++) { + GraphicsConfiguration gc = configs[i]; + if (gc != null) { + if (X11SunJDKReflection.graphicsConfigurationGetVisualID(gc) == visualID) { + if(DEBUG) { + System.err.println("Found matching AWT visual: 0x"+Long.toHexString(visualID) +" -> "+x11Config); + } + return new AWTGraphicsConfiguration(awtScreen, + x11Config.getChosenCapabilities(), x11Config.getRequestedCapabilities(), + gc, x11Config); + } + } + } + + // try again using an AWT Colormodel compatible configuration + GraphicsConfiguration gc = device.getDefaultConfiguration(); + capsChosen = AWTGraphicsConfiguration.setupCapabilitiesRGBABits(capsChosen, gc); + x11Config = (X11GraphicsConfiguration) factory.chooseGraphicsConfiguration(capsChosen, capsRequested, chooser, x11Screen); + if (x11Config == null) { + throw new GLException("Unable to choose a GraphicsConfiguration (2): "+capsChosen+",\n\t"+chooser+"\n\t"+x11Screen); + } + visualID = x11Config.getVisualID(); + for (int i = 0; i < configs.length; i++) { + gc = configs[i]; + if (X11SunJDKReflection.graphicsConfigurationGetVisualID(gc) == visualID) { + if(DEBUG) { + System.err.println("Found matching default AWT visual: 0x"+Long.toHexString(visualID) +" -> "+x11Config); + } + return new AWTGraphicsConfiguration(awtScreen, + x11Config.getChosenCapabilities(), x11Config.getRequestedCapabilities(), + gc, x11Config); + } + } + + // 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"); + } + + gc = device.getDefaultConfiguration(); + return new AWTGraphicsConfiguration(awtScreen, x11Config.getChosenCapabilities(), x11Config.getRequestedCapabilities(), gc, x11Config); + } +} |