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