aboutsummaryrefslogtreecommitdiffstats
path: root/src/net/java/games/jogl/impl/x11
diff options
context:
space:
mode:
authorKenneth Russel <[email protected]>2005-07-17 06:13:24 +0000
committerKenneth Russel <[email protected]>2005-07-17 06:13:24 +0000
commit7e7e225eaf4fddb31152ab204bf1776f26079d40 (patch)
tree522044c1fb226235fa34b9d013945f320765edd8 /src/net/java/games/jogl/impl/x11
parent9d28b7f7fffdaeee7353945000546cb73a00157b (diff)
Further context-related changes for the JSR-231 API. The GLContext
implementations on all platforms have been split into orthogonal GLDrawable and GLContext concepts. It is now possible to create more than one GLContet per GLDrawable (though this has not been tested yet). GLCanvas has been reimplemented in terms of GLDrawableFactory.getGLDrawable(). More functionality has been moved from GLDrawable to GLAutoDrawable. Reimplemented lazy sending of reshape GLEventListener events in GLCanvas and GLJPanel and deleted notion of deferred reshapes from GLDrawableHelper and elsewhere. Sharing of textures and display lists is now expressed in terms of GLContexts instead of GLDrawables. Still need to move pbuffer creation into GLDrawableFactory from the onscreen GLContext implementations. Added option to gleem ExaminerViewer to disable automatic redraws upon mouse events and respecified more of gleem to work on GLAutoDrawables rather than GLDrawables. Updated all JOGL demos to work with new APIs and slightly different initialization sequences (in particular, for pbuffers -- this will change with the addition of GLDrawableFactory.createGLPbuffer()). git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/branches/JSR-231@324 232f8b59-042b-4e1e-8c03-345bb8c30851
Diffstat (limited to 'src/net/java/games/jogl/impl/x11')
-rw-r--r--src/net/java/games/jogl/impl/x11/X11GLContext.java182
-rw-r--r--src/net/java/games/jogl/impl/x11/X11GLContextFactory.java23
-rw-r--r--src/net/java/games/jogl/impl/x11/X11GLDrawable.java172
-rw-r--r--src/net/java/games/jogl/impl/x11/X11OffscreenGLContext.java102
-rw-r--r--src/net/java/games/jogl/impl/x11/X11OffscreenGLDrawable.java143
-rw-r--r--src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java170
-rw-r--r--src/net/java/games/jogl/impl/x11/X11OnscreenGLDrawable.java174
-rw-r--r--src/net/java/games/jogl/impl/x11/X11PbufferGLContext.java266
-rw-r--r--src/net/java/games/jogl/impl/x11/X11PbufferGLDrawable.java254
9 files changed, 898 insertions, 588 deletions
diff --git a/src/net/java/games/jogl/impl/x11/X11GLContext.java b/src/net/java/games/jogl/impl/x11/X11GLContext.java
index 7077c855e..a43def0b8 100644
--- a/src/net/java/games/jogl/impl/x11/X11GLContext.java
+++ b/src/net/java/games/jogl/impl/x11/X11GLContext.java
@@ -47,9 +47,7 @@ import net.java.games.jogl.*;
import net.java.games.jogl.impl.*;
public abstract class X11GLContext extends GLContextImpl {
- protected long display;
- protected long drawable;
- protected long visualID;
+ protected X11GLDrawable drawable;
protected long context;
private boolean glXQueryExtensionsStringInitialized;
private boolean glXQueryExtensionsStringAvailable;
@@ -84,11 +82,10 @@ public abstract class X11GLContext extends GLContextImpl {
});
}
- public X11GLContext(Component component,
- GLCapabilities capabilities,
- GLCapabilitiesChooser chooser,
+ public X11GLContext(X11GLDrawable drawable,
GLContext shareWith) {
- super(component, capabilities, chooser, shareWith);
+ super(shareWith);
+ this.drawable = drawable;
}
protected GL createGL()
@@ -108,16 +105,6 @@ public abstract class X11GLContext extends GLContextImpl {
return glExtensionName;
}
- protected abstract boolean isOffscreen();
-
- public int getOffscreenContextWidth() {
- throw new GLException("Should not call this");
- }
-
- public int getOffscreenContextHeight() {
- throw new GLException("Should not call this");
- }
-
public int getOffscreenContextPixelDataType() {
throw new GLException("Should not call this");
}
@@ -126,18 +113,32 @@ public abstract class X11GLContext extends GLContextImpl {
public abstract boolean offscreenImageNeedsVerticalFlip();
- /**
- * Creates and initializes an appropriate OpenGl context. Should only be
- * called by {@link makeCurrentImpl()}.
+ /** Helper routine which usually just turns around and calls
+ * createContext (except for pbuffers, which use a different context
+ * creation mechanism). Should only be called by {@link
+ * makeCurrentImpl()}.
*/
protected abstract void create();
-
- public boolean isExtensionAvailable(String glExtensionName) {
- if (glExtensionName.equals("GL_ARB_pbuffer") ||
- glExtensionName.equals("GL_ARB_pixel_format")) {
- return isGLX13;
+
+ /**
+ * Creates and initializes an appropriate OpenGL context. Should only be
+ * called by {@link create()}.
+ */
+ protected void createContext(boolean onscreen) {
+ XVisualInfo vis = drawable.chooseVisual(onscreen);
+ X11GLContext other = (X11GLContext) GLContextShareSet.getShareContext(this);
+ long share = 0;
+ if (other != null) {
+ share = other.getContext();
+ if (share == 0) {
+ throw new GLException("GLContextShareSet returned an invalid OpenGL context");
+ }
}
- return super.isExtensionAvailable(glExtensionName);
+ context = GLX.glXCreateContext(drawable.getDisplay(), vis, share, onscreen);
+ if (context == 0) {
+ throw new GLException("Unable to create OpenGL context");
+ }
+ GLContextShareSet.contextCreated(this);
}
protected int makeCurrentImpl() throws GLException {
@@ -145,19 +146,20 @@ public abstract class X11GLContext extends GLContextImpl {
if (context == 0) {
create();
if (DEBUG) {
- System.err.println("!!! Created GL context for " + getClass().getName());
+ System.err.println(getThreadName() + ": !!! Created GL context for " + getClass().getName());
}
created = true;
}
- if (drawable == 0) {
- throw new GLException("Unable to make context current; drawable was null");
- }
- // FIXME: this cast to int would be wrong on 64-bit platforms
- // where the argument type to glXMakeCurrent would change (should
- // probably make GLXDrawable, and maybe XID, Opaque as long)
- if (!GLX.glXMakeCurrent(display, (int) drawable, context)) {
+ if (!GLX.glXMakeCurrent(drawable.getDisplay(), drawable.getDrawable(), context)) {
throw new GLException("Error making context current");
+ } else {
+ mostRecentDisplay = drawable.getDisplay();
+ if (DEBUG && VERBOSE) {
+ System.err.println(getThreadName() + ": glXMakeCurrent(display " + toHexString(drawable.getDisplay()) +
+ ", drawable " + toHexString(drawable.getDrawable()) +
+ ", context " + toHexString(context) + ") succeeded");
+ }
}
if (created) {
@@ -168,7 +170,7 @@ public abstract class X11GLContext extends GLContextImpl {
}
protected void releaseImpl() throws GLException {
- if (!GLX.glXMakeCurrent(display, 0, 0)) {
+ if (!GLX.glXMakeCurrent(drawable.getDisplay(), 0, 0)) {
throw new GLException("Error freeing OpenGL context");
}
}
@@ -177,16 +179,16 @@ public abstract class X11GLContext extends GLContextImpl {
lockAWT();
if (context != 0) {
GLX.glXDestroyContext(mostRecentDisplay, context);
+ context = 0;
+ mostRecentDisplay = 0;
+ GLContextShareSet.contextDestroyed(this);
if (DEBUG) {
System.err.println("!!! Destroyed OpenGL context " + context);
}
- context = 0;
}
unlockAWT();
}
- public abstract void swapBuffers() throws GLException;
-
protected long dynamicLookupFunction(String glFuncName) {
long res = 0;
if (!isLinuxAMD64) {
@@ -216,12 +218,12 @@ public abstract class X11GLContext extends GLContextImpl {
// Figure out whether we are running GLX version 1.3 or above and
// therefore have pbuffer support
- if (display == 0) {
+ if (drawable.getDisplay() == 0) {
throw new GLException("Expected non-null DISPLAY for querying GLX version");
}
int[] major = new int[1];
int[] minor = new int[1];
- if (!GLX.glXQueryVersion(display, major, 0, minor, 0)) {
+ if (!GLX.glXQueryVersion(drawable.getDisplay(), major, 0, minor, 0)) {
throw new GLException("glXQueryVersion failed");
}
if (DEBUG) {
@@ -253,7 +255,7 @@ public abstract class X11GLContext extends GLContextImpl {
}
public synchronized String getPlatformExtensionsString() {
- if (display == 0) {
+ if (drawable.getDisplay() == 0) {
throw new GLException("Context not current");
}
if (!glXQueryExtensionsStringInitialized) {
@@ -263,7 +265,7 @@ public abstract class X11GLContext extends GLContextImpl {
if (glXQueryExtensionsStringAvailable) {
lockAWT();
try {
- String ret = GLX.glXQueryExtensionsString(display, GLX.DefaultScreen(display));
+ String ret = GLX.glXQueryExtensionsString(drawable.getDisplay(), GLX.DefaultScreen(drawable.getDisplay()));
if (DEBUG) {
System.err.println("!!! GLX extensions: " + ret);
}
@@ -292,97 +294,17 @@ public abstract class X11GLContext extends GLContextImpl {
return available;
}
- //----------------------------------------------------------------------
- // Internals only below this point
- //
-
- protected JAWT getJAWT() {
- return X11GLContextFactory.getJAWT();
- }
-
- protected XVisualInfo chooseVisual() {
- if (!isOffscreen()) {
- // The visual has already been chosen by the time we get here;
- // it's specified by the GraphicsConfiguration of the
- // GLCanvas. Fortunately, the JAWT supplies the visual ID for
- // the component in a portable fashion, so all we have to do is
- // use XGetVisualInfo with a VisualIDMask to get the
- // corresponding XVisualInfo to pass into glXChooseVisual.
- int[] count = new int[1];
- XVisualInfo template = new XVisualInfo();
- // FIXME: probably not 64-bit clean
- template.visualid((int) visualID);
- XVisualInfo[] infos = GLX.XGetVisualInfo(display, GLX.VisualIDMask, template, count, 0);
- if (infos == null || infos.length == 0) {
- throw new GLException("Error while getting XVisualInfo for visual ID " + visualID);
- }
- // FIXME: the storage for the infos array is leaked (should
- // clean it up somehow when we're done with the visual we're
- // returning)
- return infos[0];
- } else {
- // It isn't clear to me whether we need this much code to handle
- // the offscreen case, where we're creating a pixmap into which
- // to render...this is what we (incorrectly) used to do for the
- // onscreen case
-
- int screen = 0; // FIXME: provide way to specify this?
- XVisualInfo vis = null;
- int[] count = new int[1];
- XVisualInfo template = new XVisualInfo();
- template.screen(screen);
- XVisualInfo[] infos = GLX.XGetVisualInfo(display, GLX.VisualScreenMask, template, count, 0);
- if (infos == null) {
- throw new GLException("Error while enumerating available XVisualInfos");
- }
- GLCapabilities[] caps = new GLCapabilities[infos.length];
- for (int i = 0; i < infos.length; i++) {
- caps[i] = X11GLContextFactory.xvi2GLCapabilities(display, infos[i]);
- }
- int chosen = chooser.chooseCapabilities(capabilities, caps, -1);
- if (chosen < 0 || chosen >= caps.length) {
- throw new GLException("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ")");
- }
- if (DEBUG) {
- System.err.println("Chosen visual (" + chosen + "):");
- System.err.println(caps[chosen]);
- }
- vis = infos[chosen];
- if (vis == null) {
- throw new GLException("GLCapabilitiesChooser chose an invalid visual");
- }
- // FIXME: the storage for the infos array is leaked (should
- // clean it up somehow when we're done with the visual we're
- // returning)
-
- return vis;
- }
- }
-
- protected long createContext(XVisualInfo vis, boolean onscreen) {
- X11GLContext other = (X11GLContext) GLContextShareSet.getShareContext(this);
- long share = 0;
- if (other != null) {
- share = other.getContext();
- if (share == 0) {
- throw new GLException("GLContextShareSet returned an invalid OpenGL context");
- }
- }
- long res = GLX.glXCreateContext(display, vis, share, onscreen);
- if (res != 0) {
- GLContextShareSet.contextCreated(this);
+ public boolean isExtensionAvailable(String glExtensionName) {
+ if (glExtensionName.equals("GL_ARB_pbuffer") ||
+ glExtensionName.equals("GL_ARB_pixel_format")) {
+ return isGLX13;
}
- return res;
+ return super.isExtensionAvailable(glExtensionName);
}
- // Helper routine for the overridden create() to call
- protected void chooseVisualAndCreateContext(boolean onscreen) {
- XVisualInfo vis = chooseVisual();
- context = createContext(vis, onscreen);
- if (context == 0) {
- throw new GLException("Unable to create OpenGL context");
- }
- }
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
protected long getContext() {
return context;
diff --git a/src/net/java/games/jogl/impl/x11/X11GLContextFactory.java b/src/net/java/games/jogl/impl/x11/X11GLContextFactory.java
index 3be11c002..78d03a28a 100644
--- a/src/net/java/games/jogl/impl/x11/X11GLContextFactory.java
+++ b/src/net/java/games/jogl/impl/x11/X11GLContextFactory.java
@@ -119,15 +119,22 @@ public class X11GLContextFactory extends GLContextFactory {
return null;
}
- public GLContext createGLContext(Component component,
- GLCapabilities capabilities,
- GLCapabilitiesChooser chooser,
- GLContext shareWith) {
- if (component != null) {
- return new X11OnscreenGLContext(component, capabilities, chooser, shareWith);
- } else {
- return new X11OffscreenGLContext(capabilities, chooser, shareWith);
+ public GLDrawable getGLDrawable(Object target,
+ GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser) {
+ if (target == null) {
+ throw new IllegalArgumentException("Null target");
}
+ if (!(target instanceof Component)) {
+ throw new IllegalArgumentException("GLDrawables not supported for objects of type " +
+ target.getClass().getName() + " (only Components are supported in this implementation)");
+ }
+ return new X11OnscreenGLDrawable((Component) target);
+ }
+
+ public GLDrawableImpl createOffscreenDrawable(GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser) {
+ return new X11OffscreenGLDrawable(capabilities, chooser);
}
public static GLCapabilities xvi2GLCapabilities(long display, XVisualInfo info) {
diff --git a/src/net/java/games/jogl/impl/x11/X11GLDrawable.java b/src/net/java/games/jogl/impl/x11/X11GLDrawable.java
new file mode 100644
index 000000000..32098ab43
--- /dev/null
+++ b/src/net/java/games/jogl/impl/x11/X11GLDrawable.java
@@ -0,0 +1,172 @@
+/*
+ * 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 net.java.games.jogl.impl.x11;
+
+import java.awt.Component;
+
+import net.java.games.jogl.*;
+import net.java.games.jogl.impl.*;
+
+public abstract class X11GLDrawable extends GLDrawableImpl {
+ protected static final boolean DEBUG = Debug.debug("X11GLDrawable");
+
+ protected long display;
+ protected long drawable;
+ protected long visualID;
+ protected Component component;
+ protected GLCapabilities capabilities;
+ protected GLCapabilitiesChooser chooser;
+
+ public X11GLDrawable(Component component,
+ GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser) {
+ this.component = component;
+ this.capabilities = (capabilities == null) ? null :
+ ((GLCapabilities) capabilities.clone());
+ this.chooser = chooser;
+ }
+
+ public void setRealized(boolean val) {
+ throw new GLException("Should not call this (should only be called for onscreen GLDrawables)");
+ }
+
+ public void destroy() {
+ throw new GLException("Should not call this (should only be called for offscreen GLDrawables)");
+ }
+
+ public void swapBuffers() throws GLException {
+ }
+
+ public long getDisplay() {
+ return display;
+ }
+
+ public long getDrawable() {
+ return drawable;
+ }
+
+ //---------------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ protected XVisualInfo chooseVisual(boolean onscreen) {
+ if (display == 0) {
+ throw new GLException("null display");
+ }
+
+ // FIXME
+ if (onscreen) {
+ // The visual has already been chosen by the time we get here;
+ // it's specified by the GraphicsConfiguration of the
+ // GLCanvas. Fortunately, the JAWT supplies the visual ID for
+ // the component in a portable fashion, so all we have to do is
+ // use XGetVisualInfo with a VisualIDMask to get the
+ // corresponding XVisualInfo to pass into glXChooseVisual.
+ int[] count = new int[1];
+ XVisualInfo template = new XVisualInfo();
+ // FIXME: probably not 64-bit clean
+ template.visualid((int) visualID);
+ lockAWT();
+ XVisualInfo[] infos = GLX.XGetVisualInfo(display, GLX.VisualIDMask, template, count, 0);
+ unlockAWT();
+ if (infos == null || infos.length == 0) {
+ throw new GLException("Error while getting XVisualInfo for visual ID " + visualID);
+ }
+ // FIXME: the storage for the infos array is leaked (should
+ // clean it up somehow when we're done with the visual we're
+ // returning)
+ return infos[0];
+ } else {
+ // It isn't clear to me whether we need this much code to handle
+ // the offscreen case, where we're creating a pixmap into which
+ // to render...this is what we (incorrectly) used to do for the
+ // onscreen case
+
+ int screen = 0; // FIXME: provide way to specify this?
+ XVisualInfo vis = null;
+ int[] count = new int[1];
+ XVisualInfo template = new XVisualInfo();
+ template.screen(screen);
+ XVisualInfo[] infos = null;
+ GLCapabilities[] caps = null;
+ lockAWT();
+ try {
+ infos = GLX.XGetVisualInfo(display, GLX.VisualScreenMask, template, count, 0);
+ if (infos == null) {
+ throw new GLException("Error while enumerating available XVisualInfos");
+ }
+ caps = new GLCapabilities[infos.length];
+ for (int i = 0; i < infos.length; i++) {
+ caps[i] = X11GLContextFactory.xvi2GLCapabilities(display, infos[i]);
+ }
+ } finally {
+ unlockAWT();
+ }
+ int chosen = chooser.chooseCapabilities(capabilities, caps, -1);
+ if (chosen < 0 || chosen >= caps.length) {
+ throw new GLException("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ")");
+ }
+ if (DEBUG) {
+ System.err.println("Chosen visual (" + chosen + "):");
+ System.err.println(caps[chosen]);
+ }
+ vis = infos[chosen];
+ if (vis == null) {
+ throw new GLException("GLCapabilitiesChooser chose an invalid visual");
+ }
+ // FIXME: the storage for the infos array is leaked (should
+ // clean it up somehow when we're done with the visual we're
+ // returning)
+
+ return vis;
+ }
+ }
+
+
+ // These synchronization primitives prevent the AWT from making
+ // requests from the X server asynchronously to this code.
+ protected void lockAWT() {
+ X11GLContextFactory.lockAWT();
+ }
+
+ protected void unlockAWT() {
+ X11GLContextFactory.unlockAWT();
+ }
+}
diff --git a/src/net/java/games/jogl/impl/x11/X11OffscreenGLContext.java b/src/net/java/games/jogl/impl/x11/X11OffscreenGLContext.java
index c493d3380..4397c72d8 100644
--- a/src/net/java/games/jogl/impl/x11/X11OffscreenGLContext.java
+++ b/src/net/java/games/jogl/impl/x11/X11OffscreenGLContext.java
@@ -39,46 +39,24 @@
package net.java.games.jogl.impl.x11;
-import java.awt.image.BufferedImage;
import net.java.games.jogl.*;
import net.java.games.jogl.impl.*;
public class X11OffscreenGLContext extends X11GLContext {
- private long pixmap;
- private boolean isDoubleBuffered;
- // Width and height of the underlying bitmap
- private int width;
- private int height;
+ private X11OffscreenGLDrawable drawable;
- public X11OffscreenGLContext(GLCapabilities capabilities,
- GLCapabilitiesChooser chooser,
+ public X11OffscreenGLContext(X11OffscreenGLDrawable drawable,
GLContext shareWith) {
- super(null, capabilities, chooser, shareWith);
- }
-
- protected GL createGL()
- {
- return new X11GLImpl(this);
- }
-
- protected boolean isOffscreen() {
- return true;
- }
-
- public int getOffscreenContextWidth() {
- return width;
- }
-
- public int getOffscreenContextHeight() {
- return height;
+ super(drawable, shareWith);
+ this.drawable = drawable;
}
public int getOffscreenContextPixelDataType() {
- return GL.GL_UNSIGNED_BYTE;
+ return GL.GL_UNSIGNED_BYTE;
}
public int getOffscreenContextReadBuffer() {
- if (isDoubleBuffered) {
+ if (drawable.isDoubleBuffered()) {
return GL.GL_BACK;
}
return GL.GL_FRONT;
@@ -95,9 +73,9 @@ public class X11OffscreenGLContext extends X11GLContext {
return false;
}
- public GLContext createPbufferContext(GLCapabilities capabilities,
- int initialWidth,
- int initialHeight) {
+ public GLDrawableImpl createPbufferDrawable(GLCapabilities capabilities,
+ int initialWidth,
+ int initialHeight) {
throw new GLException("Not supported");
}
@@ -109,67 +87,7 @@ public class X11OffscreenGLContext extends X11GLContext {
throw new GLException("Should not call this");
}
- protected int makeCurrentImpl() throws GLException {
- display = X11GLContextFactory.getDisplayConnection();
- if (pendingOffscreenResize) {
- if (pendingOffscreenWidth != width || pendingOffscreenHeight != height) {
- if (context != 0) {
- destroy();
- }
- width = pendingOffscreenWidth;
- height = pendingOffscreenHeight;
- pendingOffscreenResize = false;
- }
- }
- mostRecentDisplay = display;
- return super.makeCurrentImpl();
- }
-
- public void swapBuffers() throws GLException {
- }
-
- protected void releaseImpl() throws GLException {
- try {
- super.releaseImpl();
- } finally {
- display = 0;
- }
- }
-
protected void create() {
- XVisualInfo vis = chooseVisual();
- int bitsPerPixel = vis.depth();
-
- if (display == 0) {
- throw new GLException("No active display");
- }
- int screen = GLX.DefaultScreen(display);
- pixmap = GLX.XCreatePixmap(display, (int) GLX.RootWindow(display, screen), width, height, bitsPerPixel);
- if (pixmap == 0) {
- throw new GLException("XCreatePixmap failed");
- }
- drawable = GLX.glXCreateGLXPixmap(display, vis, pixmap);
- if (drawable == 0) {
- throw new GLException("glXCreateGLXPixmap failed");
- }
- context = createContext(vis, false);
- if (context == 0) {
- throw new GLException("Unable to create OpenGL context");
- }
- isDoubleBuffered = (X11GLContextFactory.glXGetConfig(display, vis, GLX.GLX_DOUBLEBUFFER, new int[1], 0) != 0);
- }
-
- protected void destroyImpl() {
- if (context != 0) {
- super.destroyImpl();
- // Must destroy OpenGL context, pixmap and GLXPixmap
- GLX.glXDestroyContext(display, context);
- GLX.glXDestroyGLXPixmap(display, (int) drawable);
- GLX.XFreePixmap(display, pixmap);
- context = 0;
- drawable = 0;
- pixmap = 0;
- GLContextShareSet.contextDestroyed(this);
- }
+ createContext(false);
}
}
diff --git a/src/net/java/games/jogl/impl/x11/X11OffscreenGLDrawable.java b/src/net/java/games/jogl/impl/x11/X11OffscreenGLDrawable.java
new file mode 100644
index 000000000..7b60612df
--- /dev/null
+++ b/src/net/java/games/jogl/impl/x11/X11OffscreenGLDrawable.java
@@ -0,0 +1,143 @@
+/*
+ * 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 net.java.games.jogl.impl.x11;
+
+import net.java.games.jogl.*;
+import net.java.games.jogl.impl.*;
+
+public class X11OffscreenGLDrawable extends X11GLDrawable {
+ private long pixmap;
+ private boolean isDoubleBuffered;
+ // Width and height of the underlying bitmap
+ private int width;
+ private int height;
+
+ public X11OffscreenGLDrawable(GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser) {
+ super(null, capabilities, chooser);
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new X11OffscreenGLContext(this, shareWith);
+ }
+
+ public void setSize(int newWidth, int newHeight) {
+ width = newWidth;
+ height = newHeight;
+ if (pixmap != 0) {
+ destroy();
+ }
+ create();
+ }
+
+ public int getWidth() {
+ return width;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+ private void create() {
+ display = X11GLContextFactory.getDisplayConnection();
+ XVisualInfo vis = chooseVisual(false);
+ int bitsPerPixel = vis.depth();
+
+ lockAWT();
+ try {
+ int screen = GLX.DefaultScreen(display);
+ pixmap = GLX.XCreatePixmap(display, (int) GLX.RootWindow(display, screen), width, height, bitsPerPixel);
+ if (pixmap == 0) {
+ throw new GLException("XCreatePixmap failed");
+ }
+ drawable = GLX.glXCreateGLXPixmap(display, vis, pixmap);
+ if (drawable == 0) {
+ GLX.XFreePixmap(display, pixmap);
+ pixmap = 0;
+ throw new GLException("glXCreateGLXPixmap failed");
+ }
+ isDoubleBuffered = (X11GLContextFactory.glXGetConfig(display, vis, GLX.GLX_DOUBLEBUFFER, new int[1], 0) != 0);
+ if (DEBUG) {
+ System.err.println("Created pixmap " + toHexString(pixmap) +
+ ", GLXPixmap " + toHexString(drawable) +
+ ", display " + toHexString(display));
+ }
+ } finally {
+ unlockAWT();
+ }
+ }
+
+ public void destroy() {
+ if (pixmap != 0) {
+ if (DEBUG) {
+ System.err.println("Destroying pixmap " + toHexString(pixmap) +
+ ", GLXPixmap " + toHexString(drawable) +
+ ", display " + toHexString(display));
+ }
+
+ // Must destroy pixmap and GLXPixmap
+ lockAWT();
+
+ 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);
+ GLX.XFreePixmap(display, pixmap);
+ unlockAWT();
+ drawable = 0;
+ pixmap = 0;
+ display = 0;
+ }
+ }
+
+ public boolean isDoubleBuffered() {
+ return isDoubleBuffered;
+ }
+}
diff --git a/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java b/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java
index 5a6fe23bb..1828f8378 100644
--- a/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java
+++ b/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java
@@ -39,47 +39,20 @@
package net.java.games.jogl.impl.x11;
-import java.awt.Component;
import java.util.*;
import net.java.games.jogl.*;
import net.java.games.jogl.impl.*;
public class X11OnscreenGLContext extends X11GLContext {
- // Variables for lockSurface/unlockSurface
- private JAWT_DrawingSurface ds;
- private JAWT_DrawingSurfaceInfo dsi;
- private JAWT_X11DrawingSurfaceInfo x11dsi;
-
- // Indicates whether the component (if an onscreen context) has been
- // realized. Plausibly, before the component is realized the JAWT
- // should return an error or NULL object from some of its
- // operations; this appears to be the case on Win32 but is not true
- // at least with Sun's current X11 implementation (1.4.x), which
- // crashes with no other error reported if the DrawingSurfaceInfo is
- // fetched from a locked DrawingSurface during the validation as a
- // result of calling show() on the main thread. To work around this
- // we prevent any JAWT or OpenGL operations from being done until
- // addNotify() is called on the component.
- protected boolean realized;
-
+ protected X11OnscreenGLDrawable drawable;
// Variables for pbuffer support
List pbuffersToInstantiate = new ArrayList();
- public X11OnscreenGLContext(Component component,
- GLCapabilities capabilities,
- GLCapabilitiesChooser chooser,
+ public X11OnscreenGLContext(X11OnscreenGLDrawable drawable,
GLContext shareWith) {
- super(component, capabilities, chooser, shareWith);
- }
-
- protected GL createGL()
- {
- return new X11GLImpl(this);
- }
-
- protected boolean isOffscreen() {
- return false;
+ super(drawable, shareWith);
+ this.drawable = drawable;
}
public int getOffscreenContextReadBuffer() {
@@ -91,17 +64,15 @@ public class X11OnscreenGLContext extends X11GLContext {
}
public boolean canCreatePbufferContext() {
- // FIXME: should we gate this on GLX 1.3 being available?
- return true;
+ return isExtensionAvailable("GL_ARB_pbuffer");
}
- public GLContext createPbufferContext(GLCapabilities capabilities,
- int initialWidth,
- int initialHeight) {
- X11PbufferGLContext ctx = new X11PbufferGLContext(capabilities, initialWidth, initialHeight);
- ctx.setSynchronized(true);
- pbuffersToInstantiate.add(ctx);
- return ctx;
+ public GLDrawableImpl createPbufferDrawable(GLCapabilities capabilities,
+ int initialWidth,
+ int initialHeight) {
+ X11PbufferGLDrawable buf = new X11PbufferGLDrawable(capabilities, initialWidth, initialHeight);
+ pbuffersToInstantiate.add(buf);
+ return buf;
}
public void bindPbufferToTexture() {
@@ -112,39 +83,39 @@ public class X11OnscreenGLContext extends X11GLContext {
throw new GLException("Should not call this");
}
- public void setSwapInterval(int interval) {
- GL gl = getGL();
- if (gl.isExtensionAvailable("GLX_SGI_swap_control")) {
- gl.glXSwapIntervalSGI(interval);
- }
- }
-
- public void setRealized() {
- realized = true;
- }
-
protected int makeCurrentImpl() throws GLException {
try {
- if (!realized) {
+ int lockRes = drawable.lockSurface();
+ if (lockRes == X11OnscreenGLDrawable.LOCK_SURFACE_NOT_READY) {
return CONTEXT_NOT_CURRENT;
}
- if (!lockSurface()) {
- return CONTEXT_NOT_CURRENT;
+ if (lockRes == X11OnscreenGLDrawable.LOCK_SURFACE_CHANGED) {
+ if (context != 0) {
+ GLX.glXDestroyContext(mostRecentDisplay, context);
+ GLContextShareSet.contextDestroyed(this);
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Destroyed OpenGL context " + toHexString(context) + " due to JAWT_LOCK_SURFACE_CHANGED");
+ }
+ context = 0;
+ }
}
int ret = super.makeCurrentImpl();
if ((ret == CONTEXT_CURRENT) ||
(ret == CONTEXT_CURRENT_NEW)) {
// Instantiate any pending pbuffers
while (!pbuffersToInstantiate.isEmpty()) {
- X11PbufferGLContext ctx =
- (X11PbufferGLContext) pbuffersToInstantiate.remove(pbuffersToInstantiate.size() - 1);
- ctx.createPbuffer(display, context, getGL());
+ X11PbufferGLDrawable buf =
+ (X11PbufferGLDrawable) pbuffersToInstantiate.remove(pbuffersToInstantiate.size() - 1);
+ buf.createPbuffer(getGL(), drawable.getDisplay());
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": created pbuffer " + buf);
+ }
}
}
return ret;
} catch (RuntimeException e) {
try {
- unlockSurface();
+ drawable.unlockSurface();
} catch (Exception e2) {
// do nothing if unlockSurface throws
}
@@ -156,88 +127,11 @@ public class X11OnscreenGLContext extends X11GLContext {
try {
super.releaseImpl();
} finally {
- unlockSurface();
- }
- }
-
- protected void destroyImpl() throws GLException {
- realized = false;
- super.destroyImpl();
- }
-
- public void swapBuffers() throws GLException {
- // FIXME: this cast to int would be wrong on 64-bit platforms
- // where the argument type to glXMakeCurrent would change (should
- // probably make GLXDrawable, and maybe XID, Opaque as long)
- GLX.glXSwapBuffers(display, (int) drawable);
- }
-
- private boolean lockSurface() throws GLException {
- if (drawable != 0) {
- throw new GLException("Surface already locked");
- }
- ds = getJAWT().GetDrawingSurface(component);
- if (ds == null) {
- // Widget not yet realized
- return false;
+ drawable.unlockSurface();
}
- int res = ds.Lock();
- if ((res & JAWTFactory.JAWT_LOCK_ERROR) != 0) {
- throw new GLException("Unable to lock surface");
- }
- // See whether the surface changed and if so destroy the old
- // OpenGL context so it will be recreated
- if ((res & JAWTFactory.JAWT_LOCK_SURFACE_CHANGED) != 0) {
- if (context != 0) {
- GLX.glXDestroyContext(display, context);
- context = 0;
- }
- }
- dsi = ds.GetDrawingSurfaceInfo();
- if (dsi == null) {
- // Widget not yet realized
- ds.Unlock();
- getJAWT().FreeDrawingSurface(ds);
- ds = null;
- return false;
- }
- x11dsi = (JAWT_X11DrawingSurfaceInfo) dsi.platformInfo();
- display = x11dsi.display();
- drawable = x11dsi.drawable();
- visualID = x11dsi.visualID();
- if (display == 0 || drawable == 0) {
- // Widget not yet realized
- ds.FreeDrawingSurfaceInfo(dsi);
- ds.Unlock();
- getJAWT().FreeDrawingSurface(ds);
- ds = null;
- dsi = null;
- x11dsi = null;
- display = 0;
- drawable = 0;
- visualID = 0;
- return false;
- }
- mostRecentDisplay = display;
- return true;
- }
-
- private void unlockSurface() {
- if (drawable == 0) {
- throw new GLException("Surface already unlocked");
- }
- ds.FreeDrawingSurfaceInfo(dsi);
- ds.Unlock();
- getJAWT().FreeDrawingSurface(ds);
- ds = null;
- dsi = null;
- x11dsi = null;
- display = 0;
- drawable = 0;
- visualID = 0;
}
protected void create() {
- chooseVisualAndCreateContext(true);
- }
+ createContext(true);
+ }
}
diff --git a/src/net/java/games/jogl/impl/x11/X11OnscreenGLDrawable.java b/src/net/java/games/jogl/impl/x11/X11OnscreenGLDrawable.java
new file mode 100644
index 000000000..9b9705122
--- /dev/null
+++ b/src/net/java/games/jogl/impl/x11/X11OnscreenGLDrawable.java
@@ -0,0 +1,174 @@
+/*
+ * 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 net.java.games.jogl.impl.x11;
+
+import java.awt.Component;
+
+import net.java.games.jogl.*;
+import net.java.games.jogl.impl.*;
+
+public class X11OnscreenGLDrawable extends X11GLDrawable {
+ public static final int LOCK_SURFACE_NOT_READY = 1;
+ public static final int LOCK_SURFACE_CHANGED = 2;
+ public static final int LOCK_SUCCESS = 3;
+
+ // Variables for lockSurface/unlockSurface
+ private JAWT_DrawingSurface ds;
+ private JAWT_DrawingSurfaceInfo dsi;
+ private JAWT_X11DrawingSurfaceInfo x11dsi;
+
+ // Indicates whether the component (if an onscreen context) has been
+ // realized. Plausibly, before the component is realized the JAWT
+ // should return an error or NULL object from some of its
+ // operations; this appears to be the case on Win32 but is not true
+ // at least with Sun's current X11 implementation (1.4.x), which
+ // crashes with no other error reported if the DrawingSurfaceInfo is
+ // fetched from a locked DrawingSurface during the validation as a
+ // result of calling show() on the main thread. To work around this
+ // we prevent any JAWT or OpenGL operations from being done until
+ // addNotify() is called on the component.
+ protected boolean realized;
+
+ public X11OnscreenGLDrawable(Component component) {
+ super(component, null, null);
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new X11OnscreenGLContext(this, shareWith);
+ }
+
+ public void setRealized(boolean realized) {
+ this.realized = realized;
+ }
+
+ public void setSize(int width, int height) {
+ component.setSize(width, height);
+ }
+
+ public int getWidth() {
+ return component.getWidth();
+ }
+
+ public int getHeight() {
+ return component.getHeight();
+ }
+
+ public void swapBuffers() throws GLException {
+ lockAWT();
+ GLX.glXSwapBuffers(display, drawable);
+ unlockAWT();
+ }
+
+ public int lockSurface() throws GLException {
+ if (!realized) {
+ return LOCK_SURFACE_NOT_READY;
+ }
+ if (drawable != 0) {
+ throw new GLException("Surface already locked");
+ }
+ ds = getJAWT().GetDrawingSurface(component);
+ if (ds == null) {
+ // Widget not yet realized
+ return LOCK_SURFACE_NOT_READY;
+ }
+ int res = ds.Lock();
+ if ((res & JAWTFactory.JAWT_LOCK_ERROR) != 0) {
+ throw new GLException("Unable to lock surface");
+ }
+ // See whether the surface changed and if so destroy the old
+ // OpenGL context so it will be recreated (NOTE: removeNotify
+ // should handle this case, but it may be possible that race
+ // conditions can cause this code to be triggered -- should test
+ // more)
+ int ret = LOCK_SUCCESS;
+ if ((res & JAWTFactory.JAWT_LOCK_SURFACE_CHANGED) != 0) {
+ ret = LOCK_SURFACE_CHANGED;
+ }
+ dsi = ds.GetDrawingSurfaceInfo();
+ if (dsi == null) {
+ // Widget not yet realized
+ ds.Unlock();
+ getJAWT().FreeDrawingSurface(ds);
+ ds = null;
+ return LOCK_SURFACE_NOT_READY;
+ }
+ x11dsi = (JAWT_X11DrawingSurfaceInfo) dsi.platformInfo();
+ display = x11dsi.display();
+ drawable = x11dsi.drawable();
+ visualID = x11dsi.visualID();
+ if (display == 0 || drawable == 0) {
+ // Widget not yet realized
+ ds.FreeDrawingSurfaceInfo(dsi);
+ ds.Unlock();
+ getJAWT().FreeDrawingSurface(ds);
+ ds = null;
+ dsi = null;
+ x11dsi = null;
+ display = 0;
+ drawable = 0;
+ visualID = 0;
+ return LOCK_SURFACE_NOT_READY;
+ }
+ return ret;
+ }
+
+ public void unlockSurface() {
+ if (drawable == 0) {
+ throw new GLException("Surface already unlocked");
+ }
+ ds.FreeDrawingSurfaceInfo(dsi);
+ ds.Unlock();
+ getJAWT().FreeDrawingSurface(ds);
+ ds = null;
+ dsi = null;
+ x11dsi = null;
+ display = 0;
+ drawable = 0;
+ visualID = 0;
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ private JAWT getJAWT() {
+ return X11GLContextFactory.getJAWT();
+ }
+}
diff --git a/src/net/java/games/jogl/impl/x11/X11PbufferGLContext.java b/src/net/java/games/jogl/impl/x11/X11PbufferGLContext.java
index 30a60ba61..bebbdb91c 100644
--- a/src/net/java/games/jogl/impl/x11/X11PbufferGLContext.java
+++ b/src/net/java/games/jogl/impl/x11/X11PbufferGLContext.java
@@ -43,40 +43,21 @@ import net.java.games.jogl.*;
import net.java.games.jogl.impl.*;
public class X11PbufferGLContext extends X11GLContext {
- private static final boolean DEBUG = Debug.debug("X11PbufferGLContext");
+ private X11PbufferGLDrawable drawable;
- private int initWidth;
- private int initHeight;
-
- private long buffer; // GLXPbuffer
- private GLXFBConfig fbConfig;
- private int width;
- private int height;
-
- // FIXME: kept around because we create the OpenGL context lazily to
- // better integrate with the X11GLContext framework
- private long parentContext;
-
- private static final int MAX_PFORMATS = 256;
- private static final int MAX_ATTRIBS = 256;
-
- public X11PbufferGLContext(GLCapabilities capabilities, int initialWidth, int initialHeight) {
- super(null, capabilities, null, null);
- this.initWidth = initialWidth;
- this.initHeight = initialHeight;
- if (initWidth <= 0 || initHeight <= 0) {
- throw new GLException("Initial width and height of pbuffer must be positive (were (" +
- initWidth + ", " + initHeight + "))");
- }
+ public X11PbufferGLContext(X11PbufferGLDrawable drawable,
+ GLContext shareWith) {
+ super(drawable, shareWith);
+ this.drawable = drawable;
}
public boolean canCreatePbufferContext() {
return false;
}
- public GLContext createPbufferContext(GLCapabilities capabilities,
- int initialWidth,
- int initialHeight) {
+ public GLDrawableImpl createPbufferDrawable(GLCapabilities capabilities,
+ int initialWidth,
+ int initialHeight) {
throw new GLException("Not supported");
}
@@ -90,169 +71,40 @@ public class X11PbufferGLContext extends X11GLContext {
throw new GLException("Not yet implemented");
}
- public void createPbuffer(long display, long parentContext, GL gl) {
- if (display == 0) {
- throw new GLException("Null display");
- }
-
- if (parentContext == 0) {
- throw new GLException("Null parentContext");
- }
-
- if (capabilities.getOffscreenRenderToTexture()) {
- throw new GLException("Render-to-texture pbuffers not supported yet on X11");
- }
-
- if (capabilities.getOffscreenRenderToTextureRectangle()) {
- throw new GLException("Render-to-texture-rectangle pbuffers not supported yet on X11");
- }
-
- int[] iattributes = new int [2*MAX_ATTRIBS];
- float[] fattributes = new float[2*MAX_ATTRIBS];
- int nfattribs = 0;
- int niattribs = 0;
-
- // Since we are trying to create a pbuffer, the GLXFBConfig we
- // request (and subsequently use) must be "p-buffer capable".
- iattributes[niattribs++] = GL.GLX_DRAWABLE_TYPE;
- iattributes[niattribs++] = GL.GLX_PBUFFER_BIT;
-
- iattributes[niattribs++] = GL.GLX_RENDER_TYPE;
- iattributes[niattribs++] = GL.GLX_RGBA_BIT;
-
- iattributes[niattribs++] = GLX.GLX_DOUBLEBUFFER;
- if (capabilities.getDoubleBuffered()) {
- iattributes[niattribs++] = GL.GL_TRUE;
- } else {
- iattributes[niattribs++] = GL.GL_FALSE;
- }
-
- iattributes[niattribs++] = GLX.GLX_DEPTH_SIZE;
- iattributes[niattribs++] = capabilities.getDepthBits();
-
- iattributes[niattribs++] = GLX.GLX_RED_SIZE;
- iattributes[niattribs++] = capabilities.getRedBits();
-
- iattributes[niattribs++] = GLX.GLX_GREEN_SIZE;
- iattributes[niattribs++] = capabilities.getGreenBits();
-
- iattributes[niattribs++] = GLX.GLX_BLUE_SIZE;
- iattributes[niattribs++] = capabilities.getBlueBits();
-
- iattributes[niattribs++] = GLX.GLX_ALPHA_SIZE;
- iattributes[niattribs++] = capabilities.getAlphaBits();
-
- if (capabilities.getStencilBits() > 0) {
- iattributes[niattribs++] = GLX.GLX_STENCIL_SIZE;
- iattributes[niattribs++] = capabilities.getStencilBits();
- }
-
- if (capabilities.getAccumRedBits() > 0 ||
- capabilities.getAccumGreenBits() > 0 ||
- capabilities.getAccumBlueBits() > 0) {
- iattributes[niattribs++] = GLX.GLX_ACCUM_RED_SIZE;
- iattributes[niattribs++] = capabilities.getAccumRedBits();
- iattributes[niattribs++] = GLX.GLX_ACCUM_GREEN_SIZE;
- iattributes[niattribs++] = capabilities.getAccumGreenBits();
- iattributes[niattribs++] = GLX.GLX_ACCUM_BLUE_SIZE;
- iattributes[niattribs++] = capabilities.getAccumBlueBits();
- }
-
- if (capabilities.getOffscreenFloatingPointBuffers()) {
- if (!gl.isExtensionAvailable("GLX_NV_float_buffer")) {
- throw new GLException("Floating-point pbuffers on X11 currently require NVidia hardware");
- }
- iattributes[niattribs++] = GLX.GLX_FLOAT_COMPONENTS_NV;
- iattributes[niattribs++] = GL.GL_TRUE;
- }
-
- // FIXME: add FSAA support? Don't want to get into a situation
- // where we have to retry the glXChooseFBConfig call if it fails
- // due to a lack of an antialiased visual...
-
- iattributes[niattribs++] = 0; // null-terminate
-
- int screen = 0; // FIXME: provide way to specify this?
- int[] nelementsTmp = new int[1];
- GLXFBConfig[] fbConfigs = GLX.glXChooseFBConfig(display, screen, iattributes, 0, nelementsTmp, 0);
- if (fbConfigs == null || fbConfigs.length == 0 || fbConfigs[0] == null) {
- throw new GLException("pbuffer creation error: glXChooseFBConfig() failed");
- }
- // Note that we currently don't allow selection of anything but
- // the first GLXFBConfig in the returned list
- GLXFBConfig fbConfig = fbConfigs[0];
- int nelements = nelementsTmp[0];
- if (nelements <= 0) {
- throw new GLException("pbuffer creation error: couldn't find a suitable frame buffer configuration");
- }
-
- if (DEBUG) {
- System.err.println("Found " + fbConfigs.length + " matching GLXFBConfigs");
- System.err.println("Parameters of default one:");
- System.err.println("render type: 0x" + Integer.toHexString(queryFBConfig(display, fbConfig, GLX.GLX_RENDER_TYPE)));
- System.err.println("rgba: " + ((queryFBConfig(display, fbConfig, GLX.GLX_RENDER_TYPE) & GLX.GLX_RGBA_BIT) != 0));
- System.err.println("r: " + queryFBConfig(display, fbConfig, GLX.GLX_RED_SIZE));
- System.err.println("g: " + queryFBConfig(display, fbConfig, GLX.GLX_GREEN_SIZE));
- System.err.println("b: " + queryFBConfig(display, fbConfig, GLX.GLX_BLUE_SIZE));
- System.err.println("a: " + queryFBConfig(display, fbConfig, GLX.GLX_ALPHA_SIZE));
- System.err.println("depth: " + queryFBConfig(display, fbConfig, GLX.GLX_DEPTH_SIZE));
- System.err.println("double buffered: " + queryFBConfig(display, fbConfig, GLX.GLX_DOUBLEBUFFER));
- }
-
- // Create the p-buffer.
- niattribs = 0;
-
- iattributes[niattribs++] = GL.GLX_PBUFFER_WIDTH;
- iattributes[niattribs++] = initWidth;
- iattributes[niattribs++] = GL.GLX_PBUFFER_HEIGHT;
- iattributes[niattribs++] = initHeight;
-
- iattributes[niattribs++] = 0;
-
- long tmpBuffer = GLX.glXCreatePbuffer(display, fbConfig, iattributes, 0);
- if (tmpBuffer == 0) {
- // FIXME: query X error code for detail error message
- throw new GLException("pbuffer creation error: glXCreatePbuffer() failed");
- }
-
- // Set up instance variables
- this.display = display;
- mostRecentDisplay = display;
- this.parentContext = parentContext;
- buffer = tmpBuffer;
- this.fbConfig = fbConfig;
-
- // Determine the actual width and height we were able to create.
- int[] tmp = new int[1];
- GLX.glXQueryDrawable(display, (int) buffer, GL.GLX_WIDTH, tmp, 0);
- width = tmp[0];
- GLX.glXQueryDrawable(display, (int) buffer, GL.GLX_HEIGHT, tmp, 0);
- height = tmp[0];
-
- if (DEBUG) {
- System.err.println("Created pbuffer " + width + " x " + height);
- }
- }
-
protected int makeCurrentImpl() throws GLException {
- if (buffer == 0) {
- // pbuffer not instantiated yet
+ if (drawable.getDrawable() == 0) {
+ // pbuffer not instantiated (yet?)
+ if (DEBUG) {
+ System.err.println("pbuffer not instantiated");
+ }
return CONTEXT_NOT_CURRENT;
}
+ // Note that we have to completely override makeCurrentImpl
+ // because the underlying makeCurrent call differs for pbuffers
lockAWT();
try {
boolean created = false;
if (context == 0) {
create();
if (DEBUG) {
- System.err.println("!!! Created GL context for " + getClass().getName());
+ System.err.println(getThreadName() + ": !!! Created GL context for " + getClass().getName());
}
created = true;
}
- if (!GLX.glXMakeContextCurrent(display, buffer, buffer, context)) {
+ if (!GLX.glXMakeContextCurrent(drawable.getDisplay(),
+ drawable.getDrawable(),
+ drawable.getDrawable(),
+ context)) {
throw new GLException("Error making context current");
+ } else {
+ mostRecentDisplay = drawable.getDisplay();
+ if (DEBUG && VERBOSE) {
+ System.err.println(getThreadName() + ": glXMakeCurrent(display " + toHexString(drawable.getDisplay()) +
+ ", drawable " + toHexString(drawable.getDrawable()) +
+ ", context " + toHexString(context) + ") succeeded");
+ }
}
if (created) {
@@ -268,7 +120,7 @@ public class X11PbufferGLContext extends X11GLContext {
protected void releaseImpl() throws GLException {
lockAWT();
try {
- if (!GLX.glXMakeContextCurrent(display, 0, 0, 0)) {
+ if (!GLX.glXMakeContextCurrent(drawable.getDisplay(), 0, 0, 0)) {
throw new GLException("Error freeing OpenGL context");
}
} finally {
@@ -276,16 +128,6 @@ public class X11PbufferGLContext extends X11GLContext {
}
}
- public void handleModeSwitch(long parentHdc, long parentHglrc) {
- throw new GLException("Not yet implemented");
- }
-
- protected boolean isOffscreen() {
- // FIXME: currently the only caller of this won't cause proper
- // resizing of the pbuffer anyway.
- return false;
- }
-
public int getOffscreenContextReadBuffer() {
throw new GLException("Should not call this");
}
@@ -294,50 +136,34 @@ public class X11PbufferGLContext extends X11GLContext {
throw new GLException("Should not call this");
}
+ public int getFloatingPointMode() {
+ return drawable.getFloatingPointMode();
+ }
+
protected void create() {
if (DEBUG) {
- System.err.println("Creating context for pbuffer " + width + " x " + height);
+ System.err.println("Creating context for pbuffer " + drawable.getWidth() +
+ " x " + drawable.getHeight());
}
// Create a gl context for the p-buffer.
- // FIXME: provide option to not share display lists with subordinate pbuffer?
- context = GLX.glXCreateNewContext(display, fbConfig, GL.GLX_RGBA_TYPE, parentContext, true);
+ X11GLContext other = (X11GLContext) GLContextShareSet.getShareContext(this);
+ long share = 0;
+ if (other != null) {
+ share = other.getContext();
+ if (share == 0) {
+ throw new GLException("GLContextShareSet returned an invalid OpenGL context");
+ }
+ }
+ context = GLX.glXCreateNewContext(drawable.getDisplay(), drawable.getFBConfig(), GL.GLX_RGBA_TYPE, share, true);
if (context == 0) {
throw new GLException("pbuffer creation error: glXCreateNewContext() failed");
}
+ GLContextShareSet.contextCreated(this);
if (DEBUG) {
- System.err.println("Created context for pbuffer " + width + " x " + height);
- }
- }
-
- protected void destroyImpl() throws GLException {
- lockAWT();
- try {
- if (context != 0) {
- super.destroyImpl();
- GLX.glXDestroyPbuffer(display, buffer);
- buffer = 0;
- }
- } finally {
- unlockAWT();
- }
- }
-
- public void swapBuffers() throws GLException {
- // FIXME: do we need to do anything if the pbuffer is double-buffered?
- }
-
- public int getFloatingPointMode() {
- // Floating-point pbuffers currently require NVidia hardware on X11
- return GLPbuffer.NV_FLOAT;
- }
-
- private int queryFBConfig(long display, GLXFBConfig fbConfig, int attrib) {
- int[] tmp = new int[1];
- if (GLX.glXGetFBConfigAttrib(display, fbConfig, attrib, tmp, 0) != 0) {
- throw new GLException("glXGetFBConfigAttrib failed");
+ System.err.println("Created context for pbuffer " + drawable.getWidth() +
+ " x " + drawable.getHeight());
}
- return tmp[0];
}
}
diff --git a/src/net/java/games/jogl/impl/x11/X11PbufferGLDrawable.java b/src/net/java/games/jogl/impl/x11/X11PbufferGLDrawable.java
new file mode 100644
index 000000000..fc37f331b
--- /dev/null
+++ b/src/net/java/games/jogl/impl/x11/X11PbufferGLDrawable.java
@@ -0,0 +1,254 @@
+/*
+ * 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 net.java.games.jogl.impl.x11;
+
+import net.java.games.jogl.*;
+import net.java.games.jogl.impl.*;
+
+public class X11PbufferGLDrawable extends X11GLDrawable {
+ private int initWidth;
+ private int initHeight;
+
+ // drawable in superclass is a GLXPbuffer
+ private GLXFBConfig fbConfig;
+ private int width;
+ private int height;
+
+ protected static final int MAX_PFORMATS = 256;
+ protected static final int MAX_ATTRIBS = 256;
+
+ public X11PbufferGLDrawable(GLCapabilities capabilities, int initialWidth, int initialHeight) {
+ super(null, capabilities, null);
+ this.initWidth = initialWidth;
+ this.initHeight = initialHeight;
+ if (initWidth <= 0 || initHeight <= 0) {
+ throw new GLException("Initial width and height of pbuffer must be positive (were (" +
+ initWidth + ", " + initHeight + "))");
+ }
+
+ if (DEBUG) {
+ System.out.println("Pbuffer caps on init: " + capabilities +
+ (capabilities.getOffscreenRenderToTexture() ? " [rtt]" : "") +
+ (capabilities.getOffscreenRenderToTextureRectangle() ? " [rect]" : "") +
+ (capabilities.getOffscreenFloatingPointBuffers() ? " [float]" : ""));
+ }
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new X11PbufferGLContext(this, shareWith);
+ }
+
+ public void destroy() {
+ lockAWT();
+ if (drawable != 0) {
+ GLX.glXDestroyPbuffer(display, drawable);
+ }
+ unlockAWT();
+ display = 0;
+ }
+
+ public void setSize(int width, int height) {
+ // FIXME
+ throw new GLException("Not yet implemented");
+ }
+
+ public int getWidth() {
+ return width;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+ public void createPbuffer(GL gl, long display) {
+ if (display == 0) {
+ throw new GLException("Null display");
+ }
+
+ if (capabilities.getOffscreenRenderToTexture()) {
+ throw new GLException("Render-to-texture pbuffers not supported yet on X11");
+ }
+
+ if (capabilities.getOffscreenRenderToTextureRectangle()) {
+ throw new GLException("Render-to-texture-rectangle pbuffers not supported yet on X11");
+ }
+
+ int[] iattributes = new int [2*MAX_ATTRIBS];
+ float[] fattributes = new float[2*MAX_ATTRIBS];
+ int nfattribs = 0;
+ int niattribs = 0;
+
+ // Since we are trying to create a pbuffer, the GLXFBConfig we
+ // request (and subsequently use) must be "p-buffer capable".
+ iattributes[niattribs++] = GL.GLX_DRAWABLE_TYPE;
+ iattributes[niattribs++] = GL.GLX_PBUFFER_BIT;
+
+ iattributes[niattribs++] = GL.GLX_RENDER_TYPE;
+ iattributes[niattribs++] = GL.GLX_RGBA_BIT;
+
+ iattributes[niattribs++] = GLX.GLX_DOUBLEBUFFER;
+ if (capabilities.getDoubleBuffered()) {
+ iattributes[niattribs++] = GL.GL_TRUE;
+ } else {
+ iattributes[niattribs++] = GL.GL_FALSE;
+ }
+
+ iattributes[niattribs++] = GLX.GLX_DEPTH_SIZE;
+ iattributes[niattribs++] = capabilities.getDepthBits();
+
+ iattributes[niattribs++] = GLX.GLX_RED_SIZE;
+ iattributes[niattribs++] = capabilities.getRedBits();
+
+ iattributes[niattribs++] = GLX.GLX_GREEN_SIZE;
+ iattributes[niattribs++] = capabilities.getGreenBits();
+
+ iattributes[niattribs++] = GLX.GLX_BLUE_SIZE;
+ iattributes[niattribs++] = capabilities.getBlueBits();
+
+ iattributes[niattribs++] = GLX.GLX_ALPHA_SIZE;
+ iattributes[niattribs++] = capabilities.getAlphaBits();
+
+ if (capabilities.getStencilBits() > 0) {
+ iattributes[niattribs++] = GLX.GLX_STENCIL_SIZE;
+ iattributes[niattribs++] = capabilities.getStencilBits();
+ }
+
+ if (capabilities.getAccumRedBits() > 0 ||
+ capabilities.getAccumGreenBits() > 0 ||
+ capabilities.getAccumBlueBits() > 0) {
+ iattributes[niattribs++] = GLX.GLX_ACCUM_RED_SIZE;
+ iattributes[niattribs++] = capabilities.getAccumRedBits();
+ iattributes[niattribs++] = GLX.GLX_ACCUM_GREEN_SIZE;
+ iattributes[niattribs++] = capabilities.getAccumGreenBits();
+ iattributes[niattribs++] = GLX.GLX_ACCUM_BLUE_SIZE;
+ iattributes[niattribs++] = capabilities.getAccumBlueBits();
+ }
+
+ if (capabilities.getOffscreenFloatingPointBuffers()) {
+ if (!gl.isExtensionAvailable("GLX_NV_float_buffer")) {
+ throw new GLException("Floating-point pbuffers on X11 currently require NVidia hardware");
+ }
+ iattributes[niattribs++] = GLX.GLX_FLOAT_COMPONENTS_NV;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ }
+
+ // FIXME: add FSAA support? Don't want to get into a situation
+ // where we have to retry the glXChooseFBConfig call if it fails
+ // due to a lack of an antialiased visual...
+
+ iattributes[niattribs++] = 0; // null-terminate
+
+ int screen = 0; // FIXME: provide way to specify this?
+ int[] nelementsTmp = new int[1];
+ GLXFBConfig[] fbConfigs = GLX.glXChooseFBConfig(display, screen, iattributes, 0, nelementsTmp, 0);
+ if (fbConfigs == null || fbConfigs.length == 0 || fbConfigs[0] == null) {
+ throw new GLException("pbuffer creation error: glXChooseFBConfig() failed");
+ }
+ // Note that we currently don't allow selection of anything but
+ // the first GLXFBConfig in the returned list
+ GLXFBConfig fbConfig = fbConfigs[0];
+ int nelements = nelementsTmp[0];
+ if (nelements <= 0) {
+ throw new GLException("pbuffer creation error: couldn't find a suitable frame buffer configuration");
+ }
+
+ if (DEBUG) {
+ System.err.println("Found " + fbConfigs.length + " matching GLXFBConfigs");
+ System.err.println("Parameters of default one:");
+ System.err.println("render type: 0x" + Integer.toHexString(queryFBConfig(display, fbConfig, GLX.GLX_RENDER_TYPE)));
+ System.err.println("rgba: " + ((queryFBConfig(display, fbConfig, GLX.GLX_RENDER_TYPE) & GLX.GLX_RGBA_BIT) != 0));
+ System.err.println("r: " + queryFBConfig(display, fbConfig, GLX.GLX_RED_SIZE));
+ System.err.println("g: " + queryFBConfig(display, fbConfig, GLX.GLX_GREEN_SIZE));
+ System.err.println("b: " + queryFBConfig(display, fbConfig, GLX.GLX_BLUE_SIZE));
+ System.err.println("a: " + queryFBConfig(display, fbConfig, GLX.GLX_ALPHA_SIZE));
+ System.err.println("depth: " + queryFBConfig(display, fbConfig, GLX.GLX_DEPTH_SIZE));
+ System.err.println("double buffered: " + queryFBConfig(display, fbConfig, GLX.GLX_DOUBLEBUFFER));
+ }
+
+ // Create the p-buffer.
+ niattribs = 0;
+
+ iattributes[niattribs++] = GL.GLX_PBUFFER_WIDTH;
+ iattributes[niattribs++] = initWidth;
+ iattributes[niattribs++] = GL.GLX_PBUFFER_HEIGHT;
+ iattributes[niattribs++] = initHeight;
+
+ iattributes[niattribs++] = 0;
+
+ long tmpBuffer = GLX.glXCreatePbuffer(display, fbConfig, iattributes, 0);
+ if (tmpBuffer == 0) {
+ // FIXME: query X error code for detail error message
+ throw new GLException("pbuffer creation error: glXCreatePbuffer() failed");
+ }
+
+ // Set up instance variables
+ this.display = display;
+ drawable = tmpBuffer;
+ this.fbConfig = fbConfig;
+
+ // Determine the actual width and height we were able to create.
+ int[] tmp = new int[1];
+ GLX.glXQueryDrawable(display, drawable, GL.GLX_WIDTH, tmp, 0);
+ width = tmp[0];
+ GLX.glXQueryDrawable(display, drawable, GL.GLX_HEIGHT, tmp, 0);
+ height = tmp[0];
+
+ if (DEBUG) {
+ System.err.println("Created pbuffer " + width + " x " + height);
+ }
+ }
+
+ public int getFloatingPointMode() {
+ // Floating-point pbuffers currently require NVidia hardware on X11
+ return GLPbuffer.NV_FLOAT;
+ }
+
+ public GLXFBConfig getFBConfig() {
+ return fbConfig;
+ }
+
+ private int queryFBConfig(long display, GLXFBConfig fbConfig, int attrib) {
+ int[] tmp = new int[1];
+ if (GLX.glXGetFBConfigAttrib(display, fbConfig, attrib, tmp, 0) != 0) {
+ throw new GLException("glXGetFBConfigAttrib failed");
+ }
+ return tmp[0];
+ }
+}