summaryrefslogtreecommitdiffstats
path: root/src/jogl
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/JoglVersion.java10
-rw-r--r--src/jogl/classes/com/jogamp/opengl/cg/CgDynamicLibraryBundleInfo.java5
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/DesktopGLDynamicLookupHelper.java5
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java73
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java30
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java13
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLDrawableImpl.java2
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLDynamicLookupHelper.java6
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLGraphicsConfigurationFactory.java97
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLGraphicsConfigurationUtil.java133
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLJNILibLoader.java63
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java18
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/SharedResourceRunner.java249
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/awt/AWTUtil.java3
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java17
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java13
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGLCapabilities.java96
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java108
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfigurationFactory.java211
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLContext.java15
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java11
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java3
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java3
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WGLGLCapabilities.java243
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsBitmapWGLDrawable.java52
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java77
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLContext.java11
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java10
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java166
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java93
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawable.java2
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java306
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java631
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java510
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java80
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java2
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLCapabilities.java116
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java60
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java453
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java150
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java283
-rw-r--r--src/jogl/classes/com/jogamp/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java22
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java59
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/awt/TextureRenderer.java3
-rw-r--r--src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java74
-rw-r--r--src/jogl/classes/javax/media/opengl/GLCapabilities.java133
-rw-r--r--src/jogl/classes/javax/media/opengl/GLContext.java6
-rw-r--r--src/jogl/classes/javax/media/opengl/GLDrawableFactory.java91
-rw-r--r--src/jogl/classes/javax/media/opengl/GLProfile.java188
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/AWTGLAutoDrawable.java1
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLCanvas.java424
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLJPanel.java122
52 files changed, 3482 insertions, 2070 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/JoglVersion.java b/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
index b096f84ae..b1db2974a 100644
--- a/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
+++ b/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
@@ -33,8 +33,10 @@ import javax.media.opengl.*;
import com.jogamp.common.os.Platform;
import com.jogamp.common.util.VersionUtil;
import com.jogamp.common.util.JogampVersion;
+import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.nativewindow.NativeWindowVersion;
import java.util.jar.Manifest;
+import javax.media.nativewindow.AbstractGraphicsDevice;
public class JoglVersion extends JogampVersion {
@@ -68,15 +70,17 @@ public class JoglVersion extends JogampVersion {
}
public static StringBuffer getGLInfo(GL gl, StringBuffer sb) {
+ AbstractGraphicsDevice device = gl.getContext().getGLDrawable().getNativeSurface()
+ .getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice();
if(null==sb) {
sb = new StringBuffer();
}
GLContext ctx = gl.getContext();
sb.append(VersionUtil.SEPERATOR).append(Platform.getNewline());
- sb.append("Default Desktop ").append(GLProfile.getDefaultDesktopDevice().getConnection()).append(": ").append(GLProfile.glAvailabilityToString(GLProfile.getDefaultDesktopDevice()));
- sb.append(Platform.getNewline());
- sb.append("Default EGL ").append(GLProfile.getDefaultEGLDevice().getConnection()).append(": ").append(GLProfile.glAvailabilityToString(GLProfile.getDefaultEGLDevice()));
+ sb.append(ReflectionUtil.getBaseName(device.getClass())).append("[type ")
+ .append(device.getType()).append(", connection ").append(device.getConnection()).append("]: ")
+ .append(GLProfile.glAvailabilityToString(device));
sb.append(Platform.getNewline());
sb.append("Swap Interval ").append(gl.getSwapInterval());
sb.append(Platform.getNewline());
diff --git a/src/jogl/classes/com/jogamp/opengl/cg/CgDynamicLibraryBundleInfo.java b/src/jogl/classes/com/jogamp/opengl/cg/CgDynamicLibraryBundleInfo.java
index c414e6684..5655d1a7a 100644
--- a/src/jogl/classes/com/jogamp/opengl/cg/CgDynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/com/jogamp/opengl/cg/CgDynamicLibraryBundleInfo.java
@@ -28,13 +28,8 @@
package com.jogamp.opengl.cg;
-import com.jogamp.common.os.DynamicLookupHelper;
import com.jogamp.common.os.DynamicLibraryBundleInfo;
-import com.jogamp.common.os.NativeLibrary;
-import com.jogamp.common.os.Platform;
import java.util.*;
-import java.security.*;
-import javax.media.opengl.GLException;
public class CgDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
private static List/*<String>*/ glueLibNames;
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/DesktopGLDynamicLookupHelper.java b/src/jogl/classes/com/jogamp/opengl/impl/DesktopGLDynamicLookupHelper.java
index 08821910f..77b6ba981 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/DesktopGLDynamicLookupHelper.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/DesktopGLDynamicLookupHelper.java
@@ -28,13 +28,8 @@
package com.jogamp.opengl.impl;
-import com.jogamp.common.os.DynamicLibraryBundle;
-import com.jogamp.common.os.DynamicLibraryBundleInfo;
-import com.jogamp.common.os.DynamicLookupHelper;
import com.jogamp.common.os.NativeLibrary;
import java.util.*;
-import java.security.*;
-import javax.media.opengl.GLException;
public class DesktopGLDynamicLookupHelper extends GLDynamicLookupHelper {
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java
index cd121979a..c597e5d88 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java
@@ -40,16 +40,17 @@
package com.jogamp.opengl.impl;
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
+
import com.jogamp.common.os.DynamicLookupHelper;
import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.gluegen.runtime.FunctionAddressResolver;
import com.jogamp.gluegen.runtime.ProcAddressTable;
import com.jogamp.gluegen.runtime.opengl.GLExtensionNames;
import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
-import java.nio.ByteBuffer;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.StringTokenizer;
+
import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeSurface;
@@ -67,9 +68,9 @@ public abstract class GLContextImpl extends GLContext {
/**
* Context full qualified name: display_type + display_connection + major + minor + ctp.
- * This is the key for all cached ProcAddressTables, etc, to support multi display/device setups.
+ * This is the key for all cached GL ProcAddressTables, etc, to support multi display/device setups.
*/
- protected String contextFQN;
+ private String contextFQN;
// Cache of the functions that are available to be called at the current
// moment in time
@@ -171,9 +172,9 @@ public abstract class GLContextImpl extends GLContext {
public GL setGL(GL gl) {
if(DEBUG) {
- String sgl1 = (null!=this.gl)?this.gl.getClass().toString()+", "+this.gl.toString():"<null>";
- String sgl2 = (null!=gl)?gl.getClass().toString()+", "+gl.toString():"<null>";
- Exception e = new Exception("Info: setGL (OpenGL "+getGLVersion()+"): "+Thread.currentThread()+", "+sgl1+" -> "+sgl2);
+ String sgl1 = (null!=this.gl)?ReflectionUtil.getBaseName(this.gl.getClass())+", "+this.gl.toString():"<null>";
+ String sgl2 = (null!=gl)?ReflectionUtil.getBaseName(gl.getClass())+", "+gl.toString():"<null>";
+ Exception e = new Exception("Info: setGL (OpenGL "+getGLVersion()+"): "+Thread.currentThread().getName()+", "+sgl1+" -> "+sgl2);
e.printStackTrace();
}
this.gl = gl;
@@ -505,7 +506,9 @@ public abstract class GLContextImpl extends GLContext {
GLContext.getAvailableGLVersionsSet(device));
}
- mapGLVersions(device);
+ if ( !GLContext.getAvailableGLVersionsSet(device) ) {
+ mapGLVersions(device);
+ }
int reqMajor;
if(glp.isGL4()) {
@@ -532,20 +535,14 @@ public abstract class GLContextImpl extends GLContext {
return _ctx;
}
- private final void mapGLVersions(AbstractGraphicsDevice device) {
- if ( !GLContext.getAvailableGLVersionsSet(device) ) {
- synchronized (GLContext.deviceVersionAvailable) {
- createContextARBMapVersionsAvailable(4, false /* core */); // GL4
- createContextARBMapVersionsAvailable(4, true /* compat */); // GL4bc
- createContextARBMapVersionsAvailable(3, false /* core */); // GL3
- createContextARBMapVersionsAvailable(3, true /* compat */); // GL3bc
- createContextARBMapVersionsAvailable(2, true /* compat */); // GL2
- GLContext.setAvailableGLVersionsSet(device);
- }
- } else {
- if(DEBUG) {
- System.err.println(getThreadName() + ": no mapping, all versions set "+device.getConnection());
- }
+ private final void mapGLVersions(AbstractGraphicsDevice device) {
+ synchronized (GLContext.deviceVersionAvailable) {
+ createContextARBMapVersionsAvailable(4, false /* core */); // GL4
+ createContextARBMapVersionsAvailable(4, true /* compat */); // GL4bc
+ createContextARBMapVersionsAvailable(3, false /* core */); // GL3
+ createContextARBMapVersionsAvailable(3, true /* compat */); // GL3bc
+ createContextARBMapVersionsAvailable(2, true /* compat */); // GL2
+ GLContext.setAvailableGLVersionsSet(device);
}
}
@@ -561,15 +558,9 @@ public abstract class GLContextImpl extends GLContext {
ctp |= CTX_PROFILE_COMPAT ;
}
- // FIXME GL3GL4:
- // To avoid OpenGL implementation bugs and raise compatibility
- // within JOGL, we map to the proper GL version.
- // This may change later when GL3 and GL4 drivers become more mature!
- // Bug: To ensure GL profile compatibility within the JOGL application
- // Bug: we always try to map against the highest GL version,
- // Bug: so the use can always cast to a higher one
- // Bug: int majorMax=GLContext.getMaxMajor();
- // Bug: int minorMax=GLContext.getMaxMinor(majorMax);
+ // To ensure GL profile compatibility within the JOGL application
+ // we always try to map against the highest GL version,
+ // so the user can always cast to the highest available one.
int majorMax, minorMax;
int majorMin, minorMin;
int major[] = new int[1];
@@ -810,7 +801,6 @@ public abstract class GLContextImpl extends GLContext {
*
* @see #setContextVersion
*/
-
protected final void setGLFunctionAvailability(boolean force, int major, int minor, int ctp) {
if(null!=this.gl && null!=glProcAddressTable && !force) {
return; // already done and not forced
@@ -819,6 +809,8 @@ public abstract class GLContextImpl extends GLContext {
setGL(createGL(getGLDrawable().getGLProfile()));
}
+ updateGLXProcAddressTable();
+
AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
contextFQN = getContextFQN(adevice, major, minor, ctp);
@@ -826,8 +818,6 @@ public abstract class GLContextImpl extends GLContext {
System.err.println(getThreadName() + ": !!! Context FQN: "+contextFQN);
}
- updateGLXProcAddressTable(major, minor, ctp);
-
//
// UpdateGLProcAddressTable functionality
//
@@ -899,7 +889,7 @@ public abstract class GLContextImpl extends GLContext {
/**
* Updates the platform's 'GLX' function cache
*/
- protected abstract void updateGLXProcAddressTable(int major, int minor, int ctp);
+ protected abstract void updateGLXProcAddressTable();
protected boolean hasNativeES2Methods = false;
@@ -992,6 +982,14 @@ public abstract class GLContextImpl extends GLContext {
return false;
}
+ protected static String getContextFQN(AbstractGraphicsDevice device, int major, int minor, int ctp) {
+ return device.getUniqueID() + "-" + toHexString(compose8bit(major, minor, ctp, 0));
+ }
+
+ protected String getContextFQN() {
+ return contextFQN;
+ }
+
/** Indicates which floating-point pbuffer implementation is in
use. Returns one of GLPbuffer.APPLE_FLOAT, GLPbuffer.ATI_FLOAT,
or GLPbuffer.NV_FLOAT. */
@@ -1008,6 +1006,7 @@ public abstract class GLContextImpl extends GLContext {
/** Only called for offscreen contexts; needed by glReadPixels */
public abstract int getOffscreenContextPixelDataType();
+
//----------------------------------------------------------------------
// Helpers for buffer object optimizations
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java
index 01e0b8298..6e30f4aa0 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableFactoryImpl.java
@@ -165,7 +165,6 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
// fix caps ..
GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
caps2.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN
- caps2.setOnscreen(false);
caps2.setPBuffer(true);
capsChosen = caps2;
} else {
@@ -207,20 +206,8 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
if(null == device) {
throw new GLException("No shared device for requested: "+deviceReq);
}
- GLCapabilitiesImmutable capsChosen;
+ GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixOffScreenGLCapabilities(capsRequested, canCreateGLPbuffer(deviceReq));
- if( capsRequested.getDoubleBuffered() || capsRequested.isOnscreen() || capsRequested.isPBuffer()) {
- // fix caps ..
- GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
- caps2.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN
- caps2.setOnscreen(false);
- if(caps2.isPBuffer() && !canCreateGLPbuffer(device)) {
- caps2.setPBuffer(false);
- }
- capsChosen = caps2;
- } else {
- capsChosen = capsRequested;
- }
device.lock();
try {
return createGLDrawable( createOffscreenSurfaceImpl(device, capsChosen, capsRequested, chooser, width, height) );
@@ -233,25 +220,12 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
GLCapabilitiesImmutable capsRequested,
GLCapabilitiesChooser chooser,
int width, int height) {
- GLCapabilitiesImmutable capsChosen;
-
AbstractGraphicsDevice device = getOrCreateSharedDevice(deviceReq);
if(null == device) {
throw new GLException("No shared device for requested: "+deviceReq);
}
+ GLCapabilitiesImmutable capsChosen = GLGraphicsConfigurationUtil.fixOffScreenGLCapabilities(capsRequested, canCreateGLPbuffer(deviceReq));
- if( capsRequested.getDoubleBuffered() || capsRequested.isOnscreen() || capsRequested.isPBuffer()) {
- // fix caps ..
- GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
- caps2.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN
- caps2.setOnscreen(false);
- if(caps2.isPBuffer() && !canCreateGLPbuffer(device)) {
- caps2.setPBuffer(false);
- }
- capsChosen = caps2;
- } else {
- capsChosen = capsRequested;
- }
device.lock();
try {
return createOffscreenSurfaceImpl(device, capsChosen, capsRequested, chooser, width, height);
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java
index 45b04fac1..4aae89bcf 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableHelper.java
@@ -103,6 +103,8 @@ public class GLDrawableHelper {
if(0>index) {
index = listeners.size();
}
+ // GLEventListener may be added after context is created,
+ // hence we earmark initialization for the next display call.
listenersToBeInit.add(listener);
if(!listenersIter) {
// fast path
@@ -142,7 +144,6 @@ public class GLDrawableHelper {
for (int i=0; i < listeners.size(); i++) {
GLEventListener listener = (GLEventListener) listeners.get(i) ;
listener.dispose(drawable);
- listenersToBeInit.add(listener);
}
listenersIter = false;
}
@@ -164,6 +165,12 @@ public class GLDrawableHelper {
listenersIter = true;
for (int i=0; i < listeners.size(); i++) {
GLEventListener listener = (GLEventListener) listeners.get(i) ;
+
+ // If make current ctx, invoked by invokGL(..), results in a new ctx, init gets called.
+ // This may happen not just for initial setup, but for ctx recreation due to resource change (drawable/window),
+ // hence the must always be initialized unconditional.
+ listenersToBeInit.add(listener);
+
if ( ! init( listener, drawable, false ) ) {
throw new GLException("GLEventListener "+listener+" already initialized: "+drawable);
}
@@ -314,7 +321,7 @@ public class GLDrawableHelper {
Runnable initAction) {
if(null==context) {
if (DEBUG) {
- Exception e = new GLException(Thread.currentThread().getName()+"Info: GLDrawableHelper " + this + ".invokeGL(): NULL GLContext");
+ Exception e = new GLException(Thread.currentThread().getName()+" Info: GLDrawableHelper " + this + ".invokeGL(): NULL GLContext");
e.printStackTrace();
}
return;
@@ -323,7 +330,7 @@ public class GLDrawableHelper {
if(null==initAction) {
// disposal case
if(!context.isCreated()) {
- throw new GLException("Dispose case (no init action given): Native context must be created: "+context);
+ throw new GLException(Thread.currentThread().getName()+" GLDrawableHelper " + this + ".invokeGL(): Dispose case (no init action given): Native context is not created: "+context);
}
}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableImpl.java
index d7d2836aa..5459d886c 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableImpl.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDrawableImpl.java
@@ -146,7 +146,7 @@ public abstract class GLDrawableImpl implements GLDrawable {
AbstractGraphicsDevice aDevice = surface.getGraphicsConfiguration().getScreen().getDevice();
if(realizedArg) {
if(NativeSurface.LOCK_SURFACE_NOT_READY >= lockSurface()) {
- throw new GLException("X11GLXDrawable.setRealized(true): already realized, but surface not ready (lockSurface)");
+ throw new GLException("GLDrawableImpl.setRealized(true): already realized, but surface not ready (lockSurface)");
}
} else {
aDevice.lock();
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLDynamicLookupHelper.java b/src/jogl/classes/com/jogamp/opengl/impl/GLDynamicLookupHelper.java
index e94a9c6e0..c88e96c5e 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/GLDynamicLookupHelper.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLDynamicLookupHelper.java
@@ -29,12 +29,6 @@
package com.jogamp.opengl.impl;
import com.jogamp.common.os.DynamicLibraryBundle;
-import com.jogamp.common.os.DynamicLibraryBundleInfo;
-import com.jogamp.common.os.DynamicLookupHelper;
-import com.jogamp.common.os.NativeLibrary;
-import java.util.*;
-import java.security.*;
-import javax.media.opengl.GLException;
public class GLDynamicLookupHelper extends DynamicLibraryBundle {
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/GLGraphicsConfigurationFactory.java
new file mode 100644
index 000000000..62770daf8
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLGraphicsConfigurationFactory.java
@@ -0,0 +1,97 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.impl;
+
+import java.util.List;
+import javax.media.nativewindow.CapabilitiesChooser;
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.nativewindow.GraphicsConfigurationFactory;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.opengl.DefaultGLCapabilitiesChooser;
+
+public abstract class GLGraphicsConfigurationFactory extends GraphicsConfigurationFactory {
+
+ protected static int chooseCapabilities(CapabilitiesChooser chooser, CapabilitiesImmutable capsRequested,
+ List /*<CapabilitiesImmutable>*/ availableCaps, int recommendedIndex) {
+ if (null == capsRequested) {
+ throw new NativeWindowException("Null requested capabilities");
+ }
+ if ( 0 == availableCaps.size() ) {
+ if (DEBUG) {
+ System.err.println("Empty available capabilities");
+ }
+ return -1; // none available
+ }
+
+ if(null == chooser && 0 <= recommendedIndex) {
+ if (DEBUG) {
+ System.err.println("chooseCapabilities: Using recommendedIndex: idx " + recommendedIndex);
+ }
+ return recommendedIndex;
+ }
+ int chosenIndex = recommendedIndex;
+
+ if (null == chooser) {
+ chooser = new DefaultGLCapabilitiesChooser();
+ }
+
+ try {
+ chosenIndex = chooser.chooseCapabilities(capsRequested, availableCaps, recommendedIndex);
+ if(0 <= chosenIndex) {
+ if (DEBUG) {
+ System.err.println("chooseCapabilities: Chosen idx " + chosenIndex);
+ }
+ return chosenIndex;
+ }
+ } catch (NativeWindowException e) {
+ if (DEBUG) {
+ e.printStackTrace();
+ }
+ }
+
+ // keep on going ..
+ // seek first available one ..
+ for (chosenIndex = 0; chosenIndex < availableCaps.size() && availableCaps.get(chosenIndex) == null; chosenIndex++) {
+ // nop
+ }
+ if (chosenIndex == availableCaps.size()) {
+ // give up ..
+ if (DEBUG) {
+ System.err.println("chooseCapabilities: Failed .. nothing available, bail out");
+ }
+ return -1;
+ }
+ if (DEBUG) {
+ System.err.println("chooseCapabilities: Fall back to 1st available idx " + chosenIndex);
+ }
+
+ return chosenIndex;
+ }
+
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLGraphicsConfigurationUtil.java b/src/jogl/classes/com/jogamp/opengl/impl/GLGraphicsConfigurationUtil.java
new file mode 100644
index 000000000..53d42259a
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLGraphicsConfigurationUtil.java
@@ -0,0 +1,133 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.impl;
+
+import java.util.ArrayList;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesImmutable;
+
+public class GLGraphicsConfigurationUtil {
+ public static final int WINDOW_BIT = 1 << 0;
+ public static final int BITMAP_BIT = 1 << 1;
+ public static final int PBUFFER_BIT = 1 << 2;
+ public static final int ALL_BITS = WINDOW_BIT | BITMAP_BIT | PBUFFER_BIT ;
+
+ public static final StringBuffer winAttributeBits2String(StringBuffer sb, int winattrbits) {
+ if(null==sb) {
+ sb = new StringBuffer();
+ }
+ boolean seperator = false;
+ if( 0 != ( WINDOW_BIT & winattrbits ) ) {
+ sb.append("WINDOW");
+ seperator=true;
+ }
+ if( 0 != ( BITMAP_BIT & winattrbits ) ) {
+ if(seperator) {
+ sb.append(", ");
+ }
+ sb.append("BITMAP");
+ seperator=true;
+ }
+ if( 0 != ( PBUFFER_BIT & winattrbits ) ) {
+ if(seperator) {
+ sb.append(", ");
+ }
+ sb.append("PBUFFER");
+ }
+ return sb;
+ }
+
+ /**
+ * @return bitmask representing the input boolean in exclusive or logic, ie only one bit will be set
+ */
+ public static final int getWinAttributeBits(boolean isOnscreen, boolean isPBuffer) {
+ int winattrbits = 0;
+ if(isOnscreen) {
+ winattrbits |= WINDOW_BIT;
+ } else if (!isPBuffer) {
+ winattrbits |= BITMAP_BIT;
+ } else {
+ winattrbits |= PBUFFER_BIT;
+ }
+ return winattrbits;
+ }
+
+ /**
+ * @see #getWinAttributeBits(boolean, boolean)
+ */
+ public static final int getWinAttributeBits(GLCapabilitiesImmutable caps) {
+ return getWinAttributeBits(caps.isOnscreen(), caps.isPBuffer());
+ }
+
+ public static final boolean addGLCapabilitiesPermutations(ArrayList capsBucket, GLCapabilitiesImmutable temp, int winattrbits) {
+ int preSize = capsBucket.size();
+ if( 0 != ( WINDOW_BIT & winattrbits ) ) {
+ GLCapabilities cpy = (GLCapabilities) temp.cloneMutable();
+ cpy.setOnscreen(true);
+ capsBucket.add(cpy);
+ }
+ if( 0 != ( PBUFFER_BIT & winattrbits ) ) {
+ GLCapabilities cpy = (GLCapabilities) temp.cloneMutable();
+ cpy.setPBuffer(true);
+ capsBucket.add(cpy);
+ }
+ if( 0 != ( BITMAP_BIT & winattrbits ) ) {
+ GLCapabilities cpy = (GLCapabilities) temp.cloneMutable();
+ cpy.setOnscreen(false);
+ cpy.setPBuffer(false);
+ capsBucket.add(cpy);
+ }
+ return capsBucket.size() > preSize;
+ }
+
+ public static GLCapabilitiesImmutable fixGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean pbufferAvailable)
+ {
+ if( !capsRequested.isOnscreen() ) {
+ return fixOffScreenGLCapabilities(capsRequested, pbufferAvailable);
+ }
+ return capsRequested;
+ }
+ public static GLCapabilitiesImmutable fixOffScreenGLCapabilities(GLCapabilitiesImmutable capsRequested, boolean pbufferAvailable)
+ {
+ if( capsRequested.getDoubleBuffered() ||
+ capsRequested.isOnscreen() ||
+ ( !pbufferAvailable && capsRequested.isPBuffer() ) )
+ {
+ // fix caps ..
+ GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
+ caps2.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN
+ caps2.setOnscreen(false);
+ if(caps2.isPBuffer() && !pbufferAvailable) {
+ caps2.setPBuffer(false);
+ }
+ return caps2;
+ }
+ return capsRequested;
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLJNILibLoader.java b/src/jogl/classes/com/jogamp/opengl/impl/GLJNILibLoader.java
deleted file mode 100644
index 1daf3358b..000000000
--- a/src/jogl/classes/com/jogamp/opengl/impl/GLJNILibLoader.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * - Redistribution of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistribution in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * Neither the name of Sun Microsystems, Inc. or the names of
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * This software is provided "AS IS," without a warranty of any kind. ALL
- * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
- * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
- * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
- * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
- * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
- * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
- * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
- * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
- * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
- * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
- *
- * You acknowledge that this software is not designed or intended for use
- * in the design, construction, operation or maintenance of any nuclear
- * facility.
- *
- * Sun gratefully acknowledges that this software was originally authored
- * and developed by Kenneth Bradley Russell and Christopher John Kline.
- */
-
-package com.jogamp.opengl.impl;
-
-// FIXME: refactor Java SE dependencies
-//import java.awt.Toolkit;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.HashSet;
-import com.jogamp.common.jvm.JNILibLoaderBase;
-
-public class GLJNILibLoader extends JNILibLoaderBase {
- public static void loadNEWT() {
- AccessController.doPrivileged(new PrivilegedAction() {
- public Object run() {
- loadLibrary("newt", nativeOSPreload, true);
- return null;
- }
- });
- }
-
- private static final String[] nativeOSPreload = { "nativewindow_x11" };
-}
-
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java
index 558cda106..5119f5360 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/GLPbufferImpl.java
@@ -104,16 +104,18 @@ public class GLPbufferImpl implements GLPbuffer {
DisposeAction disposeAction = new DisposeAction();
public void destroy() {
- if (null != context) {
- try {
- drawableHelper.invokeGL(pbufferDrawable, context, disposeAction, null);
- } catch (GLException gle) {
- gle.printStackTrace();
+ if(pbufferDrawable.isRealized()) {
+ if (null != context && context.isCreated()) {
+ try {
+ drawableHelper.invokeGL(pbufferDrawable, context, disposeAction, null);
+ } catch (GLException gle) {
+ gle.printStackTrace();
+ }
+ context.destroy();
+ // drawableHelper.reset();
}
- drawableHelper.reset();
- context.destroy();
+ pbufferDrawable.destroy();
}
- pbufferDrawable.destroy();
}
public void setSize(int width, int height) {
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/SharedResourceRunner.java b/src/jogl/classes/com/jogamp/opengl/impl/SharedResourceRunner.java
new file mode 100644
index 000000000..765c6620d
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/SharedResourceRunner.java
@@ -0,0 +1,249 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+package com.jogamp.opengl.impl;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+
+public class SharedResourceRunner implements Runnable {
+ protected static final boolean DEBUG = GLDrawableImpl.DEBUG;
+
+ public static interface Resource {
+ AbstractGraphicsDevice getDevice();
+ AbstractGraphicsScreen getScreen();
+ GLDrawableImpl getDrawable();
+ GLContextImpl getContext();
+ }
+
+ public static interface Implementation {
+ Resource createSharedResource(String connection);
+ void releaseSharedResource(Resource shared);
+ void clear();
+
+ Resource mapPut(String connection, Resource resource);
+ Resource mapGet(String connection);
+ Collection/*<Resource>*/ mapValues();
+ }
+
+ Implementation impl = null;
+
+ boolean ready = false;
+ boolean released = false;
+ boolean shouldRelease = false;
+ String initConnection = null;
+ String releaseConnection = null;
+
+ HashSet devicesTried = new HashSet();
+
+ private boolean getDeviceTried(String connection) {
+ synchronized (devicesTried) {
+ return devicesTried.contains(connection);
+ }
+ }
+ private void addDeviceTried(String connection) {
+ synchronized (devicesTried) {
+ devicesTried.add(connection);
+ }
+ }
+ private void removeDeviceTried(String connection) {
+ synchronized (devicesTried) {
+ devicesTried.remove(connection);
+ }
+ }
+
+ public SharedResourceRunner(Implementation impl) {
+ this.impl = impl;
+ }
+
+ public SharedResourceRunner.Resource getShared(AbstractGraphicsDevice device) {
+ String connection = device.getConnection();
+ return impl.mapGet(connection);
+ }
+
+ public SharedResourceRunner.Resource getOrCreateShared(AbstractGraphicsDevice device) {
+ String connection = device.getConnection();
+ SharedResourceRunner.Resource sr = impl.mapGet(connection);
+
+ if (null == sr && !getDeviceTried(connection)) {
+ addDeviceTried(connection);
+ if (DEBUG) {
+ System.err.println("getOrCreateShared() " + connection + ": trying");
+ }
+ doAndWait(connection, null);
+ sr = impl.mapGet(connection);
+ if (DEBUG) {
+ Throwable t = new Throwable("getOrCreateSharedl() " + connection + ": done");
+ t.printStackTrace();
+ }
+ }
+ return sr;
+ }
+
+ public SharedResourceRunner.Resource releaseShared(AbstractGraphicsDevice device) {
+ String connection = device.getConnection();
+ SharedResourceRunner.Resource sr = impl.mapGet(connection);
+
+ if (null != sr) {
+ removeDeviceTried(connection);
+ if (DEBUG) {
+ System.err.println("releaseShared() " + connection + ": trying");
+ }
+ doAndWait(null, connection);
+ if (DEBUG) {
+ Throwable t = new Throwable("releaseSharedl() " + connection + ": done");
+ t.printStackTrace();
+ }
+ }
+ return sr;
+ }
+
+ private final void doAndWait(String initConnection, String releaseConnection) {
+ // wait until thread becomes ready to init new device,
+ // pass the device and release the sync
+ String threadName = Thread.currentThread().getName();
+ if (DEBUG) {
+ System.err.println(threadName + " doAndWait START init: " + initConnection + ", release: "+releaseConnection);
+ }
+ synchronized (this) {
+ while (!ready) {
+ try {
+ this.wait();
+ } catch (InterruptedException ex) {
+ }
+ }
+ if (DEBUG) {
+ System.err.println(threadName + " initializeAndWait set command init: " + initConnection + ", release: "+releaseConnection);
+ }
+ this.initConnection = initConnection;
+ this.releaseConnection = releaseConnection;
+ this.notifyAll();
+
+ // wait until thread has init/released the device
+ while (!ready || null != this.initConnection || null != this.releaseConnection) {
+ try {
+ this.wait();
+ } catch (InterruptedException ex) {
+ }
+ }
+ if (DEBUG) {
+ System.err.println(threadName + " initializeAndWait END init: " + initConnection + ", release: "+releaseConnection);
+ }
+ }
+ // done
+ }
+
+ public final void releaseAndWait() {
+ synchronized (this) {
+ shouldRelease = true;
+ this.notifyAll();
+
+ while (!released) {
+ try {
+ this.wait();
+ } catch (InterruptedException ex) {
+ }
+ }
+ }
+ }
+
+ public final void run() {
+ String threadName = Thread.currentThread().getName();
+
+ if (DEBUG) {
+ System.err.println(threadName + " STARTED");
+ }
+
+ synchronized (this) {
+ while (!shouldRelease) {
+ try {
+ // wait for stop or init
+ ready = true;
+ if (DEBUG) {
+ System.err.println(threadName + " -> ready");
+ }
+ notifyAll();
+ this.wait();
+ } catch (InterruptedException ex) { }
+ ready = false;
+
+ if (!shouldRelease) {
+ if (DEBUG) {
+ System.err.println(threadName + " woke up for device connection init: " + initConnection +
+ ", release: " + releaseConnection);
+ }
+ if(null != initConnection) {
+ if (DEBUG) {
+ System.err.println(threadName + " create Shared for: " + initConnection);
+ }
+ Resource sr = impl.createSharedResource(initConnection);
+ if (null != sr) {
+ impl.mapPut(initConnection, sr);
+ }
+ }
+ if(null != releaseConnection) {
+ if (DEBUG) {
+ System.err.println(threadName + " release Shared for: " + releaseConnection);
+ }
+ Resource sr = impl.mapPut(releaseConnection, null);
+ if (null != sr) {
+ impl.releaseSharedResource(sr);
+ }
+ }
+ }
+ initConnection = null;
+ releaseConnection = null;
+ }
+
+ if (DEBUG) {
+ System.err.println(threadName + " release START");
+ }
+
+ releaseSharedResources();
+
+ if (DEBUG) {
+ System.err.println(threadName + " release END");
+ }
+
+ released = true;
+ ready = false;
+ notifyAll();
+ }
+ }
+
+ private void releaseSharedResources() {
+ Collection/*<Resource>*/ sharedResources = impl.mapValues();
+ for (Iterator iter = sharedResources.iterator(); iter.hasNext();) {
+ Resource sr = (Resource) iter.next();
+ impl.releaseSharedResource(sr);
+ }
+ impl.clear();
+ }
+}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/awt/AWTUtil.java b/src/jogl/classes/com/jogamp/opengl/impl/awt/AWTUtil.java
index 36c0a3250..081d1f9b3 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/awt/AWTUtil.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/awt/AWTUtil.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -38,8 +39,6 @@ package com.jogamp.opengl.impl.awt;
import com.jogamp.nativewindow.impl.jawt.*;
-import com.jogamp.opengl.impl.*;
-
import javax.media.opengl.*;
import java.lang.reflect.*;
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java
index 246814537..107d7fbbb 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLContext.java
@@ -41,6 +41,8 @@ import com.jogamp.gluegen.runtime.ProcAddressTable;
import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
import java.nio.*;
import java.util.*;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
public abstract class EGLContext extends GLContextImpl {
private boolean eglQueryStringInitialized;
@@ -191,21 +193,24 @@ public abstract class EGLContext extends GLContextImpl {
return true;
}
- protected final void updateGLXProcAddressTable(int major, int minor, int ctp) {
+ protected final void updateGLXProcAddressTable() {
+ AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
+ String key = adevice.getUniqueID();
if (DEBUG) {
- System.err.println(getThreadName() + ": !!! Initializing EGL extension address table");
+ System.err.println(getThreadName() + ": !!! Initializing EGLextension address table: "+key);
}
eglQueryStringInitialized = false;
eglQueryStringAvailable = false;
EGLExtProcAddressTable table = null;
synchronized(mappedContextTypeObjectLock) {
- table = (EGLExtProcAddressTable) mappedGLXProcAddress.get( contextFQN );
+ table = (EGLExtProcAddressTable) mappedGLXProcAddress.get( key );
}
if(null != table) {
eglExtProcAddressTable = table;
if(DEBUG) {
- System.err.println(getThreadName() + ": !!! GLContext EGL ProcAddressTable reusing key("+contextFQN+") -> "+table.hashCode());
+ System.err.println(getThreadName() + ": !!! GLContext EGL ProcAddressTable reusing key("+key+") -> "+table.hashCode());
}
} else {
if (eglExtProcAddressTable == null) {
@@ -215,9 +220,9 @@ public abstract class EGLContext extends GLContextImpl {
}
resetProcAddressTable(getEGLExtProcAddressTable());
synchronized(mappedContextTypeObjectLock) {
- mappedGLXProcAddress.put(contextFQN, getEGLExtProcAddressTable());
+ mappedGLXProcAddress.put(key, getEGLExtProcAddressTable());
if(DEBUG) {
- System.err.println(getThreadName() + ": !!! GLContext EGL ProcAddressTable mapping key("+contextFQN+") -> "+getEGLExtProcAddressTable().hashCode());
+ System.err.println(getThreadName() + ": !!! GLContext EGL ProcAddressTable mapping key("+key+") -> "+getEGLExtProcAddressTable().hashCode());
}
}
}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java
index f451cb9bc..c32f2f22c 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLDrawableFactory.java
@@ -37,13 +37,16 @@
package com.jogamp.opengl.impl.egl;
import javax.media.nativewindow.*;
+import javax.media.nativewindow.egl.EGLGraphicsDevice;
import javax.media.opengl.*;
+
import com.jogamp.common.JogampRuntimeException;
import com.jogamp.common.util.*;
import com.jogamp.opengl.impl.*;
import com.jogamp.nativewindow.impl.ProxySurface;
+
import java.util.HashMap;
-import javax.media.nativewindow.egl.EGLGraphicsDevice;
+import java.util.List;
public class EGLDrawableFactory extends GLDrawableFactoryImpl {
@@ -166,6 +169,10 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
return null;
}
+ SharedResource getOrCreateSharedResource(AbstractGraphicsDevice device) {
+ return (SharedResource) getOrCreateShared(device);
+ }
+
public GLDynamicLookupHelper getGLDynamicLookupHelper(int esProfile) {
if (2==esProfile) {
if(null==eglES2DynamicLookupHelper) {
@@ -184,6 +191,10 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
protected final void shutdownInstance() {}
+ protected List/*GLCapabilitiesImmutable*/ getAvailableCapabilitiesImpl(AbstractGraphicsDevice device) {
+ return EGLGraphicsConfigurationFactory.getAvailableCapabilities(this, device);
+ }
+
protected GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) {
if (target == null) {
throw new IllegalArgumentException("Null target");
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGLCapabilities.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGLCapabilities.java
new file mode 100644
index 000000000..db6d485e3
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGLCapabilities.java
@@ -0,0 +1,96 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.impl.egl;
+
+import java.util.Comparator;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
+
+public class EGLGLCapabilities extends GLCapabilities {
+ long eglcfg;
+ int eglcfgid;
+
+ /** Comparing EGLConfig ID only */
+ public static class EglCfgIDComparator implements Comparator {
+
+ public int compare(Object o1, Object o2) {
+ if ( ! ( o1 instanceof EGLGLCapabilities ) ) {
+ Class c = (null != o1) ? o1.getClass() : null ;
+ throw new ClassCastException("arg1 not a EGLGLCapabilities object: " + c);
+ }
+ if ( ! ( o2 instanceof EGLGLCapabilities ) ) {
+ Class c = (null != o2) ? o2.getClass() : null ;
+ throw new ClassCastException("arg2 not a EGLGLCapabilities object: " + c);
+ }
+
+ final EGLGLCapabilities caps1 = (EGLGLCapabilities) o1;
+ final long id1 = caps1.getEGLConfigID();
+
+ final EGLGLCapabilities caps2 = (EGLGLCapabilities) o2;
+ final long id2 = caps2.getEGLConfigID();
+
+ if(id1 > id2) {
+ return 1;
+ } else if(id1 < id2) {
+ return -1;
+ }
+ return 0;
+ }
+ }
+
+ public EGLGLCapabilities(long eglcfg, int eglcfgid, GLProfile glp) {
+ super(glp);
+ this.eglcfg = eglcfg;
+ this.eglcfgid = eglcfgid;
+ }
+
+ public Object cloneMutable() {
+ return clone();
+ }
+
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (RuntimeException e) {
+ throw new GLException(e);
+ }
+ }
+
+ final public long getEGLConfig() { return eglcfg; }
+ final public int getEGLConfigID() { return eglcfgid; }
+
+ public StringBuffer toString(StringBuffer sink) {
+ if(null == sink) {
+ sink = new StringBuffer();
+ }
+ sink.append("0x").append(Long.toHexString(eglcfgid)).append(": ");
+ return super.toString(sink);
+ }
+} \ No newline at end of file
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java
index fd37c1f6d..eca324046 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfiguration.java
@@ -36,30 +36,29 @@
package com.jogamp.opengl.impl.egl;
-import com.jogamp.common.nio.PointerBuffer;
+import java.util.ArrayList;
import javax.media.nativewindow.*;
import javax.media.nativewindow.egl.*;
import javax.media.opengl.*;
+import com.jogamp.common.nio.PointerBuffer;
+import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.opengl.impl.*;
public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable {
protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration");
- public long getNativeConfig() {
- return config;
+ public final long getNativeConfig() {
+ return ((EGLGLCapabilities)capabilitiesChosen).getEGLConfig();
}
- public int getNativeConfigID() {
- return configID;
+ public final int getNativeConfigID() {
+ return ((EGLGLCapabilities)capabilitiesChosen).getEGLConfigID();
}
EGLGraphicsConfiguration(AbstractGraphicsScreen absScreen,
- GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser,
- long cfg, int cfgID) {
+ EGLGLCapabilities capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) {
super(absScreen, capsChosen, capsRequested);
this.chooser = chooser;
- config = cfg;
- configID = cfgID;
}
public static EGLGraphicsConfiguration create(GLCapabilitiesImmutable capsRequested, AbstractGraphicsScreen absScreen, int cfgID) {
@@ -73,8 +72,8 @@ public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration imple
}
GLProfile glp = capsRequested.getGLProfile();
long cfg = EGLConfigId2EGLConfig(glp, dpy, cfgID);
- GLCapabilitiesImmutable caps = EGLConfig2Capabilities(glp, dpy, cfg, false, capsRequested.isOnscreen(), capsRequested.isPBuffer());
- return new EGLGraphicsConfiguration(absScreen, caps, capsRequested, new DefaultGLCapabilitiesChooser(), cfg, cfgID);
+ EGLGLCapabilities caps = EGLConfig2Capabilities(glp, dpy, cfg, false, capsRequested.isOnscreen(), capsRequested.isPBuffer());
+ return new EGLGraphicsConfiguration(absScreen, caps, capsRequested, new DefaultGLCapabilitiesChooser());
}
public Object clone() {
@@ -88,8 +87,6 @@ public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration imple
if(null!=newConfig) {
// FIXME: setScreen( ... );
setChosenCapabilities(newConfig.getChosenCapabilities());
- config = newConfig.getNativeConfig();
- configID = newConfig.getNativeConfigID();
if(DEBUG) {
System.err.println("!!! updateGraphicsConfiguration: "+this);
}
@@ -115,27 +112,61 @@ public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration imple
return configs.get(0);
}
- static boolean EGLConfigDrawableTypeVerify(int val, boolean onscreen, boolean usePBuffer) {
- boolean res;
+ static int EGLConfigDrawableTypeBits(final long display, final long config) {
+ int val = 0;
- if ( onscreen ) {
- res = ( 0 != (val & EGL.EGL_WINDOW_BIT) ) ;
- } else {
- if ( usePBuffer ) {
- res = ( 0 != (val & EGL.EGL_PBUFFER_BIT) ) ;
- } else {
- res = ( 0 != (val & EGL.EGL_PIXMAP_BIT) ) ;
- }
+ int[] stype = new int[1];
+ if(! EGL.eglGetConfigAttrib(display, config, EGL.EGL_SURFACE_TYPE, stype, 0)) {
+ throw new GLException("Could not determine EGL_SURFACE_TYPE !!!");
+ }
+
+ if ( 0 != ( stype[0] & EGL.EGL_WINDOW_BIT ) ) {
+ val |= GLGraphicsConfigurationUtil.WINDOW_BIT;
+ }
+ if ( 0 != ( stype[0] & EGL.EGL_PIXMAP_BIT ) ) {
+ val |= GLGraphicsConfigurationUtil.BITMAP_BIT;
+ }
+ if ( 0 != ( stype[0] & EGL.EGL_PBUFFER_BIT ) ) {
+ val |= GLGraphicsConfigurationUtil.PBUFFER_BIT;
}
- return res;
+ return val;
}
- public static GLCapabilitiesImmutable EGLConfig2Capabilities(GLProfile glp, long display, long config,
+ public static EGLGLCapabilities EGLConfig2Capabilities(GLProfile glp, long display, long config,
boolean relaxed, boolean onscreen, boolean usePBuffer) {
- GLCapabilities caps = new GLCapabilities(glp);
+ ArrayList bucket = new ArrayList();
+ final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer);
+ if( EGLConfig2Capabilities(bucket, glp, display, config, winattrmask) ) {
+ return (EGLGLCapabilities) bucket.get(0);
+ } else if ( relaxed && EGLConfig2Capabilities(bucket, glp, display, config, GLGraphicsConfigurationUtil.ALL_BITS) ) {
+ return (EGLGLCapabilities) bucket.get(0);
+ }
+ return null;
+ }
+
+ public static boolean EGLConfig2Capabilities(ArrayList capsBucket,
+ GLProfile glp, long display, long config,
+ int winattrmask) {
+ final int allDrawableTypeBits = EGLConfigDrawableTypeBits(display, config);
+ final int drawableTypeBits = winattrmask & allDrawableTypeBits;
+
+ if( 0 == drawableTypeBits ) {
+ return false;
+ }
+
int[] val = new int[1];
+ // get the configID
+ if(!EGL.eglGetConfigAttrib(display, config, EGL.EGL_CONFIG_ID, val, 0)) {
+ if(DEBUG) {
+ // FIXME: this happens on a ATI PC Emulation ..
+ System.err.println("EGL couldn't retrieve ConfigID for config "+toHexString(config)+", error "+toHexString(EGL.eglGetError()));
+ }
+ return false;
+ }
+ GLCapabilities caps = new EGLGLCapabilities(config, val[0], glp);
+
// Read the actual configuration into the choosen caps
if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_RED_SIZE, val, 0)) {
caps.setRedBits(val[0]);
@@ -177,26 +208,7 @@ public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration imple
caps.setTransparentAlphaValue(val[0]==EGL.EGL_DONT_CARE?-1:val[0]);
} */
}
- if(EGL.eglGetConfigAttrib(display, config, EGL.EGL_SURFACE_TYPE, val, 0)) {
- if(EGLConfigDrawableTypeVerify(val[0], onscreen, usePBuffer)) {
- caps.setDoubleBuffered(onscreen);
- caps.setOnscreen(onscreen);
- caps.setPBuffer(usePBuffer);
- } else if(relaxed) {
- caps.setDoubleBuffered( 0 != (val[0] & EGL.EGL_WINDOW_BIT) );
- caps.setOnscreen( 0 != (val[0] & EGL.EGL_WINDOW_BIT) );
- caps.setPBuffer ( 0 != (val[0] & EGL.EGL_PBUFFER_BIT) );
- } else {
- if(DEBUG) {
- System.err.println("EGL_SURFACE_TYPE does not match: req(onscrn "+onscreen+", pbuffer "+usePBuffer+"), got(onscreen "+( 0 != (val[0] & EGL.EGL_WINDOW_BIT) )+", pbuffer "+( 0 != (val[0] & EGL.EGL_PBUFFER_BIT) )+", pixmap "+( 0 != (val[0] & EGL.EGL_PIXMAP_BIT) )+")");
- }
- return null;
- }
- } else {
- throw new GLException("Could not determine EGL_SURFACE_TYPE !!!");
- }
-
- return caps;
+ return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, caps, drawableTypeBits );
}
public static int[] GLCapabilities2AttribList(GLCapabilitiesImmutable caps) {
@@ -288,7 +300,7 @@ public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration imple
}
public String toString() {
- return getClass().toString()+"["+getScreen()+", eglConfigID 0x"+Integer.toHexString(configID)+
+ return ReflectionUtil.getBaseName(getClass())+"["+getScreen()+", eglConfigID "+toHexString(getNativeConfigID())+
",\n\trequested " + getRequestedCapabilities()+
",\n\tchosen " + getChosenCapabilities()+
"]";
@@ -296,7 +308,5 @@ public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration imple
}
private GLCapabilitiesChooser chooser;
- private long config;
- private int configID;
}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfigurationFactory.java
index fc2416cb9..3e3d4f964 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/egl/EGLGraphicsConfigurationFactory.java
@@ -33,7 +33,6 @@
package com.jogamp.opengl.impl.egl;
-import java.io.PrintStream;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.AbstractGraphicsScreen;
@@ -41,17 +40,22 @@ import javax.media.nativewindow.CapabilitiesChooser;
import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.DefaultGraphicsScreen;
import javax.media.nativewindow.GraphicsConfigurationFactory;
-import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.egl.EGLGraphicsDevice;
-import javax.media.opengl.DefaultGLCapabilitiesChooser;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesChooser;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
+import javax.media.opengl.GLDrawableFactory;
import com.jogamp.common.nio.PointerBuffer;
+import com.jogamp.opengl.impl.GLGraphicsConfigurationFactory;
+import com.jogamp.opengl.impl.GLGraphicsConfigurationUtil;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.io.PrintStream;
/** Subclass of GraphicsConfigurationFactory used when non-AWT tookits
@@ -59,8 +63,9 @@ import com.jogamp.common.nio.PointerBuffer;
to this one to change the accepted and returned types of the
GraphicsDevice and GraphicsConfiguration abstractions. */
-public class EGLGraphicsConfigurationFactory extends GraphicsConfigurationFactory {
+public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory {
protected static final boolean DEBUG = GraphicsConfigurationFactory.DEBUG || com.jogamp.opengl.impl.Debug.debug("EGL");
+ static EGLGLCapabilities.EglCfgIDComparator EglCfgIDComparator = new EGLGLCapabilities.EglCfgIDComparator();
EGLGraphicsConfigurationFactory() {
// become the selector for KD/EGL ..
@@ -93,6 +98,41 @@ public class EGLGraphicsConfigurationFactory extends GraphicsConfigurationFactor
absScreen);
}
+ protected static List/*<EGLGLCapabilities>*/ getAvailableCapabilities(EGLDrawableFactory factory, AbstractGraphicsDevice device) {
+ EGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResource(device);
+ if(null == sharedResource) {
+ throw new GLException("Shared resource for device n/a: "+device);
+ }
+ EGLGraphicsDevice eglDevice = sharedResource.getDevice();
+ long eglDisplay = eglDevice.getHandle();
+
+ List/*<EGLGLCapabilities>*/ availableCaps = null;
+ int[] maxConfigs = new int[1];
+
+ if(!EGL.eglGetConfigs(eglDisplay, null, 0, maxConfigs, 0)) {
+ throw new GLException("Graphics configuration get maxConfigs (eglGetConfigs) call failed, error "+toHexString(EGL.eglGetError()));
+ }
+ if(0 == maxConfigs[0]) {
+ throw new GLException("Graphics configuration get maxConfigs (eglGetConfigs) no configs");
+ }
+
+ PointerBuffer configs = PointerBuffer.allocateDirect(maxConfigs[0]);
+ int[] numConfigs = new int[1];
+
+ if(!EGL.eglGetConfigs(eglDisplay, configs, configs.capacity(), numConfigs, 0)) {
+ throw new GLException("Graphics configuration get all configs (eglGetConfigs) call failed, error "+toHexString(EGL.eglGetError()));
+ }
+ if (numConfigs[0] > 0) {
+ GLProfile glp = GLProfile.getDefault(device);
+ availableCaps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs[0], GLGraphicsConfigurationUtil.ALL_BITS);
+ if( null != availableCaps ) {
+ Collections.sort(availableCaps, EglCfgIDComparator);
+ }
+ }
+
+ return availableCaps;
+ }
+
private static EGLGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilitiesImmutable capsChosen,
GLCapabilitiesImmutable capsReq,
GLCapabilitiesChooser chooser,
@@ -100,7 +140,6 @@ public class EGLGraphicsConfigurationFactory extends GraphicsConfigurationFactor
if (capsChosen == null) {
capsChosen = new GLCapabilities(null);
}
- GLProfile glp = capsChosen.getGLProfile();
if(null==absScreen) {
throw new GLException("Null AbstractGraphicsScreen");
@@ -116,12 +155,10 @@ public class EGLGraphicsConfigurationFactory extends GraphicsConfigurationFactor
throw new GLException("Invalid EGL display: "+absDevice);
}
- if(!capsChosen.isOnscreen() && capsChosen.getDoubleBuffered()) {
- // OFFSCREEN !DOUBLE_BUFFER // FIXME DBLBUFOFFSCRN
- GLCapabilities caps2 = (GLCapabilities) capsChosen.cloneMutable();
- caps2.setDoubleBuffered(false);
- capsChosen = caps2;
- }
+ EGLDrawableFactory factory = (EGLDrawableFactory) GLDrawableFactory.getEGLFactory();
+ capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, factory.canCreateGLPbuffer(absDevice) );
+
+ GLProfile glp = capsChosen.getGLProfile();
EGLGraphicsConfiguration res = eglChooseConfig(eglDisplay, capsChosen, capsReq, chooser, absScreen);
if(null!=res) {
@@ -131,43 +168,6 @@ public class EGLGraphicsConfigurationFactory extends GraphicsConfigurationFactor
System.err.println("eglChooseConfig failed with given capabilities "+capsChosen);
}
- if (chooser == null) {
- chooser = new DefaultGLCapabilitiesChooser();
- }
-
- PointerBuffer configs = PointerBuffer.allocateDirect(10);
- int[] numConfigs = new int[1];
-
- if(!EGL.eglGetConfigs(eglDisplay, configs, configs.capacity(), numConfigs, 0)) {
- throw new GLException("Graphics configuration fetch (eglGetConfigs) failed");
- }
- if (numConfigs[0] == 0) {
- throw new GLException("Graphics configuration fetch (eglGetConfigs) - no EGLConfig found");
- }
- GLCapabilitiesImmutable[] caps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs[0],
- capsChosen.isOnscreen(), capsChosen.isPBuffer());
- if(DEBUG) {
- System.err.println("EGL Get Configs: "+numConfigs[0]+", Caps "+caps.length);
- printCaps("eglGetConfigs", caps, System.err);
- }
- int chosen = -1;
- try {
- chosen = chooser.chooseCapabilities(capsChosen, caps, -1);
- } catch (NativeWindowException e) { throw new GLException(e); }
- if(chosen<0) {
- throw new GLException("Graphics configuration chooser failed");
- }
- if(DEBUG) {
- System.err.println("Chosen "+caps[chosen]);
- }
- res = eglChooseConfig(eglDisplay, caps[chosen], capsReq, chooser, absScreen);
- if(null!=res) {
- return res;
- }
- if(DEBUG) {
- System.err.println("eglChooseConfig failed with eglGetConfig/choosen capabilities "+caps[chosen]);
- }
-
// Last try .. add a fixed embedded profile [ATI, Nokia, Intel, ..]
//
// rgb888 - d16, s4
@@ -221,73 +221,100 @@ public class EGLGraphicsConfigurationFactory extends GraphicsConfigurationFactor
}
static EGLGraphicsConfiguration eglChooseConfig(long eglDisplay,
- GLCapabilitiesImmutable capsChosen0, GLCapabilitiesImmutable capsRequested,
+ GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested,
GLCapabilitiesChooser chooser,
AbstractGraphicsScreen absScreen) {
- GLProfile glp = capsChosen0.getGLProfile();
- int[] attrs = EGLGraphicsConfiguration.GLCapabilities2AttribList(capsChosen0);
- PointerBuffer configs = PointerBuffer.allocateDirect(1);
+ GLProfile glp = capsChosen.getGLProfile();
+ boolean onscreen = capsChosen.isOnscreen();
+ boolean usePBuffer = capsChosen.isPBuffer();
+ List/*<EGLGLCapabilities>*/ availableCaps = null;
+ final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer);
+ int recommendedIndex = -1;
+ long recommendedEGLConfig = -1;
+ int[] maxConfigs = new int[1];
+
+ if(!EGL.eglGetConfigs(eglDisplay, null, 0, maxConfigs, 0)) {
+ throw new GLException("Graphics configuration get maxConfigs (eglGetConfigs) call failed, error "+toHexString(EGL.eglGetError()));
+ }
+ if(0 == maxConfigs[0]) {
+ throw new GLException("Graphics configuration get maxConfigs (eglGetConfigs) no configs");
+ }
+ if (DEBUG) {
+ System.err.println("!!! eglChooseConfig maxConfigs: "+maxConfigs[0]);
+ }
+
+ int[] attrs = EGLGraphicsConfiguration.GLCapabilities2AttribList(capsChosen);
+ PointerBuffer configs = PointerBuffer.allocateDirect(maxConfigs[0]);
int[] numConfigs = new int[1];
+
+ // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice
if (!EGL.eglChooseConfig(eglDisplay,
attrs, 0,
configs, configs.capacity(),
numConfigs, 0)) {
- throw new GLException("Graphics configuration selection (eglChooseConfig) failed for "+capsChosen0);
+ throw new GLException("Graphics configuration selection (eglChooseConfig) failed for "+capsChosen+", error "+toHexString(EGL.eglGetError()));
}
if (numConfigs[0] > 0) {
- if(DEBUG) {
- GLCapabilitiesImmutable[] caps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs[0],
- capsChosen0.isOnscreen(), capsChosen0.isPBuffer());
- System.err.println("EGL Choose Configs: "+numConfigs[0]+", Caps "+caps.length);
- printCaps("eglChooseConfig", caps, System.err);
- }
- int[] val = new int[1];
- // get the configID
- if(!EGL.eglGetConfigAttrib(eglDisplay, configs.get(0), EGL.EGL_CONFIG_ID, val, 0)) {
- if(DEBUG) {
- // FIXME: this happens on a ATI PC Emulation ..
- System.err.println("EGL couldn't retrieve ConfigID for already chosen eglConfig "+capsChosen0+", error 0x"+Integer.toHexString(EGL.eglGetError()));
+ availableCaps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs[0], winattrmask);
+ if(availableCaps.size() > 0) {
+ recommendedEGLConfig = configs.get(0);
+ recommendedIndex = 0;
+ if (DEBUG) {
+ System.err.println("!!! eglChooseConfig recommended fbcfg " + toHexString(recommendedEGLConfig) + ", idx " + recommendedIndex);
+ System.err.println("!!! user caps " + capsChosen);
+ System.err.println("!!! fbcfg caps " + availableCaps.get(recommendedIndex));
}
- return null;
+ } else if (DEBUG) {
+ System.err.println("!!! eglChooseConfig no caps for recommended fbcfg " + toHexString(configs.get(0)));
+ System.err.println("!!! user caps " + capsChosen);
}
- GLCapabilitiesImmutable capsChosen1 = EGLGraphicsConfiguration.EGLConfig2Capabilities(
- glp, eglDisplay, configs.get(0),
- true, capsChosen0.isOnscreen(), capsChosen0.isPBuffer());
- if(null!=capsChosen1) {
- if(DEBUG) {
- System.err.println("eglChooseConfig found: eglDisplay 0x"+Long.toHexString(eglDisplay)+
- ", eglConfig ID 0x"+Integer.toHexString(val[0])+
- ", "+capsChosen0+" -> "+capsChosen1);
- }
- return new EGLGraphicsConfiguration(absScreen, capsChosen1, capsRequested, chooser, configs.get(0), val[0]);
+ }
+
+ // 2nd choice: get all GLCapabilities available, no preferred recommendedIndex available
+ if( null == availableCaps || 0 == availableCaps.size() ) {
+ // reset ..
+ recommendedEGLConfig = -1;
+ recommendedIndex = -1;
+
+ if(!EGL.eglGetConfigs(eglDisplay, configs, configs.capacity(), numConfigs, 0)) {
+ throw new GLException("Graphics configuration get all configs (eglGetConfigs) call failed, error "+toHexString(EGL.eglGetError()));
}
- if(DEBUG) {
- System.err.println("eglChooseConfig couldn't verify: eglDisplay 0x"+Long.toHexString(eglDisplay)+
- ", eglConfig ID 0x"+Integer.toHexString(val[0])+
- ", for "+capsChosen0);
+ if (numConfigs[0] > 0) {
+ availableCaps = eglConfigs2GLCaps(glp, eglDisplay, configs, numConfigs[0], winattrmask);
}
- } else {
+ }
+
+ if( null == availableCaps || 0 == availableCaps.size() ) {
if(DEBUG) {
- System.err.println("EGL Choose Configs: None using eglDisplay 0x"+Long.toHexString(eglDisplay)+
- ", "+capsChosen0);
+ // FIXME: this happens on a ATI PC Emulation ..
+ System.err.println("Graphics configuration 1st choice and 2nd choice failed - no configs");
}
+ return null;
}
- return null;
+
+ int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex);
+ if ( 0 > chosenIndex ) {
+ if (DEBUG) {
+ Thread.dumpStack();
+ }
+ return null;
+ }
+ EGLGLCapabilities chosenCaps = (EGLGLCapabilities) availableCaps.get(chosenIndex);
+
+ return new EGLGraphicsConfiguration(absScreen, chosenCaps, capsRequested, chooser);
}
- static GLCapabilitiesImmutable[] eglConfigs2GLCaps(GLProfile glp, long eglDisplay, PointerBuffer configs, int num,
- boolean onscreen, boolean usePBuffer) {
- GLCapabilitiesImmutable[] caps = new GLCapabilitiesImmutable[num];
+ static List/*<GLCapabilitiesImmutable>*/ eglConfigs2GLCaps(GLProfile glp, long eglDisplay, PointerBuffer configs, int num, int winattrmask) {
+ ArrayList caps = new ArrayList(num);
for(int i=0; i<num; i++) {
- caps[i] = EGLGraphicsConfiguration.EGLConfig2Capabilities(glp, eglDisplay, configs.get(i),
- true, onscreen, usePBuffer);
+ EGLGraphicsConfiguration.EGLConfig2Capabilities(caps, glp, eglDisplay, configs.get(i), winattrmask);
}
return caps;
}
- static void printCaps(String prefix, GLCapabilitiesImmutable[] caps, PrintStream out) {
- for(int i=0; i<caps.length; i++) {
- out.println(prefix+"["+i+"] "+caps[i]);
+ static void printCaps(String prefix, List/*GLCapabilitiesImmutable*/ caps, PrintStream out) {
+ for(int i=0; i<caps.size(); i++) {
+ out.println(prefix+"["+i+"] "+caps.get(i));
}
}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLContext.java
index 6a916765a..3450c456e 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLContext.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLContext.java
@@ -223,18 +223,21 @@ public abstract class MacOSXCGLContext extends GLContextImpl
}
}
- protected final void updateGLXProcAddressTable(int major, int minor, int ctp) {
+ protected final void updateGLXProcAddressTable() {
+ AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
+ String key = adevice.getUniqueID();
if (DEBUG) {
- System.err.println(getThreadName() + ": !!! Initializing CGL extension address table");
+ System.err.println(getThreadName() + ": !!! Initializing CGL extension address table: "+key);
}
CGLExtProcAddressTable table = null;
synchronized(mappedContextTypeObjectLock) {
- table = (CGLExtProcAddressTable) mappedGLXProcAddress.get( contextFQN );
+ table = (CGLExtProcAddressTable) mappedGLXProcAddress.get( key );
}
if(null != table) {
cglExtProcAddressTable = table;
if(DEBUG) {
- System.err.println(getThreadName() + ": !!! GLContext CGL ProcAddressTable reusing key("+contextFQN+") -> "+table.hashCode());
+ System.err.println(getThreadName() + ": !!! GLContext CGL ProcAddressTable reusing key("+key+") -> "+table.hashCode());
}
} else {
if (cglExtProcAddressTable == null) {
@@ -244,9 +247,9 @@ public abstract class MacOSXCGLContext extends GLContextImpl
}
resetProcAddressTable(getCGLExtProcAddressTable());
synchronized(mappedContextTypeObjectLock) {
- mappedGLXProcAddress.put(contextFQN, getCGLExtProcAddressTable());
+ mappedGLXProcAddress.put(key, getCGLExtProcAddressTable());
if(DEBUG) {
- System.err.println(getThreadName() + ": !!! GLContext CGL ProcAddressTable mapping key("+contextFQN+") -> "+getCGLExtProcAddressTable().hashCode());
+ System.err.println(getThreadName() + ": !!! GLContext CGL ProcAddressTable mapping key("+key+") -> "+getCGLExtProcAddressTable().hashCode());
}
}
}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java
index 1895c8e67..421bae715 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java
@@ -41,14 +41,17 @@
package com.jogamp.opengl.impl.macosx.cgl;
import java.nio.*;
+import java.util.HashMap;
+import java.util.List;
+
import javax.media.nativewindow.*;
+import javax.media.nativewindow.macosx.MacOSXGraphicsDevice;
import javax.media.opengl.*;
+
import com.jogamp.common.JogampRuntimeException;
import com.jogamp.common.util.*;
import com.jogamp.opengl.impl.*;
import com.jogamp.nativewindow.impl.ProxySurface;
-import java.util.HashMap;
-import javax.media.nativewindow.macosx.MacOSXGraphicsDevice;
public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
private static final DesktopGLDynamicLookupHelper macOSXCGLDynamicLookupHelper;
@@ -123,6 +126,10 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
protected final void shutdownInstance() {}
+ protected List/*GLCapabilitiesImmutable*/ getAvailableCapabilitiesImpl(AbstractGraphicsDevice device) {
+ throw new UnsupportedOperationException("not yet implemented");
+ }
+
protected GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) {
if (target == null) {
throw new IllegalArgumentException("Null target");
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java
index 5d7a0375b..cc06a6775 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java
@@ -33,6 +33,7 @@
package com.jogamp.opengl.impl.macosx.cgl;
+import com.jogamp.opengl.impl.GLGraphicsConfigurationFactory;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.CapabilitiesChooser;
@@ -47,7 +48,7 @@ import javax.media.opengl.GLCapabilitiesImmutable;
to this one to change the accepted and returned types of the
GraphicsDevice and GraphicsConfiguration abstractions. */
-public class MacOSXCGLGraphicsConfigurationFactory extends GraphicsConfigurationFactory {
+public class MacOSXCGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory {
protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration");
MacOSXCGLGraphicsConfigurationFactory() {
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java
index 702d66fce..95b6f473f 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java
@@ -33,6 +33,7 @@
package com.jogamp.opengl.impl.macosx.cgl.awt;
+import com.jogamp.opengl.impl.GLGraphicsConfigurationFactory;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
@@ -54,7 +55,7 @@ import javax.media.opengl.GLException;
import com.jogamp.opengl.impl.macosx.cgl.MacOSXCGLGraphicsConfiguration;
-public class MacOSXAWTCGLGraphicsConfigurationFactory extends GraphicsConfigurationFactory {
+public class MacOSXAWTCGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory {
protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration");
public MacOSXAWTCGLGraphicsConfigurationFactory() {
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WGLGLCapabilities.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WGLGLCapabilities.java
new file mode 100644
index 000000000..b5be4bf8d
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WGLGLCapabilities.java
@@ -0,0 +1,243 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.impl.windows.wgl;
+
+import java.util.Comparator;
+
+import com.jogamp.nativewindow.impl.windows.GDI;
+import com.jogamp.nativewindow.impl.windows.PIXELFORMATDESCRIPTOR;
+import javax.media.opengl.GL;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
+
+public class WGLGLCapabilities extends GLCapabilities {
+ PIXELFORMATDESCRIPTOR pfd;
+ int pfdID;
+ int arb_pixelformat; // -1 PFD, 0 NOP, 1 ARB
+
+ /** Comparing pfd id only */
+ public static class PfdIDComparator implements Comparator {
+
+ public int compare(Object o1, Object o2) {
+ if ( ! ( o1 instanceof WGLGLCapabilities ) ) {
+ Class c = (null != o1) ? o1.getClass() : null ;
+ throw new ClassCastException("arg1 not a WGLGLCapabilities object: " + c);
+ }
+ if ( ! ( o2 instanceof WGLGLCapabilities ) ) {
+ Class c = (null != o2) ? o2.getClass() : null ;
+ throw new ClassCastException("arg2 not a WGLGLCapabilities object: " + c);
+ }
+
+ final WGLGLCapabilities caps1 = (WGLGLCapabilities) o1;
+ final long id1 = caps1.getPFDID();
+
+ final WGLGLCapabilities caps2 = (WGLGLCapabilities) o2;
+ final long id2 = caps2.getPFDID();
+
+ if(id1 > id2) {
+ return 1;
+ } else if(id1 < id2) {
+ return -1;
+ }
+ return 0;
+ }
+ }
+
+ public WGLGLCapabilities(PIXELFORMATDESCRIPTOR pfd, int pfdID, GLProfile glp) {
+ super(glp);
+ this.pfd = pfd;
+ this.pfdID = pfdID;
+ this.arb_pixelformat = 0;
+ }
+
+ public boolean setValuesByGDI() {
+ arb_pixelformat = -1;
+
+ setRedBits(pfd.getCRedBits());
+ setGreenBits(pfd.getCGreenBits());
+ setBlueBits(pfd.getCBlueBits());
+ setAlphaBits(pfd.getCAlphaBits());
+ setAccumRedBits(pfd.getCAccumRedBits());
+ setAccumGreenBits(pfd.getCAccumGreenBits());
+ setAccumBlueBits(pfd.getCAccumBlueBits());
+ setAccumAlphaBits(pfd.getCAccumAlphaBits());
+ setDepthBits(pfd.getCDepthBits());
+ setStencilBits(pfd.getCStencilBits());
+ setDoubleBuffered((pfd.getDwFlags() & GDI.PFD_DOUBLEBUFFER) != 0);
+ setStereo((pfd.getDwFlags() & GDI.PFD_STEREO) != 0);
+ setHardwareAccelerated((pfd.getDwFlags() & GDI.PFD_GENERIC_FORMAT) == 0
+ || (pfd.getDwFlags() & GDI.PFD_GENERIC_ACCELERATED) != 0);
+ // n/a with non ARB/GDI method:
+ // multisample
+ // opaque
+ // pbuffer
+
+ return true;
+ }
+
+ public boolean setValuesByARB(final int[] iattribs, final int niattribs, final int[] iresults) {
+ arb_pixelformat = 1;
+
+ for (int i = 0; i < niattribs; i++) {
+ int attr = iattribs[i];
+ switch (attr) {
+ case WGLExt.WGL_DRAW_TO_WINDOW_ARB:
+ case WGLExt.WGL_DRAW_TO_BITMAP_ARB:
+ case WGLExt.WGL_DRAW_TO_PBUFFER_ARB:
+ break;
+
+ case WGLExt.WGL_ACCELERATION_ARB:
+ setHardwareAccelerated(iresults[i] == WGLExt.WGL_FULL_ACCELERATION_ARB);
+ break;
+
+ case WGLExt.WGL_SUPPORT_OPENGL_ARB:
+ if (iresults[i] != GL.GL_TRUE) {
+ return false;
+ }
+ break;
+
+ case WGLExt.WGL_DEPTH_BITS_ARB:
+ setDepthBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_STENCIL_BITS_ARB:
+ setStencilBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_DOUBLE_BUFFER_ARB:
+ setDoubleBuffered(iresults[i] == GL.GL_TRUE);
+ break;
+
+ case WGLExt.WGL_STEREO_ARB:
+ setStereo(iresults[i] == GL.GL_TRUE);
+ break;
+
+ case WGLExt.WGL_PIXEL_TYPE_ARB:
+ // Fail softly with unknown results here
+ if (iresults[i] == WGLExt.WGL_TYPE_RGBA_ARB ||
+ iresults[i] == WGLExt.WGL_TYPE_RGBA_FLOAT_ARB) {
+ setPbufferFloatingPointBuffers(true);
+ }
+ break;
+
+ case WGLExt.WGL_FLOAT_COMPONENTS_NV:
+ if (iresults[i] != 0) {
+ setPbufferFloatingPointBuffers(true);
+ }
+ break;
+
+ case WGLExt.WGL_RED_BITS_ARB:
+ setRedBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_GREEN_BITS_ARB:
+ setGreenBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_BLUE_BITS_ARB:
+ setBlueBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_ALPHA_BITS_ARB:
+ setAlphaBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_ACCUM_RED_BITS_ARB:
+ setAccumRedBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_ACCUM_GREEN_BITS_ARB:
+ setAccumGreenBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_ACCUM_BLUE_BITS_ARB:
+ setAccumBlueBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_ACCUM_ALPHA_BITS_ARB:
+ setAccumAlphaBits(iresults[i]);
+ break;
+
+ case WGLExt.WGL_SAMPLE_BUFFERS_ARB:
+ setSampleBuffers(iresults[i] != 0);
+ break;
+
+ case WGLExt.WGL_SAMPLES_ARB:
+ setNumSamples(iresults[i]);
+ break;
+
+ default:
+ throw new GLException("Unknown pixel format attribute " + iattribs[i]);
+ }
+ }
+ return true;
+ }
+
+ public Object cloneMutable() {
+ return clone();
+ }
+
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (RuntimeException e) {
+ throw new GLException(e);
+ }
+ }
+
+ final public PIXELFORMATDESCRIPTOR getPFD() { return pfd; }
+ final public int getPFDID() { return pfdID; }
+
+ final public boolean isSetByARB() { return 0 < arb_pixelformat; }
+ final public boolean isSetByGDI() { return 0 > arb_pixelformat; }
+ final public boolean isSet() { return 0 != arb_pixelformat; }
+
+ public StringBuffer toString(StringBuffer sink) {
+ if(null == sink) {
+ sink = new StringBuffer();
+ }
+ sink.append(pfdID).append(" ");
+ switch (arb_pixelformat) {
+ case -1:
+ sink.append("gdi");
+ break;
+ case 0:
+ sink.append("nop");
+ break;
+ case 1:
+ sink.append("arb");
+ break;
+ default:
+ throw new InternalError("invalid arb_pixelformat: " + arb_pixelformat);
+ }
+ sink.append(": ");
+ return super.toString(sink);
+ }
+} \ No newline at end of file
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsBitmapWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsBitmapWGLDrawable.java
index 0d360b339..c61a8d0e4 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsBitmapWGLDrawable.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsBitmapWGLDrawable.java
@@ -40,6 +40,7 @@
package com.jogamp.opengl.impl.windows.wgl;
+import com.jogamp.common.nio.PointerBuffer;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.SurfaceChangeable;
import javax.media.opengl.GLContext;
@@ -73,11 +74,19 @@ public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable {
}
private void create() {
+ int werr;
NativeSurface ns = getNativeSurface();
+ if(DEBUG) {
+ System.err.println("WindowsBitmapWGLDrawable (1): "+ns);
+ }
WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)ns.getGraphicsConfiguration().getNativeGraphicsConfiguration();
GLCapabilitiesImmutable capabilities = (GLCapabilitiesImmutable)config.getRequestedCapabilities();
int width = getWidth();
int height = getHeight();
+
+ //
+ // 1. Create DIB Section
+ //
BITMAPINFO info = BITMAPINFO.create();
BITMAPINFOHEADER header = info.getBmiHeader();
int bitsPerPixel = (capabilities.getRedBits() +
@@ -97,22 +106,42 @@ public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable {
header.setBiClrUsed(0);
header.setBiClrImportant(0);
header.setBiCompression(GDI.BI_RGB);
- header.setBiSizeImage(width * height * bitsPerPixel / 8);
+ int byteNum = width * height * ( bitsPerPixel >> 3 ) ;
+ header.setBiSizeImage(byteNum);
+
+ PointerBuffer pb = PointerBuffer.allocateDirect(1);
+ hbitmap = GDI.CreateDIBSection(0, info, GDI.DIB_RGB_COLORS, pb, 0, 0);
+ werr = GDI.GetLastError();
+ if(DEBUG) {
+ long p = ( pb.capacity() > 0 ) ? pb.get(0) : 0;
+ System.err.println("WindowsBitmapWGLDrawable: pb sz/ptr "+pb.capacity() + ", "+toHexString(p));
+ System.err.println("WindowsBitmapWGLDrawable: " + width+"x"+height +
+ ", bpp " + bitsPerPixel +
+ ", bytes " + byteNum +
+ ", header sz " + header.size() +
+ ", DIB ptr num " + pb.capacity()+
+ ", "+capabilities+
+ ", werr "+werr);
+ }
+ if (hbitmap == 0) {
+ throw new GLException("Error creating offscreen bitmap of " + ns + ", werr " + werr);
+ }
+ //
+ // 2. Create memory DC (device context) , and associate it with the DIB.
+ //
long hdc = GDI.CreateCompatibleDC(0);
+ werr = GDI.GetLastError();
if (hdc == 0) {
- System.out.println("LastError: " + GDI.GetLastError());
- throw new GLException("Error creating device context for offscreen OpenGL context");
+ GDI.DeleteObject(hbitmap);
+ hbitmap = 0;
+ throw new GLException("Error creating device context for offscreen OpenGL context, werr "+werr);
}
((SurfaceChangeable)ns).setSurfaceHandle(hdc);
-
- hbitmap = GDI.CreateDIBSection(hdc, info, GDI.DIB_RGB_COLORS, null, 0, 0);
- if (hbitmap == 0) {
- GDI.DeleteDC(hdc);
- hdc = 0;
- throw new GLException("Error creating offscreen bitmap of width " + width +
- ", height " + height);
+ if(DEBUG) {
+ System.err.println("WindowsBitmapWGLDrawable (2): "+ns);
}
+
if ((origbitmap = GDI.SelectObject(hdc, hbitmap)) == 0) {
GDI.DeleteObject(hbitmap);
hbitmap = 0;
@@ -120,7 +149,8 @@ public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable {
hdc = 0;
throw new GLException("Error selecting bitmap into new device context");
}
- config.updateGraphicsConfiguration(getFactory(), ns);
+
+ config.updateGraphicsConfiguration(getFactory(), ns, null);
}
protected void destroyImpl() {
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java
index 015ef61a4..a307e295d 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsDummyWGLDrawable.java
@@ -47,31 +47,40 @@ import javax.media.opengl.GLProfile;
import javax.media.nativewindow.AbstractGraphicsScreen;
import com.jogamp.nativewindow.impl.ProxySurface;
import com.jogamp.nativewindow.impl.windows.GDI;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.NativeSurface;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLException;
public class WindowsDummyWGLDrawable extends WindowsWGLDrawable {
- private static final int f_dim = 128;
+ private static final int f_dim = 64;
private long hwnd, hdc;
protected WindowsDummyWGLDrawable(GLDrawableFactory factory, GLCapabilitiesImmutable caps, AbstractGraphicsScreen absScreen) {
super(factory, new ProxySurface(WindowsWGLGraphicsConfigurationFactory.createDefaultGraphicsConfiguration(caps, absScreen)), true);
hwnd = GDI.CreateDummyWindow(0, 0, f_dim, f_dim);
- hdc = GDI.GetDC(hwnd);
+ if(0 == hwnd) {
+ throw new GLException("Error hwnd 0, werr: "+GDI.GetLastError());
+ }
+ // manual debug only - GDI.ShowWindow(hwnd, GDI.SW_SHOW);
ProxySurface ns = (ProxySurface) getNativeSurface();
- ns.setSurfaceHandle(hdc);
ns.setSize(f_dim, f_dim);
- WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)ns.getGraphicsConfiguration().getNativeGraphicsConfiguration();
-
+
+ if(NativeSurface.LOCK_SURFACE_NOT_READY >= lockSurface()) {
+ throw new GLException("WindowsDummyWGLDrawable: surface not ready (lockSurface)");
+ }
try {
- config.updateGraphicsConfiguration(factory, ns);
+ WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)ns.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ config.updateGraphicsConfiguration(factory, ns, null);
if (DEBUG) {
System.err.println("!!! WindowsDummyWGLDrawable: "+config);
}
} catch (Throwable t) {
destroyImpl();
throw new GLException(t);
+ } finally {
+ unlockSurface();
}
}
@@ -80,10 +89,56 @@ public class WindowsDummyWGLDrawable extends WindowsWGLDrawable {
caps.setDepthBits(16);
caps.setDoubleBuffered(true);
caps.setOnscreen (true);
- caps.setPBuffer (true);
return new WindowsDummyWGLDrawable(factory, caps, absScreen);
}
+ public int lockSurface() throws GLException {
+ int res = NativeSurface.LOCK_SURFACE_NOT_READY;
+ ProxySurface ns = (ProxySurface) getNativeSurface();
+ AbstractGraphicsDevice adevice = ns.getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice();
+ adevice.lock();
+ try {
+ res = ns.lockSurface();
+ if(NativeSurface.LOCK_SUCCESS == res) {
+ if(0 == hdc) {
+ hdc = GDI.GetDC(hwnd);
+ ns.setSurfaceHandle(hdc);
+ if(0 == hdc) {
+ res = NativeSurface.LOCK_SURFACE_NOT_READY;
+ ns.unlockSurface();
+ throw new GLException("Error hdc 0, werr: "+GDI.GetLastError());
+ // finally will unlock adevice
+ }
+ }
+ } else {
+ Throwable t = new Throwable("Error lock failed - res "+res+", hwnd "+toHexString(hwnd)+", hdc "+toHexString(hdc));
+ t.printStackTrace();
+ }
+ } finally {
+ if( NativeSurface.LOCK_SURFACE_NOT_READY == res ) {
+ adevice.unlock();
+ }
+ }
+ return res;
+ }
+
+ public void unlockSurface() {
+ ProxySurface ns = (ProxySurface) getNativeSurface();
+ ns.validateSurfaceLocked();
+ AbstractGraphicsDevice adevice = ns.getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice();
+
+ try {
+ if ( 0 != hdc && 0 != hwnd && ns.getSurfaceRecursionCount() == 0) {
+ GDI.ReleaseDC(hwnd, hdc);
+ hdc=0;
+ ns.setSurfaceHandle(hdc);
+ }
+ surface.unlockSurface();
+ } finally {
+ adevice.unlock();
+ }
+ }
+
public void setSize(int width, int height) {
}
@@ -96,10 +151,6 @@ public class WindowsDummyWGLDrawable extends WindowsWGLDrawable {
}
public GLContext createContext(GLContext shareWith) {
- if (hdc == 0) {
- // Construction failed
- return null;
- }
// FIXME: figure out how to hook back in the Java 2D / JOGL bridge
return new WindowsWGLContext(this, shareWith);
}
@@ -108,10 +159,12 @@ public class WindowsDummyWGLDrawable extends WindowsWGLDrawable {
if (hdc != 0) {
GDI.ReleaseDC(hwnd, hdc);
hdc = 0;
+ ProxySurface ns = (ProxySurface) getNativeSurface();
+ ns.setSurfaceHandle(hdc);
}
if (hwnd != 0) {
GDI.ShowWindow(hwnd, GDI.SW_HIDE);
- GDI.DestroyWindow(hwnd);
+ GDI.DestroyDummyWindow(hwnd);
hwnd = 0;
}
}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLContext.java
index fd70842ac..d8d410d39 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLContext.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLContext.java
@@ -66,9 +66,6 @@ public class WindowsExternalWGLContext extends WindowsWGLContext {
}
GLContextShareSet.contextCreated(this);
setGLFunctionAvailability(false, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY);
- WindowsWGLGraphicsConfiguration config =
- (WindowsWGLGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
- config.updateGraphicsConfiguration(drawable.getFactory(), drawable.getNativeSurface());
getGLStateTracker().setEnabled(false); // external context usage can't track state in Java
}
@@ -87,12 +84,8 @@ public class WindowsExternalWGLContext extends WindowsWGLContext {
}
AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS);
- WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfiguration.create(hdc, pfdID, glp, aScreen, true, true);
-
- ProxySurface ns = new ProxySurface(cfg);
- ns.setSurfaceHandle(hdc);
-
- return new WindowsExternalWGLContext(new Drawable(factory, ns), ctx, cfg);
+ WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfiguration.create(factory, hdc, pfdID, glp, aScreen, true, true);
+ return new WindowsExternalWGLContext(new Drawable(factory, new ProxySurface(cfg, hdc)), ctx, cfg);
}
public int makeCurrent() throws GLException {
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java
index 66a5c80a4..f3329b73b 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsExternalWGLDrawable.java
@@ -69,14 +69,8 @@ public class WindowsExternalWGLDrawable extends WindowsWGLDrawable {
}
AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS);
- WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfiguration.create(hdc, pfdID, glp, aScreen, true, true);
-
- ProxySurface ns = new ProxySurface(cfg);
- ns.setSurfaceHandle(hdc);
-
- cfg.updateGraphicsConfiguration(factory, ns);
-
- return new WindowsExternalWGLDrawable(factory, ns);
+ WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfiguration.create(factory, hdc, pfdID, glp, aScreen, true, true);
+ return new WindowsExternalWGLDrawable(factory, new ProxySurface(cfg, hdc));
}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java
index 47b33dd6b..720ac84ca 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsPbufferWGLDrawable.java
@@ -50,7 +50,6 @@ import javax.media.opengl.GLPbuffer;
import javax.media.opengl.GLProfile;
import com.jogamp.nativewindow.impl.windows.GDI;
-import com.jogamp.nativewindow.impl.windows.PIXELFORMATDESCRIPTOR;
import javax.media.opengl.GLCapabilitiesImmutable;
public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
@@ -144,7 +143,7 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
}
if(!WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList(capabilities,
- iattributes, sharedCtx, -1, true, floatModeTmp)){
+ iattributes, sharedCtx, -1, floatModeTmp)){
throw new GLException("Pbuffer-related extensions not supported");
}
@@ -174,96 +173,57 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
throw new GLException("pbuffer creation error: Couldn't find a suitable pixel format");
}
- boolean haveMultisample = sharedCtx.isExtensionAvailable("WGL_ARB_multisample");
-
if (DEBUG) {
System.err.println("" + nformats + " suitable pixel formats found");
- // query pixel format
- iattributes[0] = WGLExt.WGL_RED_BITS_ARB;
- iattributes[1] = WGLExt.WGL_GREEN_BITS_ARB;
- iattributes[2] = WGLExt.WGL_BLUE_BITS_ARB;
- iattributes[3] = WGLExt.WGL_ALPHA_BITS_ARB;
- iattributes[4] = WGLExt.WGL_DEPTH_BITS_ARB;
- iattributes[5] = (useFloat ? (ati ? WGLExt.WGL_PIXEL_TYPE_ARB : WGLExt.WGL_FLOAT_COMPONENTS_NV) : WGLExt.WGL_RED_BITS_ARB);
- iattributes[6] = (haveMultisample ? WGLExt.WGL_SAMPLE_BUFFERS_ARB : WGLExt.WGL_RED_BITS_ARB);
- iattributes[7] = (haveMultisample ? WGLExt.WGL_SAMPLES_ARB : WGLExt.WGL_RED_BITS_ARB);
- iattributes[8] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB;
- int[] ivalues = new int[9];
for (int i = 0; i < nformats; i++) {
- if (!wglExt.wglGetPixelFormatAttribivARB(parentHdc, pformats[i], 0, 9, iattributes, 0, ivalues, 0)) {
- throw new GLException("Error while querying pixel format " + pformats[i] +
- "'s (index " + i + "'s) capabilities for debugging");
- }
- System.err.print("pixel format " + pformats[i] + " (index " + i + "): ");
- System.err.print( "r: " + ivalues[0]);
- System.err.print(" g: " + ivalues[1]);
- System.err.print(" b: " + ivalues[2]);
- System.err.print(" a: " + ivalues[3]);
- System.err.print(" depth: " + ivalues[4]);
- if (haveMultisample) {
- System.err.print(" multisample: " + ivalues[6]);
- }
- System.err.print(" samples: " + ivalues[7]);
- if (useFloat) {
- if (ati) {
- if (ivalues[5] == WGLExt.WGL_TYPE_RGBA_FLOAT_ARB) {
- System.err.print(" [ati float]");
- } else if (ivalues[5] != WGLExt.WGL_TYPE_RGBA_ARB) {
- System.err.print(" [unknown pixel type " + ivalues[5] + "]");
- }
- } else {
- if (ivalues[5] != 0) {
- System.err.print(" [float]");
- }
- }
- }
-
- if (ivalues[8] != 0) {
- System.err.print(" [pbuffer]");
- }
- System.err.println();
+ WGLGLCapabilities dbgCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedCtx, parentHdc, pformats[i], glProfile, false, true);
+ System.err.println("pixel format " + pformats[i] + " (index " + i + "): " + dbgCaps);
}
}
+ int pfdid = 0;
long tmpBuffer = 0;
- int whichFormat = -1;
- // Loop is a workaround for bugs in NVidia's recent drivers
- for (whichFormat = 0; whichFormat < nformats; whichFormat++) {
- int format = pformats[whichFormat];
-
- // Create the p-buffer.
- niattribs = 0;
-
- if (rtt) {
- iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FORMAT_ARB;
- if (useFloat) {
- iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FLOAT_RGB_NV;
- } else {
- iattributes[niattribs++] = WGLExt.WGL_TEXTURE_RGBA_ARB;
- }
+ {
+ int whichFormat;
+ // Loop is a workaround for bugs in NVidia's recent drivers
+ for (whichFormat = 0; whichFormat < nformats; whichFormat++) {
+ int format = pformats[whichFormat];
+
+ // Create the p-buffer.
+ niattribs = 0;
+
+ if (rtt) {
+ iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FORMAT_ARB;
+ if (useFloat) {
+ iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FLOAT_RGB_NV;
+ } else {
+ iattributes[niattribs++] = WGLExt.WGL_TEXTURE_RGBA_ARB;
+ }
- iattributes[niattribs++] = WGLExt.WGL_TEXTURE_TARGET_ARB;
- iattributes[niattribs++] = rect ? WGLExt.WGL_TEXTURE_RECTANGLE_NV : WGLExt.WGL_TEXTURE_2D_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_TEXTURE_TARGET_ARB;
+ iattributes[niattribs++] = rect ? WGLExt.WGL_TEXTURE_RECTANGLE_NV : WGLExt.WGL_TEXTURE_2D_ARB;
- iattributes[niattribs++] = WGLExt.WGL_MIPMAP_TEXTURE_ARB;
- iattributes[niattribs++] = GL.GL_FALSE;
+ iattributes[niattribs++] = WGLExt.WGL_MIPMAP_TEXTURE_ARB;
+ iattributes[niattribs++] = GL.GL_FALSE;
- iattributes[niattribs++] = WGLExt.WGL_PBUFFER_LARGEST_ARB;
- iattributes[niattribs++] = GL.GL_FALSE;
- }
+ iattributes[niattribs++] = WGLExt.WGL_PBUFFER_LARGEST_ARB;
+ iattributes[niattribs++] = GL.GL_FALSE;
+ }
- iattributes[niattribs++] = 0;
+ iattributes[niattribs++] = 0;
- tmpBuffer = wglExt.wglCreatePbufferARB(parentHdc, format, getWidth(), getHeight(), iattributes, 0);
- if (tmpBuffer != 0) {
- // Done
- break;
- }
- }
+ tmpBuffer = wglExt.wglCreatePbufferARB(parentHdc, format, getWidth(), getHeight(), iattributes, 0);
+ if (tmpBuffer != 0) {
+ // Done
+ break;
+ }
+ }
- if (tmpBuffer == 0) {
- throw new GLException("pbuffer creation error: wglCreatePbuffer() failed: tried " + nformats +
- " pixel formats, last error was: " + wglGetLastError());
+ if (0 == tmpBuffer) {
+ throw new GLException("pbuffer creation error: wglCreatePbuffer() failed: tried " + nformats +
+ " pixel formats, last error was: " + wglGetLastError());
+ }
+ pfdid = pformats[whichFormat];
}
// Get the device context.
@@ -280,48 +240,14 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
// Re-query chosen pixel format
{
- niattribs = 0;
- iattributes[niattribs++] = WGLExt.WGL_ACCELERATION_ARB;
- iattributes[niattribs++] = WGLExt.WGL_RED_BITS_ARB;
- iattributes[niattribs++] = WGLExt.WGL_GREEN_BITS_ARB;
- iattributes[niattribs++] = WGLExt.WGL_BLUE_BITS_ARB;
- iattributes[niattribs++] = WGLExt.WGL_ALPHA_BITS_ARB;
- iattributes[niattribs++] = WGLExt.WGL_DEPTH_BITS_ARB;
- iattributes[niattribs++] = WGLExt.WGL_STENCIL_BITS_ARB;
- iattributes[niattribs++] = WGLExt.WGL_DOUBLE_BUFFER_ARB;
- iattributes[niattribs++] = WGLExt.WGL_STEREO_ARB;
- iattributes[niattribs++] = WGLExt.WGL_ACCUM_RED_BITS_ARB;
- iattributes[niattribs++] = WGLExt.WGL_ACCUM_GREEN_BITS_ARB;
- iattributes[niattribs++] = WGLExt.WGL_ACCUM_BLUE_BITS_ARB;
- iattributes[niattribs++] = WGLExt.WGL_ACCUM_ALPHA_BITS_ARB;
- iattributes[niattribs++] = (useFloat ? (ati ? WGLExt.WGL_PIXEL_TYPE_ARB : WGLExt.WGL_FLOAT_COMPONENTS_NV) : WGLExt.WGL_RED_BITS_ARB);
- iattributes[niattribs++] = (haveMultisample ? WGLExt.WGL_SAMPLE_BUFFERS_ARB : WGLExt.WGL_RED_BITS_ARB);
- iattributes[niattribs++] = (haveMultisample ? WGLExt.WGL_SAMPLES_ARB : WGLExt.WGL_RED_BITS_ARB);
- iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB;
- int[] ivalues = new int[niattribs];
- if (wglExt.wglGetPixelFormatAttribivARB(parentHdc, pformats[whichFormat], 0, niattribs, iattributes, 0, ivalues, 0)) {
- GLCapabilitiesImmutable newCaps = WindowsWGLGraphicsConfiguration.AttribList2GLCapabilities(glProfile, iattributes, niattribs, ivalues, false, true);
- if(null == newCaps|| newCaps.isOnscreen() || !newCaps.isPBuffer()) {
- throw new GLException("Error: Selected Onscreen Caps for PBuffer: "+newCaps);
- }
- PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor();
- if (GDI.DescribePixelFormat(parentHdc, pformats[whichFormat], pfd.size(), pfd) == 0) {
- if (DEBUG) {
- System.err.println("Unable to describe pixel format (Continue: true) " + whichFormat + "/" + nformats + " pfdID " + pformats[whichFormat]+":\n\t"+newCaps);
- }
- }
- config.setCapsPFD(newCaps, pfd, pformats[whichFormat], true);
- } else {
- PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor();
- if (GDI.DescribePixelFormat(parentHdc, pformats[whichFormat], pfd.size(), pfd) == 0) {
- throw new GLException("Unable to describe pixel format " + pformats[whichFormat]);
- }
- GLCapabilitiesImmutable newCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, pfd, false, true);
- if(newCaps.isOnscreen()) {
- throw new GLException("Error: Selected Onscreen Caps for PBuffer: "+newCaps+"\n\t"+newCaps);
- }
- config.setCapsPFD(newCaps, pfd, pformats[whichFormat], false);
+ WGLGLCapabilities newCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedCtx, parentHdc, pfdid, glProfile, false, true);
+ if(null == newCaps) {
+ throw new GLException("pbuffer creation error: unable to re-query chosen PFD ID: " + pfdid + ", hdc " + this.toHexString(tmpHdc));
+ }
+ if(newCaps.isOnscreen() || !newCaps.isPBuffer()) {
+ throw new GLException("Error: Selected Onscreen Caps for PBuffer: "+newCaps);
}
+ config.setCapsPFD(newCaps);
}
// Determine the actual width and height we were able to create.
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java
index e85308371..7d38f8ee8 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLContext.java
@@ -48,6 +48,7 @@ import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
+import javax.media.opengl.GLCapabilitiesImmutable;
import com.jogamp.gluegen.runtime.ProcAddressTable;
import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
@@ -55,16 +56,14 @@ import com.jogamp.nativewindow.impl.windows.GDI;
import com.jogamp.opengl.impl.GLContextImpl;
import com.jogamp.opengl.impl.GLContextShareSet;
import com.jogamp.opengl.impl.GLDrawableImpl;
-import javax.media.opengl.GLCapabilitiesImmutable;
-
public class WindowsWGLContext extends GLContextImpl {
static final Map/*<String, String>*/ functionNameMap;
static final Map/*<String, String>*/ extensionNameMap;
private boolean wglGetExtensionsStringEXTInitialized;
private boolean wglGetExtensionsStringEXTAvailable;
- private boolean wglMakeContextCurrentInitialized;
- private boolean wglMakeContextCurrentAvailable;
+ private boolean wglGLReadDrawableAvailableSet;
+ private boolean wglGLReadDrawableAvailable;
private WGLExt wglExt;
// Table that holds the addresses of the native C-language entry points for
// WGL extension functions.
@@ -89,8 +88,8 @@ public class WindowsWGLContext extends GLContextImpl {
protected void resetState() {
wglGetExtensionsStringEXTInitialized=false;
wglGetExtensionsStringEXTAvailable=false;
- wglMakeContextCurrentInitialized=false;
- wglMakeContextCurrentAvailable=false;
+ wglGLReadDrawableAvailableSet=false;
+ wglGLReadDrawableAvailable=false;
// no inner state _wglExt=null;
wglExtProcAddressTable=null;
}
@@ -100,6 +99,9 @@ public class WindowsWGLContext extends GLContextImpl {
}
/* package private */ final WGLExt getWGLExt() {
+ if( null == getWGLExtProcAddressTable()) {
+ throw new InternalError("Null WGLExtProcAddressTable");
+ }
if (wglExt == null) {
wglExt = new WGLExtImpl(this);
}
@@ -107,27 +109,27 @@ public class WindowsWGLContext extends GLContextImpl {
}
public final boolean isGLReadDrawableAvailable() {
- if(!wglMakeContextCurrentInitialized && null != getWGLExtProcAddressTable()) {
+ if(!wglGLReadDrawableAvailableSet && null != getWGLExtProcAddressTable()) {
WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory)drawable.getFactoryImpl();
AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
AbstractGraphicsDevice device = config.getScreen().getDevice();
switch( factory.isReadDrawableAvailable(device) ) {
case 1:
- wglMakeContextCurrentAvailable = true;
- wglMakeContextCurrentInitialized=true;
+ wglGLReadDrawableAvailable = true;
+ wglGLReadDrawableAvailableSet=true;
break;
case 0:
- wglMakeContextCurrentAvailable = false;
- wglMakeContextCurrentInitialized=true;
+ wglGLReadDrawableAvailable = false;
+ wglGLReadDrawableAvailableSet=true;
break;
}
}
- return wglMakeContextCurrentAvailable;
+ return wglGLReadDrawableAvailable;
}
private final boolean wglMakeContextCurrent(long hDrawDC, long hReadDC, long ctx) {
boolean ok = false;
- if(wglMakeContextCurrentAvailable) {
+ if(wglGLReadDrawableAvailable) {
// needs initilized WGL ProcAddress table
ok = getWGLExt().wglMakeContextCurrent(hDrawDC, hReadDC, ctx);
} else if ( hDrawDC == hReadDC ) {
@@ -136,10 +138,17 @@ public class WindowsWGLContext extends GLContextImpl {
// should not happen due to 'isGLReadDrawableAvailable()' query in GLContextImpl
throw new InternalError("Given readDrawable but no driver support");
}
+ int werr = ( !ok ) ? GDI.GetLastError() : GDI.ERROR_SUCCESS;
+ if(DEBUG && !ok) {
+ Throwable t = new Throwable ("Info: wglMakeContextCurrent draw "+
+ this.toHexString(hDrawDC) + ", read " + this.toHexString(hReadDC) +
+ ", ctx " + this.toHexString(ctx) + ", werr " + werr);
+ t.printStackTrace();
+ }
if(!ok && 0==hDrawDC && 0==hReadDC) {
// Some GPU's falsely fails with a zero error code (success),
// in case this is a release context request we tolerate this
- return GDI.GetLastError() == GDI.ERROR_SUCCESS ;
+ return werr == GDI.ERROR_SUCCESS ;
}
return ok;
}
@@ -162,15 +171,15 @@ public class WindowsWGLContext extends GLContextImpl {
}
protected long createContextARBImpl(long share, boolean direct, int ctp, int major, int minor) {
- WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory)drawable.getFactoryImpl();
- AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
- AbstractGraphicsDevice device = config.getScreen().getDevice();
- WindowsWGLContext sharedContext = (WindowsWGLContext) factory.getOrCreateSharedContextImpl(device);
- WGLExt _wglExt;
- if(null==sharedContext) {
- _wglExt = getWGLExt();
- } else {
- _wglExt = sharedContext.getWGLExt();
+ if( null == getWGLExtProcAddressTable()) {
+ updateGLXProcAddressTable();
+ }
+ WGLExt _wglExt = getWGLExt();
+ if(DEBUG) {
+ System.err.println(getThreadName()+" - WindowWGLContext.createContextARBImpl: "+getGLVersion(major, minor, ctp, "@creation") +
+ ", handle "+toHexString(drawable.getHandle()) + ", share "+toHexString(share)+", direct "+direct+
+ ", wglCreateContextAttribsARB: "+toHexString(wglExtProcAddressTable._addressof_wglCreateContextAttribsARB));
+ Thread.dumpStack();
}
boolean ctBwdCompat = 0 != ( CTX_PROFILE_COMPAT & ctp ) ;
@@ -221,8 +230,7 @@ public class WindowsWGLContext extends GLContextImpl {
}
if(0!=ctx) {
- // cannot use wglMakeContextCurrent since WGLExt ProcAddressTable is not ready yet.
- if( !WGL.wglMakeCurrent(drawable.getHandle(), ctx) ) {
+ if (!wglMakeContextCurrent(drawable.getHandle(), drawableRead.getHandle(), ctx)) {
if(DEBUG) {
System.err.println("WindowsWGLContext.createContextARB couldn't make current "+getGLVersion(major, minor, ctp, "@creation"));
}
@@ -231,7 +239,7 @@ public class WindowsWGLContext extends GLContextImpl {
ctx = 0;
} else {
if (DEBUG) {
- System.err.println(getThreadName() + ": createContextARBImpl: OK "+getGLVersion(major, minor, ctp, "@creation")+", share "+share+", direct "+direct+", hasSharedContext "+(null!=sharedContext));
+ System.err.println(getThreadName() + ": createContextARBImpl: OK "+getGLVersion(major, minor, ctp, "@creation")+", share "+share+", direct "+direct);
}
// the following is issued by the caller 'GLContextImpl.createContextARB()'
// setGLFunctionAvailability(true, major, minor, ctp);
@@ -253,7 +261,7 @@ public class WindowsWGLContext extends GLContextImpl {
WindowsWGLContext sharedContext = (WindowsWGLContext) factory.getOrCreateSharedContextImpl(device);
GLCapabilitiesImmutable glCaps = drawable.getChosenGLCapabilities();
- isGLReadDrawableAvailable(); // trigger setup wglMakeContextCurrentAvailable
+ isGLReadDrawableAvailable(); // trigger setup wglGLReadDrawableAvailable
// Windows can set up sharing of display lists after creation time
WindowsWGLContext other = (WindowsWGLContext) GLContextShareSet.getShareContext(this);
@@ -315,12 +323,12 @@ public class WindowsWGLContext extends GLContextImpl {
if(0!=contextHandle) {
share = 0; // mark as shared thx to the ARB create method
- WGL.wglMakeCurrent(0, 0); // the ARB create method used WGL.wglMakeCurrent(0, 0)
- if(0!=temp_ctx) {
+ if(0!=temp_ctx) {
+ WGL.wglMakeCurrent(0, 0);
WGL.wglDeleteContext(temp_ctx);
- }
- if (!wglMakeContextCurrent(drawable.getHandle(), drawableRead.getHandle(), contextHandle)) {
- throw new GLException("Cannot make previous verified context current: 0x" + toHexString(contextHandle) + ", werr: " + GDI.GetLastError());
+ if (!wglMakeContextCurrent(drawable.getHandle(), drawableRead.getHandle(), contextHandle)) {
+ throw new GLException("Cannot make previous verified context current: 0x" + toHexString(contextHandle) + ", werr: " + GDI.GetLastError());
+ }
}
} else {
if(glCaps.getGLProfile().isGL3()) {
@@ -385,23 +393,26 @@ public class WindowsWGLContext extends GLContextImpl {
}
}
- protected final void updateGLXProcAddressTable(int major, int minor, int ctp) {
+ protected final void updateGLXProcAddressTable() {
+ AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
+ String key = adevice.getUniqueID();
if (DEBUG) {
- System.err.println(getThreadName() + ": !!! Initializing WGL extension address table for " + this);
+ System.err.println(getThreadName() + ": !!! Initializing WGL extension address table: "+key);
}
wglGetExtensionsStringEXTInitialized=false;
wglGetExtensionsStringEXTAvailable=false;
- wglMakeContextCurrentInitialized=false;
- wglMakeContextCurrentAvailable=false;
+ wglGLReadDrawableAvailableSet=false;
+ wglGLReadDrawableAvailable=false;
WGLExtProcAddressTable table = null;
synchronized(mappedContextTypeObjectLock) {
- table = (WGLExtProcAddressTable) mappedGLXProcAddress.get( contextFQN );
+ table = (WGLExtProcAddressTable) mappedGLXProcAddress.get( key );
}
if(null != table) {
wglExtProcAddressTable = table;
if(DEBUG) {
- System.err.println(getThreadName() + ": !!! GLContext WGL ProcAddressTable reusing key("+contextFQN+") -> "+table.hashCode());
+ System.err.println(getThreadName() + ": !!! GLContext WGL ProcAddressTable reusing key("+key+") -> "+table.hashCode());
}
} else {
if (wglExtProcAddressTable == null) {
@@ -409,11 +420,11 @@ public class WindowsWGLContext extends GLContextImpl {
// share them among contexts classes (GL4, GL4bc, GL3, GL3bc, ..)
wglExtProcAddressTable = new WGLExtProcAddressTable(new GLProcAddressResolver());
}
- resetProcAddressTable(getWGLExtProcAddressTable());
+ resetProcAddressTable(wglExtProcAddressTable);
synchronized(mappedContextTypeObjectLock) {
- mappedGLXProcAddress.put(contextFQN, getWGLExtProcAddressTable());
+ mappedGLXProcAddress.put(key, getWGLExtProcAddressTable());
if(DEBUG) {
- System.err.println(getThreadName() + ": !!! GLContext WGL ProcAddressTable mapping key("+contextFQN+") -> "+getWGLExtProcAddressTable().hashCode());
+ System.err.println(getThreadName() + ": !!! GLContext WGL ProcAddressTable mapping key("+key+") -> "+getWGLExtProcAddressTable().hashCode());
}
}
}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawable.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawable.java
index a98366f58..83b52fbcb 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawable.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawable.java
@@ -68,7 +68,7 @@ public abstract class WindowsWGLDrawable extends GLDrawableImpl {
NativeSurface ns = getNativeSurface();
WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)ns.getGraphicsConfiguration().getNativeGraphicsConfiguration();
- config.updateGraphicsConfiguration(getFactory(), ns);
+ config.updateGraphicsConfiguration(getFactory(), ns, null);
if (DEBUG) {
System.err.println("!!! WindowsWGLDrawable.setRealized(true): "+config);
}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java
index 903e1af81..674690e50 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java
@@ -45,8 +45,6 @@ import java.nio.ShortBuffer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
import javax.media.nativewindow.AbstractGraphicsDevice;
@@ -55,6 +53,8 @@ import javax.media.nativewindow.DefaultGraphicsScreen;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.windows.WindowsGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLCapabilitiesChooser;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawable;
@@ -62,15 +62,17 @@ import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
import com.jogamp.common.JogampRuntimeException;
+import com.jogamp.common.nio.PointerBuffer;
import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.nativewindow.impl.ProxySurface;
import com.jogamp.nativewindow.impl.windows.GDI;
+import com.jogamp.nativewindow.impl.windows.RegisteredClassFactory;
import com.jogamp.opengl.impl.DesktopGLDynamicLookupHelper;
+import com.jogamp.opengl.impl.GLContextImpl;
import com.jogamp.opengl.impl.GLDrawableFactoryImpl;
import com.jogamp.opengl.impl.GLDrawableImpl;
import com.jogamp.opengl.impl.GLDynamicLookupHelper;
-import javax.media.nativewindow.AbstractGraphicsConfiguration;
-import javax.media.opengl.GLCapabilitiesImmutable;
+import com.jogamp.opengl.impl.SharedResourceRunner;
public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
private static final DesktopGLDynamicLookupHelper windowsWGLDynamicLookupHelper;
@@ -108,31 +110,182 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
}
defaultDevice = new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
+
+ // Init shared resources off thread
+ // Will be released via ShutdownHook
+ sharedResourceImpl = new SharedResourceImplementation();
+ sharedResourceRunner = new SharedResourceRunner(sharedResourceImpl);
+ sharedResourceThread = new Thread(sharedResourceRunner, Thread.currentThread().getName()+"-SharedResourceRunner");
+ sharedResourceThread.setDaemon(true); // Allow JVM to exit, even if this one is running
+ sharedResourceThread.start();
}
- static class SharedResource {
+ WindowsGraphicsDevice defaultDevice;
+ SharedResourceImplementation sharedResourceImpl;
+ SharedResourceRunner sharedResourceRunner;
+ Thread sharedResourceThread;
+ HashMap/*<connection, SharedResource>*/ sharedMap = new HashMap();
+
+ long processAffinityChanges = 0;
+ PointerBuffer procMask = PointerBuffer.allocateDirect(1);
+ PointerBuffer sysMask = PointerBuffer.allocateDirect(1);
+
+ protected void enterThreadCriticalZone() {
+ synchronized (sysMask) {
+ if( 0 == processAffinityChanges) {
+ long pid = GDI.GetCurrentProcess();
+ if ( GDI.GetProcessAffinityMask(pid, procMask, sysMask) ) {
+ if(DEBUG) {
+ System.err.println("WindowsWGLDrawableFactory.enterThreadCriticalZone() - 0x" + Long.toHexString(pid) + " - " + Thread.currentThread().getName());
+ Thread.dumpStack();
+ }
+ processAffinityChanges = pid;
+ GDI.SetProcessAffinityMask(pid, 1);
+ }
+ }
+ }
+ }
+
+ protected void leaveThreadCriticalZone() {
+ synchronized (sysMask) {
+ if( 0 != processAffinityChanges) {
+ long pid = GDI.GetCurrentProcess();
+ if( pid != processAffinityChanges) {
+ throw new GLException("PID doesn't match: set PID 0x" + Long.toHexString(processAffinityChanges) +
+ " this PID 0x" + Long.toHexString(pid) );
+ }
+ if(DEBUG) {
+ System.err.println("WindowsWGLDrawableFactory.leaveThreadCriticalZone() - 0x" + Long.toHexString(pid) + " - " + Thread.currentThread().getName());
+ }
+ GDI.SetProcessAffinityMask(pid, sysMask.get(0));
+ }
+ }
+ }
+
+ static class SharedResource implements SharedResourceRunner.Resource {
private WindowsGraphicsDevice device;
+ private AbstractGraphicsScreen screen;
private WindowsDummyWGLDrawable drawable;
private WindowsWGLContext context;
private boolean canCreateGLPbuffer;
private boolean readDrawableAvailable;
- SharedResource(WindowsGraphicsDevice dev, WindowsDummyWGLDrawable draw, WindowsWGLContext ctx,
+ SharedResource(WindowsGraphicsDevice dev, AbstractGraphicsScreen scrn, WindowsDummyWGLDrawable draw, WindowsWGLContext ctx,
boolean readBufferAvail, boolean canPbuffer) {
device = dev;
+ screen = scrn;
drawable = draw;
context = ctx;
canCreateGLPbuffer = canPbuffer;
readDrawableAvailable = readBufferAvail;
}
- WindowsGraphicsDevice getDevice() { return device; }
- WindowsWGLContext getContext() { return context; }
- boolean canCreateGLPbuffer() { return canCreateGLPbuffer; }
- boolean isReadDrawableAvailable() { return readDrawableAvailable; }
+ final public AbstractGraphicsDevice getDevice() { return device; }
+ final public AbstractGraphicsScreen getScreen() { return screen; }
+ final public GLDrawableImpl getDrawable() { return drawable; }
+ final public GLContextImpl getContext() { return context; }
+ final boolean canCreateGLPbuffer() { return canCreateGLPbuffer; }
+ final boolean isReadDrawableAvailable() { return readDrawableAvailable; }
+ }
+
+ class SharedResourceImplementation implements SharedResourceRunner.Implementation {
+ public void clear() {
+ synchronized(sharedMap) {
+ sharedMap.clear();
+ }
+ }
+ public SharedResourceRunner.Resource mapPut(String connection, SharedResourceRunner.Resource resource) {
+ synchronized(sharedMap) {
+ return (SharedResourceRunner.Resource) sharedMap.put(connection, resource);
+ }
+ }
+ public SharedResourceRunner.Resource mapGet(String connection) {
+ synchronized(sharedMap) {
+ return (SharedResourceRunner.Resource) sharedMap.get(connection);
+ }
+ }
+ public Collection/*<Resource>*/ mapValues() {
+ synchronized(sharedMap) {
+ return sharedMap.values();
+ }
+ }
+
+ public SharedResourceRunner.Resource createSharedResource(String connection) {
+ WindowsGraphicsDevice sharedDevice = new WindowsGraphicsDevice(connection, AbstractGraphicsDevice.DEFAULT_UNIT);
+ sharedDevice.lock();
+ try {
+ AbstractGraphicsScreen absScreen = new DefaultGraphicsScreen(sharedDevice, 0);
+ if (null == absScreen) {
+ throw new GLException("Couldn't create shared screen for device: "+sharedDevice+", idx 0");
+ }
+ GLProfile glp = GLProfile.getMinDesktop(sharedDevice);
+ if (null == glp) {
+ throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice);
+ }
+ WindowsDummyWGLDrawable sharedDrawable = WindowsDummyWGLDrawable.create(WindowsWGLDrawableFactory.this, glp, absScreen);
+ if (null == sharedDrawable) {
+ throw new GLException("Couldn't create shared drawable for screen: "+absScreen+", "+glp);
+ }
+ WindowsWGLContext sharedContext = (WindowsWGLContext) sharedDrawable.createContext(null);
+ if (null == sharedContext) {
+ throw new GLException("Couldn't create shared context for drawable: "+sharedDrawable);
+ }
+ sharedContext.setSynchronized(true);
+ boolean canCreateGLPbuffer;
+ boolean readDrawableAvailable;
+ sharedContext.makeCurrent();
+ try {
+ canCreateGLPbuffer = sharedContext.getGL().isExtensionAvailable(GL_ARB_pbuffer);
+ readDrawableAvailable = sharedContext.isExtensionAvailable(WGL_ARB_make_current_read) &&
+ sharedContext.isFunctionAvailable(wglMakeContextCurrent);
+ } finally {
+ sharedContext.release();
+ }
+ if (DEBUG) {
+ System.err.println("!!! SharedDevice: " + sharedDevice);
+ System.err.println("!!! SharedScreen: " + absScreen);
+ System.err.println("!!! SharedContext: " + sharedContext);
+ System.err.println("!!! pbuffer avail: " + canCreateGLPbuffer);
+ System.err.println("!!! readDrawable: " + readDrawableAvailable);
+ }
+ return new SharedResource(sharedDevice, absScreen, sharedDrawable, sharedContext, readDrawableAvailable, canCreateGLPbuffer);
+ } catch (Throwable t) {
+ throw new GLException("WindowsWGLDrawableFactory - Could not initialize shared resources for "+connection, t);
+ } finally {
+ sharedDevice.unlock();
+ }
+ }
+
+ public void releaseSharedResource(SharedResourceRunner.Resource shared) {
+ SharedResource sr = (SharedResource) shared;
+ if (DEBUG) {
+ System.err.println("!!! Shutdown Shared:");
+ System.err.println("!!! Device : " + sr.device);
+ System.err.println("!!! Screen : " + sr.screen);
+ System.err.println("!!! Drawable: " + sr.drawable);
+ System.err.println("!!! CTX : " + sr.context);
+ }
+
+ if (null != sr.context) {
+ // may cause JVM SIGSEGV: sharedContext.destroy();
+ sr.context = null;
+ }
+
+ if (null != sr.drawable) {
+ sr.drawable.destroy();
+ sr.drawable = null;
+ }
+
+ if (null != sr.screen) {
+ sr.screen = null;
+ }
+
+ if (null != sr.device) {
+ sr.device.close();
+ sr.device = null;
+ }
+ }
}
- HashMap/*<connection, SharedResource>*/ sharedMap = new HashMap();
- WindowsGraphicsDevice defaultDevice;
public final AbstractGraphicsDevice getDefaultDevice() {
return defaultDevice;
@@ -145,62 +298,24 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
return false;
}
- HashSet devicesTried = new HashSet();
- private final boolean getDeviceTried(String connection) {
- synchronized(devicesTried) {
- return devicesTried.contains(connection);
- }
- }
- private final void addDeviceTried(String connection) {
- synchronized(devicesTried) {
- devicesTried.add(connection);
- }
- }
-
final static String GL_ARB_pbuffer = "GL_ARB_pbuffer";
final static String WGL_ARB_make_current_read = "WGL_ARB_make_current_read";
final static String wglMakeContextCurrent = "wglMakeContextCurrent";
- private SharedResource getOrCreateShared(AbstractGraphicsDevice device) {
- String connection = device.getConnection();
- SharedResource sr;
- synchronized(sharedMap) {
- sr = (SharedResource) sharedMap.get(connection);
+ protected final GLContext getSharedContextImpl(AbstractGraphicsDevice device) {
+ SharedResourceRunner.Resource sr = sharedResourceRunner.getShared(device);
+ if(null!=sr) {
+ return sr.getContext();
}
- if(null==sr && !getDeviceTried(connection)) {
- addDeviceTried(connection);
- NativeWindowFactory.getDefaultToolkitLock().lock(); // OK
- try {
- WindowsGraphicsDevice sharedDevice = new WindowsGraphicsDevice(connection, AbstractGraphicsDevice.DEFAULT_UNIT);
- GLProfile glp = GLProfile.getDefault(/*sharedDevice*/); // can't fetch device profile, which shared resource we create here
- AbstractGraphicsScreen absScreen = new DefaultGraphicsScreen(sharedDevice, 0);
- WindowsDummyWGLDrawable sharedDrawable = WindowsDummyWGLDrawable.create(this, glp, absScreen);
- WindowsWGLContext ctx = (WindowsWGLContext) sharedDrawable.createContext(null);
- ctx.makeCurrent();
- boolean canCreateGLPbuffer = ctx.getGL().isExtensionAvailable(GL_ARB_pbuffer);
- boolean readDrawableAvailable = ctx.isExtensionAvailable(WGL_ARB_make_current_read) &&
- ctx.isFunctionAvailable(wglMakeContextCurrent);
- ctx.release();
- sr = new SharedResource(sharedDevice, sharedDrawable, ctx, readDrawableAvailable, canCreateGLPbuffer);
- synchronized(sharedMap) {
- sharedMap.put(connection, sr);
- }
- if (DEBUG) {
- System.err.println("!!! SharedContext: "+ctx+", pbuffer supported "+canCreateGLPbuffer+
- ", readDrawable supported "+readDrawableAvailable);
- }
+ return null;
+ }
- } catch (Throwable t) {
- throw new GLException("WindowsWGLDrawableFactory - Could not initialize shared resources", t);
- } finally {
- NativeWindowFactory.getDefaultToolkitLock().unlock(); // OK
- }
- }
- return sr;
+ protected final boolean hasSharedContextImpl(AbstractGraphicsDevice device) {
+ return null != getSharedContextImpl(device);
}
protected final GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device) {
- SharedResource sr = getOrCreateShared(device);
+ SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device);
if(null!=sr) {
return sr.getContext();
}
@@ -208,43 +323,32 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
}
protected AbstractGraphicsDevice getOrCreateSharedDeviceImpl(AbstractGraphicsDevice device) {
- SharedResource sr = getOrCreateShared(device);
+ SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device);
if(null!=sr) {
return sr.getDevice();
}
return null;
}
- protected final void shutdownInstance() {
- if (DEBUG) {
- Exception e = new Exception("Debug");
- e.printStackTrace();
+ protected WindowsWGLDrawable getOrCreateSharedDrawable(AbstractGraphicsDevice device) {
+ SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device);
+ if(null!=sr) {
+ return (WindowsWGLDrawable) sr.getDrawable();
}
- Collection/*<SharedResource>*/ sharedResources = sharedMap.values();
- for(Iterator iter=sharedResources.iterator(); iter.hasNext(); ) {
- SharedResource sr = (SharedResource) iter.next();
-
- if (DEBUG) {
- System.err.println("!!! Shutdown Shared:");
- System.err.println("!!! Drawable: "+sr.drawable);
- System.err.println("!!! CTX : "+sr.context);
- }
+ return null;
+ }
- if (null != sr.context) {
- // may cause JVM SIGSEGV: sharedContext.destroy();
- sr.context = null;
- }
+ SharedResource getOrCreateSharedResource(AbstractGraphicsDevice device) {
+ return (SharedResource) sharedResourceRunner.getOrCreateShared(device);
+ }
- if (null != sr.drawable) {
- // may cause JVM SIGSEGV: sharedDrawable.destroy();
- sr.drawable = null;
- }
+ protected final void shutdownInstance() {
+ sharedResourceRunner.releaseAndWait();
+ RegisteredClassFactory.shutdownSharedClasses();
+ }
- }
- sharedMap.clear();
- if (DEBUG) {
- System.err.println("!!! Shutdown Shared Finished");
- }
+ protected List/*GLCapabilitiesImmutable*/ getAvailableCapabilitiesImpl(AbstractGraphicsDevice device) {
+ return WindowsWGLGraphicsConfigurationFactory.getAvailableCapabilities(this, device);
}
protected final GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) {
@@ -267,7 +371,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
// PBuffer GLDrawable Creation
final AbstractGraphicsDevice device = config.getScreen().getDevice();
- final SharedResource sr = getOrCreateShared(device);
+ final SharedResource sr = (SharedResource) sharedResourceRunner.getOrCreateShared(device);
if(null==sr) {
throw new IllegalArgumentException("No shared resource for "+device);
}
@@ -278,19 +382,17 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
if (lastContext != null) {
lastContext.release();
}
- synchronized(sr.context) {
- sr.context.makeCurrent();
- try {
- GLDrawableImpl pbufferDrawable = new WindowsPbufferWGLDrawable(WindowsWGLDrawableFactory.this, target,
- sr.drawable,
- sr.context);
- returnList.add(pbufferDrawable);
- } finally {
- sr.context.release();
- if (lastContext != null) {
- lastContext.makeCurrent();
- }
- }
+ sr.context.makeCurrent();
+ try {
+ GLDrawableImpl pbufferDrawable = new WindowsPbufferWGLDrawable(WindowsWGLDrawableFactory.this, target,
+ sr.drawable,
+ sr.context);
+ returnList.add(pbufferDrawable);
+ } finally {
+ sr.context.release();
+ if (lastContext != null) {
+ lastContext.makeCurrent();
+ }
}
}
};
@@ -303,7 +405,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
* and -1 if undefined yet, ie no shared device exist at this point.
*/
public final int isReadDrawableAvailable(AbstractGraphicsDevice device) {
- SharedResource sr = getOrCreateShared((null!=device)?device:defaultDevice);
+ SharedResource sr = (SharedResource) sharedResourceRunner.getOrCreateShared((null!=device)?device:defaultDevice);
if(null!=sr) {
return sr.isReadDrawableAvailable() ? 1 : 0 ;
}
@@ -311,7 +413,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
}
public final boolean canCreateGLPbuffer(AbstractGraphicsDevice device) {
- SharedResource sr = getOrCreateShared((null!=device)?device:defaultDevice);
+ SharedResource sr = (SharedResource) sharedResourceRunner.getOrCreateShared((null!=device)?device:defaultDevice);
if(null!=sr) {
return sr.canCreateGLPbuffer();
}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java
index aa1b1b70d..36d78b38d 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfiguration.java
@@ -33,12 +33,15 @@
package com.jogamp.opengl.impl.windows.wgl;
+import java.util.ArrayList;
+import java.util.List;
+
import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.DefaultGraphicsConfiguration;
import javax.media.nativewindow.NativeSurface;
-import javax.media.opengl.DefaultGLCapabilitiesChooser;
+import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.opengl.GL;
-import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLCapabilitiesChooser;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
@@ -48,84 +51,128 @@ import javax.media.opengl.GLProfile;
import com.jogamp.nativewindow.impl.windows.GDI;
import com.jogamp.nativewindow.impl.windows.PIXELFORMATDESCRIPTOR;
import com.jogamp.opengl.impl.GLContextImpl;
-import javax.media.opengl.GLCapabilitiesImmutable;
+import com.jogamp.opengl.impl.GLGraphicsConfigurationUtil;
public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable {
// Keep this under the same debug flag as the drawable factory for convenience
protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration");
+ final static String WGL_ARB_pixel_format = "WGL_ARB_pixel_format";
+ final static String WGL_ARB_multisample = "WGL_ARB_multisample";
+
protected static final int MAX_PFORMATS = 256;
protected static final int MAX_ATTRIBS = 256;
- private PIXELFORMATDESCRIPTOR pixelfmt;
- private int pixelfmtID;
- private boolean isChosen = false;
private GLCapabilitiesChooser chooser;
- private boolean choosenByWGLPixelFormat=false;
+ private boolean isChosen = false;
WindowsWGLGraphicsConfiguration(AbstractGraphicsScreen screen,
GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested,
- PIXELFORMATDESCRIPTOR pixelfmt, int pixelfmtID, GLCapabilitiesChooser chooser) {
+ GLCapabilitiesChooser chooser) {
super(screen, capsChosen, capsRequested);
this.chooser=chooser;
- this.pixelfmt = pixelfmt;
- this.pixelfmtID = pixelfmtID;
+ this.isChosen = false;
}
- static WindowsWGLGraphicsConfiguration create(long hdc, int pfdID,
+ WindowsWGLGraphicsConfiguration(AbstractGraphicsScreen screen,
+ WGLGLCapabilities capsChosen, GLCapabilitiesImmutable capsRequested) {
+ super(screen, capsChosen, capsRequested);
+ setCapsPFD(capsChosen);
+ this.chooser=null;
+ }
+
+
+ static WindowsWGLGraphicsConfiguration create(GLDrawableFactory _factory, long hdc, int pfdID,
GLProfile glp, AbstractGraphicsScreen screen, boolean onscreen, boolean usePBuffer)
{
+ if(_factory==null) {
+ throw new GLException("Null factory");
+ }
+ if(hdc==0) {
+ throw new GLException("Null HDC");
+ }
if(pfdID<=0) {
throw new GLException("Invalid pixelformat id "+pfdID);
}
if(null==glp) {
glp = GLProfile.getDefault(screen.getDevice());
}
- PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor();
- if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) {
- throw new GLException("Unable to describe pixel format " + pfdID);
+ WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory) _factory;
+ AbstractGraphicsDevice device = screen.getDevice();
+ WindowsWGLContext sharedContext = (WindowsWGLContext) factory.getOrCreateSharedContextImpl(device);
+ boolean hasARB = null != sharedContext && sharedContext.isExtensionAvailable(WGL_ARB_pixel_format) ;
+
+ WGLGLCapabilities caps = null;
+
+ if(hasARB) {
+ sharedContext.makeCurrent();
+ try {
+ caps = wglARBPFID2GLCapabilities(sharedContext, hdc, pfdID, glp, onscreen, usePBuffer);
+ } finally {
+ sharedContext.release();
+ }
+ } else if(!usePBuffer) {
+ caps = PFD2GLCapabilities(glp, hdc, pfdID, onscreen);
}
-
- GLCapabilitiesImmutable caps = PFD2GLCapabilities(glp, pfd, onscreen, usePBuffer);
if(null==caps) {
- throw new GLException("Couldn't choose Capabilities by: HDC 0x"+Long.toHexString(hdc)+", pfdID "+pfdID);
+ throw new GLException("Couldn't choose Capabilities by: HDC 0x"+Long.toHexString(hdc)+", pfdID "+pfdID+", hasARB "+hasARB);
}
- WindowsWGLGraphicsConfiguration cfg = new WindowsWGLGraphicsConfiguration(screen, caps, caps, pfd, pfdID, new DefaultGLCapabilitiesChooser());
- cfg.setCapsPFD(caps, pfd, pfdID, false);
- return cfg;
+ return new WindowsWGLGraphicsConfiguration(screen, caps, caps);
}
public Object clone() {
return super.clone();
}
- final void updateGraphicsConfiguration(GLDrawableFactory factory, NativeSurface ns) {
- WindowsWGLGraphicsConfigurationFactory.updateGraphicsConfiguration(chooser, factory, ns);
+ /**
+ * Updates the graphics configuration in case it has been determined yet.<br>
+ * Uses the NativeSurface's HDC.<br>
+ * Ensures that a PIXELFORMAT is set.
+ *
+ * @param factory
+ * @param ns
+ * @param pfIDs optional pool of preselected PixelFormat IDs, maybe null for unrestricted selection
+ *
+ * @see #isDetermined()
+ */
+ public final void updateGraphicsConfiguration(GLDrawableFactory factory, NativeSurface ns, int[] pfIDs) {
+ WindowsWGLGraphicsConfigurationFactory.updateGraphicsConfiguration(chooser, factory, ns, pfIDs);
}
- void setCapsPFD(GLCapabilitiesImmutable caps, PIXELFORMATDESCRIPTOR pfd, int pfdID, boolean choosenByWGLPixelFormat) {
- this.pixelfmt = pfd;
- this.pixelfmtID = pfdID;
+ /**
+ * Preselect the graphics configuration in case it has been determined yet.<br>
+ * Uses a shared device's HDC and the given pfdIDs to preselect the pfd.
+ * No PIXELFORMAT is set.
+ *
+ * @param factory
+ * @param pfIDs optional pool of preselected PixelFormat IDs, maybe null for unrestricted selection
+ *
+ * @see #isDetermined()
+ */
+ public final void preselectGraphicsConfiguration(GLDrawableFactory factory, int[] pfdIDs) {
+ AbstractGraphicsDevice device = getNativeGraphicsConfiguration().getScreen().getDevice();
+ WindowsWGLGraphicsConfigurationFactory.preselectGraphicsConfiguration(chooser, factory, device, this, pfdIDs);
+ }
+
+ final void setCapsPFD(WGLGLCapabilities caps) {
setChosenCapabilities(caps);
this.isChosen=true;
- this.choosenByWGLPixelFormat=choosenByWGLPixelFormat;
if (DEBUG) {
- System.err.println("*** setCapsPFD: WGL-Choosen "+choosenByWGLPixelFormat+", pfdID "+pfdID+", "+caps);
+ System.err.println("*** setCapsPFD: "+caps);
}
}
- public boolean getCapabilitiesChosen() {
- return isChosen;
- }
-
- public PIXELFORMATDESCRIPTOR getPixelFormat() { return pixelfmt; }
- public int getPixelFormatID() { return pixelfmtID; }
- public boolean isChoosenByWGL() { return choosenByWGLPixelFormat; }
+ public final boolean isDetermined() { return isChosen; }
+ public final PIXELFORMATDESCRIPTOR getPixelFormat() { return isChosen ? ((WGLGLCapabilities)capabilitiesChosen).getPFD() : null; }
+ public final int getPixelFormatID() { return isChosen ? ((WGLGLCapabilities)capabilitiesChosen).getPFDID() : 0; }
+ public final boolean isChoosenByARB() { return isChosen ? ((WGLGLCapabilities)capabilitiesChosen).isSetByARB() : false; }
static int fillAttribsForGeneralWGLARBQuery(boolean haveWGLARBMultisample, int[] iattributes) {
int niattribs = 0;
iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_WINDOW_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_BITMAP_ARB;
iattributes[niattribs++] = WGLExt.WGL_ACCELERATION_ARB;
iattributes[niattribs++] = WGLExt.WGL_SUPPORT_OPENGL_ARB;
iattributes[niattribs++] = WGLExt.WGL_DEPTH_BITS_ARB;
@@ -145,6 +192,10 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio
iattributes[niattribs++] = WGLExt.WGL_SAMPLE_BUFFERS_ARB;
iattributes[niattribs++] = WGLExt.WGL_SAMPLES_ARB;
}
+ // pbo float buffer
+ iattributes[niattribs++] = WGLExt.WGL_PIXEL_TYPE_ARB; // ati
+ iattributes[niattribs++] = WGLExt.WGL_FLOAT_COMPONENTS_NV; // nvidia
+
return niattribs;
}
@@ -159,177 +210,147 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio
return true;
}
- static GLCapabilitiesImmutable wglARBPFID2GLCapabilities(WindowsWGLContext sharedCtx, long hdc, int pfdID,
- GLProfile glp, boolean onscreen, boolean usePBuffer) {
- boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable("WGL_ARB_pixel_format");
+ static int[] wglAllARBPFIDs(WindowsWGLContext sharedCtx, long hdc) {
+ int[] iattributes = new int[1];
+ int[] iresults = new int[1];
+
+ WGLExt wglExt = sharedCtx.getWGLExt();
+ iattributes[0] = WGLExt.WGL_NUMBER_PIXEL_FORMATS_ARB;
+ if (!wglExt.wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, iattributes, 0, iresults, 0)) {
+ if(DEBUG) {
+ System.err.println("GetPixelFormatAttribivARB: Failed - HDC 0x" + Long.toHexString(hdc) +
+ ", LastError: " + GDI.GetLastError());
+ Thread.dumpStack();
+ }
+ return null;
+ }
+ int numFormats = iresults[0];
+ if(0 == numFormats) {
+ if(DEBUG) {
+ System.err.println("GetPixelFormatAttribivARB: No formats - HDC 0x" + Long.toHexString(hdc) +
+ ", LastError: " + GDI.GetLastError());
+ Thread.dumpStack();
+ }
+ return null;
+ }
+ int[] pfdIDs = new int[numFormats];
+ for (int i = 0; i < numFormats; i++) {
+ pfdIDs[i] = 1 + i;
+ }
+ return pfdIDs;
+ }
+
+ static WGLGLCapabilities wglARBPFID2GLCapabilities(WindowsWGLContext sharedCtx, long hdc, int pfdID,
+ GLProfile glp, boolean onscreen, boolean usePBuffer) {
+ boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable(WGL_ARB_pixel_format);
if (!haveWGLChoosePixelFormatARB) {
return null;
}
- boolean haveWGLARBMultisample = sharedCtx.isExtensionAvailable("WGL_ARB_multisample");
+ boolean haveWGLARBMultisample = sharedCtx.isExtensionAvailable(WGL_ARB_multisample);
int[] iattributes = new int [2*MAX_ATTRIBS];
int[] iresults = new int [2*MAX_ATTRIBS];
- iattributes[0] = WGLExt.WGL_NUMBER_PIXEL_FORMATS_ARB;
- if (sharedCtx.getWGLExt().wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, iattributes, 0, iresults, 0)) {
- if(iresults[0] > 0 ) {
- int niattribs = fillAttribsForGeneralWGLARBQuery(haveWGLARBMultisample, iattributes);
- if (!sharedCtx.getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdID, 0, niattribs, iattributes, 0, iresults, 0)) {
- throw new GLException("wglARBPFID2GLCapabilities: Error getting pixel format attributes for pixel format " + pfdID + " of device context");
- }
- return AttribList2GLCapabilities(glp, iattributes, niattribs, iresults,
- onscreen, usePBuffer);
- }
+ int niattribs = fillAttribsForGeneralWGLARBQuery(haveWGLARBMultisample, iattributes);
+
+ if (!sharedCtx.getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdID, 0, niattribs, iattributes, 0, iresults, 0)) {
+ throw new GLException("wglARBPFID2GLCapabilities: Error getting pixel format attributes for pixel format " + pfdID + " of device context");
}
- long lastErr = GDI.GetLastError();
- // Intel Extreme graphics fails with a zero error code
- if (lastErr != 0) {
- throw new GLException("wglARBPFID2GLCapabilities: Unable to enumerate pixel formats of window using wglGetPixelFormatAttribivARB: error code " + GDI.GetLastError());
+ ArrayList bucket = new ArrayList(1);
+ final int winattrbits = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer);
+ if(AttribList2GLCapabilities(bucket, glp, hdc, pfdID, iattributes, niattribs, iresults, winattrbits)) {
+ return (WGLGLCapabilities) bucket.get(0);
}
return null;
}
- static int wglChoosePixelFormatARB(long hdc, WindowsWGLContext sharedContext,
- GLCapabilitiesImmutable capabilities,
- int[] iattributes, int accelerationMode, float[] fattributes,
- int[] pformats)
+ static int[] wglChoosePixelFormatARB(long hdc, WindowsWGLContext sharedContext,
+ GLCapabilitiesImmutable capabilities,
+ int[] iattributes, int accelerationMode, float[] fattributes)
{
- int numFormats = -1;
-
- if(WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList(capabilities,
- iattributes,
- sharedContext,
- accelerationMode,
- false,
- null)) {
- int[] numFormatsTmp = new int[1];
- if (sharedContext.getWGLExt().wglChoosePixelFormatARB(hdc,
- iattributes, 0,
- fattributes, 0,
- WindowsWGLGraphicsConfiguration.MAX_PFORMATS,
- pformats, 0,
- numFormatsTmp, 0)) {
- numFormats = numFormatsTmp[0];
- if (DEBUG) {
- System.err.println("wglChoosePixelFormatARB1: NumFormats (wglChoosePixelFormatARB) accelMode 0x" +
- Integer.toHexString(accelerationMode) + ": " + numFormats + " / " + WindowsWGLGraphicsConfiguration.MAX_PFORMATS);
- }
- } else {
- if (DEBUG) {
- System.err.println("wglChoosePixelFormatARB1: wglChoosePixelFormatARB failed: " + GDI.GetLastError() );
- Thread.dumpStack();
- }
- }
- } else {
- if (DEBUG) {
- System.err.println("wglChoosePixelFormatARB1: GLCapabilities2AttribList failed: " + GDI.GetLastError() );
- Thread.dumpStack();
- }
- }
- return numFormats;
- }
- static GLCapabilitiesImmutable[] wglARBPFIDs2GLCapabilities(WindowsWGLContext sharedCtx, long hdc, int[] pfdIDs, int numFormats,
- GLProfile glp, boolean onscreen, boolean usePBuffer) {
- boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable("WGL_ARB_pixel_format");
- if (!haveWGLChoosePixelFormatARB) {
+ if ( !WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList(capabilities,
+ iattributes, sharedContext, accelerationMode, null))
+ {
+ if (DEBUG) {
+ System.err.println("wglChoosePixelFormatARB1: GLCapabilities2AttribList failed: " + GDI.GetLastError());
+ Thread.dumpStack();
+ }
return null;
}
- boolean haveWGLARBMultisample = sharedCtx.isExtensionAvailable("WGL_ARB_multisample");
-
- GLCapabilitiesImmutable[] caps = new GLCapabilitiesImmutable[numFormats];
- int[] iattributes = new int [2*MAX_ATTRIBS];
- int[] iresults = new int [2*MAX_ATTRIBS];
- int niattribs = fillAttribsForGeneralWGLARBQuery(haveWGLARBMultisample, iattributes);
-
- for(int i = 0; i<numFormats; i++) {
- if ( pfdIDs[i] >= 1 &&
- sharedCtx.getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdIDs[i], 0, niattribs, iattributes, 0, iresults, 0) ) {
- caps[i] = AttribList2GLCapabilities(glp, iattributes, niattribs, iresults, onscreen, usePBuffer);
- } else {
- if (DEBUG) {
- System.err.println("wglARBPFIDs2GLCapabilities: Cannot get pixel format attributes for pixel format " +
- i + "/" + numFormats + ": " + pfdIDs[i]);
- }
- caps[i] = null;
+ int[] pformatsTmp = new int[WindowsWGLGraphicsConfiguration.MAX_PFORMATS];
+ int[] numFormatsTmp = new int[1];
+ if ( !sharedContext.getWGLExt().wglChoosePixelFormatARB(hdc, iattributes, 0,
+ fattributes, 0,
+ WindowsWGLGraphicsConfiguration.MAX_PFORMATS,
+ pformatsTmp, 0, numFormatsTmp, 0))
+ {
+ if (DEBUG) {
+ System.err.println("wglChoosePixelFormatARB1: wglChoosePixelFormatARB failed: " + GDI.GetLastError());
+ Thread.dumpStack();
}
+ return null;
}
- return caps;
+ int numFormats = numFormatsTmp[0];
+ int[] pformats = null;
+ if( 0 < numFormats ) {
+ pformats = new int[numFormats];
+ System.arraycopy(pformatsTmp, 0, pformats, 0, numFormats);
+ }
+ if (DEBUG) {
+ System.err.println("wglChoosePixelFormatARB1: NumFormats (wglChoosePixelFormatARB) accelMode 0x"
+ + Integer.toHexString(accelerationMode) + ": " + numFormats);
+ }
+ return pformats;
}
- /**
- *
- * @param sharedCtx
- * @param hdc
- * @param glp
- * @param onscreen
- * @param usePBuffer
- * @param pfIDs stores the PIXELFORMAT ID for the GLCapabilitiesImmutable[]
- * @return the resulting GLCapabilitiesImmutable[]
- */
- static GLCapabilitiesImmutable[] wglARBAllPFIDs2GLCapabilities(WindowsWGLContext sharedCtx, long hdc,
- GLProfile glp, boolean onscreen, boolean usePBuffer, int[] pfIDs) {
- boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable("WGL_ARB_pixel_format");
+ static List /*<GLCapabilitiesImmutable>*/ wglARBPFIDs2GLCapabilities(WindowsWGLContext sharedCtx, long hdc, int[] pfdIDs,
+ GLProfile glp, boolean onscreen, boolean usePBuffer) {
+ final int winattrbits = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer);
+ return wglARBPFIDs2GLCapabilitiesImpl(sharedCtx, hdc, pfdIDs, glp, winattrbits);
+ }
+
+ static List /*<GLCapabilitiesImmutable>*/ wglARBPFIDs2AllGLCapabilities(WindowsWGLContext sharedCtx, long hdc, int[] pfdIDs,
+ GLProfile glp) {
+ return wglARBPFIDs2GLCapabilitiesImpl(sharedCtx, hdc, pfdIDs, glp, GLGraphicsConfigurationUtil.ALL_BITS);
+ }
+
+ private static List /*<GLCapabilitiesImmutable>*/ wglARBPFIDs2GLCapabilitiesImpl(WindowsWGLContext sharedCtx, long hdc, int[] pfdIDs,
+ GLProfile glp, int winattrbits) {
+ boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable(WGL_ARB_pixel_format);
if (!haveWGLChoosePixelFormatARB) {
return null;
}
- boolean haveWGLARBMultisample = sharedCtx.isExtensionAvailable("WGL_ARB_multisample");
-
- // Produce a list of GLCapabilities to give to the
- // GLCapabilitiesChooser.
- // Use wglGetPixelFormatAttribivARB instead of
- // DescribePixelFormat to get higher-precision information
- // about the pixel format (should make the GLCapabilities
- // more precise as well...i.e., remove the
- // "HardwareAccelerated" bit, which is basically
- // meaningless, and put in whether it can render to a
- // window, to a pbuffer, or to a pixmap)
- GLCapabilitiesImmutable[] availableCaps = null;
- int numFormats = 0;
- int niattribs = 0;
- int[] iattributes = new int[2 * MAX_ATTRIBS];
- int[] iresults = new int[2 * MAX_ATTRIBS];
+ boolean haveWGLARBMultisample = sharedCtx.isExtensionAvailable(WGL_ARB_multisample);
+ final int numFormats = pfdIDs.length;
- WGLExt wglExt = sharedCtx.getWGLExt();
- iattributes[0] = WGLExt.WGL_NUMBER_PIXEL_FORMATS_ARB;
- if (wglExt.wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, iattributes, 0, iresults, 0)) {
- numFormats = iresults[0];
- if (DEBUG) {
- System.err.println("wglARBAllPFIDs2GLCapabilities: wglGetPixelFormatAttribivARB reported WGL_NUMBER_PIXEL_FORMATS = " + numFormats + ", pfIDs sz "+pfIDs.length);
- }
- if (numFormats > pfIDs.length) {
- numFormats = pfIDs.length;
- }
+ int[] iattributes = new int [2*MAX_ATTRIBS];
+ int[] iresults = new int [2*MAX_ATTRIBS];
+ int niattribs = fillAttribsForGeneralWGLARBQuery(haveWGLARBMultisample, iattributes);
- niattribs = fillAttribsForGeneralWGLARBQuery(haveWGLARBMultisample, iattributes);
+ ArrayList bucket = new ArrayList();
- availableCaps = new GLCapabilitiesImmutable[numFormats];
- for (int i = 0; i < numFormats; i++) {
- pfIDs[i] = i + 1;
- if (!wglExt.wglGetPixelFormatAttribivARB(hdc, pfIDs[i], 0, niattribs, iattributes, 0, iresults, 0)) {
- throw new GLException("wglARBAllPFIDs2GLCapabilities: Error getting pixel format attributes for pixel format " + pfIDs[i]);
- }
- availableCaps[i] = AttribList2GLCapabilities(glp, iattributes, niattribs, iresults, onscreen, usePBuffer);
- }
- } else {
- long lastErr = GDI.GetLastError();
- // Some GPU's falsely fails with a zero error code (success)
- if (lastErr != GDI.ERROR_SUCCESS) {
- throw new GLException("wglARBAllPFIDs2GLCapabilities: Unable to enumerate pixel formats of window using wglGetPixelFormatAttribivARB: error code " + lastErr);
+ for(int i = 0; i<numFormats; i++) {
+ if ( pfdIDs[i] >= 1 &&
+ sharedCtx.getWGLExt().wglGetPixelFormatAttribivARB(hdc, pfdIDs[i], 0, niattribs, iattributes, 0, iresults, 0) ) {
+ AttribList2GLCapabilities(bucket, glp, hdc, pfdIDs[i], iattributes, niattribs, iresults, winattrbits);
+ } else if (DEBUG) {
+ System.err.println("wglARBPFIDs2GLCapabilities: Cannot get pixel format attributes for pixel format " +
+ i + "/" + numFormats + ": " + pfdIDs[i] + ", " +
+ GLGraphicsConfigurationUtil.winAttributeBits2String(null, winattrbits).toString());
}
}
- return availableCaps;
+ return bucket;
}
static boolean GLCapabilities2AttribList(GLCapabilitiesImmutable caps,
int[] iattributes,
GLContextImpl sharedCtx,
- int accellerationValue,
- boolean pbuffer,
+ int accellerationValue,
int[] floatMode) throws GLException {
- boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable("WGL_ARB_pixel_format");
- boolean haveWGLARBMultisample = sharedCtx.isExtensionAvailable("WGL_ARB_multisample");
+ boolean haveWGLChoosePixelFormatARB = sharedCtx.isExtensionAvailable(WGL_ARB_pixel_format);
+ boolean haveWGLARBMultisample = sharedCtx.isExtensionAvailable(WGL_ARB_multisample);
if(DEBUG) {
System.err.println("HDC2GLCapabilities: ARB_pixel_format: "+haveWGLChoosePixelFormatARB);
System.err.println("HDC2GLCapabilities: ARB_multisample : "+haveWGLARBMultisample);
@@ -339,6 +360,9 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio
return false;
}
+ boolean onscreen = caps.isOnscreen();
+ boolean pbuffer = caps.isPBuffer();
+
int niattribs = 0;
iattributes[niattribs++] = WGLExt.WGL_SUPPORT_OPENGL_ARB;
@@ -347,11 +371,14 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio
iattributes[niattribs++] = WGLExt.WGL_ACCELERATION_ARB;
iattributes[niattribs++] = accellerationValue;
}
- if (pbuffer) {
+ if (onscreen) {
+ iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_WINDOW_ARB;
+ iattributes[niattribs++] = GL.GL_TRUE;
+ } else if (pbuffer) {
iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_PBUFFER_ARB;
iattributes[niattribs++] = GL.GL_TRUE;
} else {
- iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_WINDOW_ARB;
+ iattributes[niattribs++] = WGLExt.WGL_DRAW_TO_BITMAP_ARB;
iattributes[niattribs++] = GL.GL_TRUE;
}
@@ -488,204 +515,120 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio
return true;
}
- public static final int WINDOW_BIT = 1 << 0 ;
- public static final int BITMAP_BIT = 1 << 1 ;
- public static final int PBUFFER_BIT = 1 << 2 ;
-
- static int WGLConfig2DrawableTypeBits(int[] iattribs,
- int niattribs,
- int[] iresults) {
+ static int AttribList2DrawableTypeBits(final int[] iattribs, final int niattribs, final int[] iresults) {
int val = 0;
for (int i = 0; i < niattribs; i++) {
int attr = iattribs[i];
switch (attr) {
case WGLExt.WGL_DRAW_TO_WINDOW_ARB:
- if(iresults[i] == GL.GL_TRUE) val |= WINDOW_BIT;
+ if(iresults[i] == GL.GL_TRUE) val |= GLGraphicsConfigurationUtil.WINDOW_BIT;
break;
case WGLExt.WGL_DRAW_TO_BITMAP_ARB:
- if(iresults[i] == GL.GL_TRUE) val |= BITMAP_BIT;
+ if(iresults[i] == GL.GL_TRUE) val |= GLGraphicsConfigurationUtil.BITMAP_BIT;
break;
case WGLExt.WGL_DRAW_TO_PBUFFER_ARB:
- if(iresults[i] == GL.GL_TRUE) val |= PBUFFER_BIT;
+ if(iresults[i] == GL.GL_TRUE) val |= GLGraphicsConfigurationUtil.PBUFFER_BIT;
break;
}
}
return val;
}
- static boolean WGLConfigDrawableTypeVerify(int val, boolean onscreen, boolean usePBuffer) {
- boolean res;
+ static boolean AttribList2GLCapabilities( ArrayList capsBucket,
+ final GLProfile glp, final long hdc, final int pfdID, final int[] iattribs,
+ final int niattribs,
+ final int[] iresults, final int winattrmask) {
+ final int allDrawableTypeBits = AttribList2DrawableTypeBits(iattribs, niattribs, iresults);
+ int drawableTypeBits = winattrmask & allDrawableTypeBits;
- if ( onscreen ) {
- res = ( 0 != (val & WINDOW_BIT) ) ;
- } else {
- if ( usePBuffer ) {
- res = ( 0 != (val & PBUFFER_BIT) ) ;
- } else {
- res = ( 0 != (val & BITMAP_BIT) ) ;
- }
+ if( 0 == drawableTypeBits ) {
+ return false;
}
+ PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor();
- return res;
- }
-
- static GLCapabilitiesImmutable AttribList2GLCapabilities(
- GLProfile glp, int[] iattribs,
- int niattribs,
- int[] iresults,
- boolean onscreen, boolean usePBuffer) {
- GLCapabilities res = new GLCapabilities(glp);
- int drawableTypeBits = WGLConfig2DrawableTypeBits(iattribs, niattribs, iresults);
- if(WGLConfigDrawableTypeVerify(drawableTypeBits, onscreen, usePBuffer)) {
- res.setOnscreen(onscreen);
- res.setPBuffer(usePBuffer);
- } else {
- if(DEBUG) {
- System.err.println("WGL DrawableType does not match: req(onscrn "+onscreen+", pbuffer "+usePBuffer+"), got(onscreen "+( 0 != (drawableTypeBits & WINDOW_BIT) )+", pbuffer "+( 0 != (drawableTypeBits & PBUFFER_BIT) )+", pixmap "+( 0 != (drawableTypeBits & BITMAP_BIT))+")");
+ if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) {
+ // remove displayable bits, since pfdID is non displayable
+ drawableTypeBits = drawableTypeBits & ~(GLGraphicsConfigurationUtil.WINDOW_BIT | GLGraphicsConfigurationUtil.BITMAP_BIT);
+ if( 0 == drawableTypeBits ) {
+ return false;
}
- return null;
+ // non displayable requested (pbuffer)
}
+ WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp);
+ res.setValuesByARB(iattribs, niattribs, iresults);
- for (int i = 0; i < niattribs; i++) {
- int attr = iattribs[i];
- switch (attr) {
- case WGLExt.WGL_DRAW_TO_WINDOW_ARB:
- case WGLExt.WGL_DRAW_TO_BITMAP_ARB:
- case WGLExt.WGL_DRAW_TO_PBUFFER_ARB:
- break;
+ return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits );
+ }
- case WGLExt.WGL_ACCELERATION_ARB:
- res.setHardwareAccelerated(iresults[i] == WGLExt.WGL_FULL_ACCELERATION_ARB);
- break;
+ //
+ // GDI PIXELFORMAT
+ //
- case WGLExt.WGL_SUPPORT_OPENGL_ARB:
- if (iresults[i] != GL.GL_TRUE) {
- return null;
- }
- break;
+ static int[] wglAllGDIPFIDs(long hdc) {
+ int numFormats = GDI.DescribePixelFormat(hdc, 1, 0, null);
+ if (numFormats == 0) {
+ throw new GLException("DescribePixelFormat: No formats - HDC 0x" + Long.toHexString(hdc) +
+ ", LastError: " + GDI.GetLastError());
+ }
+ int[] pfdIDs = new int[numFormats];
+ for (int i = 0; i < numFormats; i++) {
+ pfdIDs[i] = 1 + i;
+ }
+ return pfdIDs;
+ }
- case WGLExt.WGL_DEPTH_BITS_ARB:
- res.setDepthBits(iresults[i]);
- break;
+ static int PFD2DrawableTypeBits(PIXELFORMATDESCRIPTOR pfd) {
+ int val = 0;
- case WGLExt.WGL_STENCIL_BITS_ARB:
- res.setStencilBits(iresults[i]);
- break;
+ int dwFlags = pfd.getDwFlags();
- case WGLExt.WGL_DOUBLE_BUFFER_ARB:
- res.setDoubleBuffered(iresults[i] == GL.GL_TRUE);
- break;
+ if( 0 != (GDI.PFD_DRAW_TO_WINDOW & dwFlags ) ) {
+ val |= GLGraphicsConfigurationUtil.WINDOW_BIT;
+ }
+ if( 0 != (GDI.PFD_DRAW_TO_BITMAP & dwFlags ) ) {
+ val |= GLGraphicsConfigurationUtil.BITMAP_BIT;
+ }
+ return val;
+ }
- case WGLExt.WGL_STEREO_ARB:
- res.setStereo(iresults[i] == GL.GL_TRUE);
- break;
+ static WGLGLCapabilities PFD2GLCapabilities(GLProfile glp, long hdc, int pfdID, boolean onscreen) {
+ final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, false);
+ ArrayList capsBucket = new ArrayList(1);
+ if( PFD2GLCapabilities(capsBucket, glp, hdc, pfdID, winattrmask) ) {
+ return (WGLGLCapabilities) capsBucket.get(0);
+ }
+ return null;
+ }
- case WGLExt.WGL_PIXEL_TYPE_ARB:
- // Fail softly with unknown results here
- if (iresults[i] == WGLExt.WGL_TYPE_RGBA_ARB||
- iresults[i] == WGLExt.WGL_TYPE_RGBA_FLOAT_ARB) {
- res.setPbufferFloatingPointBuffers(true);
- }
- break;
+ static boolean PFD2GLCapabilities(ArrayList capsBucket, final GLProfile glp, final long hdc, final int pfdID, final int winattrmask) {
+ PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor(hdc, pfdID);
+ if(null == pfd) {
+ return false;
+ }
+ if ((pfd.getDwFlags() & GDI.PFD_SUPPORT_OPENGL) == 0) {
+ return false;
+ }
+ final int allDrawableTypeBits = PFD2DrawableTypeBits(pfd);
+ final int drawableTypeBits = winattrmask & allDrawableTypeBits;
- case WGLExt.WGL_FLOAT_COMPONENTS_NV:
- if (iresults[i] != 0) {
- res.setPbufferFloatingPointBuffers(true);
- }
- break;
-
- case WGLExt.WGL_RED_BITS_ARB:
- res.setRedBits(iresults[i]);
- break;
-
- case WGLExt.WGL_GREEN_BITS_ARB:
- res.setGreenBits(iresults[i]);
- break;
-
- case WGLExt.WGL_BLUE_BITS_ARB:
- res.setBlueBits(iresults[i]);
- break;
-
- case WGLExt.WGL_ALPHA_BITS_ARB:
- res.setAlphaBits(iresults[i]);
- break;
-
- case WGLExt.WGL_ACCUM_RED_BITS_ARB:
- res.setAccumRedBits(iresults[i]);
- break;
-
- case WGLExt.WGL_ACCUM_GREEN_BITS_ARB:
- res.setAccumGreenBits(iresults[i]);
- break;
-
- case WGLExt.WGL_ACCUM_BLUE_BITS_ARB:
- res.setAccumBlueBits(iresults[i]);
- break;
-
- case WGLExt.WGL_ACCUM_ALPHA_BITS_ARB:
- res.setAccumAlphaBits(iresults[i]);
- break;
-
- case WGLExt.WGL_SAMPLE_BUFFERS_ARB:
- res.setSampleBuffers(iresults[i] != 0);
- break;
-
- case WGLExt.WGL_SAMPLES_ARB:
- res.setNumSamples(iresults[i]);
- break;
-
- default:
- throw new GLException("Unknown pixel format attribute " + iattribs[i]);
- }
+ if( 0 == drawableTypeBits ) {
+ return false;
}
- return res;
- }
- // PIXELFORMAT
+ WGLGLCapabilities res = new WGLGLCapabilities(pfd, pfdID, glp);
+ res.setValuesByGDI();
- static GLCapabilitiesImmutable PFD2GLCapabilities(GLProfile glp, PIXELFORMATDESCRIPTOR pfd, boolean onscreen, boolean usePBuffer) {
- if ((pfd.getDwFlags() & GDI.PFD_SUPPORT_OPENGL) == 0) {
- return null;
- }
- GLCapabilities res = new GLCapabilities(glp);
- res.setRedBits (pfd.getCRedBits());
- res.setGreenBits (pfd.getCGreenBits());
- res.setBlueBits (pfd.getCBlueBits());
- res.setAlphaBits (pfd.getCAlphaBits());
- res.setAccumRedBits (pfd.getCAccumRedBits());
- res.setAccumGreenBits(pfd.getCAccumGreenBits());
- res.setAccumBlueBits (pfd.getCAccumBlueBits());
- res.setAccumAlphaBits(pfd.getCAccumAlphaBits());
- res.setDepthBits (pfd.getCDepthBits());
- res.setStencilBits (pfd.getCStencilBits());
- res.setDoubleBuffered((pfd.getDwFlags() & GDI.PFD_DOUBLEBUFFER) != 0);
- res.setStereo ((pfd.getDwFlags() & GDI.PFD_STEREO) != 0);
- res.setHardwareAccelerated( (pfd.getDwFlags() & GDI.PFD_GENERIC_FORMAT) == 0 ||
- (pfd.getDwFlags() & GDI.PFD_GENERIC_ACCELERATED) != 0 );
- res.setOnscreen ( onscreen && ((pfd.getDwFlags() & GDI.PFD_DRAW_TO_WINDOW) != 0) );
- res.setPBuffer ( usePBuffer );
- /* FIXME: Missing ??
- if (GLXUtil.isMultisampleAvailable()) {
- res.setSampleBuffers(glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLE_BUFFERS, tmp, 0) != 0);
- res.setNumSamples (glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLES, tmp, 0));
- }
- res.setBackgroundOpaque(glXGetFBConfig(display, fbcfg, GLX.GLX_TRANSPARENT_TYPE, tmp, 0) != GLX.GLX_NONE);
- try {
- res.setPbufferFloatingPointBuffers(glXGetFBConfig(display, fbcfg, GLXExt.GLX_FLOAT_COMPONENTS_NV, tmp, 0) != GL.GL_FALSE);
- } catch (Exception e) {}
- */
- return res;
+ return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits );
}
- static PIXELFORMATDESCRIPTOR GLCapabilities2PFD(GLCapabilitiesImmutable caps) {
+ static PIXELFORMATDESCRIPTOR GLCapabilities2PFD(GLCapabilitiesImmutable caps, PIXELFORMATDESCRIPTOR pfd) {
int colorDepth = (caps.getRedBits() +
caps.getGreenBits() +
caps.getBlueBits());
if (colorDepth < 15) {
throw new GLException("Bit depths < 15 (i.e., non-true-color) not supported");
}
- PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor();
int pfdFlags = (GDI.PFD_SUPPORT_OPENGL |
GDI.PFD_GENERIC_ACCELERATED);
if (caps.getDoubleBuffered()) {
@@ -718,27 +661,35 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio
pfd.setCStencilBits((byte) caps.getStencilBits());
pfd.setILayerType((byte) GDI.PFD_MAIN_PLANE);
- /* FIXME: Missing:
- caps.getSampleBuffers()
- caps.getNumSamples ()
- }
- caps.getBackgroundOpaque()
- try {
- caps.getPbufferFloatingPointBuffers()
- } catch (Exception e) {}
- */
+ // n/a with non ARB/GDI method:
+ // multisample
+ // opaque
+ // pbuffer
return pfd;
}
- static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor() {
+ static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor(long hdc, int pfdID) {
PIXELFORMATDESCRIPTOR pfd = PIXELFORMATDESCRIPTOR.create();
pfd.setNSize((short) pfd.size());
pfd.setNVersion((short) 1);
+ if(0 != hdc && 1 <= pfdID) {
+ if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) {
+ // Accelerated pixel formats that are non displayable
+ if(DEBUG) {
+ System.err.println("Info: Non displayable pixel format " + pfdID + " of device context: error code " + GDI.GetLastError());
+ }
+ return null;
+ }
+ }
return pfd;
}
+ static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor() {
+ return createPixelFormatDescriptor(0, 0);
+ }
+
public String toString() {
- return "WindowsWGLGraphicsConfiguration["+getScreen()+", pfdID " + pixelfmtID + ", wglChoosen "+choosenByWGLPixelFormat+
+ return "WindowsWGLGraphicsConfiguration["+getScreen()+", pfdID " + getPixelFormatID() + ", ARB-Choosen " + isChoosenByARB() +
",\n\trequested " + getRequestedCapabilities() +
",\n\tchosen " + getChosenCapabilities() +
"]";
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
index 87bbec018..812829168 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
@@ -39,10 +39,10 @@ import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.CapabilitiesChooser;
import javax.media.nativewindow.DefaultGraphicsScreen;
import javax.media.nativewindow.GraphicsConfigurationFactory;
+import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.NativeSurface;
-import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.NativeWindowFactory;
-import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLCapabilitiesChooser;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
@@ -50,17 +50,22 @@ import javax.media.opengl.GLProfile;
import com.jogamp.nativewindow.impl.windows.GDI;
import com.jogamp.nativewindow.impl.windows.PIXELFORMATDESCRIPTOR;
-import javax.media.nativewindow.CapabilitiesImmutable;
-import javax.media.opengl.DefaultGLCapabilitiesChooser;
-import javax.media.opengl.GLCapabilitiesImmutable;
+import com.jogamp.opengl.impl.GLGraphicsConfigurationFactory;
+import com.jogamp.opengl.impl.GLGraphicsConfigurationUtil;
+import com.jogamp.opengl.impl.SharedResourceRunner;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
/** Subclass of GraphicsConfigurationFactory used when non-AWT tookits
are used on Windows 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 WindowsWGLGraphicsConfigurationFactory extends GraphicsConfigurationFactory {
+public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory {
protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration");
+ static WGLGLCapabilities.PfdIDComparator PfdIDComparator = new WGLGLCapabilities.PfdIDComparator();
WindowsWGLGraphicsConfigurationFactory() {
GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.windows.WindowsGraphicsDevice.class, this);
@@ -82,10 +87,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio
static WindowsWGLGraphicsConfiguration createDefaultGraphicsConfiguration(GLCapabilitiesImmutable caps,
AbstractGraphicsScreen absScreen) {
- if(null==absScreen) {
- absScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS);
- }
- return new WindowsWGLGraphicsConfiguration(absScreen, caps, caps, WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(caps), -1, null);
+ return chooseGraphicsConfigurationStatic(caps, caps, null, absScreen);
}
static WindowsWGLGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilitiesImmutable capsChosen,
@@ -95,21 +97,82 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio
if(null==absScreen) {
absScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS);
}
+ AbstractGraphicsDevice absDevice = absScreen.getDevice();
+
+ capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities(
+ capsChosen, GLDrawableFactory.getDesktopFactory().canCreateGLPbuffer(absDevice) );
- if(!capsChosen.isOnscreen() && capsChosen.getDoubleBuffered()) {
- // OFFSCREEN !DOUBLE_BUFFER // FIXME DBLBUFOFFSCRN
- GLCapabilities caps2 = (GLCapabilities) capsChosen.cloneMutable();
- caps2.setDoubleBuffered(false);
- capsChosen = caps2;
+ return new WindowsWGLGraphicsConfiguration( absScreen, capsChosen, capsReq, (GLCapabilitiesChooser)chooser );
+ }
+
+ protected static List/*<WGLGLCapabilities>*/ getAvailableCapabilities(WindowsWGLDrawableFactory factory, AbstractGraphicsDevice device) {
+ SharedResourceRunner.Resource sharedResource = factory.getOrCreateSharedResource(device);
+ if(null == sharedResource) {
+ throw new GLException("Shared resource for device n/a: "+device);
+ }
+ WindowsWGLDrawable sharedDrawable = (WindowsWGLDrawable) sharedResource.getDrawable();
+ GLCapabilitiesImmutable capsChosen = sharedDrawable.getChosenGLCapabilities();
+ WindowsWGLContext sharedContext = (WindowsWGLContext) sharedResource.getContext();
+ List availableCaps = null;
+
+ sharedDrawable.lockSurface();
+ try {
+ long hdc = sharedDrawable.getHandle();
+ if (0 == hdc) {
+ throw new GLException("Error: HDC is null");
+ }
+ if (sharedContext.isExtensionAvailable(WindowsWGLGraphicsConfiguration.WGL_ARB_pixel_format)) {
+ availableCaps = getAvailableGLCapabilitiesARB(hdc, sharedContext, capsChosen.getGLProfile());
+ }
+ if( null == availableCaps || 0 == availableCaps.size() ) {
+ availableCaps = getAvailableGLCapabilitiesGDI(hdc, capsChosen);
+ }
+ } finally {
+ sharedDrawable.unlockSurface();
}
- return new WindowsWGLGraphicsConfiguration(absScreen, capsChosen, capsReq,
- WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(capsChosen), -1,
- (GLCapabilitiesChooser)chooser);
+ if( null != availableCaps ) {
+ Collections.sort(availableCaps, PfdIDComparator);
+ }
+ return availableCaps;
}
+ static List/*<WGLGLCapabilities>*/ getAvailableGLCapabilitiesARB(long hdc, WindowsWGLContext sharedContext, GLProfile glProfile) {
+ int[] pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFIDs(sharedContext, hdc);
+ return WindowsWGLGraphicsConfiguration.wglARBPFIDs2AllGLCapabilities(sharedContext, hdc, pformats, glProfile);
+ }
+
+ static List/*<WGLGLCapabilities>*/ getAvailableGLCapabilitiesGDI(long hdc, GLCapabilitiesImmutable capsChosen) {
+ boolean onscreen = capsChosen.isOnscreen();
+ if(capsChosen.isPBuffer()) {
+ return null;
+ }
+ GLProfile glProfile = capsChosen.getGLProfile();
+
+ int[] pformats = WindowsWGLGraphicsConfiguration.wglAllGDIPFIDs(hdc);
+ int numFormats = pformats.length;
+ ArrayList bucket = new ArrayList(numFormats);
+ for (int i = 0; i < numFormats; i++) {
+ bucket.add( WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, hdc, pformats[i], onscreen) );
+ }
+ return bucket;
+ }
+
+ /**
+ *
+ * @param chooser
+ * @param _factory
+ * @param ns
+ * @param pfIDs optional pool of preselected PixelFormat IDs, maybe null for unrestricted selection
+ */
static void updateGraphicsConfiguration(CapabilitiesChooser chooser,
- GLDrawableFactory _factory, NativeSurface ns) {
+ GLDrawableFactory factory, NativeSurface ns, int[] pfdIDs) {
+ if (chooser != null && !(chooser instanceof GLCapabilitiesChooser)) {
+ throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects");
+ }
+ if (factory == null) {
+ throw new IllegalArgumentException("GLDrawableFactory is null");
+ }
if (ns == null) {
throw new IllegalArgumentException("NativeSurface is null");
}
@@ -118,22 +181,75 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio
throw new GLException("Error: HDC is null");
}
WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration) ns.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+
+ if(!config.isDetermined()) {
+ updateGraphicsConfiguration(config, chooser, factory, hdc, false, pfdIDs);
+ } else {
+ // set PFD if not set yet
+ int pfdID = -1;
+ boolean set = false;
+ if ( 1 > ( pfdID = GDI.GetPixelFormat(hdc) ) ) {
+ if (!GDI.SetPixelFormat(hdc, config.getPixelFormatID(), config.getPixelFormat())) {
+ throw new GLException("Unable to set pixel format " + config.getPixelFormatID() +
+ " for device context " + toHexString(hdc) +
+ ": error code " + GDI.GetLastError());
+ }
+ set = true;
+ pfdID = config.getPixelFormatID();
+ }
+ if (DEBUG) {
+ System.err.println("!!! setPixelFormat (post): hdc "+toHexString(hdc) +", "+config.getPixelFormatID()+" -> "+pfdID+", set: "+set);
+ Thread.dumpStack();
+ }
+ }
+ }
+
+ static void preselectGraphicsConfiguration(CapabilitiesChooser chooser,
+ GLDrawableFactory _factory, AbstractGraphicsDevice device,
+ WindowsWGLGraphicsConfiguration config, int[] pfdIDs) {
if (chooser != null && !(chooser instanceof GLCapabilitiesChooser)) {
throw new IllegalArgumentException("This NativeWindowFactory accepts only GLCapabilitiesChooser objects");
}
+ if (_factory == null) {
+ throw new IllegalArgumentException("GLDrawableFactory is null");
+ }
+ if (config == null) {
+ throw new IllegalArgumentException("WindowsWGLGraphicsConfiguration is null");
+ }
+ WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory) _factory;
+ WindowsWGLDrawable sharedDrawable = factory.getOrCreateSharedDrawable(device);
+ if(null == sharedDrawable) {
+ throw new IllegalArgumentException("Shared Drawable is null");
+ }
+ sharedDrawable.lockSurface();
+ try {
+ long hdc = sharedDrawable.getHandle();
+ if (0 == hdc) {
+ throw new GLException("Error: HDC is null");
+ }
+ updateGraphicsConfiguration(config, chooser, factory, hdc, true, pfdIDs);
+ } finally {
+ sharedDrawable.unlockSurface();
+ }
+ }
+ private static void updateGraphicsConfiguration(WindowsWGLGraphicsConfiguration config, CapabilitiesChooser chooser,
+ GLDrawableFactory factory, long hdc, boolean extHDC, int[] pfdIDs) {
if (DEBUG) {
- System.err.println("updateGraphicsConfiguration: hdc "+toHexString(hdc));
+ if(extHDC) {
+ System.err.println("updateGraphicsConfiguration(using shared): hdc "+toHexString(hdc));
+ } else {
+ System.err.println("updateGraphicsConfiguration(using target): hdc "+toHexString(hdc));
+ }
System.err.println("!!! user chosen caps " + config.getChosenCapabilities());
}
-
- if( !updateGraphicsConfigurationARB(hdc, config, chooser, (WindowsWGLDrawableFactory) _factory) ) {
- updateGraphicsConfigurationGDI(hdc, config, chooser, (WindowsWGLDrawableFactory) _factory);
+ if( !updateGraphicsConfigurationARB(hdc, extHDC, config, chooser, (WindowsWGLDrawableFactory)factory, pfdIDs) ) {
+ updateGraphicsConfigurationGDI(hdc, extHDC, config, chooser, pfdIDs);
}
}
- private static boolean updateGraphicsConfigurationARB(long hdc, WindowsWGLGraphicsConfiguration config,
- CapabilitiesChooser chooser, WindowsWGLDrawableFactory factory) {
+ private static boolean updateGraphicsConfigurationARB(long hdc, boolean extHDC, WindowsWGLGraphicsConfiguration config,
+ CapabilitiesChooser chooser, WindowsWGLDrawableFactory factory, int[] pformats) {
AbstractGraphicsDevice device = config.getScreen().getDevice();
WindowsWGLContext sharedContext = (WindowsWGLContext) factory.getOrCreateSharedContextImpl(device);
if (null == sharedContext) {
@@ -142,282 +258,204 @@ public class WindowsWGLGraphicsConfigurationFactory extends GraphicsConfiguratio
}
return false;
}
+ if (!sharedContext.isExtensionAvailable(WindowsWGLGraphicsConfiguration.WGL_ARB_pixel_format)) {
+ if (DEBUG) {
+ System.err.println("updateGraphicsConfigurationARB: "+WindowsWGLGraphicsConfiguration.WGL_ARB_pixel_format+" not available");
+ }
+ return false;
+ }
+
GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities();
boolean onscreen = capsChosen.isOnscreen();
boolean usePBuffer = capsChosen.isPBuffer();
GLProfile glProfile = capsChosen.getGLProfile();
- int pixelFormatSet = -1; // 1-based pixel format
- GLCapabilitiesImmutable pixelFormatCaps = null;
-
- GLCapabilitiesImmutable[] availableCaps = null;
- int[] pformats = null; // if != null, then index matches availableCaps
- int numFormats = -1;
- int recommendedIndex = -1;
-
- synchronized (sharedContext) {
- sharedContext.makeCurrent();
- try {
- if (!sharedContext.isExtensionAvailable("WGL_ARB_pixel_format")) {
- if (DEBUG) {
- System.err.println("updateGraphicsConfigurationARB: wglChoosePixelFormatARB not available");
- }
- return false;
+ WGLGLCapabilities pixelFormatCaps = null; // chosen or preset PFD ID's caps
+ boolean pixelFormatSet = false; // indicates a preset PFD ID [caps]
+
+ sharedContext.makeCurrent();
+ try {
+ final int presetPFDID = extHDC ? -1 : GDI.GetPixelFormat(hdc) ;
+ if ( 1 <= presetPFDID ) {
+ // Pixelformat already set by either
+ // - a previous preselectGraphicsConfiguration() call on the same HDC,
+ // - the graphics driver, copying the HDC's pixelformat to the new one,
+ // - or the Java2D/OpenGL pipeline's configuration
+ if (DEBUG) {
+ System.err.println("updateGraphicsConfigurationARB: Pixel format already chosen for HDC: " + toHexString(hdc)
+ + ", pixelformat " + presetPFDID);
}
- if ((pixelFormatSet = GDI.GetPixelFormat(hdc)) >= 1) {
- // Pixelformat already set by either
- // - a previous updateGraphicsConfiguration() call on the same HDC,
- // - the graphics driver, copying the HDC's pixelformat to the new one,
- // - or the Java2D/OpenGL pipeline's configuration
- if (DEBUG) {
- System.err.println("updateGraphicsConfigurationARB: Pixel format already chosen for HDC: " + toHexString(hdc)
- + ", pixelformat " + pixelFormatSet);
- }
-
- // only fetch the specific one ..
- pixelFormatCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedContext, hdc, pixelFormatSet, glProfile, onscreen, usePBuffer);
- } else {
+ pixelFormatSet = true;
+ pixelFormatCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedContext, hdc, presetPFDID, glProfile, onscreen, usePBuffer);
+ } else {
+ int recommendedIndex = -1; // recommended index
+
+ if(null == pformats) {
+ // No given PFD IDs
+ //
+ // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice
int[] iattributes = new int[2 * WindowsWGLGraphicsConfiguration.MAX_ATTRIBS];
float[] fattributes = new float[1];
- pformats = new int[WindowsWGLGraphicsConfiguration.MAX_PFORMATS];
-
- // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice
- numFormats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(hdc, sharedContext, capsChosen,
- iattributes, -1, fattributes, pformats);
- if (0 < numFormats) {
- availableCaps = WindowsWGLGraphicsConfiguration.wglARBPFIDs2GLCapabilities(sharedContext, hdc, pformats, numFormats,
- glProfile, onscreen, usePBuffer);
- if (null != availableCaps) {
- recommendedIndex = 0;
- pixelFormatCaps = availableCaps[0];
- if (DEBUG) {
- System.err.println("updateGraphicsConfigurationARB: NumFormats (wglChoosePixelFormatARB) " + numFormats + " / " + WindowsWGLGraphicsConfiguration.MAX_PFORMATS);
- System.err.println("updateGraphicsConfigurationARB: Used wglChoosePixelFormatARB to recommend pixel format " + pformats[recommendedIndex] + ", idx " + recommendedIndex);
- System.err.println("!!! recommended caps " + pixelFormatCaps);
- }
+ pformats = WindowsWGLGraphicsConfiguration.wglChoosePixelFormatARB(hdc, sharedContext, capsChosen,
+ iattributes, -1, fattributes);
+
+ if (null != pformats) {
+ recommendedIndex = 0;
+ } else {
+ if(DEBUG) {
+ System.err.println("updateGraphicsConfigurationARB: wglChoosePixelFormatARB failed with: "+capsChosen);
}
- }
-
- // 2nd choice: get all GLCapabilities available, no preferred recommendedIndex available
- if (null == availableCaps) {
+ // 2nd choice: get all GLCapabilities available, no preferred recommendedIndex available
+ pformats = WindowsWGLGraphicsConfiguration.wglAllARBPFIDs(sharedContext, hdc);
if (DEBUG) {
- System.err.println("updateGraphicsConfigurationARB: wglChoosePixelFormatARB failed (Query all formats without recommendation): " + GDI.GetLastError());
+ System.err.println("updateGraphicsConfigurationARB: NumFormats (wglAllARBPFIDs) " + pformats.length);
}
- availableCaps = WindowsWGLGraphicsConfiguration.wglARBAllPFIDs2GLCapabilities(sharedContext, hdc,
- glProfile, onscreen, usePBuffer, pformats);
- if (null != availableCaps) {
- numFormats = availableCaps.length;
+ }
+ if (null == pformats) {
+ if (DEBUG) {
+ Thread.dumpStack();
}
+ return false;
}
}
- } finally {
- sharedContext.release();
- }
- } // synchronized(factory.sharedContext)
-
- if (pixelFormatSet <= 0 && null == availableCaps) {
- if (DEBUG) {
- System.err.println("updateGraphicsConfigurationARB: No PixelFormat chosen via ARB ... (LastError: " + GDI.GetLastError() + ")");
- }
- return false;
- }
-
- int pfdID;
- if (pixelFormatSet <= 0) {
- if (null == pixelFormatCaps && null == chooser) {
- chooser = new DefaultGLCapabilitiesChooser();
- }
-
- int chosenIndex = recommendedIndex;
- try {
- if (null != chooser) {
- chosenIndex = chooser.chooseCapabilities(capsChosen, availableCaps, recommendedIndex);
- pixelFormatCaps = availableCaps[chosenIndex];
+ List /*<WGLGLCapabilities>*/ availableCaps =
+ WindowsWGLGraphicsConfiguration.wglARBPFIDs2GLCapabilities(sharedContext, hdc, pformats,
+ glProfile, onscreen, usePBuffer);
+ if( null == availableCaps || 0 == availableCaps.size() ) {
if (DEBUG) {
- System.err.println("updateGraphicsConfigurationARB: chooser: idx " + chosenIndex);
- System.err.println("!!! chosen caps " + pixelFormatCaps);
+ System.err.println("updateGraphicsConfigurationARB: wglARBPFIDs2GLCapabilities failed with " + pformats.length +
+ " pfd ids, onscreen " + onscreen + ", pbuffer " + usePBuffer);
+ Thread.dumpStack();
}
+ return false;
}
- } catch (NativeWindowException e) {
+
if (DEBUG) {
- e.printStackTrace();
+ System.err.println("updateGraphicsConfigurationARB: " + pformats.length +
+ " pfd ids, onscreen " + onscreen + ", pbuffer " + usePBuffer + ", " + availableCaps.size() + " glcaps");
+ if(0 <= recommendedIndex) {
+ System.err.println("updateGraphicsConfigurationARB: Used wglChoosePixelFormatARB to recommend pixel format " +
+ pformats[recommendedIndex] + ", idx " + recommendedIndex +", "+availableCaps.get(recommendedIndex));
+ }
}
- }
- if (chosenIndex < 0) {
- // keep on going ..
- // seek first available one ..
- for (chosenIndex = 0; chosenIndex < availableCaps.length && availableCaps[chosenIndex] == null; chosenIndex++) {
- // nop
- }
- if (chosenIndex == availableCaps.length) {
- // give up ..
+ int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex);
+ if ( 0 > chosenIndex ) {
if (DEBUG) {
- System.err.println("updateGraphicsConfigurationARB: Failed .. nothing available, bail out");
+ Thread.dumpStack();
}
return false;
}
- pixelFormatCaps = availableCaps[chosenIndex];
+ pixelFormatCaps = (WGLGLCapabilities) availableCaps.get(chosenIndex);
+ if( null == pixelFormatCaps) {
+ throw new GLException("Null Capabilities with "+
+ " chosen pfdID: native recommended "+ (recommendedIndex+1) +
+ " chosen "+pixelFormatCaps.getPFDID());
+ }
if (DEBUG) {
- System.err.println("updateGraphicsConfigurationARB: Failed .. unable to choose config, using first available idx: " + chosenIndex);
- System.err.println("!!! fallback caps " + pixelFormatCaps);
+ System.err.println("!!! chosen pfdID (ARB): native recommended "+ (recommendedIndex+1) +
+ " chosen "+pixelFormatCaps);
}
}
- pfdID = pformats[chosenIndex];
- } else {
- pfdID = pixelFormatSet;
- }
- if (DEBUG) {
- System.err.println("updateGraphicsConfigurationARB: using pfdID "+pfdID);
- }
-
- PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor();
-
- if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) {
- throw new GLException("updateGraphicsConfigurationARB: Error describing the chosen pixel format: " + pfdID + ", " + GDI.GetLastError());
+ } finally {
+ sharedContext.release();
}
- if (pixelFormatSet <= 0) {
- if (!GDI.SetPixelFormat(hdc, pfdID, pfd)) {
- throw new GLException("Unable to set pixel format " + pfdID +
+ if ( !extHDC && !pixelFormatSet ) {
+ if (!GDI.SetPixelFormat(hdc, pixelFormatCaps.getPFDID(), pixelFormatCaps.getPFD())) {
+ throw new GLException("Unable to set pixel format " + pixelFormatCaps.getPFDID() +
" for device context " + toHexString(hdc) +
": error code " + GDI.GetLastError());
}
+ if (DEBUG) {
+ System.err.println("!!! setPixelFormat (ARB): hdc "+toHexString(hdc) +", "+config.getPixelFormatID()+" -> "+pixelFormatCaps.getPFDID());
+ }
}
-
- config.setCapsPFD(pixelFormatCaps, pfd, pfdID, true);
+ config.setCapsPFD(pixelFormatCaps);
return true;
}
- private static boolean updateGraphicsConfigurationGDI(long hdc, WindowsWGLGraphicsConfiguration config,
- CapabilitiesChooser chooser, WindowsWGLDrawableFactory factory) {
+ private static boolean updateGraphicsConfigurationGDI(long hdc, boolean extHDC, WindowsWGLGraphicsConfiguration config,
+ CapabilitiesChooser chooser, int[] pformats) {
GLCapabilitiesImmutable capsChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities();
+ if(capsChosen.isPBuffer()) {
+ if (DEBUG) {
+ System.err.println("updateGraphicsConfigurationGDI: no pbuffer supported on GDI: " + capsChosen);
+ }
+ return false;
+ }
boolean onscreen = capsChosen.isOnscreen();
- boolean usePBuffer = capsChosen.isPBuffer();
GLProfile glProfile = capsChosen.getGLProfile();
- int pixelFormatSet = -1; // 1-based pixel format
- GLCapabilitiesImmutable pixelFormatCaps = null;
+ ArrayList/*<WGLGLCapabilities>*/ availableCaps = new ArrayList();
+ int pfdID; // chosen or preset PFD ID
+ WGLGLCapabilities pixelFormatCaps = null; // chosen or preset PFD ID's caps
+ boolean pixelFormatSet = false; // indicates a preset PFD ID [caps]
- GLCapabilitiesImmutable[] availableCaps = null;
- int numFormats = -1;
- int recommendedIndex = -1;
-
- if ((pixelFormatSet = GDI.GetPixelFormat(hdc)) != 0) {
+ if ( !extHDC && 1 <= ( pfdID = GDI.GetPixelFormat(hdc) ) ) {
// Pixelformat already set by either
- // - a previous updateGraphicsConfiguration() call on the same HDC,
+ // - a previous preselectGraphicsConfiguration() call on the same HDC,
// - the graphics driver, copying the HDC's pixelformat to the new one,
// - or the Java2D/OpenGL pipeline's configuration
if (DEBUG) {
System.err.println("updateGraphicsConfigurationGDI: NOTE: pixel format already chosen for HDC: " + toHexString(hdc)
- + ", pixelformat " + pixelFormatSet);
+ + ", pixelformat " + pfdID);
}
- }
+ pixelFormatSet = true;
+ pixelFormatCaps = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, hdc, pfdID, onscreen);
+ } else {
+ if(null == pformats) {
+ pformats = WindowsWGLGraphicsConfiguration.wglAllGDIPFIDs(hdc);
+ }
+ final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, false);
- int recommendedPixelFormat = pixelFormatSet;
+ for (int i = 0; i < pformats.length; i++) {
+ WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(availableCaps, glProfile, hdc, pformats[i], winattrmask);
+ }
- numFormats = GDI.DescribePixelFormat(hdc, 1, 0, null);
- if (numFormats == 0) {
- throw new GLException("Unable to enumerate pixel formats of window "
- + toHexString(hdc) + " for GLCapabilitiesChooser (LastError: " + GDI.GetLastError() + ")");
- }
- if (DEBUG) {
- System.err.println("updateGraphicsConfigurationGDI: NumFormats (DescribePixelFormat) " + numFormats);
- }
-
- PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor();
- availableCaps = new GLCapabilitiesImmutable[numFormats];
- for (int i = 0; i < numFormats; i++) {
- if (GDI.DescribePixelFormat(hdc, 1 + i, pfd.size(), pfd) == 0) {
- throw new GLException("Error describing pixel format " + (1 + i) + " of device context");
+ // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice
+ PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor();
+ pfd = WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(capsChosen, pfd);
+ pfdID = GDI.ChoosePixelFormat(hdc, pfd);
+ int recommendedIndex = -1 ;
+ if( 1 <= pfdID ) {
+ // seek index ..
+ for (recommendedIndex = availableCaps.size() - 1 ;
+ 0 <= recommendedIndex && pfdID != ((WGLGLCapabilities) availableCaps.get(recommendedIndex)).getPFDID();
+ recommendedIndex--)
+ { /* nop */ }
}
- availableCaps[i] = WindowsWGLGraphicsConfiguration.PFD2GLCapabilities(glProfile, pfd, onscreen, usePBuffer);
- }
-
- int pfdID;
-
- if (pixelFormatSet <= 0) {
- pfd = WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(capsChosen);
- recommendedPixelFormat = GDI.ChoosePixelFormat(hdc, pfd);
- recommendedIndex = recommendedPixelFormat - 1;
- pixelFormatCaps = availableCaps[recommendedIndex];
+ // 2nd choice: if no preferred recommendedIndex available
if (DEBUG) {
- System.err.println("updateGraphicsConfigurationGDI: ChoosePixelFormat(HDC " + toHexString(hdc) + ") = " + recommendedPixelFormat + " (LastError: " + GDI.GetLastError() + ")");
- System.err.println("!!! recommended caps " + pixelFormatCaps);
+ System.err.println("updateGraphicsConfigurationGDI: ChoosePixelFormat(HDC " + toHexString(hdc) + ") = " + pfdID + ", idx " + recommendedIndex + " (LastError: " + GDI.GetLastError() + ")");
}
-
- int chosenIndex = recommendedIndex;
- try {
- if (null != chooser) {
- chosenIndex = chooser.chooseCapabilities(capsChosen, availableCaps, recommendedIndex);
- pixelFormatCaps = availableCaps[chosenIndex];
- if (DEBUG) {
- System.err.println("updateGraphicsConfigurationGDI: chooser: idx " + chosenIndex);
- System.err.println("!!! chosen caps " + pixelFormatCaps);
- }
- }
- } catch (NativeWindowException e) {
+ int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex);
+ if ( 0 > chosenIndex ) {
if (DEBUG) {
- e.printStackTrace();
+ Thread.dumpStack();
}
+ return false;
}
-
- if (chosenIndex < 0) {
- // keep on going ..
- // seek first available one ..
- for (chosenIndex = 0; chosenIndex < availableCaps.length && availableCaps[chosenIndex] == null; chosenIndex++) {
- // nop
- }
- if (chosenIndex == availableCaps.length) {
- // give up ..
- if (DEBUG) {
- System.err.println("updateGraphicsConfigurationGDI: Failed .. nothing available, bail out");
- }
- return false;
- }
- pixelFormatCaps = availableCaps[chosenIndex];
- if (DEBUG) {
- System.err.println("updateGraphicsConfigurationGDI: Failed .. unable to choose config, using first available idx: " + chosenIndex);
- System.err.println("!!! fallback caps " + pixelFormatCaps);
- }
- }
- pfdID = chosenIndex + 1;
- } else {
- pfdID = pixelFormatSet;
- pixelFormatCaps = availableCaps[pixelFormatSet-1];
+ pixelFormatCaps = (WGLGLCapabilities) availableCaps.get(chosenIndex);
if (DEBUG) {
- System.err.println("updateGraphicsConfigurationGDI: Using preset PFID: " + pixelFormatSet);
- System.err.println("!!! preset caps " + pixelFormatCaps);
+ System.err.println("!!! chosen pfdID (GDI): native recommended "+ (recommendedIndex+1) +
+ ", caps " + pixelFormatCaps);
}
}
- if (DEBUG) {
- System.err.println("updateGraphicsConfigurationGDI: using pfdID "+pfdID);
- }
-
- if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) {
- throw new GLException("Error describing the chosen pixel format: " + pfdID + ", " + GDI.GetLastError());
- }
- if (pixelFormatSet <= 0) {
- if (!GDI.SetPixelFormat(hdc, pfdID, pfd)) {
- throw new GLException("Unable to set pixel format " + pfdID +
+ if ( !extHDC && !pixelFormatSet ) {
+ if (!GDI.SetPixelFormat(hdc, pixelFormatCaps.getPFDID(), pixelFormatCaps.getPFD())) {
+ throw new GLException("Unable to set pixel format " + pixelFormatCaps.getPFDID() +
" for device context " + toHexString(hdc) +
": error code " + GDI.GetLastError());
}
+ if (DEBUG) {
+ System.err.println("!!! setPixelFormat (GDI): hdc "+toHexString(hdc) +", "+config.getPixelFormatID()+" -> " + pixelFormatCaps.getPFDID());
+ }
}
-
- config.setCapsPFD(pixelFormatCaps, pfd, pfdID, true);
+ config.setCapsPFD(pixelFormatCaps);
return true;
-
- }
-
- static String getThreadName() {
- return Thread.currentThread().getName();
- }
-
- static String toHexString(long hex) {
- return "0x" + Long.toHexString(hex);
}
}
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java
index da4f2113d..f753c08c5 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -33,6 +34,9 @@
package com.jogamp.opengl.impl.windows.wgl.awt;
+import com.jogamp.common.util.ArrayHashSet;
+import com.jogamp.nativewindow.impl.jawt.windows.Win32SunJDKReflection;
+import com.jogamp.opengl.impl.GLGraphicsConfigurationFactory;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
@@ -53,8 +57,9 @@ import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLException;
import com.jogamp.opengl.impl.windows.wgl.WindowsWGLGraphicsConfiguration;
+import javax.media.opengl.GLDrawableFactory;
-public class WindowsAWTWGLGraphicsConfigurationFactory extends GraphicsConfigurationFactory {
+public class WindowsAWTWGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory {
protected static final boolean DEBUG = com.jogamp.opengl.impl.Debug.debug("GraphicsConfiguration");
public WindowsAWTWGLGraphicsConfigurationFactory() {
@@ -72,6 +77,9 @@ public class WindowsAWTWGLGraphicsConfigurationFactory extends GraphicsConfigura
if(null==absScreen) {
absScreen = AWTGraphicsScreen.createScreenDevice(-1, AbstractGraphicsDevice.DEFAULT_UNIT);
+ if(DEBUG) {
+ System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: creating default device: "+absScreen);
+ }
}
AWTGraphicsScreen awtScreen = (AWTGraphicsScreen) absScreen;
device = ((AWTGraphicsDevice)awtScreen.getDevice()).getGraphicsDevice();
@@ -92,28 +100,74 @@ public class WindowsAWTWGLGraphicsConfigurationFactory extends GraphicsConfigura
if(DEBUG) {
System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: got "+absScreen);
}
- GraphicsConfiguration gc = device.getDefaultConfiguration();
+
WindowsGraphicsDevice winDevice = new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
DefaultGraphicsScreen winScreen = new DefaultGraphicsScreen(winDevice, awtScreen.getIndex());
- if(DEBUG) {
- System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: made "+winScreen);
- }
+ GraphicsConfigurationFactory configFactory = GraphicsConfigurationFactory.getFactory(winDevice);
+ GLDrawableFactory drawableFactory = GLDrawableFactory.getFactory( ((GLCapabilitiesImmutable)capsChosen).getGLProfile() );
WindowsWGLGraphicsConfiguration winConfig = (WindowsWGLGraphicsConfiguration)
- GraphicsConfigurationFactory.getFactory(winDevice).chooseGraphicsConfiguration(capsChosen,
- capsRequested,
- chooser, winScreen);
-
+ configFactory.chooseGraphicsConfiguration(capsChosen,
+ capsRequested,
+ chooser, winScreen);
if (winConfig == null) {
throw new GLException("Unable to choose a GraphicsConfiguration: "+capsChosen+",\n\t"+chooser+"\n\t"+winScreen);
}
- if(DEBUG) {
- System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: chosen "+winConfig);
+ GraphicsConfiguration chosenGC = null;
+
+ // 1st Choice: Create an AWT GraphicsConfiguration with the desired PFD
+ // This gc will probably not be able to support GDI (WGL_SUPPORT_GDI_ARB, PFD_SUPPORT_GDI)
+ // however on most GPUs this is the current situation for Windows,
+ // otherwise no hardware accelerated PFD could be achieved.
+ // - preselect with no constrains
+ // - try to create dedicated GC
+ winConfig.preselectGraphicsConfiguration(drawableFactory, null);
+ if ( 1 <= winConfig.getPixelFormatID() ) {
+ chosenGC = Win32SunJDKReflection.graphicsConfigurationGet(device, winConfig.getPixelFormatID());
+ if(DEBUG) {
+ System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: Found new AWT PFD ID "+winConfig.getPixelFormatID()+" -> "+winConfig);
+ }
+ }
+
+ if( null == chosenGC ) {
+ // 2nd Choice: Choose and match the GL Visual with AWT:
+ // - collect all AWT PFDs
+ // - choose a GL config from the pool of AWT PFDs
+ //
+ // The resulting GraphicsConfiguration has to be 'forced' on the AWT native peer,
+ // ie. returned by GLCanvas's getGraphicsConfiguration() befor call by super.addNotify().
+ //
+
+ // collect all available PFD IDs
+ GraphicsConfiguration[] configs = device.getConfigurations();
+ int[] pfdIDs = new int[configs.length];
+ ArrayHashSet pfdIDOSet = new ArrayHashSet();
+ for (int i = 0; i < configs.length; i++) {
+ GraphicsConfiguration gc = configs[i];
+ pfdIDs[i] = Win32SunJDKReflection.graphicsConfigurationGetPixelFormatID(gc);
+ pfdIDOSet.add(new Integer(pfdIDs[i]));
+ if(DEBUG) {
+ System.err.println("AWT pfd["+i+"] "+pfdIDs[i]);
+ }
+ }
+ if(DEBUG) {
+ System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: PFD IDs: "+pfdIDs.length+", unique: "+pfdIDOSet.size());
+ }
+ winConfig.preselectGraphicsConfiguration(drawableFactory, pfdIDs);
+ int gcIdx = pfdIDOSet.indexOf(new Integer(winConfig.getPixelFormatID()));
+ if( 0 > gcIdx ) {
+ chosenGC = configs[gcIdx];
+ if(DEBUG) {
+ System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: Found matching AWT PFD ID "+winConfig.getPixelFormatID()+" -> "+winConfig);
+ }
+ }
}
- // We have nothing to match .. so choose the default
+ if ( null == chosenGC ) {
+ throw new GLException("Unable to determine GraphicsConfiguration: "+winConfig);
+ }
return new AWTGraphicsConfiguration(awtScreen, winConfig.getChosenCapabilities(), winConfig.getRequestedCapabilities(),
- gc, winConfig);
+ chosenGC, winConfig);
}
}
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
index 72698d759..1f2bf9344 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11DummyGLXDrawable.java
@@ -35,7 +35,7 @@ import com.jogamp.nativewindow.impl.*;
import com.jogamp.nativewindow.impl.x11.*;
public class X11DummyGLXDrawable extends X11OnscreenGLXDrawable {
- private static final int f_dim = 128;
+ private static final int f_dim = 64;
private long dummyWindow = 0;
/**
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLCapabilities.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLCapabilities.java
new file mode 100644
index 000000000..e3a1e7d72
--- /dev/null
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLCapabilities.java
@@ -0,0 +1,116 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.opengl.impl.x11.glx;
+
+import com.jogamp.nativewindow.impl.x11.XVisualInfo;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
+import java.util.Comparator;
+
+public class X11GLCapabilities extends GLCapabilities {
+ XVisualInfo xVisualInfo;
+ long fbcfg;
+ int fbcfgid;
+
+ /** Comparing xvisual id only */
+ public static class XVisualIDComparator implements Comparator {
+
+ public int compare(Object o1, Object o2) {
+ if ( ! ( o1 instanceof X11GLCapabilities ) ) {
+ Class c = (null != o1) ? o1.getClass() : null ;
+ throw new ClassCastException("arg1 not a X11GLCapabilities object: " + c);
+ }
+ if ( ! ( o2 instanceof X11GLCapabilities ) ) {
+ Class c = (null != o2) ? o2.getClass() : null ;
+ throw new ClassCastException("arg2 not a X11GLCapabilities object: " + c);
+ }
+
+ final X11GLCapabilities caps1 = (X11GLCapabilities) o1;
+ final long id1 = caps1.getXVisualID();
+
+ final X11GLCapabilities caps2 = (X11GLCapabilities) o2;
+ final long id2 = caps2.getXVisualID();
+
+ if(id1 > id2) {
+ return 1;
+ } else if(id1 < id2) {
+ return -1;
+ }
+ return 0;
+ }
+ }
+
+ public X11GLCapabilities(XVisualInfo xVisualInfo, long fbcfg, int fbcfgid, GLProfile glp) {
+ super(glp);
+ this.xVisualInfo = xVisualInfo;
+ this.fbcfg = fbcfg;
+ this.fbcfgid = fbcfgid;
+ }
+
+ public X11GLCapabilities(XVisualInfo xVisualInfo, GLProfile glp) {
+ super(glp);
+ this.xVisualInfo = xVisualInfo;
+ this.fbcfg = 0;
+ this.fbcfgid = -1;
+ }
+
+ public Object cloneMutable() {
+ return clone();
+ }
+
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (RuntimeException e) {
+ throw new GLException(e);
+ }
+ }
+
+ final public XVisualInfo getXVisualInfo() { return xVisualInfo; }
+ final public long getXVisualID() { return xVisualInfo.getVisualid(); }
+
+ final public long getFBConfig() { return fbcfg; }
+ final public int getFBConfigID() { return fbcfgid; }
+ final public boolean isFBConfig() { return 0!=fbcfg && fbcfgid>0; }
+
+ public StringBuffer toString(StringBuffer sink) {
+ if(null == sink) {
+ sink = new StringBuffer();
+ }
+ sink.append("0x").append(Long.toHexString(xVisualInfo.getVisualid())).append(" ");
+ if(isFBConfig()) {
+ sink.append("0x").append(Integer.toHexString(fbcfgid));
+ } else {
+ sink.append("----");
+ }
+ sink.append(": ");
+ return super.toString(sink);
+ }
+} \ No newline at end of file
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
index fddfb4cd1..dd25f241e 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXContext.java
@@ -40,11 +40,14 @@
package com.jogamp.opengl.impl.x11.glx;
-import com.jogamp.common.util.VersionNumber;
import java.nio.*;
import java.util.*;
+
import javax.media.opengl.*;
import javax.media.nativewindow.*;
+import javax.media.nativewindow.x11.X11GraphicsDevice;
+
+import com.jogamp.common.util.VersionNumber;
import com.jogamp.opengl.impl.*;
import com.jogamp.gluegen.runtime.ProcAddressTable;
import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
@@ -119,21 +122,23 @@ public abstract class X11GLXContext extends GLContextImpl {
protected Map/*<String, String>*/ getExtensionNameMap() { return extensionNameMap; }
- public final boolean isGLReadDrawableAvailable() {
+ public final boolean isGLXVersionGreaterEqualOneThree() {
if(null == glXVersion) {
X11GLXDrawableFactory factory = (X11GLXDrawableFactory)drawable.getFactoryImpl();
X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
- AbstractGraphicsDevice device = config.getScreen().getDevice();
+ X11GraphicsDevice device = (X11GraphicsDevice) config.getScreen().getDevice();
glXVersion = factory.getGLXVersion(device);
- if( null != glXVersion ) {
- glXVersionOneThreeCapable = glXVersion.compareTo(factory.versionOneThree)>=0;
- }
+ glXVersionOneThreeCapable = ( null != glXVersion ) ? glXVersion.compareTo(X11GLXDrawableFactory.versionOneThree) >= 0 : false ;
}
return glXVersionOneThreeCapable;
}
+ public final boolean isGLReadDrawableAvailable() {
+ return isGLXVersionGreaterEqualOneThree();
+ }
+
private final boolean glXMakeContextCurrent(long dpy, long writeDrawable, long readDrawable, long ctx) {
boolean res = false;
@@ -173,18 +178,13 @@ public abstract class X11GLXContext extends GLContextImpl {
}
protected long createContextARBImpl(long share, boolean direct, int ctp, int major, int minor) {
- X11GLXDrawableFactory factory = (X11GLXDrawableFactory)drawable.getFactoryImpl();
-
- X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
- AbstractGraphicsDevice device = config.getScreen().getDevice();
- X11GLXContext sharedContext = (X11GLXContext) factory.getOrCreateSharedContextImpl(device);
- long display = device.getHandle();
-
- GLXExt glXExt;
- if(null==sharedContext) {
- glXExt = getGLXExt();
- } else {
- glXExt = sharedContext.getGLXExt();
+ updateGLXProcAddressTable();
+ GLXExt _glXExt = getGLXExt();
+ if(DEBUG) {
+ System.err.println("X11GLXContext.createContextARBImpl: "+getGLVersion(major, minor, ctp, "@creation") +
+ ", handle "+toHexString(drawable.getHandle()) + ", share "+toHexString(share)+", direct "+direct+
+ ", glXCreateContextAttribsARB: "+toHexString(glXExtProcAddressTable._addressof_glXCreateContextAttribsARB));
+ Thread.dumpStack();
}
boolean ctBwdCompat = 0 != ( CTX_PROFILE_COMPAT & ctp ) ;
@@ -224,11 +224,15 @@ public abstract class X11GLXContext extends GLContextImpl {
}
}
+ X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ AbstractGraphicsDevice device = config.getScreen().getDevice();
+ long display = device.getHandle();
+
try {
// critical path, a remote display might not support this command,
// hence we need to catch the X11 Error within this block.
X11Util.XSync(display, false);
- ctx = glXExt.glXCreateContextAttribsARB(display, config.getFBConfig(), share, direct, attribs, 0);
+ ctx = _glXExt.glXCreateContextAttribsARB(display, config.getFBConfig(), share, direct, attribs, 0);
X11Util.XSync(display, false);
} catch (RuntimeException re) {
if(DEBUG) {
@@ -247,7 +251,7 @@ public abstract class X11GLXContext extends GLContextImpl {
ctx = 0;
} else {
if (DEBUG) {
- System.err.println(getThreadName() + ": createContextARBImpl: OK "+getGLVersion(major, minor, ctp, "@creation")+", share "+share+", direct "+direct+", hasSharedContext "+(null!=sharedContext));
+ System.err.println(getThreadName() + ": createContextARBImpl: OK "+getGLVersion(major, minor, ctp, "@creation")+", share "+share+", direct "+direct);
}
// the following is issued by the caller 'GLContextImpl.createContextARB()'
// setGLFunctionAvailability(true, major, minor, ctp);
@@ -458,21 +462,24 @@ public abstract class X11GLXContext extends GLContextImpl {
// Should check for X errors and raise GLException
}
- protected final void updateGLXProcAddressTable(int major, int minor, int ctp) {
+ protected final void updateGLXProcAddressTable() {
+ AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
+ String key = adevice.getUniqueID();
if (DEBUG) {
- System.err.println(getThreadName() + ": !!! Initializing GLX extension address table");
+ System.err.println(getThreadName() + ": !!! Initializing GLX extension address table: "+key);
}
glXQueryExtensionsStringInitialized = false;
glXQueryExtensionsStringAvailable = false;
GLXExtProcAddressTable table = null;
synchronized(mappedContextTypeObjectLock) {
- table = (GLXExtProcAddressTable) mappedGLXProcAddress.get( contextFQN );
+ table = (GLXExtProcAddressTable) mappedGLXProcAddress.get( key );
}
if(null != table) {
glXExtProcAddressTable = table;
if(DEBUG) {
- System.err.println(getThreadName() + ": !!! GLContext GLX ProcAddressTable reusing key("+contextFQN+") -> "+table.hashCode());
+ System.err.println(getThreadName() + ": !!! GLContext GLX ProcAddressTable reusing key("+key+") -> "+table.hashCode());
}
} else {
if (glXExtProcAddressTable == null) {
@@ -480,9 +487,10 @@ public abstract class X11GLXContext extends GLContextImpl {
}
resetProcAddressTable(getGLXExtProcAddressTable());
synchronized(mappedContextTypeObjectLock) {
- mappedGLXProcAddress.put(contextFQN, getGLXExtProcAddressTable());
+ mappedGLXProcAddress.put(key, getGLXExtProcAddressTable());
if(DEBUG) {
- System.err.println(getThreadName() + ": !!! GLContext GLX ProcAddressTable mapping key("+contextFQN+") -> "+getGLXExtProcAddressTable().hashCode());
+ System.err.println(getThreadName() + ": !!! GLContext GLX ProcAddressTable mapping key("+key+") -> "+getGLXExtProcAddressTable().hashCode());
+ Thread.dumpStack();
}
}
}
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
index 3abbcee57..709e2ddab 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java
@@ -37,7 +37,11 @@
package com.jogamp.opengl.impl.x11.glx;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
import java.nio.*;
+
import javax.media.nativewindow.*;
import javax.media.nativewindow.x11.*;
import javax.media.opengl.*;
@@ -47,10 +51,6 @@ import com.jogamp.common.JogampRuntimeException;
import com.jogamp.common.util.*;
import com.jogamp.nativewindow.impl.ProxySurface;
import com.jogamp.nativewindow.impl.x11.*;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
@@ -72,6 +72,13 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
}
}
+ public static VersionNumber getGLXVersion(X11GraphicsDevice device) {
+ int[] major = new int[1];
+ int[] minor = new int[1];
+ GLXUtil.getGLXVersion(device.getHandle(), major, minor);
+ return new VersionNumber(major[0], minor[0], 0);
+ }
+
public GLDynamicLookupHelper getGLDynamicLookupHelper(int profile) {
return x11GLXDynamicLookupHelper;
}
@@ -90,204 +97,22 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
defaultDevice = new X11GraphicsDevice(X11Util.getNullDisplayName(), AbstractGraphicsDevice.DEFAULT_UNIT);
- // Init shared resources via own thread
+ // Init shared resources off thread
// Will be released via ShutdownHook
- sharedResourcesRunner = new SharedResourcesRunner();
- sharedResourcesThread = new Thread(sharedResourcesRunner, Thread.currentThread().getName()+"-SharedResourcesRunner");
- sharedResourcesThread.setDaemon(true); // Allow JVM to exit, even if this one is running
- sharedResourcesThread.start();
+ sharedResourceImpl = new SharedResourceImplementation();
+ sharedResourceRunner = new SharedResourceRunner(sharedResourceImpl);
+ sharedResourceThread = new Thread(sharedResourceRunner, Thread.currentThread().getName()+"-SharedResourceRunner");
+ sharedResourceThread.setDaemon(true); // Allow JVM to exit, even if this one is running
+ sharedResourceThread.start();
}
- class SharedResourcesRunner implements Runnable {
- boolean ready = false;
- boolean released = false;
- boolean shouldRelease = false;
- String initConnection = null;
- SharedResource result = null;
-
- public final void initializeAndWait(String connection) {
- // wait until thread becomes ready to init new device,
- // pass the device and release the sync
- String threadName = Thread.currentThread().getName();
- if (DEBUG) {
- System.err.println(threadName+ " initializeAndWait START: "+connection);
- }
- synchronized (this) {
- while (!ready) {
- try {
- this.wait();
- } catch (InterruptedException ex) { }
- }
- if (DEBUG) {
- System.err.println(threadName+ " initializeAndWait set command: "+connection);
- }
- initConnection = connection;
- this.notifyAll();
-
- // wait until thread has initialized the device
- while (!ready || null != initConnection) {
- try {
- this.wait();
- } catch (InterruptedException ex) { }
- }
- if (DEBUG) {
- System.err.println(threadName+ " initializeAndWait done: "+connection);
- }
- }
- // done
- }
-
- public final void releaseAndWait() {
- synchronized (this) {
- shouldRelease = true;
- this.notifyAll();
-
- while (!released) {
- try {
- this.wait();
- } catch (InterruptedException ex) {
- }
- }
- }
- }
-
- public final void run() {
- String threadName = Thread.currentThread().getName();
-
- synchronized (this) {
- if (DEBUG) {
- System.err.println(threadName+ " STARTED -> ready");
- }
-
- while (!shouldRelease) {
- try {
- // wait for stop or init
- ready = true;
- this.wait();
- } catch (InterruptedException ex) { }
- ready = false;
-
- if(!shouldRelease && null!=initConnection) {
- if (DEBUG) {
- System.err.println(threadName+ " create Shared for: "+initConnection);
- }
- SharedResource sr = createSharedResource(initConnection);
- if(null!=sr) {
- synchronized(sharedMap) {
- sharedMap.put(initConnection, sr);
- }
- }
- if (DEBUG) {
- String msg = "Info: (" + threadName + ") initializedSharedResource for device connection: "+initConnection+" -> ready";
- System.err.println(msg);
- Throwable t = new Throwable(msg);
- t.printStackTrace();
- }
- }
- initConnection = null;
- notifyAll();
- }
-
- if (DEBUG) {
- System.err.println(threadName+ " release START");
- }
-
- releaseSharedResources();
-
- if (DEBUG) {
- System.err.println(threadName+ " release END");
- }
-
- released = true;
- ready = false;
- notifyAll();
- }
- }
-
- private final SharedResource createSharedResource(String connection) {
- X11GraphicsDevice sharedDevice = new X11GraphicsDevice(X11Util.createDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT);
- sharedDevice.setCloseDisplay(true);
- sharedDevice.lock();
- try {
- String glXVendorName = GLXUtil.getVendorName(sharedDevice.getHandle());
- X11GraphicsScreen sharedScreen = new X11GraphicsScreen(sharedDevice, 0);
- X11DummyGLXDrawable sharedDrawable = X11DummyGLXDrawable.create(sharedScreen, X11GLXDrawableFactory.this,
- GLProfile.getDefault(sharedDevice));
- if (null == sharedScreen || null == sharedDrawable) {
- throw new GLException("Couldn't init shared screen(" + sharedScreen + ")/drawable(" + sharedDrawable + ")");
- }
- X11GLXContext sharedContext;
- VersionNumber glXVersion;
- try {
- X11GLXContext ctx = (X11GLXContext) sharedDrawable.createContext(null);
- ctx.makeCurrent();
- {
- int[] major = new int[1];
- int[] minor = new int[1];
- GLXUtil.getGLXVersion(sharedDevice.getHandle(), major, minor);
- glXVersion = new VersionNumber(major[0], minor[0], 0);
- }
- ctx.release();
- sharedContext = ctx;
- } catch (Throwable t) {
- throw new GLException("X11GLXDrawableFactory - Could not initialize shared resources", t);
- }
- if (null == sharedContext) {
- throw new GLException("X11GLXDrawableFactory - Shared Context is null");
- }
- if (DEBUG) {
- System.err.println("!!! SharedDevice: "+sharedDevice);
- System.err.println("!!! SharedScreen: "+sharedScreen);
- System.err.println("!!! SharedContext: "+sharedContext);
- System.err.println("!!! GLX Vendor: "+glXVendorName);
- System.err.println("!!! GLX Version: "+glXVersion +
- " >= 1.3: " + ( glXVersion.compareTo(versionOneThree) >= 0 ) );
- }
- return new SharedResource(sharedDevice, sharedScreen, sharedDrawable, sharedContext, glXVersion, glXVendorName);
- } finally {
- sharedDevice.unlock();
- }
- }
-
- private final void releaseSharedResources() {
- Collection/*<SharedResource>*/ sharedResources = sharedMap.values();
- for(Iterator iter=sharedResources.iterator(); iter.hasNext(); ) {
- SharedResource sr = (SharedResource) iter.next();
-
- if (DEBUG) {
- System.err.println("!!! Shutdown Shared:");
- System.err.println("!!! Device : "+sr.device);
- System.err.println("!!! Screen : "+sr.screen);
- System.err.println("!!! Drawable: "+sr.drawable);
- System.err.println("!!! CTX : "+sr.context);
- }
-
- if (null != sr.context) {
- // may cause JVM SIGSEGV: sharedContext.destroy();
- sr.context = null;
- }
-
- if (null != sr.drawable) {
- // may cause JVM SIGSEGV: sharedDrawable.destroy();
- sr.drawable = null;
- }
-
- if (null != sr.screen) {
- sr.screen = null;
- }
-
- if (null != sr.device) {
- sr.device.close();
- sr.device=null;
- }
- }
- sharedMap.clear();
- }
- }
- Thread sharedResourcesThread = null;
- SharedResourcesRunner sharedResourcesRunner=null;
+ X11GraphicsDevice defaultDevice;
+ SharedResourceImplementation sharedResourceImpl;
+ SharedResourceRunner sharedResourceRunner;
+ Thread sharedResourceThread;
+ HashMap/*<connection, SharedResource>*/ sharedMap = new HashMap();
- static class SharedResource {
+ static class SharedResource implements SharedResourceRunner.Resource {
X11GraphicsDevice device;
X11GraphicsScreen screen;
X11DummyGLXDrawable drawable;
@@ -297,7 +122,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
boolean isGLXVendorNVIDIA;
VersionNumber glXVersion;
- SharedResource(X11GraphicsDevice dev, X11GraphicsScreen scrn,
+ SharedResource(X11GraphicsDevice dev, X11GraphicsScreen scrn,
X11DummyGLXDrawable draw, X11GLXContext ctx,
VersionNumber glXVer, String glXVendor) {
device = dev;
@@ -309,16 +134,119 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
isGLXVendorATI = GLXUtil.isVendorATI(glXVendorName);
isGLXVendorNVIDIA = GLXUtil.isVendorNVIDIA(glXVendorName);
}
- X11GraphicsDevice getDevice() { return device; }
- X11GraphicsScreen getScreen() { return screen; }
- X11GLXContext getContext() { return context; }
- String getGLXVendorName() { return glXVendorName; }
- boolean isGLXVendorATI() { return isGLXVendorATI; }
- boolean isGLXVendorNVIDIA() { return isGLXVendorNVIDIA; }
- VersionNumber getGLXVersion() { return glXVersion; }
+ final public AbstractGraphicsDevice getDevice() { return device; }
+ final public AbstractGraphicsScreen getScreen() { return screen; }
+ final public GLDrawableImpl getDrawable() { return drawable; }
+ final public GLContextImpl getContext() { return context; }
+
+ final String getGLXVendorName() { return glXVendorName; }
+ final boolean isGLXVendorATI() { return isGLXVendorATI; }
+ final boolean isGLXVendorNVIDIA() { return isGLXVendorNVIDIA; }
+ final VersionNumber getGLXVersion() { return glXVersion; }
+ final boolean isGLXVersionGreaterEqualOneThree() {
+ return ( null != glXVersion ) ? glXVersion.compareTo(versionOneThree) >= 0 : false ;
+ }
+ }
+
+ class SharedResourceImplementation implements SharedResourceRunner.Implementation {
+ public void clear() {
+ synchronized(sharedMap) {
+ sharedMap.clear();
+ }
+ }
+ public SharedResourceRunner.Resource mapPut(String connection, SharedResourceRunner.Resource resource) {
+ synchronized(sharedMap) {
+ return (SharedResourceRunner.Resource) sharedMap.put(connection, resource);
+ }
+ }
+ public SharedResourceRunner.Resource mapGet(String connection) {
+ synchronized(sharedMap) {
+ return (SharedResourceRunner.Resource) sharedMap.get(connection);
+ }
+ }
+ public Collection/*<Resource>*/ mapValues() {
+ synchronized(sharedMap) {
+ return sharedMap.values();
+ }
+ }
+
+ public SharedResourceRunner.Resource createSharedResource(String connection) {
+ X11GraphicsDevice sharedDevice = new X11GraphicsDevice(X11Util.createDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT);
+ sharedDevice.setCloseDisplay(true);
+ sharedDevice.lock();
+ try {
+ String glXVendorName = GLXUtil.getVendorName(sharedDevice.getHandle());
+ X11GraphicsScreen sharedScreen = new X11GraphicsScreen(sharedDevice, 0);
+ if (null == sharedScreen) {
+ throw new GLException("Couldn't create shared screen for device: "+sharedDevice+", idx 0");
+ }
+ GLProfile glp = GLProfile.getMinDesktop(sharedDevice);
+ if (null == glp) {
+ throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice);
+ }
+ X11DummyGLXDrawable sharedDrawable = X11DummyGLXDrawable.create(sharedScreen, X11GLXDrawableFactory.this, glp);
+ if (null == sharedDrawable) {
+ throw new GLException("Couldn't create shared drawable for screen: "+sharedScreen+", "+glp);
+ }
+ X11GLXContext sharedContext = (X11GLXContext) sharedDrawable.createContext(null);
+ if (null == sharedContext) {
+ throw new GLException("Couldn't create shared context for drawable: "+sharedDrawable);
+ }
+ sharedContext.setSynchronized(true);
+ VersionNumber glXVersion = getGLXVersion(sharedDevice);
+ boolean madeCurrent = false;
+ sharedContext.makeCurrent();
+ try {
+ madeCurrent = sharedContext.isCurrent();
+ } finally {
+ sharedContext.release();
+ }
+ if (DEBUG) {
+ System.err.println("!!! SharedDevice: " + sharedDevice);
+ System.err.println("!!! SharedScreen: " + sharedScreen);
+ System.err.println("!!! SharedContext: " + sharedContext + ", madeCurrent " + madeCurrent);
+ System.err.println("!!! GLX Vendor: " + glXVendorName);
+ System.err.println("!!! GLX Version: " + glXVersion
+ + " >= 1.3: " + (glXVersion.compareTo(versionOneThree) >= 0));
+ }
+ return new SharedResource(sharedDevice, sharedScreen, sharedDrawable, sharedContext, glXVersion, glXVendorName);
+ } catch (Throwable t) {
+ throw new GLException("WindowsWGLDrawableFactory - Could not initialize shared resources for "+connection, t);
+ } finally {
+ sharedDevice.unlock();
+ }
+ }
+
+ public void releaseSharedResource(SharedResourceRunner.Resource shared) {
+ SharedResource sr = (SharedResource) shared;
+ if (DEBUG) {
+ System.err.println("!!! Shutdown Shared:");
+ System.err.println("!!! Device : " + sr.device);
+ System.err.println("!!! Screen : " + sr.screen);
+ System.err.println("!!! Drawable: " + sr.drawable);
+ System.err.println("!!! CTX : " + sr.context);
+ }
+
+ if (null != sr.context) {
+ // may cause JVM SIGSEGV: sharedContext.destroy();
+ sr.context = null;
+ }
+
+ if (null != sr.drawable) {
+ // may cause JVM SIGSEGV: sharedDrawable.destroy();
+ sr.drawable = null;
+ }
+
+ if (null != sr.screen) {
+ sr.screen = null;
+ }
+
+ if (null != sr.device) {
+ sr.device.close();
+ sr.device = null;
+ }
+ }
}
- HashMap/*<connection, SharedResource>*/ sharedMap = new HashMap();
- X11GraphicsDevice defaultDevice;
public final AbstractGraphicsDevice getDefaultDevice() {
return defaultDevice;
@@ -331,44 +259,8 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
return false;
}
- HashSet devicesTried = new HashSet();
- private final boolean getDeviceTried(String connection) {
- synchronized(devicesTried) {
- return devicesTried.contains(connection);
- }
- }
- private final void addDeviceTried(String connection) {
- synchronized(devicesTried) {
- devicesTried.add(connection);
- }
- }
-
- private SharedResource getOrCreateShared(AbstractGraphicsDevice device) {
- String connection = device.getConnection();
- SharedResource sr;
- synchronized(sharedMap) {
- sr = (SharedResource) sharedMap.get(connection);
- }
-
- if(null==sr && !getDeviceTried(connection)) {
- addDeviceTried(connection);
- if (DEBUG) {
- System.err.println("getOrCreateShared() "+connection+": trying");
- }
- sharedResourcesRunner.initializeAndWait(connection);
- synchronized(sharedMap) {
- sr = (SharedResource) sharedMap.get(connection);
- }
- if(DEBUG) {
- Throwable t = new Throwable("getOrCreateSharedl() "+connection+": done");
- t.printStackTrace();
- }
- }
- return sr;
- }
-
protected final GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device) {
- SharedResource sr = getOrCreateShared(device);
+ SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device);
if(null!=sr) {
return sr.getContext();
}
@@ -376,7 +268,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
}
protected AbstractGraphicsDevice getOrCreateSharedDeviceImpl(AbstractGraphicsDevice device) {
- SharedResource sr = getOrCreateShared(device);
+ SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device);
if(null!=sr) {
return sr.getDevice();
}
@@ -384,53 +276,53 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
}
protected final long getOrCreateSharedDpy(AbstractGraphicsDevice device) {
- SharedResource sr = getOrCreateShared(device);
+ SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device);
if(null!=sr) {
return sr.getDevice().getHandle();
}
return 0;
}
- protected final VersionNumber getGLXVersion(AbstractGraphicsDevice device) {
- SharedResource sr = getOrCreateShared(device);
- if(null!=sr) {
- return sr.getGLXVersion();
- }
- return null;
+ SharedResource getOrCreateSharedResource(AbstractGraphicsDevice device) {
+ return (SharedResource) sharedResourceRunner.getOrCreateShared(device);
}
- protected final String getGLXVendorName(AbstractGraphicsDevice device) {
- SharedResource sr = getOrCreateShared(device);
+ public final String getGLXVendorName(AbstractGraphicsDevice device) {
+ SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device);
if(null!=sr) {
- return sr.getGLXVendorName();
+ return ((SharedResource)sr).getGLXVendorName();
}
return GLXUtil.getVendorName(device.getHandle());
}
- protected final boolean isGLXVendorATI(AbstractGraphicsDevice device) {
- SharedResource sr = getOrCreateShared(device);
+ public final boolean isGLXVendorATI(AbstractGraphicsDevice device) {
+ SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device);
if(null!=sr) {
- return sr.isGLXVendorATI();
+ return ((SharedResource)sr).isGLXVendorATI();
}
return GLXUtil.isVendorATI(device.getHandle());
}
- protected final boolean isGLXVendorNVIDIA(AbstractGraphicsDevice device) {
- SharedResource sr = getOrCreateShared(device);
+ public final boolean isGLXVendorNVIDIA(AbstractGraphicsDevice device) {
+ SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device);
if(null!=sr) {
- return sr.isGLXVendorNVIDIA();
+ return ((SharedResource)sr).isGLXVendorNVIDIA();
}
return GLXUtil.isVendorNVIDIA(device.getHandle());
}
protected final void shutdownInstance() {
- sharedResourcesRunner.releaseAndWait();
+ sharedResourceRunner.releaseAndWait();
// Don't really close pending Display connections,
// since this may trigger a JVM exception
X11Util.shutdown( false, DEBUG );
}
+ protected List/*GLCapabilitiesImmutable*/ getAvailableCapabilitiesImpl(AbstractGraphicsDevice device) {
+ return X11GLXGraphicsConfigurationFactory.getAvailableCapabilities(this, device);
+ }
+
protected final GLDrawableImpl createOnscreenDrawableImpl(NativeSurface target) {
if (target == null) {
throw new IllegalArgumentException("Null target");
@@ -458,15 +350,13 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
* The dummy context shall also use the same Display,
* since switching Display in this regard is another ATI bug.
*/
- SharedResource sr = getOrCreateShared(device);
+ SharedResource sr = (SharedResource) sharedResourceRunner.getOrCreateShared(device);
if( null!=sr && sr.isGLXVendorATI() && null == GLContext.getCurrent() ) {
- synchronized(sr.context) {
- sr.context.makeCurrent();
- try {
- pbufferDrawable = new X11PbufferGLXDrawable(this, target);
- } finally {
- sr.context.release();
- }
+ sr.getContext().makeCurrent();
+ try {
+ pbufferDrawable = new X11PbufferGLXDrawable(this, target);
+ } finally {
+ sr.getContext().release();
}
} else {
pbufferDrawable = new X11PbufferGLXDrawable(this, target);
@@ -474,19 +364,26 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
return pbufferDrawable;
}
- public final boolean glXVersionGreaterEqualOneThree(AbstractGraphicsDevice device) {
- VersionNumber glXVersion = getGLXVersion(device);
- return ( null != glXVersion ) ? glXVersion.compareTo(versionOneThree) >= 0 : false ;
+ public final boolean isGLXVersionGreaterEqualOneThree(AbstractGraphicsDevice device) {
+ SharedResource sr = (SharedResource) sharedResourceRunner.getOrCreateShared(device);
+ if(null!=sr) {
+ return sr.isGLXVersionGreaterEqualOneThree();
+ }
+ if( device instanceof X11GraphicsDevice ) {
+ VersionNumber v = getGLXVersion( (X11GraphicsDevice) device);
+ return ( null != v ) ? v.compareTo(versionOneThree) >= 0 : false ;
+ }
+ return false;
}
public final boolean canCreateGLPbuffer(AbstractGraphicsDevice device) {
if(null == device) {
- SharedResource sr = getOrCreateShared(defaultDevice);
+ SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(defaultDevice);
if(null!=sr) {
device = sr.getDevice();
}
}
- return glXVersionGreaterEqualOneThree(device);
+ return isGLXVersionGreaterEqualOneThree(device);
}
protected final NativeSurface createOffscreenSurfaceImpl(AbstractGraphicsDevice device,
@@ -494,9 +391,9 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
GLCapabilitiesChooser chooser,
int width, int height) {
X11GraphicsScreen screen = null;
- SharedResource sr = getOrCreateShared(device);
+ SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device);
if(null!=sr) {
- screen = sr.getScreen();
+ screen = (X11GraphicsScreen) sr.getScreen();
}
if(null==screen) {
return null;
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
index 3dbaab21b..f7779ab28 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java
@@ -33,10 +33,13 @@
package com.jogamp.opengl.impl.x11.glx;
-import com.jogamp.common.nio.PointerBuffer;
+import java.util.ArrayList;
+
import javax.media.nativewindow.*;
import javax.media.nativewindow.x11.*;
import javax.media.opengl.*;
+
+import com.jogamp.common.nio.PointerBuffer;
import com.jogamp.opengl.impl.*;
import com.jogamp.nativewindow.impl.x11.*;
@@ -44,17 +47,12 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration");
public static final int MAX_ATTRIBS = 128;
- private long fbConfig;
- private int fbConfigID;
private GLCapabilitiesChooser chooser;
X11GLXGraphicsConfiguration(X11GraphicsScreen screen,
- GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser,
- XVisualInfo info, long fbcfg, int fbcfgID) {
- super(screen, capsChosen, capsRequested, info);
+ X11GLCapabilities capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser) {
+ super(screen, capsChosen, capsRequested, capsChosen.getXVisualInfo());
this.chooser=chooser;
- fbConfig = fbcfg;
- fbConfigID = fbcfgID;
}
static X11GLXGraphicsConfiguration create(GLProfile glp, X11GraphicsScreen x11Screen, int fbcfgID) {
@@ -70,23 +68,23 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
if(null==glp) {
glp = GLProfile.getDefault(x11Screen.getDevice());
}
- GLCapabilitiesImmutable caps = GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, GLXUtil.isMultisampleAvailable(display));
+ X11GLCapabilities 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.glXGetVisualFromFBConfig(display, fbcfg);
- if(null==xvi) {
- throw new GLException("XVisualInfo null of "+toHexString(fbcfg));
- }
- return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser(), xvi, fbcfg, fbcfgID);
+ return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser());
}
public Object clone() {
return super.clone();
}
- public long getFBConfig() { return fbConfig; }
- public int getFBConfigID() { return fbConfigID; }
+ public final long getFBConfig() {
+ return ((X11GLCapabilities)capabilitiesChosen).getFBConfig();
+ }
+ public final int getFBConfigID() {
+ return ((X11GLCapabilities)capabilitiesChosen).getFBConfigID();
+ }
void updateGraphicsConfiguration() {
X11GLXGraphicsConfiguration newConfig = (X11GLXGraphicsConfiguration)
@@ -96,8 +94,6 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
// FIXME: setScreen( ... );
setXVisualInfo(newConfig.getXVisualInfo());
setChosenCapabilities(newConfig.getChosenCapabilities());
- fbConfig = newConfig.getFBConfig();
- fbConfigID = newConfig.getFBConfigID();
if(DEBUG) {
System.err.println("!!! updateGraphicsConfiguration: "+this);
}
@@ -220,49 +216,63 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
return true;
}
- static boolean GLXFBConfigDrawableTypeVerify(int val, boolean onscreen, boolean usePBuffer) {
- boolean res;
+ static int FBCfgDrawableTypeBits(final long display, final long fbcfg) {
+ int val = 0;
- 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) ) ;
- }
- }
+ int[] tmp = new int[1];
+ int fbtype = glXGetFBConfig(display, fbcfg, GLX.GLX_DRAWABLE_TYPE, tmp, 0);
- return res;
+ if ( 0 != ( fbtype & GLX.GLX_WINDOW_BIT ) ) {
+ val |= GLGraphicsConfigurationUtil.WINDOW_BIT;
+ }
+ if ( 0 != ( fbtype & GLX.GLX_PIXMAP_BIT ) ) {
+ val |= GLGraphicsConfigurationUtil.BITMAP_BIT;
+ }
+ if ( 0 != ( fbtype & GLX.GLX_PBUFFER_BIT ) ) {
+ val |= GLGraphicsConfigurationUtil.PBUFFER_BIT;
+ }
+ return val;
}
- static GLCapabilitiesImmutable GLXFBConfig2GLCapabilities(GLProfile glp, long display, long fbcfg,
+ static X11GLCapabilities GLXFBConfig2GLCapabilities(GLProfile glp, long display, long fbcfg,
boolean relaxed, boolean onscreen, boolean usePBuffer,
boolean isMultisampleAvailable) {
- 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;
+ ArrayList bucket = new ArrayList();
+ final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer);
+ if( GLXFBConfig2GLCapabilities(bucket, glp, display, fbcfg, winattrmask, isMultisampleAvailable) ) {
+ return (X11GLCapabilities) bucket.get(0);
+ } else if ( relaxed && GLXFBConfig2GLCapabilities(bucket, glp, display, fbcfg, GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable) ) {
+ return (X11GLCapabilities) bucket.get(0);
}
- 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 {
+ return null;
+ }
+
+ static boolean GLXFBConfig2GLCapabilities(ArrayList capsBucket,
+ GLProfile glp, long display, long fbcfg,
+ int winattrmask, boolean isMultisampleAvailable) {
+ final int allDrawableTypeBits = FBCfgDrawableTypeBits(display, fbcfg);
+ int drawableTypeBits = winattrmask & allDrawableTypeBits;
+
+ int fbcfgid = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfg);
+ XVisualInfo visualInfo = GLX.glXGetVisualFromFBConfig(display, fbcfg);
+ if(null == visualInfo) {
if(DEBUG) {
- System.err.println("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) )+")");
+ System.err.println("X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities: Null XVisualInfo for FBConfigID 0x" + Integer.toHexString(fbcfgid));
}
- return null;
+ // onscreen must have an XVisualInfo
+ drawableTypeBits = drawableTypeBits & ~GLGraphicsConfigurationUtil.WINDOW_BIT;
}
+
+ if( 0 == drawableTypeBits ) {
+ return false;
+ }
+
+ int[] tmp = new int[1];
+ if(GLX.GLX_BAD_ATTRIBUTE == GLX.glXGetFBConfigAttrib(display, fbcfg, GLX.GLX_RENDER_TYPE, tmp, 0)) {
+ return false;
+ }
+
+ GLCapabilities res = new X11GLCapabilities(visualInfo, fbcfg, fbcfgid, glp);
res.setDoubleBuffered(glXGetFBConfig(display, fbcfg, GLX.GLX_DOUBLEBUFFER, tmp, 0) != 0);
res.setStereo (glXGetFBConfig(display, fbcfg, GLX.GLX_STEREO, tmp, 0) != 0);
res.setHardwareAccelerated(glXGetFBConfig(display, fbcfg, GLX.GLX_CONFIG_CAVEAT, tmp, 0) != GLX.GLX_SLOW_CONFIG);
@@ -297,7 +307,8 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
try {
res.setPbufferFloatingPointBuffers(glXGetFBConfig(display, fbcfg, GLXExt.GLX_FLOAT_COMPONENTS_NV, tmp, 0) != GL.GL_FALSE);
} catch (Exception e) {}
- return res;
+
+ return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits );
}
private static String glXGetFBConfigErrorCode(int err) {
@@ -352,26 +363,34 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
return res;
}
- static GLCapabilitiesImmutable XVisualInfo2GLCapabilities(GLProfile glp, long display, XVisualInfo info,
- boolean onscreen, boolean usePBuffer, boolean isMultisampleEnabled) {
+ static boolean XVisualInfo2GLCapabilities(ArrayList capsBucket,
+ GLProfile glp, long display, XVisualInfo info,
+ final int winattrmask, boolean isMultisampleEnabled) {
+ final int allDrawableTypeBits = GLGraphicsConfigurationUtil.WINDOW_BIT | GLGraphicsConfigurationUtil.BITMAP_BIT ;
+ final int drawableTypeBits = winattrmask & allDrawableTypeBits;
+
+ if( 0 == drawableTypeBits ) {
+ return false;
+ }
+
int[] tmp = new int[1];
int val = glXGetConfig(display, info, GLX.GLX_USE_GL, tmp, 0);
if (val == 0) {
if(DEBUG) {
System.err.println("Visual ("+toHexString(info.getVisualid())+") does not support OpenGL");
}
- return null;
+ return false;
}
val = glXGetConfig(display, info, GLX.GLX_RGBA, tmp, 0);
if (val == 0) {
if(DEBUG) {
System.err.println("Visual ("+toHexString(info.getVisualid())+") does not support RGBA");
}
- return null;
+ return false;
}
- GLCapabilities res = new GLCapabilities(glp);
- res.setOnscreen (onscreen);
- res.setPBuffer (usePBuffer);
+
+ GLCapabilities res = new X11GLCapabilities(info, glp);
+
res.setDoubleBuffered(glXGetConfig(display, info, GLX.GLX_DOUBLEBUFFER, tmp, 0) != 0);
res.setStereo (glXGetConfig(display, info, GLX.GLX_STEREO, tmp, 0) != 0);
// Note: use of hardware acceleration is determined by
@@ -393,7 +412,8 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
res.setSampleBuffers(glXGetConfig(display, info, GLX.GLX_SAMPLE_BUFFERS, tmp, 0) != 0);
res.setNumSamples (glXGetConfig(display, info, GLX.GLX_SAMPLES, tmp, 0));
}
- return res;
+
+ return GLGraphicsConfigurationUtil.addGLCapabilitiesPermutations(capsBucket, res, drawableTypeBits);
}
private static String glXGetConfigErrorCode(int err) {
@@ -417,16 +437,8 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
return tmp[tmp_offset];
}
- static String toHexString(int val) {
- return "0x"+Integer.toHexString(val);
- }
-
- static String toHexString(long val) {
- return "0x"+Long.toHexString(val);
- }
-
public String toString() {
- return "X11GLXGraphicsConfiguration["+getScreen()+", visualID " + toHexString(getVisualID()) + ", fbConfigID " + toHexString(fbConfigID) +
+ return "X11GLXGraphicsConfiguration["+getScreen()+", visualID " + toHexString(getVisualID()) + ", fbConfigID " + toHexString(getFBConfigID()) +
",\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
index 327ecd0be..b391dc948 100644
--- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java
@@ -39,12 +39,13 @@ import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.CapabilitiesChooser;
import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.GraphicsConfigurationFactory;
-import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.x11.X11GraphicsScreen;
+import javax.media.nativewindow.x11.X11GraphicsDevice;
import javax.media.opengl.DefaultGLCapabilitiesChooser;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesChooser;
import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
@@ -53,6 +54,12 @@ import com.jogamp.nativewindow.impl.x11.X11Lib;
import com.jogamp.nativewindow.impl.x11.X11Util;
import com.jogamp.nativewindow.impl.x11.XVisualInfo;
import com.jogamp.opengl.impl.Debug;
+import com.jogamp.opengl.impl.GLGraphicsConfigurationFactory;
+import com.jogamp.opengl.impl.GLGraphicsConfigurationUtil;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
/** Subclass of GraphicsConfigurationFactory used when non-AWT toolkits
@@ -60,8 +67,9 @@ import com.jogamp.opengl.impl.Debug;
to this one to change the accepted and returned types of the
GraphicsDevice and GraphicsConfiguration abstractions. */
-public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFactory {
+public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory {
protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration");
+ static X11GLCapabilities.XVisualIDComparator XVisualIDComparator = new X11GLCapabilities.XVisualIDComparator();
X11GLXGraphicsConfigurationFactory() {
GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.x11.X11GraphicsDevice.class, this);
@@ -88,6 +96,86 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
(GLCapabilitiesChooser)chooser, (X11GraphicsScreen)absScreen);
}
+ protected static List/*<X11GLCapabilities>*/ getAvailableCapabilities(X11GLXDrawableFactory factory, AbstractGraphicsDevice device) {
+ X11GLXDrawableFactory.SharedResource sharedResource = factory.getOrCreateSharedResource(device);
+ if(null == sharedResource) {
+ throw new GLException("Shared resource for device n/a: "+device);
+ }
+ X11GraphicsScreen sharedScreen = (X11GraphicsScreen) sharedResource.getScreen();
+ X11GLXDrawable sharedDrawable = (X11GLXDrawable) sharedResource.getDrawable();
+ GLCapabilitiesImmutable capsChosen = sharedDrawable.getChosenGLCapabilities();
+ GLProfile glp = capsChosen.getGLProfile();
+
+ List/*GLCapabilitiesImmutable*/ availableCaps = null;
+
+ if( sharedResource.isGLXVersionGreaterEqualOneThree() ) {
+ availableCaps = getAvailableGLCapabilitiesFBConfig(sharedScreen, glp);
+ }
+ if( null == availableCaps || 0 == availableCaps.size() ) {
+ availableCaps = getAvailableGLCapabilitiesXVisual(sharedScreen, glp);
+ }
+ if( null != availableCaps ) {
+ Collections.sort(availableCaps, XVisualIDComparator);
+ }
+ return availableCaps;
+ }
+
+ static List/*<X11GLCapabilities>*/ getAvailableGLCapabilitiesFBConfig(X11GraphicsScreen x11Screen, GLProfile glProfile) {
+ PointerBuffer fbcfgsL = null;
+
+ // Utilizing FBConfig
+ //
+ AbstractGraphicsDevice absDevice = x11Screen.getDevice();
+ long display = absDevice.getHandle();
+
+ int screen = x11Screen.getIndex();
+ boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display);
+ int[] count = { -1 };
+ ArrayList availableCaps = new ArrayList();
+
+ fbcfgsL = GLX.glXChooseFBConfig(display, screen, null, 0, count, 0);
+ if (fbcfgsL == null || fbcfgsL.limit()<=0) {
+ if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesFBConfig: Failed glXChooseFBConfig ("+x11Screen+"): "+fbcfgsL+", "+count[0]);
+ }
+ return null;
+ }
+ for (int i = 0; i < fbcfgsL.limit(); i++) {
+ if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, display, fbcfgsL.get(i), GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable) ) {
+ if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesFBConfig: FBConfig invalid (2): ("+x11Screen+"): fbcfg: "+toHexString(fbcfgsL.get(i)));
+ }
+ }
+ }
+ return availableCaps;
+ }
+
+ static List/*<X11GLCapabilities>*/ getAvailableGLCapabilitiesXVisual(X11GraphicsScreen x11Screen, GLProfile glProfile) {
+ AbstractGraphicsDevice absDevice = x11Screen.getDevice();
+ long display = absDevice.getHandle();
+
+ int screen = x11Screen.getIndex();
+ boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display);
+
+ int[] count = new int[1];
+ XVisualInfo template = XVisualInfo.create();
+ template.setScreen(screen);
+ XVisualInfo[] infos = X11Util.XGetVisualInfo(display, X11Lib.VisualScreenMask, template, count, 0);
+ if (infos == null || infos.length<1) {
+ throw new GLException("Error while enumerating available XVisualInfos");
+ }
+ ArrayList availableCaps = new ArrayList();
+ for (int i = 0; i < infos.length; i++) {
+ if( !X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(availableCaps, glProfile, display, infos[i], GLGraphicsConfigurationUtil.ALL_BITS, isMultisampleAvailable) ) {
+ if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesXVisual: XVisual invalid: ("+x11Screen+"): fbcfg: "+toHexString(infos[i].getVisualid()));
+ }
+ }
+ }
+ return availableCaps;
+ }
+
+
static X11GLXGraphicsConfiguration chooseGraphicsConfigurationStatic(GLCapabilitiesImmutable capsChosen,
GLCapabilitiesImmutable capsReq,
GLCapabilitiesChooser chooser,
@@ -99,18 +187,16 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
if (capsChosen == null) {
capsChosen = new GLCapabilities(null);
}
+ X11GraphicsDevice x11Device = (X11GraphicsDevice) x11Screen.getDevice();
+ X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();
- if(!capsChosen.isOnscreen() && capsChosen.getDoubleBuffered()) {
- // OFFSCREEN !DOUBLE_BUFFER // FIXME DBLBUFOFFSCRN
- GLCapabilities caps2 = (GLCapabilities) capsChosen.cloneMutable();
- caps2.setDoubleBuffered(false);
- capsChosen = caps2;
- }
-
+ capsChosen = GLGraphicsConfigurationUtil.fixGLCapabilities( capsChosen, factory.canCreateGLPbuffer(x11Device) );
boolean usePBuffer = capsChosen.isPBuffer();
- X11GLXGraphicsConfiguration res;
- res = chooseGraphicsConfigurationFBConfig(capsChosen, capsReq, chooser, x11Screen);
+ X11GLXGraphicsConfiguration res = null;
+ if( factory.isGLXVersionGreaterEqualOneThree(x11Device) ) {
+ res = chooseGraphicsConfigurationFBConfig(capsChosen, capsReq, chooser, x11Screen);
+ }
if(null==res) {
if(usePBuffer) {
throw new GLException("Error: Couldn't create X11GLXGraphicsConfiguration based on FBConfig for "+capsChosen);
@@ -138,14 +224,8 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
}
return null;
}
- XVisualInfo visualInfo = GLX.glXGetVisualFromFBConfig(display, fbcfg);
- if (visualInfo==null) {
- System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXGetVisualFromFBConfig ("+x11Screen+", "+toHexString(fbcfg)+")");
- return null;
- }
- GLCapabilitiesImmutable caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, GLXUtil.isMultisampleAvailable(display));
- return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser(), visualInfo, fbcfg, fbID);
-
+ X11GLCapabilities caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, GLXUtil.isMultisampleAvailable(display));
+ return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser());
}
private static X11GLXGraphicsConfiguration chooseGraphicsConfigurationFBConfig(GLCapabilitiesImmutable capsChosen,
@@ -154,10 +234,7 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
X11GraphicsScreen x11Screen) {
long recommendedFBConfig = -1;
int recommendedIndex = -1;
- int retFBID=-1;
- GLCapabilitiesImmutable[] availableCaps = null;
PointerBuffer fbcfgsL = null;
- XVisualInfo retXVisualInfo = null;
GLProfile glProfile = capsChosen.getGLProfile();
boolean onscreen = capsChosen.isOnscreen();
boolean usePBuffer = capsChosen.isPBuffer();
@@ -171,39 +248,39 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display);
int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capsChosen, true, isMultisampleAvailable, display, screen);
int[] count = { -1 };
+ ArrayList/*<X11GLCapabilities>*/ availableCaps = new ArrayList();
+ final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(onscreen, usePBuffer);
// 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice
fbcfgsL = GLX.glXChooseFBConfig(display, screen, attribs, 0, count, 0);
if (fbcfgsL != null && fbcfgsL.limit()>0) {
- availableCaps = new GLCapabilitiesImmutable[fbcfgsL.limit()];
for (int i = 0; i < fbcfgsL.limit(); i++) {
- if( !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfgsL.get(i) ) ) {
+ if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, display, fbcfgsL.get(i), winattrmask, isMultisampleAvailable) ) {
if(DEBUG) {
System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (1): ("+x11Screen+","+capsChosen+"): fbcfg: "+toHexString(fbcfgsL.get(i)));
}
- } else {
- availableCaps[i] = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfgsL.get(i),
- false, onscreen, usePBuffer, isMultisampleAvailable);
}
}
- if(availableCaps[0]!=null) {
+ if(availableCaps.size() > 0) {
recommendedFBConfig = fbcfgsL.get(0);
recommendedIndex=0;
if (DEBUG) {
System.err.println("!!! glXChooseFBConfig recommended fbcfg " + toHexString(recommendedFBConfig) + ", idx " + recommendedIndex);
System.err.println("!!! user caps " + capsChosen);
- System.err.println("!!! fbcfg caps " + availableCaps[recommendedIndex]);
- }
- } else {
- if (DEBUG) {
- System.err.println("!!! glXChooseFBConfig no caps for recommended fbcfg " + toHexString(recommendedFBConfig));
- System.err.println("!!! user caps " + capsChosen);
+ System.err.println("!!! fbcfg caps " + availableCaps.get(recommendedIndex));
}
+ } else if (DEBUG) {
+ System.err.println("!!! glXChooseFBConfig no caps for recommended fbcfg " + toHexString(fbcfgsL.get(0)));
+ System.err.println("!!! user caps " + capsChosen);
}
}
// 2nd choice: get all GLCapabilities available, no preferred recommendedIndex available
- if(null == availableCaps) {
+ if( 0 == availableCaps.size() ) {
+ // reset ..
+ recommendedFBConfig = -1;
+ recommendedIndex = -1;
+
fbcfgsL = GLX.glXChooseFBConfig(display, screen, null, 0, count, 0);
if (fbcfgsL == null || fbcfgsL.limit()<=0) {
if(DEBUG) {
@@ -212,78 +289,24 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
return null;
}
- availableCaps = new GLCapabilitiesImmutable[fbcfgsL.limit()];
for (int i = 0; i < fbcfgsL.limit(); i++) {
- if( !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfgsL.get(i) ) ) {
+ if( !X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(availableCaps, glProfile, display, fbcfgsL.get(i), winattrmask, isMultisampleAvailable) ) {
if(DEBUG) {
System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: FBConfig invalid (2): ("+x11Screen+"): fbcfg: "+toHexString(fbcfgsL.get(i)));
}
- } else {
- availableCaps[i] = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfgsL.get(i),
- false, onscreen, usePBuffer, isMultisampleAvailable);
}
}
}
-
- if( recommendedIndex < 1 && null==chooser) {
- chooser = new DefaultGLCapabilitiesChooser();
- }
-
- int chosenIndex = recommendedIndex;
- try {
- if(null != chooser) {
- chosenIndex = chooser.chooseCapabilities(capsChosen, availableCaps, recommendedIndex);
- if(DEBUG) {
- System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig chooser: idx "+chosenIndex);
- System.err.println("!!! user caps " + capsChosen);
- System.err.println("!!! chosen caps " + availableCaps[chosenIndex]);
- }
- }
- } catch (NativeWindowException e) {
- if(DEBUG) {
- e.printStackTrace();
- }
- }
-
- if (chosenIndex < 0) {
- // keep on going ..
- // seek first available one ..
- for(chosenIndex = 0; chosenIndex < availableCaps.length && availableCaps[chosenIndex]==null; chosenIndex++) {
- // nop
- }
- if(chosenIndex==availableCaps.length) {
- // give up ..
- if(DEBUG) {
- System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig Failed .. nothing available, bail out");
- }
- return null;
- }
- if(DEBUG) {
- System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig Failed .. unable to choose config, using first available idx: "+chosenIndex);
- System.err.println("!!! user caps " + capsChosen);
- System.err.println("!!! fallback caps " + availableCaps[chosenIndex]);
- }
- } else if (chosenIndex >= availableCaps.length) {
- if(DEBUG) {
- System.err.println("GLCapabilitiesChooser specified invalid index (expected 0.." + (availableCaps.length - 1) + ", got "+chosenIndex+")");
+ int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex);
+ if ( 0 > chosenIndex ) {
+ if (DEBUG) {
+ Thread.dumpStack();
}
return null;
}
+ X11GLCapabilities chosenCaps = (X11GLCapabilities) availableCaps.get(chosenIndex);
- retFBID = X11GLXGraphicsConfiguration.glXFBConfig2FBConfigID(display, fbcfgsL.get(chosenIndex));
-
- retXVisualInfo = GLX.glXGetVisualFromFBConfig(display, fbcfgsL.get(chosenIndex));
- if (retXVisualInfo==null) {
- if(DEBUG) {
- System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed glXGetVisualFromFBConfig ("+x11Screen+", "+fbcfgsL.get(chosenIndex) +" (Continue: "+(false==availableCaps[chosenIndex].isOnscreen())+"):\n\t"+availableCaps[chosenIndex]);
- }
- if(availableCaps[chosenIndex].isOnscreen()) {
- // Onscreen drawables shall have a XVisual ..
- return null;
- }
- }
-
- return new X11GLXGraphicsConfiguration(x11Screen, availableCaps[chosenIndex], capsReq, chooser, retXVisualInfo, fbcfgsL.get(chosenIndex), retFBID);
+ return new X11GLXGraphicsConfiguration(x11Screen, chosenCaps, capsReq, chooser);
}
private static X11GLXGraphicsConfiguration chooseGraphicsConfigurationXVisual(GLCapabilitiesImmutable capsChosen,
@@ -294,16 +317,10 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
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 = capsChosen.getGLProfile();
- boolean onscreen = capsChosen.isOnscreen();
- GLCapabilitiesImmutable[] caps = null;
+ final int winattrmask = GLGraphicsConfigurationUtil.getWinAttributeBits(capsChosen.isOnscreen(), false /* pbuffer */);
+ ArrayList availableCaps = new ArrayList();
int recommendedIndex = -1;
- XVisualInfo retXVisualInfo = null;
- int chosen=-1;
AbstractGraphicsDevice absDevice = x11Screen.getDevice();
long display = absDevice.getHandle();
@@ -311,8 +328,8 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
int screen = x11Screen.getIndex();
boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display);
int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capsChosen, false, isMultisampleAvailable, display, screen);
- XVisualInfo[] infos = null;
+ // 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice
XVisualInfo recommendedVis = GLX.glXChooseVisual(display, screen, attribs, 0);
if (DEBUG) {
System.err.print("!!! glXChooseVisual recommended ");
@@ -322,51 +339,39 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
System.err.println("visual id " + toHexString(recommendedVis.getVisualid()));
}
}
+
+ // 2nd choice: get all GLCapabilities available, preferred recommendedIndex might be available if 1st choice was successful
int[] count = new int[1];
XVisualInfo template = XVisualInfo.create();
template.setScreen(screen);
- infos = X11Util.XGetVisualInfo(display, X11Lib.VisualScreenMask, template, count, 0);
+ XVisualInfo[] infos = X11Util.XGetVisualInfo(display, X11Lib.VisualScreenMask, template, count, 0);
if (infos == null || infos.length<1) {
throw new GLException("Error while enumerating available XVisualInfos");
}
- caps = new GLCapabilitiesImmutable[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 chosenIndex by glXChooseVisual
- if (recommendedVis != null && recommendedVis.getVisualid() == infos[i].getVisualid()) {
- recommendedIndex = i;
+ if( !X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(availableCaps, glProfile, display, infos[i], winattrmask, isMultisampleAvailable) ) {
+ if(DEBUG) {
+ System.err.println("X11GLXGraphicsConfiguration.getAvailableGLCapabilitiesXVisual: XVisual invalid: ("+x11Screen+"): fbcfg: "+toHexString(infos[i].getVisualid()));
+ }
+ } else {
+ // Attempt to find the visual chosenIndex by glXChooseVisual
+ if (recommendedVis != null && recommendedVis.getVisualid() == infos[i].getVisualid()) {
+ recommendedIndex = availableCaps.size() - 1;
+ }
}
}
- try {
- chosen = chooser.chooseCapabilities(capsChosen, 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]);
- return new X11GLXGraphicsConfiguration(x11Screen, caps[chosen], capsReq, chooser, retXVisualInfo, 0, -1);
- }
- static String toHexString(int val) {
- return "0x"+Integer.toHexString(val);
- }
+ int chosenIndex = chooseCapabilities(chooser, capsChosen, availableCaps, recommendedIndex);
+ if ( 0 > chosenIndex ) {
+ if (DEBUG) {
+ Thread.dumpStack();
+ }
+ return null;
+ }
+ X11GLCapabilities chosenCaps = (X11GLCapabilities) availableCaps.get(chosenIndex);
- static String toHexString(long val) {
- return "0x"+Long.toHexString(val);
+ return new X11GLXGraphicsConfiguration(x11Screen, chosenCaps, capsReq, chooser);
}
}
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
index 0fbe7a1c9..898a8a658 100644
--- 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
@@ -43,10 +43,8 @@ import javax.media.opengl.*;
import com.jogamp.opengl.impl.*;
import com.jogamp.nativewindow.impl.jawt.x11.*;
import com.jogamp.nativewindow.impl.x11.*;
-import com.jogamp.opengl.impl.x11.glx.X11GLXGraphicsConfigurationFactory;
-import java.awt.image.ColorModel;
-public class X11AWTGLXGraphicsConfigurationFactory extends GraphicsConfigurationFactory {
+public class X11AWTGLXGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory {
protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration");
public X11AWTGLXGraphicsConfigurationFactory() {
@@ -91,11 +89,11 @@ public class X11AWTGLXGraphicsConfigurationFactory extends GraphicsConfiguration
displayHandle = X11Util.createDisplay(null);
owner = true;
if(DEBUG) {
- System.err.println("X11AWTGLXGraphicsConfigurationFactory: using a thread local X11 display");
+ System.err.println(Thread.currentThread().getName() + " - X11AWTGLXGraphicsConfigurationFactory: using a thread local X11 display");
}
} else {
if(DEBUG) {
- System.err.println("X11AWTGLXGraphicsConfigurationFactory: using AWT X11 display 0x"+Long.toHexString(displayHandle));
+ System.err.println(Thread.currentThread().getName() + " - X11AWTGLXGraphicsConfigurationFactory: using AWT X11 display 0x"+Long.toHexString(displayHandle));
}
/**
* May cause an exception on NVidia X11 Display destruction,
@@ -153,15 +151,13 @@ public class X11AWTGLXGraphicsConfigurationFactory extends GraphicsConfiguration
visualID = x11Config.getVisualID();
for (int i = 0; i < configs.length; i++) {
gc = configs[i];
- if (gc != null) {
- if (X11SunJDKReflection.graphicsConfigurationGetVisualID(gc) == visualID) {
- if(DEBUG) {
- System.err.println("Found matching default AWT visual: 0x"+Long.toHexString(visualID) +" -> "+x11Config);
- }
- return new AWTGraphicsConfiguration(awtScreen,
- x11Config.getChosenCapabilities(), x11Config.getRequestedCapabilities(),
- gc, x11Config);
+ if (X11SunJDKReflection.graphicsConfigurationGetVisualID(gc) == visualID) {
+ if(DEBUG) {
+ System.err.println("Found matching default AWT visual: 0x"+Long.toHexString(visualID) +" -> "+x11Config);
}
+ return new AWTGraphicsConfiguration(awtScreen,
+ x11Config.getChosenCapabilities(), x11Config.getRequestedCapabilities(),
+ gc, x11Config);
}
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java
index f22e11cb7..6073a75f8 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/awt/TextRenderer.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -43,11 +44,9 @@ import com.jogamp.opengl.impl.Debug;
import com.jogamp.opengl.util.*;
import com.jogamp.opengl.util.packrect.*;
import com.jogamp.opengl.util.texture.*;
-import com.jogamp.opengl.util.texture.awt.*;
import java.awt.AlphaComposite;
import java.awt.Color;
-import java.awt.Composite;
// For debugging purposes
import java.awt.EventQueue;
@@ -71,7 +70,6 @@ import java.security.*;
import javax.media.opengl.*;
import javax.media.opengl.glu.*;
-import javax.media.opengl.glu.gl2.*;
import javax.media.opengl.awt.*;
@@ -720,7 +718,7 @@ public class TextRenderer {
// The OpenGL spec is unclear about whether this changes the
// buffer bindings, so preemptively zero out the GL_ARRAY_BUFFER
// binding
- if (is15Available(gl)) {
+ if (getUseVertexArrays() && is15Available(gl)) {
try {
gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0);
} catch (Exception e) {
@@ -1236,7 +1234,7 @@ public class TextRenderer {
// The OpenGL spec is unclear about whether this changes the
// buffer bindings, so preemptively zero out the GL_ARRAY_BUFFER
// binding
- if (is15Available(gl)) {
+ if (getUseVertexArrays() && is15Available(gl)) {
try {
gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0);
} catch (Exception e) {
@@ -1558,6 +1556,8 @@ public class TextRenderer {
final int undefined = -2;
FontRenderContext fontRenderContext;
List/*<Glyph>*/ glyphsOutput = new ArrayList/*<Glyph>*/();
+ HashMap/*<String, GlyphVector>*/fullGlyphVectorCache = new HashMap/*<String, GlyphVector>*/();
+ HashMap/*<Character, GlyphMetrics>*/glyphMetricsCache = new HashMap/*<Character, GlyphMetrics>*/();
// The mapping from unicode character to font-specific glyph ID
int[] unicodes2Glyphs;
// The mapping from glyph ID to Glyph
@@ -1573,8 +1573,13 @@ public class TextRenderer {
public List/*<Glyph>*/ getGlyphs(CharSequence inString) {
glyphsOutput.clear();
- iter.initFromCharSequence(inString);
- GlyphVector fullRunGlyphVector = font.createGlyphVector(getFontRenderContext(), iter);
+ GlyphVector fullRunGlyphVector;
+ fullRunGlyphVector = (GlyphVector) fullGlyphVectorCache.get(inString.toString());
+ if (fullRunGlyphVector == null) {
+ iter.initFromCharSequence(inString);
+ fullRunGlyphVector = font.createGlyphVector(getFontRenderContext(), iter);
+ fullGlyphVectorCache.put(inString.toString(), fullRunGlyphVector);
+ }
boolean complex = (fullRunGlyphVector.getLayoutFlags() != 0);
if (complex || DISABLE_GLYPH_CACHE) {
// Punt to the robust version of the renderer
@@ -1585,7 +1590,13 @@ public class TextRenderer {
int lengthInGlyphs = fullRunGlyphVector.getNumGlyphs();
int i = 0;
while (i < lengthInGlyphs) {
- Glyph glyph = getGlyph(inString, fullRunGlyphVector, i);
+ Character letter = CharacterCache.valueOf(inString.charAt(i));
+ GlyphMetrics metrics = (GlyphMetrics) glyphMetricsCache.get(letter);
+ if (metrics == null) {
+ metrics = fullRunGlyphVector.getGlyphMetrics(i);
+ glyphMetricsCache.put(letter, metrics);
+ }
+ Glyph glyph = getGlyph(inString, metrics, i);
if (glyph != null) {
glyphsOutput.add(glyph);
i++;
@@ -1594,7 +1605,7 @@ public class TextRenderer {
// the cache
StringBuffer buf = new StringBuffer();
while (i < lengthInGlyphs &&
- getGlyph(inString, fullRunGlyphVector, i) == null) {
+ getGlyph(inString, fullRunGlyphVector.getGlyphMetrics(i), i) == null) {
buf.append(inString.charAt(i++));
}
glyphsOutput.add(new Glyph(buf.toString(),
@@ -1645,7 +1656,7 @@ public class TextRenderer {
// if the unicode or glyph ID would be out of bounds of the
// glyph cache.
private Glyph getGlyph(CharSequence inString,
- GlyphVector fullRunGlyphVector,
+ GlyphMetrics glyphMetrics,
int index) {
char unicodeID = inString.charAt(index);
@@ -1661,7 +1672,7 @@ public class TextRenderer {
// Must fabricate the glyph
singleUnicode[0] = unicodeID;
GlyphVector gv = font.createGlyphVector(getFontRenderContext(), singleUnicode);
- return getGlyph(unicodeID, gv, fullRunGlyphVector.getGlyphMetrics(index));
+ return getGlyph(unicodeID, gv, glyphMetrics);
}
// It's unclear whether this variant might produce less
@@ -1698,6 +1709,26 @@ public class TextRenderer {
return glyph;
}
}
+
+ private static class CharacterCache {
+ private CharacterCache() {
+ }
+
+ static final Character cache[] = new Character[127 + 1];
+
+ static {
+ for (int i = 0; i < cache.length; i++) {
+ cache[i] = new Character((char) i);
+ }
+ }
+
+ public static Character valueOf(char c) {
+ if (c <= 127) { // must cache
+ return CharacterCache.cache[c];
+ }
+ return new Character(c);
+ }
+ }
class Pipelined_QuadRenderer {
int mOutstandingGlyphsVerticesPipeline = 0;
@@ -1712,7 +1743,7 @@ public class TextRenderer {
mVertCoords = Buffers.newDirectFloatBuffer(kTotalBufferSizeCoordsVerts);
mTexCoords = Buffers.newDirectFloatBuffer(kTotalBufferSizeCoordsTex);
- usingVBOs = is15Available(gl);
+ usingVBOs = getUseVertexArrays() && is15Available(gl);
if (usingVBOs) {
try {
@@ -1918,7 +1949,7 @@ public class TextRenderer {
* rendering, or whether text is rendered using the OpenGL
* immediate mode commands. Defaults to true.
*/
- public boolean getUseVertexArrays() {
+ public final boolean getUseVertexArrays() {
return useVertexArrays;
}
@@ -1943,7 +1974,7 @@ public class TextRenderer {
return smoothing;
}
- private boolean is15Available(GL gl) {
+ private final boolean is15Available(GL gl) {
if (!checkFor_isExtensionAvailable_GL_VERSION_1_5) {
isExtensionAvailable_GL_VERSION_1_5 = gl.isExtensionAvailable("GL_VERSION_1_5");
checkFor_isExtensionAvailable_GL_VERSION_1_5 = true;
diff --git a/src/jogl/classes/com/jogamp/opengl/util/awt/TextureRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/awt/TextureRenderer.java
index bc5aa517e..86dca59f4 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/awt/TextureRenderer.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/awt/TextureRenderer.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -47,10 +48,8 @@ import java.awt.Rectangle;
import java.awt.image.*;
import javax.media.opengl.*;
-import javax.media.opengl.glu.*;
import javax.media.opengl.glu.gl2.*;
import com.jogamp.opengl.util.texture.*;
-import com.jogamp.opengl.util.texture.spi.*;
import com.jogamp.opengl.util.texture.awt.*;
/** Provides the ability to render into an OpenGL {@link
diff --git a/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java b/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java
index 695fad5a9..ecba18147 100644
--- a/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java
+++ b/src/jogl/classes/javax/media/opengl/DefaultGLCapabilitiesChooser.java
@@ -42,6 +42,7 @@ package javax.media.opengl;
import javax.media.nativewindow.NativeWindowException;
import com.jogamp.opengl.impl.Debug;
+import java.util.List;
import javax.media.nativewindow.CapabilitiesImmutable;
/** <P> The default implementation of the {@link
@@ -85,38 +86,40 @@ import javax.media.nativewindow.CapabilitiesImmutable;
public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser {
private static final boolean DEBUG = Debug.debug("CapabilitiesChooser");
- public int chooseCapabilities(CapabilitiesImmutable desired,
- CapabilitiesImmutable[] available,
- int windowSystemRecommendedChoice) {
- GLCapabilitiesImmutable _desired = (GLCapabilitiesImmutable) desired;
- GLCapabilitiesImmutable[] _available = (GLCapabilitiesImmutable[]) available;
- int availnum = 0;
-
- for (int i = 0; i < _available.length; i++) {
- if(null != _available[i]) { availnum++; }
+ public int chooseCapabilities(final CapabilitiesImmutable desired,
+ final List /*<CapabilitiesImmutable>*/ available,
+ final int windowSystemRecommendedChoice) {
+ if ( null == desired ) {
+ throw new NativeWindowException("Null desired capabilities");
+ }
+ if ( 0 == available.size() ) {
+ throw new NativeWindowException("Empty available capabilities");
}
+ final GLCapabilitiesImmutable gldes = (GLCapabilitiesImmutable) desired;
+ final int availnum = available.size();
+
if (DEBUG) {
- System.err.println("Desired: " + _desired);
- System.err.println("Available: Valid " + availnum + "/" + _available.length);
- for (int i = 0; i < _available.length; i++) {
- System.err.println(i + ": " + _available[i]);
+ System.err.println("Desired: " + gldes);
+ System.err.println("Available: " + availnum);
+ for (int i = 0; i < available.size(); i++) {
+ System.err.println(i + ": " + available.get(i));
}
System.err.println("Window system's recommended choice: " + windowSystemRecommendedChoice);
}
if (windowSystemRecommendedChoice >= 0 &&
- windowSystemRecommendedChoice < _available.length &&
- _available[windowSystemRecommendedChoice] != null) {
+ windowSystemRecommendedChoice < availnum &&
+ null != available.get(windowSystemRecommendedChoice)) {
if (DEBUG) {
System.err.println("Choosing window system's recommended choice of " + windowSystemRecommendedChoice);
- System.err.println(_available[windowSystemRecommendedChoice]);
+ System.err.println(available.get(windowSystemRecommendedChoice));
}
return windowSystemRecommendedChoice;
}
// Create score array
- int[] scores = new int[_available.length];
+ int[] scores = new int[availnum];
int NO_SCORE = -9999999;
int DOUBLE_BUFFER_MISMATCH_PENALTY = 1000;
int STENCIL_MISMATCH_PENALTY = 500;
@@ -131,18 +134,18 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser {
scores[i] = NO_SCORE;
}
// Compute score for each
- for (int i = 0; i < scores.length; i++) {
- GLCapabilitiesImmutable cur = _available[i];
+ for (int i = 0; i < availnum; i++) {
+ GLCapabilitiesImmutable cur = (GLCapabilitiesImmutable) available.get(i);
if (cur == null) {
continue;
}
- if (_desired.isOnscreen() != cur.isOnscreen()) {
+ if (gldes.isOnscreen() != cur.isOnscreen()) {
continue;
}
- if (!_desired.isOnscreen() && _desired.isPBuffer() && !cur.isPBuffer()) {
+ if (!gldes.isOnscreen() && gldes.isPBuffer() && !cur.isPBuffer()) {
continue; // only skip if requested Offscreen && PBuffer, but no PBuffer available
}
- if (_desired.getStereo() != cur.getStereo()) {
+ if (gldes.getStereo() != cur.getStereo()) {
continue;
}
int score = 0;
@@ -150,20 +153,20 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser {
// (Note that this decides the direction of all other penalties)
score += (COLOR_MISMATCH_PENALTY_SCALE *
((cur.getRedBits() + cur.getGreenBits() + cur.getBlueBits() + cur.getAlphaBits()) -
- (_desired.getRedBits() + _desired.getGreenBits() + _desired.getBlueBits() + _desired.getAlphaBits())));
+ (gldes.getRedBits() + gldes.getGreenBits() + gldes.getBlueBits() + gldes.getAlphaBits())));
// Compute difference in depth buffer depth
score += (DEPTH_MISMATCH_PENALTY_SCALE * sign(score) *
- Math.abs(cur.getDepthBits() - _desired.getDepthBits()));
+ Math.abs(cur.getDepthBits() - gldes.getDepthBits()));
// Compute difference in accumulation buffer depth
score += (ACCUM_MISMATCH_PENALTY_SCALE * sign(score) *
Math.abs((cur.getAccumRedBits() + cur.getAccumGreenBits() + cur.getAccumBlueBits() + cur.getAccumAlphaBits()) -
- (_desired.getAccumRedBits() + _desired.getAccumGreenBits() + _desired.getAccumBlueBits() + _desired.getAccumAlphaBits())));
+ (gldes.getAccumRedBits() + gldes.getAccumGreenBits() + gldes.getAccumBlueBits() + gldes.getAccumAlphaBits())));
// Compute difference in stencil bits
- score += STENCIL_MISMATCH_PENALTY_SCALE * sign(score) * (cur.getStencilBits() - _desired.getStencilBits());
- if (cur.getDoubleBuffered() != _desired.getDoubleBuffered()) {
+ score += STENCIL_MISMATCH_PENALTY_SCALE * sign(score) * (cur.getStencilBits() - gldes.getStencilBits());
+ if (cur.getDoubleBuffered() != gldes.getDoubleBuffered()) {
score += sign(score) * DOUBLE_BUFFER_MISMATCH_PENALTY;
}
- if ((_desired.getStencilBits() > 0) && (cur.getStencilBits() == 0)) {
+ if ((gldes.getStencilBits() > 0) && (cur.getStencilBits() == 0)) {
score += sign(score) * STENCIL_MISMATCH_PENALTY;
}
scores[i] = score;
@@ -172,12 +175,12 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser {
// non-hardware-accelerated visuals out
boolean gotHW = false;
int maxAbsoluteHWScore = 0;
- for (int i = 0; i < scores.length; i++) {
+ for (int i = 0; i < availnum; i++) {
int score = scores[i];
if (score == NO_SCORE) {
continue;
}
- GLCapabilitiesImmutable cur = _available[i];
+ GLCapabilitiesImmutable cur = (GLCapabilitiesImmutable) available.get(i);
if (cur.getHardwareAccelerated()) {
int absScore = Math.abs(score);
if (!gotHW ||
@@ -188,12 +191,12 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser {
}
}
if (gotHW) {
- for (int i = 0; i < scores.length; i++) {
+ for (int i = 0; i < availnum; i++) {
int score = scores[i];
if (score == NO_SCORE) {
continue;
}
- GLCapabilitiesImmutable cur = _available[i];
+ GLCapabilitiesImmutable cur = (GLCapabilitiesImmutable) available.get(i);
if (!cur.getHardwareAccelerated()) {
if (score <= 0) {
score -= maxAbsoluteHWScore;
@@ -207,7 +210,7 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser {
if (DEBUG) {
System.err.print("Scores: [");
- for (int i = 0; i < _available.length; i++) {
+ for (int i = 0; i < availnum; i++) {
if (i > 0) {
System.err.print(",");
}
@@ -219,7 +222,7 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser {
// Ready to select. Choose score closest to 0.
int scoreClosestToZero = NO_SCORE;
int chosenIndex = -1;
- for (int i = 0; i < scores.length; i++) {
+ for (int i = 0; i < availnum; i++) {
int score = scores[i];
if (score == NO_SCORE) {
continue;
@@ -238,7 +241,7 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser {
if (DEBUG) {
System.err.println("Chosen index: " + chosenIndex);
System.err.println("Chosen capabilities:");
- System.err.println(_available[chosenIndex]);
+ System.err.println(available.get(chosenIndex));
}
return chosenIndex;
@@ -250,4 +253,5 @@ public class DefaultGLCapabilitiesChooser implements GLCapabilitiesChooser {
}
return 1;
}
+
}
diff --git a/src/jogl/classes/javax/media/opengl/GLCapabilities.java b/src/jogl/classes/javax/media/opengl/GLCapabilities.java
index 82f83dc82..1ae9e40aa 100644
--- a/src/jogl/classes/javax/media/opengl/GLCapabilities.java
+++ b/src/jogl/classes/javax/media/opengl/GLCapabilities.java
@@ -143,6 +143,56 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
return res;
}
+ /** comparing hw/sw, stereo, multisample, stencil, RGBA and depth only */
+ public int compareTo(Object o) {
+ if ( ! ( o instanceof GLCapabilities ) ) {
+ Class c = (null != o) ? o.getClass() : null ;
+ throw new ClassCastException("Not a GLCapabilities object: " + c);
+ }
+
+ final GLCapabilities caps = (GLCapabilities) o;
+
+ if(hardwareAccelerated && !caps.hardwareAccelerated) {
+ return 1;
+ } else if(!hardwareAccelerated && caps.hardwareAccelerated) {
+ return -1;
+ }
+
+ if(stereo && !caps.stereo) {
+ return 1;
+ } else if(!stereo && caps.stereo) {
+ return -1;
+ }
+
+ final int ms = sampleBuffers ? numSamples : 0;
+ final int xms = caps.sampleBuffers ? caps.numSamples : 0;
+
+ if(ms > xms) {
+ return 1;
+ } else if( ms < xms ) {
+ return -1;
+ }
+
+ if(stencilBits > caps.stencilBits) {
+ return 1;
+ } else if(stencilBits < caps.stencilBits) {
+ return -1;
+ }
+
+ final int sc = super.compareTo(caps); // RGBA
+ if(0 != sc) {
+ return sc;
+ }
+
+ if(depthBits > caps.depthBits) {
+ return 1;
+ } else if(depthBits < caps.depthBits) {
+ return -1;
+ }
+
+ return 0; // they are equal: hw/sw, stereo, multisample, stencil, RGBA and depth
+ }
+
/** Returns the GL profile you desire or used by the drawable. */
public GLProfile getGLProfile() {
return glProfile;
@@ -158,11 +208,30 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
return pbuffer;
}
- /** Enables or disables pbuffer usage. */
+ /**
+ * Enables or disables pbuffer usage.<br>
+ * If enabled, onscreen := false.
+ * Defaults to false.
+ */
public void setPBuffer(boolean onOrOff) {
+ if(onOrOff) {
+ setOnscreen(false);
+ }
pbuffer = onOrOff;
}
+ /**
+ * Sets whether the drawable surface supports onscreen.<br>
+ * If enabled, pbuffer := false.<br>
+ * Defaults to true.
+ */
+ public void setOnscreen(boolean onscreen) {
+ if(onscreen) {
+ setPBuffer(false);
+ }
+ super.setOnscreen(onscreen);
+ }
+
/** Indicates whether double-buffering is enabled. */
public boolean getDoubleBuffered() {
return doubleBuffered;
@@ -340,28 +409,54 @@ public class GLCapabilities extends Capabilities implements Cloneable, GLCapabil
return pbufferRenderToTextureRectangle;
}
+ public StringBuffer toString(StringBuffer sink) {
+ if(null == sink) {
+ sink = new StringBuffer();
+ }
+
+ int samples = sampleBuffers ? numSamples : 0 ;
+
+ super.toString(sink);
+
+ sink.append(", accum-rgba ").append(accumRedBits).append("/").append(accumGreenBits).append("/").append(accumBlueBits).append("/").append(accumAlphaBits);
+ sink.append(", dp/st/ms: ").append(depthBits).append("/").append(stencilBits).append("/").append(samples);
+ if(doubleBuffered) {
+ sink.append(", dbl");
+ } else {
+ sink.append(", one");
+ }
+ if(stereo) {
+ sink.append(", stereo");
+ } else {
+ sink.append(", mono ");
+ }
+ if(hardwareAccelerated) {
+ sink.append(", hw, ");
+ } else {
+ sink.append(", sw, ");
+ }
+ sink.append(glProfile);
+ if(!isOnscreen()) {
+ if(pbuffer) {
+ sink.append(", pbuffer [r2t ").append(pbufferRenderToTexture?1:0)
+ .append(", r2tr ").append(pbufferRenderToTextureRectangle?1:0)
+ .append(", float ").append(pbufferFloatingPointBuffers?1:0)
+ .append("]");
+ } else {
+ sink.append(", pixmap");
+ }
+ }
+
+ return sink;
+ }
+
/** Returns a textual representation of this GLCapabilities
object. */
public String toString() {
StringBuffer msg = new StringBuffer();
- msg.append("GLCapabilities[");
- msg.append(super.toString());
- msg.append(", GL profile: " + glProfile +
- ", PBuffer: " + pbuffer +
- ", DoubleBuffered: " + doubleBuffered +
- ", Stereo: " + stereo +
- ", HardwareAccelerated: " + hardwareAccelerated +
- ", DepthBits: " + depthBits +
- ", StencilBits: " + stencilBits +
- ", Red Accum: " + accumRedBits +
- ", Green Accum: " + accumGreenBits +
- ", Blue Accum: " + accumBlueBits +
- ", Alpha Accum: " + accumAlphaBits +
- ", Multisample: " + sampleBuffers +
- ", Num samples: "+(sampleBuffers ? numSamples : 0));
- msg.append(", PBuffer-FloatingPointBuffers: "+pbufferFloatingPointBuffers+
- ", PBuffer-RenderToTexture: "+pbufferRenderToTexture+
- ", PBuffer-RenderToTextureRectangle: "+pbufferRenderToTextureRectangle+ "]");
+ msg.append("GLCaps[");
+ toString(msg);
+ msg.append("]");
return msg.toString();
}
}
diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java
index 72073deef..4c9b737d5 100644
--- a/src/jogl/classes/javax/media/opengl/GLContext.java
+++ b/src/jogl/classes/javax/media/opengl/GLContext.java
@@ -40,10 +40,10 @@
package javax.media.opengl;
-import com.jogamp.opengl.impl.Debug;
import java.util.HashMap;
import java.util.HashSet;
import javax.media.nativewindow.AbstractGraphicsDevice;
+import com.jogamp.opengl.impl.Debug;
/** Abstraction for an OpenGL rendering context. In order to perform
OpenGL rendering, a context must be "made current" on the current
@@ -579,10 +579,6 @@ public abstract class GLContext {
*/
private static /*final*/ HashSet/*<UniqueDeviceString>*/ deviceVersionsAvailableSet = new HashSet();
- protected static String getContextFQN(AbstractGraphicsDevice device, int major, int minor, int ctp) {
- return device.getUniqueID() + "-" + toHexString(compose8bit(major, minor, ctp, 0));
- }
-
protected static String getDeviceVersionAvailableKey(AbstractGraphicsDevice device, int major, int profile) {
return device.getUniqueID() + "-" + toHexString(compose8bit(major, profile, 0, 0));
}
diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
index f9591e84d..500173cf2 100644
--- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
+++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
@@ -40,14 +40,14 @@
package javax.media.opengl;
-import com.jogamp.common.JogampRuntimeException;
-import com.jogamp.common.impl.Debug;
-import com.jogamp.common.util.ReflectionUtil;
-
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
-import java.util.HashSet;
+import java.util.List;
+
+import com.jogamp.common.JogampRuntimeException;
+import com.jogamp.common.impl.Debug;
+import com.jogamp.common.util.ReflectionUtil;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeSurface;
@@ -221,6 +221,9 @@ public abstract class GLDrawableFactory {
}
}
+ protected void enterThreadCriticalZone() {};
+ protected void leaveThreadCriticalZone() {};
+
protected abstract void shutdownInstance();
/**
@@ -237,6 +240,24 @@ public abstract class GLDrawableFactory {
*/
public abstract boolean getIsDeviceCompatible(AbstractGraphicsDevice device);
+ protected final AbstractGraphicsDevice validateDevice(AbstractGraphicsDevice device) {
+ if(null==device) {
+ device = getDefaultDevice();
+ if(null==device) {
+ throw new InternalError("no default device");
+ }
+ if (GLProfile.DEBUG) {
+ System.err.println("Info: GLDrawableFactory.validateDevice: using default device : "+device);
+ }
+ } else if( !getIsDeviceCompatible(device) ) {
+ if (GLProfile.DEBUG) {
+ System.err.println("Info: GLDrawableFactory.validateDevice: device not compatible : "+device);
+ }
+ return null;
+ }
+ return device;
+ }
+
/**
* Returns true if a shared context is already mapped to the <code>device</code> {@link AbstractGraphicsDevice#getConnection()},
* or if a new shared context could be created and mapped. Otherwise return false.<br>
@@ -256,24 +277,28 @@ public abstract class GLDrawableFactory {
* @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
*/
protected final GLContext getOrCreateSharedContext(AbstractGraphicsDevice device) {
- if(null==device) {
- device = getDefaultDevice();
- if(null==device) {
- throw new InternalError("no default device");
- }
- if (GLProfile.DEBUG) {
- System.err.println("Info: GLDrawableFactory.getOrCreateSharedContext: using default device : "+device);
- }
- } else if( !getIsDeviceCompatible(device) ) {
- if (GLProfile.DEBUG) {
- System.err.println("Info: GLDrawableFactory.getOrCreateSharedContext: device not compatible : "+device);
- }
- return null;
+ device = validateDevice(device);
+ if(null!=device) {
+ return getOrCreateSharedContextImpl(device);
}
- return getOrCreateSharedContextImpl(device);
+ return null;
}
protected abstract GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device);
+ /**
+ * Returns the sole GLDrawableFactory instance for the desktop (X11, WGL, ..) if exist or null
+ */
+ public static GLDrawableFactory getDesktopFactory() {
+ return nativeOSFactory;
+ }
+
+ /**
+ * Returns the sole GLDrawableFactory instance for EGL if exist or null
+ */
+ public static GLDrawableFactory getEGLFactory() {
+ return eglFactory;
+ }
+
/**
* Returns the sole GLDrawableFactory instance.
*
@@ -298,6 +323,34 @@ public abstract class GLDrawableFactory {
throw new GLException("No native platform GLDrawableFactory, nor EGLDrawableFactory available: "+glProfileImplName);
}
+ protected static GLDrawableFactory getFactoryImpl(AbstractGraphicsDevice device) throws GLException {
+ if(null != nativeOSFactory && nativeOSFactory.getIsDeviceCompatible(device)) {
+ return nativeOSFactory;
+ }
+ if(null != eglFactory && eglFactory.getIsDeviceCompatible(device)) {
+ return eglFactory;
+ }
+ throw new GLException("No native platform GLDrawableFactory, nor EGLDrawableFactory available: "+device);
+ }
+
+ /**
+ * Returns an array of available GLCapabilities for the device.<br>
+ * The list is sorted by the native ID, ascending.<br>
+ * The chosen GLProfile statement in the result may not refer to the maximum available profile
+ * due to implementation constraints, ie using the shared resource.
+ *
+ * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
+ * @return A list of {@link javax.media.opengl.GLCapabilitiesImmutable}'s, maybe empty if none is available.
+ */
+ public final List/*GLCapabilitiesImmutable*/ getAvailableCapabilities(AbstractGraphicsDevice device) {
+ device = validateDevice(device);
+ if(null!=device) {
+ return getAvailableCapabilitiesImpl(device);
+ }
+ return null;
+ }
+ protected abstract List/*GLCapabilitiesImmutable*/ getAvailableCapabilitiesImpl(AbstractGraphicsDevice device);
+
//----------------------------------------------------------------------
// Methods to create high-level objects
diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java
index c7b1e80cf..10d92b050 100644
--- a/src/jogl/classes/javax/media/opengl/GLProfile.java
+++ b/src/jogl/classes/javax/media/opengl/GLProfile.java
@@ -47,12 +47,13 @@ import com.jogamp.opengl.impl.GLDrawableFactoryImpl;
import com.jogamp.opengl.impl.GLDynamicLookupHelper;
import com.jogamp.opengl.impl.DesktopGLDynamicLookupHelper;
import com.jogamp.opengl.JoglVersion;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.security.*;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.opengl.fixedfunc.GLPointerFunc;
import javax.media.nativewindow.NativeWindowFactory;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.security.*;
+import java.util.List;
/**
* Specifies the the OpenGL profile.
@@ -70,8 +71,13 @@ public class GLProfile {
/**
* Static one time initialization of JOGL.
* <p>
+ * The parameter <code>firstUIActionOnProcess</code> has an impact on concurrent locking,<br>
+ * see {@link javax.media.nativewindow.NativeWindowFactory#initSingleton(boolean) NativeWindowFactory.initSingleton(firstUIActionOnProcess)}.
+ * </p>
+ * <p>
* Applications shall call this methods <b>ASAP</b>, before any other UI invocation.<br>
- * You may issue the call in your main function.<br>
+ * You may issue the call in your <code>main class</code> static block, which is the earliest point in your application/applet lifecycle,
+ * or within the <code>main function</code>.<br>
* In case applications are able to initialize JOGL before any other UI action,<br>
* they shall invoke this method with <code>firstUIActionOnProcess=true</code> and benefit from fast native multithreading support on all platforms if possible.</P>
* <P>
@@ -341,17 +347,35 @@ public class GLProfile {
/**
* All GL Profiles in the order of default detection.
- * Desktop compatibility profiles (the one with fixed function pipeline) comes first.
- *
- * FIXME GL3GL4: Due to GL3 and GL4 implementation bugs, we still choose GL2 first, if available!
+ * Desktop compatibility profiles (the one with fixed function pipeline) comes first
+ * from highest to lowest version.
*
* <ul>
- * <li> GL2
- * <li> GL3bc
* <li> GL4bc
+ * <li> GL3bc
+ * <li> GL2
* <li> GL2GL3
+ * <li> GL4
* <li> GL3
+ * <li> GL2ES2
+ * <li> GLES2
+ * <li> GL2ES1
+ * <li> GLES1
+ * </ul>
+ *
+ */
+ public static final String[] GL_PROFILE_LIST_ALL = new String[] { GL4bc, GL3bc, GL2, GL2GL3, GL4, GL3, GL2ES2, GLES2, GL2ES1, GLES1 };
+
+ /**
+ * Order of maximum profiles.
+ *
+ * <ul>
+ * <li> GL4bc
* <li> GL4
+ * <li> GL3bc
+ * <li> GL3
+ * <li> GL2
+ * <li> GL2GL3
* <li> GL2ES2
* <li> GLES2
* <li> GL2ES1
@@ -359,7 +383,21 @@ public class GLProfile {
* </ul>
*
*/
- public static final String[] GL_PROFILE_LIST_ALL = new String[] { GL2, GL3bc, GL4bc, GL2GL3, GL3, GL4, GL2ES2, GLES2, GL2ES1, GLES1 };
+ public static final String[] GL_PROFILE_LIST_MAX = new String[] { GL4bc, GL4, GL3bc, GL3, GL2, GL2GL3, GL2ES2, GLES2, GL2ES1, GLES1 };
+
+ /**
+ * Order of minimum original desktop profiles.
+ *
+ * <ul>
+ * <li> GL2
+ * <li> GL3bc
+ * <li> GL4bc
+ * <li> GL3
+ * <li> GL4
+ * </ul>
+ *
+ */
+ public static final String[] GL_PROFILE_LIST_MIN_DESKTOP = new String[] { GL2, GL3bc, GL4bc, GL3, GL4 };
/**
* Order of maximum fixed function profiles
@@ -389,13 +427,11 @@ public class GLProfile {
* </ul>
*
*/
- public static final String[] GL_PROFILE_LIST_MAX_PROGSHADER = new String[] { GL4, GL4bc, GL3, GL3bc, GL2, GL2ES2, GLES2 };
+ public static final String[] GL_PROFILE_LIST_MAX_PROGSHADER = new String[] { GL4bc, GL4, GL3bc, GL3, GL2, GL2ES2, GLES2 };
/**
* All GL2ES2 Profiles in the order of default detection.
*
- * FIXME GL3GL4: Due to GL3 and GL4 implementation bugs, we still choose GL2 first, if available!
- *
* <ul>
* <li> GL2ES2
* <li> GL2
@@ -405,13 +441,11 @@ public class GLProfile {
* </ul>
*
*/
- public static final String[] GL_PROFILE_LIST_GL2ES2 = new String[] { GL2ES2, GL2, GL3, GL4, GLES2 };
+ public static final String[] GL_PROFILE_LIST_GL2ES2 = new String[] { GL2ES2, GL4, GL3, GL2, GLES2 };
/**
* All GL2ES1 Profiles in the order of default detection.
*
- * FIXME GL3GL4: Due to GL3 and GL4 implementation bugs, we still choose GL2 first, if available!
- *
* <ul>
* <li> GL2ES1
* <li> GL2
@@ -421,7 +455,7 @@ public class GLProfile {
* </ul>
*
*/
- public static final String[] GL_PROFILE_LIST_GL2ES1 = new String[] { GL2ES1, GL2, GL3bc, GL4bc, GLES1 };
+ public static final String[] GL_PROFILE_LIST_GL2ES1 = new String[] { GL2ES1, GL4bc, GL3bc, GL2, GLES1 };
/**
* All GLES Profiles in the order of default detection.
@@ -449,7 +483,48 @@ public class GLProfile {
}
/**
- * Returns the highest profile, implementing the fixed function pipeline
+ * Returns the highest profile.
+ * It selects the first of the set: {@link GLProfile#GL_PROFILE_LIST_MAX}
+ *
+ * @throws GLException if no implementation for the given profile is found.
+ * @see #GL_PROFILE_LIST_MAX
+ */
+ public static GLProfile getMaximum(AbstractGraphicsDevice device)
+ throws GLException
+ {
+ return get(device, GL_PROFILE_LIST_MAX);
+ }
+
+ /** Uses the default device */
+ public static GLProfile getMaximum()
+ throws GLException
+ {
+ return get(GL_PROFILE_LIST_MAX);
+ }
+
+ /**
+ * Returns the lowest desktop profile.
+ * It selects the first of the set: {@link GLProfile#GL_PROFILE_LIST_MIN_DESKTOP}
+ *
+ * @throws GLException if no implementation for the given profile is found.
+ * @see #GL_PROFILE_LIST_MIN_DESKTOP
+ */
+ public static GLProfile getMinDesktop(AbstractGraphicsDevice device)
+ throws GLException
+ {
+ return get(device, GL_PROFILE_LIST_MIN_DESKTOP);
+ }
+
+ /** Uses the default device */
+ public static GLProfile getMinDesktop()
+ throws GLException
+ {
+ return get(GL_PROFILE_LIST_MIN_DESKTOP);
+ }
+
+
+ /**
+ * Returns the highest profile, implementing the fixed function pipeline.
* It selects the first of the set: {@link GLProfile#GL_PROFILE_LIST_MAX_FIXEDFUNC}
*
* @throws GLException if no implementation for the given profile is found.
@@ -1082,6 +1157,7 @@ public class GLProfile {
* Throws an GLException if no profile could be found at all.
*/
private static void initProfilesForDefaultDevices(boolean firstUIActionOnProcess) {
+ NativeWindowFactory.initSingleton(firstUIActionOnProcess);
if(DEBUG) {
System.err.println("GLProfile.init firstUIActionOnProcess: "+ firstUIActionOnProcess
@@ -1092,8 +1168,6 @@ public class GLProfile {
System.err.println(JoglVersion.getInstance());
}
- NativeWindowFactory.initSingleton(firstUIActionOnProcess);
-
ClassLoader classloader = GLProfile.class.getClassLoader();
isAWTAvailable = NativeWindowFactory.isAWTAvailable() &&
@@ -1187,7 +1261,7 @@ public class GLProfile {
boolean addedAnyProfile = initProfilesForDevice(defaultDesktopDevice) ||
initProfilesForDevice(defaultEGLDevice);
-
+
if(DEBUG) {
System.err.println("GLProfile.init isAWTAvailable "+isAWTAvailable);
System.err.println("GLProfile.init has desktopFactory "+(null!=desktopFactory));
@@ -1196,8 +1270,8 @@ public class GLProfile {
System.err.println("GLProfile.init has eglFactory "+(null!=eglFactory));
System.err.println("GLProfile.init hasGLES1Impl "+hasGLES1Impl);
System.err.println("GLProfile.init hasGLES2Impl "+hasGLES2Impl);
- System.err.println("GLProfile.init defaultDesktopDevice "+defaultDevice);
- System.err.println("GLProfile.init defaultEGLDevice "+defaultDevice);
+ System.err.println("GLProfile.init defaultDesktopDevice "+defaultDesktopDevice);
+ System.err.println("GLProfile.init defaultEGLDevice "+defaultEGLDevice);
System.err.println("GLProfile.init defaultDevice "+defaultDevice);
}
@@ -1211,10 +1285,22 @@ public class GLProfile {
* @return true if any profile for the device exists, otherwise false
*/
private static synchronized boolean initProfilesForDevice(AbstractGraphicsDevice device) {
+ if(null == device) {
+ return false;
+ }
+ GLDrawableFactory factory = GLDrawableFactory.getFactoryImpl(device);
+ factory.enterThreadCriticalZone();
+ try {
+ return initProfilesForDeviceImpl(device);
+ } finally {
+ factory.leaveThreadCriticalZone();
+ }
+ }
+ private static synchronized boolean initProfilesForDeviceImpl(AbstractGraphicsDevice device) {
boolean isSet = GLContext.getAvailableGLVersionsSet(device);
if(DEBUG) {
- String msg = "Info: GLProfile.initProfilesForDevice: "+device.getConnection()+", isSet "+isSet;
+ String msg = "Info: GLProfile.initProfilesForDevice: "+device+", isSet "+isSet;
Throwable t = new Throwable(msg);
t.printStackTrace();
// System.err.println(msg);
@@ -1234,7 +1320,7 @@ public class GLProfile {
// hence querying all available GLProfiles
boolean desktopSharedCtxAvail = desktopFactory.getIsSharedContextAvailable(device);
if (DEBUG) {
- System.err.println("GLProfile.initProfilesForDevice: "+device.getConnection()+": desktop Shared Ctx "+desktopSharedCtxAvail);
+ System.err.println("GLProfile.initProfilesForDevice: "+device+": desktop Shared Ctx "+desktopSharedCtxAvail);
}
if( null == GLContext.getAvailableGLVersion(device, 2, GLContext.CTX_PROFILE_COMPAT) ) {
// nobody yet set the available desktop versions, see {@link GLContextImpl#makeCurrent},
@@ -1243,13 +1329,8 @@ public class GLProfile {
2, GLContext.CTX_PROFILE_COMPAT,
1, 5, GLContext.CTX_PROFILE_COMPAT|GLContext.CTX_OPTION_ANY);
}
- computeProfileMap(device, false /* desktopCtxUndef*/, false /* eglCtxUndef */);
- addedDesktopProfile = null != GLProfile.getDefault(device);
- } else if(DEBUG) {
- System.err.println("GLProfile: DesktopFactory - Device is not available: "+device.getConnection());
- }
-
- if( null!=eglFactory && ( hasGLES2Impl || hasGLES1Impl ) && eglFactory.getIsDeviceCompatible(device)) {
+ addedDesktopProfile = computeProfileMap(device, false /* desktopCtxUndef*/, false /* eglCtxUndef */);
+ } else if( null!=eglFactory && ( hasGLES2Impl || hasGLES1Impl ) && eglFactory.getIsDeviceCompatible(device)) {
// 1st pretend we have all EGL profiles ..
computeProfileMap(device, false /* desktopCtxUndef*/, true /* eglCtxUndef */);
@@ -1257,7 +1338,7 @@ public class GLProfile {
// hence querying all available GLProfiles
boolean eglSharedCtxAvail = eglFactory.getIsSharedContextAvailable(device);
if (DEBUG) {
- System.err.println("GLProfile.initProfilesForDevice: "+device.getConnection()+": egl Shared Ctx "+eglSharedCtxAvail);
+ System.err.println("GLProfile.initProfilesForDevice: "+device+": egl Shared Ctx "+eglSharedCtxAvail);
}
if(hasGLES2Impl && null == GLContext.getAvailableGLVersion(device, 2, GLContext.CTX_PROFILE_ES) ) {
// nobody yet set the available desktop versions, see {@link GLContextImpl#makeCurrent},
@@ -1273,10 +1354,12 @@ public class GLProfile {
1, GLContext.CTX_PROFILE_ES,
1, 0, GLContext.CTX_PROFILE_ES|GLContext.CTX_OPTION_ANY);
}
- computeProfileMap(device, false /* desktopCtxUndef*/, false /* eglCtxUndef */);
- addedEGLProfile = null != GLProfile.get(device, GL_PROFILE_LIST_GLES);
- } else if(DEBUG) {
- System.err.println("GLProfile: EGLFactory - Device is not available: "+device.getConnection());
+ addedEGLProfile = computeProfileMap(device, false /* desktopCtxUndef*/, false /* eglCtxUndef */);
+ } else {
+ setProfileMap(device, new HashMap()); // empty
+ if(DEBUG) {
+ System.err.println("GLProfile: EGLFactory - Device is not available: "+device);
+ }
}
if(!GLContext.getAvailableGLVersionsSet(device)) {
@@ -1288,9 +1371,16 @@ public class GLProfile {
System.err.println("GLProfile.initProfilesForDevice: "+device.getConnection()+": "+glAvailabilityToString(device));
if(addedDesktopProfile) {
dumpGLInfo(desktopFactory, device);
- }
- if(addedEGLProfile) {
+ List/*<GLCapabilitiesImmutable>*/ availCaps = desktopFactory.getAvailableCapabilities(device);
+ for(int i=0; i<availCaps.size(); i++) {
+ System.err.println(availCaps.get(i));
+ }
+ } else if(addedEGLProfile) {
dumpGLInfo(eglFactory, device);
+ List/*<GLCapabilitiesImmutable>*/ availCaps = eglFactory.getAvailableCapabilities(device);
+ for(int i=0; i<availCaps.size(); i++) {
+ System.err.println(availCaps.get(i));
+ }
}
}
@@ -1299,16 +1389,12 @@ public class GLProfile {
private static void dumpGLInfo(GLDrawableFactoryImpl factory, AbstractGraphicsDevice device) {
GLContext ctx = factory.getOrCreateSharedContext(device);
- AbstractGraphicsDevice nativeDevice = ctx.getGLDrawable().getNativeSurface()
- .getGraphicsConfiguration().getNativeGraphicsConfiguration()
- .getScreen().getDevice();
- nativeDevice.lock();
+ System.err.println("GLProfile.dumpGLInfo: "+ctx);
+ ctx.makeCurrent();
try {
- ctx.makeCurrent();
System.err.println(JoglVersion.getGLInfo(ctx.getGL(), null));
- ctx.release();
} finally {
- nativeDevice.unlock();
+ ctx.release();
}
}
@@ -1359,7 +1445,7 @@ public class GLProfile {
sb.append("]");
}
- private static void computeProfileMap(AbstractGraphicsDevice device, boolean desktopCtxUndef, boolean eglCtxUndef) {
+ private static boolean computeProfileMap(AbstractGraphicsDevice device, boolean desktopCtxUndef, boolean eglCtxUndef) {
if (DEBUG) {
System.err.println("GLProfile.init map "+device.getConnection()+", desktopCtxUndef "+desktopCtxUndef+", eglCtxUndef "+eglCtxUndef);
}
@@ -1390,6 +1476,7 @@ public class GLProfile {
_mappedProfiles.put(GL_DEFAULT, defaultGLProfile);
}
setProfileMap(device, _mappedProfiles);
+ return _mappedProfiles.size() > 0;
}
/**
@@ -1489,11 +1576,10 @@ public class GLProfile {
String deviceKey = device.getUniqueID();
HashMap map = (HashMap) deviceConn2ProfileMap.get(deviceKey);
if(null==map) {
- map = new HashMap();
- synchronized ( deviceConn2ProfileMap ) {
- deviceConn2ProfileMap.put(deviceKey, map);
- }
initProfilesForDevice(device);
+ if( null == deviceConn2ProfileMap.get(deviceKey) ) {
+ throw new InternalError("initProfilesForDevice(..) didn't issue setProfileMap(..) on "+device);
+ }
}
return map;
}
diff --git a/src/jogl/classes/javax/media/opengl/awt/AWTGLAutoDrawable.java b/src/jogl/classes/javax/media/opengl/awt/AWTGLAutoDrawable.java
index d92cec389..d1e725b00 100644
--- a/src/jogl/classes/javax/media/opengl/awt/AWTGLAutoDrawable.java
+++ b/src/jogl/classes/javax/media/opengl/awt/AWTGLAutoDrawable.java
@@ -40,7 +40,6 @@
package javax.media.opengl.awt;
import javax.media.opengl.*;
-import javax.media.opengl.glu.*;
public interface AWTGLAutoDrawable extends GLAutoDrawable, ComponentEvents {
/** Requests a new width and height for this AWTGLAutoDrawable. */
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
index 8b20b9ed1..acabe58a5 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
@@ -40,31 +40,62 @@
package javax.media.opengl.awt;
-import com.jogamp.common.GlueGenVersion;
-import com.jogamp.common.util.VersionUtil;
-import com.jogamp.nativewindow.NativeWindowVersion;
-import javax.media.opengl.*;
-import javax.media.nativewindow.*;
-import javax.media.nativewindow.awt.*;
-
-import com.jogamp.opengl.impl.*;
-import com.jogamp.opengl.JoglVersion;
+import java.beans.Beans;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.awt.Canvas;
import java.awt.Color;
-import java.awt.Component;
import java.awt.FontMetrics;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
-import java.awt.Window;
-import java.awt.event.WindowEvent;
-import java.awt.event.WindowAdapter;
-import java.awt.geom.*;
-import java.beans.*;
-import java.lang.reflect.*;
-import java.security.*;
+import java.awt.geom.Rectangle2D;
+
+import java.awt.EventQueue;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.media.nativewindow.WindowClosingProtocol;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.GraphicsConfigurationFactory;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.nativewindow.awt.AWTGraphicsConfiguration;
+import javax.media.nativewindow.awt.AWTGraphicsDevice;
+import javax.media.nativewindow.awt.AWTGraphicsScreen;
+import javax.media.nativewindow.awt.AWTWindowClosingProtocol;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GLAnimatorControl;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesChooser;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.GLRunnable;
+import javax.media.opengl.Threading;
+
+import com.jogamp.nativewindow.NativeWindowVersion;
+import com.jogamp.common.GlueGenVersion;
+import com.jogamp.common.util.VersionUtil;
+import com.jogamp.opengl.JoglVersion;
+
+import com.jogamp.common.util.locks.RecursiveLock;
+import com.jogamp.opengl.impl.Debug;
+import com.jogamp.opengl.impl.GLContextImpl;
+import com.jogamp.opengl.impl.GLDrawableHelper;
+import com.jogamp.opengl.impl.ThreadingImpl;
// FIXME: Subclasses need to call resetGLFunctionAvailability() on their
// context whenever the displayChanged() function is called on our
@@ -104,7 +135,7 @@ import java.security.*;
* </ul>
*/
-public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
+public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosingProtocol {
private static final boolean DEBUG;
private static final GLProfile defaultGLProfile;
@@ -126,6 +157,13 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
private GLContext shareWith;
private GraphicsDevice device;
+ private AWTWindowClosingProtocol awtWindowClosingProtocol =
+ new AWTWindowClosingProtocol(this, new Runnable() {
+ public void run() {
+ GLCanvas.this.destroy();
+ }
+ });
+
/** Creates a new GLCanvas component with a default set of OpenGL
capabilities, using the default OpenGL capabilities selection
mechanism, on the default screen device. */
@@ -202,33 +240,6 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
this.device = device;
}
- protected interface DestroyMethod {
- public void destroyMethod();
- }
-
- /* package private */ final static Object addClosingListener(Component c, final DestroyMethod d) {
- WindowAdapter cl = null;
- Window w = getWindow(c);
- if(null!=w) {
- cl = new WindowAdapter() {
- public void windowClosing(WindowEvent e) {
- // we have to issue this call rigth away,
- // otherwise the window gets destroyed
- d.destroyMethod();
- }
- };
- w.addWindowListener(cl);
- }
- return cl;
- }
-
- private final static Window getWindow(Component c) {
- while ( c!=null && ! ( c instanceof Window ) ) {
- c = c.getParent();
- }
- return (Window)c;
- }
-
/**
* Overridden to choose a GraphicsConfiguration on a parent container's
* GraphicsDevice because both devices
@@ -340,18 +351,33 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
}
public GLContext createContext(GLContext shareWith) {
- return drawable.createContext(shareWith);
+ drawableSync.lock();
+ try {
+ return (null != drawable) ? drawable.createContext(shareWith) : null;
+ } finally {
+ drawableSync.unlock();
+ }
}
public void setRealized(boolean realized) {
}
public boolean isRealized() {
- return ( null != drawable ) ? drawable.isRealized() : false;
+ drawableSync.lock();
+ try {
+ return ( null != drawable ) ? drawable.isRealized() : false;
+ } finally {
+ drawableSync.unlock();
+ }
}
- private Object closingListener = null;
- private Object closingListenerLock = new Object();
+ public int getDefaultCloseOperation() {
+ return awtWindowClosingProtocol.getDefaultCloseOperation();
+ }
+
+ public int setDefaultCloseOperation(int op) {
+ return awtWindowClosingProtocol.setDefaultCloseOperation(op);
+ }
public void display() {
if( !validateGLDrawable() ) {
@@ -359,63 +385,63 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
}
maybeDoSingleThreadedWorkaround(displayOnEventDispatchThreadAction,
displayAction);
- if(null==closingListener) {
- synchronized(closingListenerLock) {
- if(null==closingListener) {
- closingListener=addClosingListener(this, new DestroyMethod() {
- public void destroyMethod() { destroy(); } });
- }
- }
- }
+
+ awtWindowClosingProtocol.addClosingListenerOneShot();
}
private void dispose(boolean regenerate) {
- if(DEBUG) {
- Exception ex1 = new Exception("Info: dispose("+regenerate+") - start");
- ex1.printStackTrace();
- }
-
- if(null!=context) {
- boolean animatorPaused = false;
- GLAnimatorControl animator = getAnimator();
- if(null!=animator) {
- // can't remove us from animator for recreational addNotify()
- animatorPaused = animator.pause();
+ drawableSync.lock();
+ try {
+ if(DEBUG) {
+ Exception ex1 = new Exception("Info: dispose("+regenerate+") - start, hasContext " +
+ (null!=context) + ", hasDrawable " + (null!=drawable));
+ ex1.printStackTrace();
}
- disposeRegenerate=regenerate;
-
- if (Threading.isSingleThreaded() &&
- !Threading.isOpenGLThread()) {
- // Workaround for termination issues with applets --
- // sun.applet.AppletPanel should probably be performing the
- // remove() call on the EDT rather than on its own thread
- // Hint: User should run remove from EDT.
- if (ThreadingImpl.isAWTMode() &&
- Thread.holdsLock(getTreeLock())) {
- // The user really should not be invoking remove() from this
- // thread -- but since he/she is, we can not go over to the
- // EDT at this point. Try to destroy the context from here.
- if(context.isCreated()) {
- drawableHelper.invokeGL(drawable, context, disposeAction, null);
+ if(null!=context) {
+ boolean animatorPaused = false;
+ GLAnimatorControl animator = getAnimator();
+ if(null!=animator) {
+ // can't remove us from animator for recreational addNotify()
+ animatorPaused = animator.pause();
+ }
+
+ disposeRegenerate=regenerate;
+
+ if (Threading.isSingleThreaded() &&
+ !Threading.isOpenGLThread()) {
+ // Workaround for termination issues with applets --
+ // sun.applet.AppletPanel should probably be performing the
+ // remove() call on the EDT rather than on its own thread
+ // Hint: User should run remove from EDT.
+ if (ThreadingImpl.isAWTMode() &&
+ Thread.holdsLock(getTreeLock())) {
+ // The user really should not be invoking remove() from this
+ // thread -- but since he/she is, we can not go over to the
+ // EDT at this point. Try to destroy the context from here.
+ if(context.isCreated()) {
+ drawableHelper.invokeGL(drawable, context, disposeAction, null);
+ }
+ } else if(context.isCreated()) {
+ Threading.invokeOnOpenGLThread(disposeOnEventDispatchThreadAction);
+ }
+ } else if(context.isCreated()) {
+ drawableHelper.invokeGL(drawable, context, disposeAction, null);
}
- } else if(context.isCreated()) {
- Threading.invokeOnOpenGLThread(disposeOnEventDispatchThreadAction);
- }
- } else if(context.isCreated()) {
- drawableHelper.invokeGL(drawable, context, disposeAction, null);
- }
- if(animatorPaused) {
- animator.resume();
+ if(animatorPaused) {
+ animator.resume();
+ }
+ }
+ if(!regenerate) {
+ disposeAbstractGraphicsDevice();
}
- }
- if(!regenerate) {
- disposeAbstractGraphicsDeviceAction.run();
- }
- if(DEBUG) {
- System.err.println("dispose("+regenerate+") - stop");
+ if(DEBUG) {
+ System.err.println("dispose("+regenerate+") - stop");
+ }
+ } finally {
+ drawableSync.unlock();
}
}
@@ -459,6 +485,8 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
}
}
+ RecursiveLock drawableSync = new RecursiveLock();
+
/** Overridden to track when this component is added to a container.
Subclasses which override this method must call
super.addNotify() in their addNotify() method in order to
@@ -472,59 +500,71 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
ex1.printStackTrace();
}
- /**
- * 'super.addNotify()' determines the GraphicsConfiguration,
- * while calling this class's overriden 'getGraphicsConfiguration()' method
- * after which it creates the native peer.
- * Hence we have to set the 'awtConfig' before since it's GraphicsConfiguration
- * is being used in getGraphicsConfiguration().
- * This code order also allows recreation, ie re-adding the GLCanvas.
- */
- awtConfig = chooseGraphicsConfiguration(capsReqUser, capsReqUser, chooser, device);
- if(null==awtConfig) {
- throw new GLException("Error: NULL AWTGraphicsConfiguration");
- }
+ drawableSync.lock();
+ try {
+ /**
+ * 'super.addNotify()' determines the GraphicsConfiguration,
+ * while calling this class's overriden 'getGraphicsConfiguration()' method
+ * after which it creates the native peer.
+ * Hence we have to set the 'awtConfig' before since it's GraphicsConfiguration
+ * is being used in getGraphicsConfiguration().
+ * This code order also allows recreation, ie re-adding the GLCanvas.
+ */
+ awtConfig = chooseGraphicsConfiguration(capsReqUser, capsReqUser, chooser, device);
+ if(null==awtConfig) {
+ throw new GLException("Error: NULL AWTGraphicsConfiguration");
+ }
- if (!Beans.isDesignTime()) {
- // no lock required, since this resource ain't available yet
- drawable = GLDrawableFactory.getFactory(capsReqUser.getGLProfile())
- .createGLDrawable(NativeWindowFactory.getNativeWindow(this, awtConfig));
- context = (GLContextImpl) drawable.createContext(shareWith);
- context.setSynchronized(true);
- }
+ if (!Beans.isDesignTime()) {
+ // no lock required, since this resource ain't available yet
+ drawable = GLDrawableFactory.getFactory(capsReqUser.getGLProfile())
+ .createGLDrawable(NativeWindowFactory.getNativeWindow(this, awtConfig));
+ context = (GLContextImpl) drawable.createContext(shareWith);
+ context.setSynchronized(true);
+ }
- // before native peer is valid: X11
- disableBackgroundErase();
+ // before native peer is valid: X11
+ disableBackgroundErase();
- // issues getGraphicsConfiguration() and creates the native peer
- super.addNotify();
+ // issues getGraphicsConfiguration() and creates the native peer
+ super.addNotify();
- // after native peer is valid: Windows
- disableBackgroundErase();
+ // after native peer is valid: Windows
+ disableBackgroundErase();
- validateGLDrawable();
+ // init drawable by paint/display makes the init sequence more equal
+ // for all launch flavors (applet/javaws/..)
+ // validateGLDrawable();
- if(DEBUG) {
- System.err.println(Thread.currentThread().getName()+" - Info: addNotify - end");
+ if(DEBUG) {
+ System.err.println(Thread.currentThread().getName()+" - Info: addNotify - end: peer: "+getPeer());
+ }
+ } finally {
+ drawableSync.unlock();
}
}
private boolean validateGLDrawable() {
boolean realized = false;
if (!Beans.isDesignTime()) {
- if ( null != drawable ) {
- realized = drawable.isRealized();
- if ( !realized && 0 < drawable.getWidth() * drawable.getHeight() ) {
- drawable.setRealized(true);
- realized = true;
- sendReshape=true; // ensure a reshape is being send ..
- if(DEBUG) {
- String msg = Thread.currentThread().getName()+" - Realized Drawable: "+drawable.toString();
- // System.err.println(msg);
- Throwable t = new Throwable(msg);
- t.printStackTrace();
+ drawableSync.lock();
+ try {
+ if ( null != drawable ) {
+ realized = drawable.isRealized();
+ if ( !realized && 0 < drawable.getWidth() * drawable.getHeight() ) {
+ drawable.setRealized(true);
+ realized = true;
+ sendReshape=true; // ensure a reshape is being send ..
+ if(DEBUG) {
+ String msg = Thread.currentThread().getName()+" - Realized Drawable: "+drawable.toString();
+ // System.err.println(msg);
+ Throwable t = new Throwable(msg);
+ t.printStackTrace();
+ }
}
}
+ } finally {
+ drawableSync.unlock();
}
}
return realized;
@@ -544,18 +584,24 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
ex1.printStackTrace();
}
+ awtWindowClosingProtocol.removeClosingListener();
+
if (Beans.isDesignTime()) {
super.removeNotify();
} else {
+ drawableSync.lock();
try {
dispose(false);
} finally {
+ context=null;
drawable=null;
+ awtConfig=null;
super.removeNotify();
+ drawableSync.unlock();
}
}
if(DEBUG) {
- System.err.println(Thread.currentThread().getName()+" - Info: removeNotify - end");
+ System.err.println(Thread.currentThread().getName()+" - Info: removeNotify - end, peer: "+getPeer());
}
}
@@ -662,15 +708,30 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
}
public NativeSurface getNativeSurface() {
- return drawable.getNativeSurface();
+ drawableSync.lock();
+ try {
+ return (null != drawable) ? drawable.getNativeSurface() : null;
+ } finally {
+ drawableSync.unlock();
+ }
}
public long getHandle() {
- return drawable.getHandle();
+ drawableSync.lock();
+ try {
+ return (null != drawable) ? drawable.getHandle() : 0;
+ } finally {
+ drawableSync.unlock();
+ }
}
public GLDrawableFactory getFactory() {
- return drawable.getFactory();
+ drawableSync.lock();
+ try {
+ return (null != drawable) ? drawable.getFactory() : null;
+ } finally {
+ drawableSync.unlock();
+ }
}
public String toString() {
@@ -703,6 +764,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
if(null!=drawable) {
drawable.setRealized(false);
+ drawable=null;
}
if(disposeRegenerate) {
@@ -743,13 +805,34 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
}
boolean closed = adevice.close();
if(DEBUG) {
- System.err.println("GLCanvas.dispose(false): closed GraphicsDevice: "+adeviceMsg+", result: "+closed);
+ System.err.println(Thread.currentThread().getName() + " - GLCanvas.dispose(false): closed GraphicsDevice: "+adeviceMsg+", result: "+closed);
}
}
+ awtConfig=null;
}
}
private DisposeAbstractGraphicsDeviceAction disposeAbstractGraphicsDeviceAction = new DisposeAbstractGraphicsDeviceAction();
+ /**
+ * Disposes the AbstractGraphicsDevice within EDT,
+ * since resources created (X11: Display), must be destroyed in the same thread, where they have been created.
+ *
+ * @see #chooseGraphicsConfiguration(javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesChooser, java.awt.GraphicsDevice)
+ */
+ void disposeAbstractGraphicsDevice() {
+ if( EventQueue.isDispatchThread() || Thread.holdsLock(getTreeLock()) ) {
+ disposeAbstractGraphicsDeviceAction.run();
+ } else {
+ try {
+ EventQueue.invokeAndWait(disposeAbstractGraphicsDeviceAction);
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (InterruptedException e) {
+ throw new GLException(e);
+ }
+ }
+ }
+
class InitAction implements Runnable {
public void run() {
drawableHelper.init(GLCanvas.this);
@@ -851,20 +934,55 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
}
}
- private static AWTGraphicsConfiguration chooseGraphicsConfiguration(GLCapabilitiesImmutable capsChosen,
- GLCapabilitiesImmutable capsRequested,
- GLCapabilitiesChooser chooser,
- GraphicsDevice device) {
+ /**
+ * Issues the GraphicsConfigurationFactory's choosing facility within EDT,
+ * since resources created (X11: Display), must be destroyed in the same thread, where they have been created.
+ *
+ * @param capsChosen
+ * @param capsRequested
+ * @param chooser
+ * @param device
+ * @return the chosen AWTGraphicsConfiguration
+ *
+ * @see #disposeAbstractGraphicsDevice()
+ */
+ private AWTGraphicsConfiguration chooseGraphicsConfiguration(final GLCapabilitiesImmutable capsChosen,
+ final GLCapabilitiesImmutable capsRequested,
+ final GLCapabilitiesChooser chooser,
+ final GraphicsDevice device) {
// Make GLCanvas behave better in NetBeans GUI builder
if (Beans.isDesignTime()) {
return null;
}
- AbstractGraphicsScreen aScreen = AWTGraphicsScreen.createScreenDevice(device, AbstractGraphicsDevice.DEFAULT_UNIT);
- AWTGraphicsConfiguration config = (AWTGraphicsConfiguration)
- GraphicsConfigurationFactory.getFactory(AWTGraphicsDevice.class).chooseGraphicsConfiguration(capsChosen,
- capsRequested,
- chooser, aScreen);
+ final AbstractGraphicsScreen aScreen = AWTGraphicsScreen.createScreenDevice(device, AbstractGraphicsDevice.DEFAULT_UNIT);
+ AWTGraphicsConfiguration config = null;
+
+ if( EventQueue.isDispatchThread() || Thread.holdsLock(getTreeLock()) ) {
+ config = (AWTGraphicsConfiguration)
+ GraphicsConfigurationFactory.getFactory(AWTGraphicsDevice.class).chooseGraphicsConfiguration(capsChosen,
+ capsRequested,
+ chooser, aScreen);
+ } else {
+ try {
+ final ArrayList bucket = new ArrayList(1);
+ EventQueue.invokeAndWait(new Runnable() {
+ public void run() {
+ AWTGraphicsConfiguration c = (AWTGraphicsConfiguration)
+ GraphicsConfigurationFactory.getFactory(AWTGraphicsDevice.class).chooseGraphicsConfiguration(capsChosen,
+ capsRequested,
+ chooser, aScreen);
+ bucket.add(c);
+ }
+ });
+ config = ( bucket.size() > 0 ) ? (AWTGraphicsConfiguration)bucket.get(0) : null ;
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (InterruptedException e) {
+ throw new GLException(e);
+ }
+ }
+
if (config == null) {
throw new GLException("Error: Couldn't fetch AWTGraphicsConfiguration");
}
@@ -881,6 +999,12 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
System.err.println(NativeWindowVersion.getInstance());
System.err.println(JoglVersion.getInstance());
+ GLDrawableFactory factory = GLDrawableFactory.getDesktopFactory();
+ List/*<GLCapabilitiesImmutable>*/ availCaps = factory.getAvailableCapabilities(null);
+ for(int i=0; i<availCaps.size(); i++) {
+ System.err.println(availCaps.get(i));
+ }
+
GLCapabilitiesImmutable caps = new GLCapabilities( GLProfile.getDefault(GLProfile.getDefaultDesktopDevice()) );
Frame frame = new Frame("JOGL AWT Test");
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
index c8bfe94d8..46c799d71 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
@@ -40,19 +40,57 @@
package javax.media.opengl.awt;
-import javax.media.opengl.*;
-import javax.media.nativewindow.*;
-
-import java.awt.*;
-import java.awt.geom.*;
-import java.awt.image.*;
-import java.beans.*;
-import java.nio.*;
-import java.security.*;
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+import java.beans.Beans;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+
+import java.awt.Color;
+import java.awt.EventQueue;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+import java.awt.Rectangle;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferByte;
+import java.awt.image.DataBufferInt;
import javax.swing.JPanel;
+
+import javax.media.nativewindow.WindowClosingProtocol;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.awt.AWTWindowClosingProtocol;
+
+import javax.media.opengl.DefaultGLCapabilitiesChooser;
+import javax.media.opengl.GL;
+import javax.media.opengl.GL2;
+import javax.media.opengl.GL2GL3;
+import javax.media.opengl.GLAnimatorControl;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesChooser;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLPbuffer;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.GLRunnable;
+import javax.media.opengl.Threading;
import com.jogamp.opengl.util.FBObject;
-import com.jogamp.opengl.impl.*;
-import com.jogamp.opengl.impl.awt.*;
+import com.jogamp.opengl.impl.Debug;
+import com.jogamp.opengl.impl.GLContextImpl;
+import com.jogamp.opengl.impl.GLDrawableFactoryImpl;
+import com.jogamp.opengl.impl.GLDrawableHelper;
+import com.jogamp.opengl.impl.GLDrawableImpl;
+import com.jogamp.opengl.impl.ThreadingImpl;
+import com.jogamp.opengl.impl.awt.Java2D;
+import com.jogamp.opengl.impl.awt.Java2DGLContext;
// FIXME: Subclasses need to call resetGLFunctionAvailability() on their
// context whenever the displayChanged() function is called on their
@@ -85,7 +123,7 @@ import com.jogamp.opengl.impl.awt.*;
* </P>
*/
-public class GLJPanel extends JPanel implements AWTGLAutoDrawable {
+public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosingProtocol {
private static final boolean DEBUG = Debug.debug("GLJPanel");
private static final boolean VERBOSE = Debug.verbose();
@@ -129,8 +167,8 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable {
!Debug.isPropertyDefined("jogl.gljpanel.noogl", true, localACC);
// For handling reshape events lazily
- private int reshapeX;
- private int reshapeY;
+ // private int reshapeX;
+ // private int reshapeY;
private int reshapeWidth;
private int reshapeHeight;
@@ -139,6 +177,13 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable {
private int viewportX;
private int viewportY;
+ private AWTWindowClosingProtocol awtWindowClosingProtocol =
+ new AWTWindowClosingProtocol(this, new Runnable() {
+ public void run() {
+ GLJPanel.this.destroy();
+ }
+ });
+
static {
// Force eager initialization of part of the Java2D class since
// otherwise it's likely it will try to be initialized while on
@@ -255,6 +300,19 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable {
drawableHelper.invokeGL(disposeDrawable, disposeContext, disposeAction, null);
}
+ if(!regenerate) {
+ AbstractGraphicsDevice adevice = disposeDrawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice();
+ String adeviceMsg=null;
+ if(DEBUG) {
+ adeviceMsg = adevice.toString();
+ }
+ // boolean closed = adevice.close();
+ boolean closed = false;
+ if (DEBUG) {
+ System.err.println("GLJPanel.dispose(false): closed GraphicsDevice: " + adeviceMsg + ", result: " + closed);
+ }
+ }
+
backend.setContext(disposeContext);
if(null==disposeContext) {
isInitialized = false;
@@ -352,6 +410,9 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable {
Exception ex1 = new Exception("Info: removeNotify - start");
ex1.printStackTrace();
}
+
+ awtWindowClosingProtocol.removeClosingListener();
+
dispose(false);
if (backend != null) {
backend.destroy();
@@ -374,8 +435,8 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable {
public void reshape(int x, int y, int width, int height) {
super.reshape(x, y, width, height);
- reshapeX = x;
- reshapeY = y;
+ // reshapeX = x;
+ // reshapeY = y;
reshapeWidth = width;
reshapeHeight = height;
handleReshape = true;
@@ -560,17 +621,16 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable {
// a different implementation -- try again
} while (backend == null);
- if(null==closingListener) {
- synchronized(closingListenerLock) {
- if(null==closingListener) {
- closingListener=GLCanvas.addClosingListener(this, new GLCanvas.DestroyMethod() {
- public void destroyMethod() { destroy(); } });
- }
- }
- }
+ awtWindowClosingProtocol.addClosingListenerOneShot();
+ }
+
+ public int getDefaultCloseOperation() {
+ return awtWindowClosingProtocol.getDefaultCloseOperation();
+ }
+
+ public int setDefaultCloseOperation(int op) {
+ return awtWindowClosingProtocol.setDefaultCloseOperation(op);
}
- private Object closingListener = null;
- private Object closingListenerLock = new Object();
private void handleReshape() {
panelWidth = reshapeWidth;
@@ -656,16 +716,6 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable {
disposeDrawable.setRealized(true);
disposeContext = (GLContextImpl) disposeDrawable.createContext(shareWith);
disposeContext.setSynchronized(true);
- } else {
- AbstractGraphicsDevice adevice = disposeDrawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice();
- String adeviceMsg=null;
- if(DEBUG) {
- adeviceMsg = adevice.toString();
- }
- boolean closed = adevice.close();
- if (DEBUG) {
- System.err.println("GLJPanel.dispose(false): closed GraphicsDevice: " + adeviceMsg + ", result: " + closed);
- }
}
}
}