aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <sgothel@jausoft.com>2012-02-20 18:03:36 +0100
committerSven Gothel <sgothel@jausoft.com>2012-02-20 18:03:36 +0100
commita4c7bf0420e369e71561d2847f2fc444ce5abafa (patch)
treeeaf13946a0ef653fc9de163a911484be10f33379
parent505525c857bc4d62815a69463e263d0c2c847ac1 (diff)
API Change [GLProfile/GLContext]: Add notion of hardware acceleration in GLProfile.get<Profile>() methods.
We need to distinguish between software and hardware accelerated OpenGL profiles to allow choosing the proper profiles [default, GL2ES1, GL2ES2, ..] on platforms where both, software and hardware implementations exist (GL, GLES2, ..). Where no preference is being requested, hardware acceleration is favored: GLProfile.getDefault() GLProfile.getGL2ES1() GLProfile.getGL2ES2() Some method signatures needed to change GLProfile: getMaxProgrammable(AbstractGraphicsDevice device) -> getMaxProgrammable(AbstractGraphicsDevice device, boolean favorHardwareRasterizer) GLProfile adds: isHardwareRasterizer() Determination whether a hardware acceleration is being used or not is extended in GLContextImpl by querying the current context's GL_RENDERER string. If the latter contains 'software' (case insensitive) it is not hardware accelerated. At least this works w/ newer Mesa3D impl, where GLX_SLOW_CONFIG is not set!
-rw-r--r--make/build-jogl.xml1
-rw-r--r--src/jogl/classes/javax/media/opengl/GLContext.java60
-rw-r--r--src/jogl/classes/javax/media/opengl/GLProfile.java220
-rw-r--r--src/jogl/classes/jogamp/opengl/GLContextImpl.java73
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java2
-rw-r--r--src/jogl/native/JoglCommon.c21
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLProfile01NEWT.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestTransformFeedbackVaryingsBug407NEWT.java2
10 files changed, 271 insertions, 114 deletions
diff --git a/make/build-jogl.xml b/make/build-jogl.xml
index 2ddd2296a..3873f3b20 100644
--- a/make/build-jogl.xml
+++ b/make/build-jogl.xml
@@ -1471,6 +1471,7 @@
<target name="c.build.jogl.prepare" depends="c.build.jogl.prepare.openMAX">
<javah destdir="${build.jogl}/gensrc/native/jogl" classpath="${javah.classpath}" class="jogamp.opengl.GLDebugMessageHandler" />
+ <javah destdir="${build.jogl}/gensrc/native/jogl" classpath="${javah.classpath}" class="jogamp.opengl.GLContextImpl" />
<!-- Generate the waveout Mixer header -->
<!-- FIXME: this is temporary until we move this to another workspace -->
<!--javah destdir="${build.jogl}/gensrc/native/jogl" classpath="${javah.classpath}" class="com.jogamp.audio.windows.waveout.Mixer" /-->
diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java
index 9e861bf52..894f44b9f 100644
--- a/src/jogl/classes/javax/media/opengl/GLContext.java
+++ b/src/jogl/classes/javax/media/opengl/GLContext.java
@@ -861,8 +861,14 @@ public abstract class GLContext {
return val;
}
- protected static Integer getAvailableGLVersion(AbstractGraphicsDevice device, int reqMajor, int profile) {
- String key = getDeviceVersionAvailableKey(device, reqMajor, profile);
+ /**
+ * @param device the device to request whether the profile is available for
+ * @param reqMajor Key Value either 1, 2, 3 or 4
+ * @param reqProfile Key Value either {@link #CTX_PROFILE_COMPAT}, {@link #CTX_PROFILE_CORE} or {@link #CTX_PROFILE_ES}
+ * @return the available GL version as encoded with {@link #composeBits(int, int, int), otherwise <code>null</code>
+ */
+ protected static Integer getAvailableGLVersion(AbstractGraphicsDevice device, int reqMajor, int reqProfile) {
+ String key = getDeviceVersionAvailableKey(device, reqMajor, reqProfile);
Integer val;
synchronized(deviceVersionAvailable) {
val = deviceVersionAvailable.get( key );
@@ -877,8 +883,8 @@ public abstract class GLContext {
* @param minor if not null, returns the used minor version
* @param ctp if not null, returns the used context profile
*/
- protected static boolean getAvailableGLVersion(AbstractGraphicsDevice device,
- int reqMajor, int reqProfile, int[] major, int minor[], int ctp[]) {
+ protected static boolean getAvailableGLVersion(AbstractGraphicsDevice device, int reqMajor, int reqProfile,
+ int[] major, int minor[], int ctp[]) {
Integer valI = getAvailableGLVersion(device, reqMajor, reqProfile);
if(null==valI) {
@@ -898,7 +904,7 @@ public abstract class GLContext {
}
return true;
}
-
+
/**
* returns the highest GLProfile string regarding the implementation version and context profile bits.
* @throws GLException if version and context profile bits could not be mapped to a GLProfile
@@ -937,39 +943,47 @@ public abstract class GLContext {
}
/**
- * @param major Key Value either 1, 2, 3 or 4
- * @param profile Key Value either {@link #CTX_PROFILE_COMPAT}, {@link #CTX_PROFILE_CORE} or {@link #CTX_PROFILE_ES}
+ * @param device the device to request whether the profile is available for
+ * @param reqMajor Key Value either 1, 2, 3 or 4
+ * @param reqProfile Key Value either {@link #CTX_PROFILE_COMPAT}, {@link #CTX_PROFILE_CORE} or {@link #CTX_PROFILE_ES}
+ * @param isHardware return value of one boolean, whether the profile is a hardware rasterizer or not
+ * @return true if the requested GL version is available regardless of a software or hardware rasterizer, otherwise false.
*/
- public static boolean isGLVersionAvailable(AbstractGraphicsDevice device, int major, int profile) {
- return null != getAvailableGLVersion(device, major, profile);
+ public static boolean isGLVersionAvailable(AbstractGraphicsDevice device, int reqMajor, int reqProfile, boolean isHardware[]) {
+ Integer valI = getAvailableGLVersion(device, reqMajor, reqProfile);
+ if(null==valI) {
+ return false;
+ }
+ isHardware[0] = 0 == ( valI.intValue() & GLContext.CTX_IMPL_ACCEL_SOFT ) ;
+ return true;
}
- public static boolean isGLES1Available(AbstractGraphicsDevice device) {
- return isGLVersionAvailable(device, 1, GLContext.CTX_PROFILE_ES);
+ public static boolean isGLES1Available(AbstractGraphicsDevice device, boolean isHardware[]) {
+ return isGLVersionAvailable(device, 1, GLContext.CTX_PROFILE_ES, isHardware);
}
- public static boolean isGLES2Available(AbstractGraphicsDevice device) {
- return isGLVersionAvailable(device, 2, GLContext.CTX_PROFILE_ES);
+ public static boolean isGLES2Available(AbstractGraphicsDevice device, boolean isHardware[]) {
+ return isGLVersionAvailable(device, 2, GLContext.CTX_PROFILE_ES, isHardware);
}
- public static boolean isGL4bcAvailable(AbstractGraphicsDevice device) {
- return isGLVersionAvailable(device, 4, CTX_PROFILE_COMPAT);
+ public static boolean isGL4bcAvailable(AbstractGraphicsDevice device, boolean isHardware[]) {
+ return isGLVersionAvailable(device, 4, CTX_PROFILE_COMPAT, isHardware);
}
- public static boolean isGL4Available(AbstractGraphicsDevice device) {
- return isGLVersionAvailable(device, 4, CTX_PROFILE_CORE);
+ public static boolean isGL4Available(AbstractGraphicsDevice device, boolean isHardware[]) {
+ return isGLVersionAvailable(device, 4, CTX_PROFILE_CORE, isHardware);
}
- public static boolean isGL3bcAvailable(AbstractGraphicsDevice device) {
- return isGLVersionAvailable(device, 3, CTX_PROFILE_COMPAT);
+ public static boolean isGL3bcAvailable(AbstractGraphicsDevice device, boolean isHardware[]) {
+ return isGLVersionAvailable(device, 3, CTX_PROFILE_COMPAT, isHardware);
}
- public static boolean isGL3Available(AbstractGraphicsDevice device) {
- return isGLVersionAvailable(device, 3, CTX_PROFILE_CORE);
+ public static boolean isGL3Available(AbstractGraphicsDevice device, boolean isHardware[]) {
+ return isGLVersionAvailable(device, 3, CTX_PROFILE_CORE, isHardware);
}
- public static boolean isGL2Available(AbstractGraphicsDevice device) {
- return isGLVersionAvailable(device, 2, CTX_PROFILE_COMPAT);
+ public static boolean isGL2Available(AbstractGraphicsDevice device, boolean isHardware[]) {
+ return isGLVersionAvailable(device, 2, CTX_PROFILE_COMPAT, isHardware);
}
/**
diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java
index 9f0093230..b32cd2962 100644
--- a/src/jogl/classes/javax/media/opengl/GLProfile.java
+++ b/src/jogl/classes/javax/media/opengl/GLProfile.java
@@ -545,6 +545,7 @@ public class GLProfile {
/** Returns a default GLProfile object, reflecting the best for the running platform.
* It selects the first of the set {@link GLProfile#GL_PROFILE_LIST_ALL}
+ * and favors hardware acceleration.
* @throws GLException if no profile is available for the device.
* @see #GL_PROFILE_LIST_ALL
*/
@@ -553,7 +554,10 @@ public class GLProfile {
return glp;
}
- /** Uses the default device
+ /** Returns a default GLProfile object, reflecting the best for the running platform.
+ * It selects the first of the set {@link GLProfile#GL_PROFILE_LIST_ALL}
+ * and favors hardware acceleration.
+ * <p>Uses the default device.</p>
* @throws GLException if no profile is available for the default device.
*/
public static GLProfile getDefault() {
@@ -567,20 +571,20 @@ public class GLProfile {
* @throws GLException if no profile is available for the device.
* @see #GL_PROFILE_LIST_MAX
*/
- public static GLProfile getMaximum(AbstractGraphicsDevice device)
+ public static GLProfile getMaximum(AbstractGraphicsDevice device, boolean favorHardwareRasterizer)
throws GLException
{
- return get(device, GL_PROFILE_LIST_MAX);
+ return get(device, GL_PROFILE_LIST_MAX, favorHardwareRasterizer);
}
/** Uses the default device
* @throws GLException if no profile is available for the default device.
* @see #GL_PROFILE_LIST_MAX
*/
- public static GLProfile getMaximum()
+ public static GLProfile getMaximum(boolean favorHardwareRasterizer)
throws GLException
{
- return get(GL_PROFILE_LIST_MAX);
+ return get(GL_PROFILE_LIST_MAX, favorHardwareRasterizer);
}
/**
@@ -590,20 +594,20 @@ public class GLProfile {
* @throws GLException if no desktop profile is available for the device.
* @see #GL_PROFILE_LIST_MIN
*/
- public static GLProfile getMinimum(AbstractGraphicsDevice device)
+ public static GLProfile getMinimum(AbstractGraphicsDevice device, boolean favorHardwareRasterizer)
throws GLException
{
- return get(device, GL_PROFILE_LIST_MIN);
+ return get(device, GL_PROFILE_LIST_MIN, favorHardwareRasterizer);
}
/** Uses the default device
* @throws GLException if no desktop profile is available for the default device.
* @see #GL_PROFILE_LIST_MIN
*/
- public static GLProfile getMinimum()
+ public static GLProfile getMinimum(boolean favorHardwareRasterizer)
throws GLException
{
- return get(GL_PROFILE_LIST_MIN);
+ return get(GL_PROFILE_LIST_MIN, favorHardwareRasterizer);
}
@@ -614,20 +618,20 @@ public class GLProfile {
* @throws GLException if no fixed function profile is available for the device.
* @see #GL_PROFILE_LIST_MAX_FIXEDFUNC
*/
- public static GLProfile getMaxFixedFunc(AbstractGraphicsDevice device)
+ public static GLProfile getMaxFixedFunc(AbstractGraphicsDevice device, boolean favorHardwareRasterizer)
throws GLException
{
- return get(device, GL_PROFILE_LIST_MAX_FIXEDFUNC);
+ return get(device, GL_PROFILE_LIST_MAX_FIXEDFUNC, favorHardwareRasterizer);
}
/** Uses the default device
* @throws GLException if no fixed function profile is available for the default device.
* @see #GL_PROFILE_LIST_MAX_FIXEDFUNC
*/
- public static GLProfile getMaxFixedFunc()
+ public static GLProfile getMaxFixedFunc(boolean favorHardwareRasterizer)
throws GLException
{
- return get(GL_PROFILE_LIST_MAX_FIXEDFUNC);
+ return get(GL_PROFILE_LIST_MAX_FIXEDFUNC, favorHardwareRasterizer);
}
/**
@@ -637,20 +641,20 @@ public class GLProfile {
* @throws GLException if no programmable profile is available for the device.
* @see #GL_PROFILE_LIST_MAX_PROGSHADER
*/
- public static GLProfile getMaxProgrammable(AbstractGraphicsDevice device)
+ public static GLProfile getMaxProgrammable(AbstractGraphicsDevice device, boolean favorHardwareRasterizer)
throws GLException
{
- return get(device, GL_PROFILE_LIST_MAX_PROGSHADER);
+ return get(device, GL_PROFILE_LIST_MAX_PROGSHADER, favorHardwareRasterizer);
}
/** Uses the default device
* @throws GLException if no programmable profile is available for the default device.
* @see #GL_PROFILE_LIST_MAX_PROGSHADER
*/
- public static GLProfile getMaxProgrammable()
+ public static GLProfile getMaxProgrammable(boolean favorHardwareRasterizer)
throws GLException
{
- return get(GL_PROFILE_LIST_MAX_PROGSHADER);
+ return get(GL_PROFILE_LIST_MAX_PROGSHADER, favorHardwareRasterizer);
}
/**
@@ -659,6 +663,7 @@ public class GLProfile {
* <pre>
* GLProfile.get(device, GLProfile.GL2ES1).getImpl());
* </pre>
+ * <p>Selection favors hardware rasterizer.</p>
*
* @throws GLException if no GL2ES1 compatible profile is available for the default device.
* @see #get(AbstractGraphicsDevice, String)
@@ -672,6 +677,7 @@ public class GLProfile {
/**
* Calls {@link #getGL2ES1(AbstractGraphicsDevice)} using the default device.
+ * <p>Selection favors hardware rasterizer.</p>
* @see #getGL2ES1(AbstractGraphicsDevice)
*/
public static GLProfile getGL2ES1()
@@ -686,6 +692,7 @@ public class GLProfile {
* <pre>
* GLProfile.get(device, GLProfile.GL2ES2).getImpl());
* </pre>
+ * <p>Selection favors hardware rasterizer.</p>
*
* @throws GLException if no GL2ES2 compatible profile is available for the default device.
* @see #get(AbstractGraphicsDevice, String)
@@ -699,6 +706,7 @@ public class GLProfile {
/**
* Calls {@link #getGL2ES2(AbstractGraphicsDevice)} using the default device.
+ * <p>Selection favors hardware rasterizer.</p>
* @see #getGL2ES2(AbstractGraphicsDevice)
*/
public static GLProfile getGL2ES2()
@@ -747,31 +755,45 @@ public class GLProfile {
* where an implementation is available.
*
* @param device a valid AbstractGraphicsDevice, or <code>null</null> for the default device.
- * @param profiles array of valid GLProfile name ({@link #GL4bc}, {@link #GL4}, {@link #GL2}, ..)
+ * @param profiles array of valid GLProfile name ({@link #GL4bc}, {@link #GL4}, {@link #GL2}, ..)
+ * @param favorHardwareRasterizer set to true, if hardware rasterizer shall be favored, otherwise false.
* @throws GLException if the non of the requested profiles is available for the device.
*/
- public static GLProfile get(AbstractGraphicsDevice device, String[] profiles)
+ public static GLProfile get(AbstractGraphicsDevice device, String[] profiles, boolean favorHardwareRasterizer)
throws GLException
{
+ GLProfile glProfileAny = null;
+
HashMap<String /*GLProfile_name*/, GLProfile> map = getProfileMap(device, true);
for(int i=0; i<profiles.length; i++) {
- String profile = profiles[i];
- GLProfile glProfile = map.get(profile);
+ final GLProfile glProfile = map.get(profiles[i]);
if(null!=glProfile) {
- return glProfile;
+ if(!favorHardwareRasterizer) {
+ return glProfile;
+ }
+ if(glProfile.isHardwareRasterizer()) {
+ return glProfile;
+ }
+ if(null==glProfileAny) {
+ glProfileAny = glProfile;
+ }
}
}
+ if(null!=glProfileAny) {
+ return glProfileAny;
+ }
throw new GLException("Profiles "+array2String(profiles)+" not available on device "+device);
}
/** Uses the default device
* @param profiles array of valid GLProfile name ({@link #GL4bc}, {@link #GL4}, {@link #GL2}, ..)
+ * @param favorHardwareRasterizer set to true, if hardware rasterizer shall be favored, otherwise false.
* @throws GLException if the non of the requested profiles is available for the default device.
*/
- public static GLProfile get(String[] profiles)
+ public static GLProfile get(String[] profiles, boolean favorHardwareRasterizer)
throws GLException
{
- return get(defaultDevice, profiles);
+ return get(defaultDevice, profiles, favorHardwareRasterizer);
}
/** Indicates whether the native OpenGL ES1 profile is in use.
@@ -886,6 +908,11 @@ public class GLProfile {
return null != profileImpl ? profileImpl : this;
}
+ /** return true if impl. is a hardware rasterizer, otherwise false. */
+ public final boolean isHardwareRasterizer() {
+ return isHardwareRasterizer;
+ }
+
/**
* return this profiles implementation name, eg. GL2ES2 -> GL2, or GL3 -> GL3
*/
@@ -1261,7 +1288,7 @@ public class GLProfile {
}
public String toString() {
- return "GLProfile[" + getName() + "/" + getImplName() + "]";
+ return "GLProfile[" + getName() + "/" + getImplName() + "."+(this.isHardwareRasterizer?"hw":"sw")+"]";
}
private static /*final*/ boolean isAWTAvailable;
@@ -1459,12 +1486,8 @@ public class GLProfile {
if (DEBUG) {
System.err.println("GLProfile.initProfilesForDevice: "+device+": desktop Shared Ctx "+desktopSharedCtxAvail);
}
- if( hasDesktopGLFactory && null == GLContext.getAvailableGLVersion(device, 2, GLContext.CTX_PROFILE_COMPAT) ) {
- // nobody yet set the available desktop versions, see {@link GLContextImpl#makeCurrent},
- // so we have to add the usual suspect
- GLContext.mapAvailableGLVersion(device,
- 2, GLContext.CTX_PROFILE_COMPAT,
- 1, 5, GLContext.CTX_PROFILE_COMPAT);
+ if( hasDesktopGLFactory && !GLContext.getAvailableGLVersionsSet(device) ) {
+ throw new InternalError("Available GLVersions not set");
}
addedDesktopProfile = computeProfileMap(device, false /* desktopCtxUndef*/, false /* esCtxUndef */);
}
@@ -1502,12 +1525,18 @@ public class GLProfile {
GLContext.mapAvailableGLVersion(device,
2, GLContext.CTX_PROFILE_ES,
2, 0, GLContext.CTX_PROFILE_ES|GLContext.CTX_IMPL_ES2_COMPAT);
+ if (DEBUG) {
+ System.err.println(GLContext.getThreadName() + ": !!! initProfilesForDeviceCritical-MapVersionsAvailable HAVE: ES2 -> ES 2.0");
+ }
}
if( hasGLES1Impl ) {
// Always favor the native ES1 impl.
GLContext.mapAvailableGLVersion(device,
1, GLContext.CTX_PROFILE_ES,
1, 0, GLContext.CTX_PROFILE_ES);
+ if (DEBUG) {
+ System.err.println(GLContext.getThreadName() + ": !!! initProfilesForDeviceCritical-MapVersionsAvailable HAVE: ES1 -> ES 1.0");
+ }
}
addedEGLProfile = computeProfileMap(device, false /* desktopCtxUndef*/, false /* esCtxUndef */);
}
@@ -1596,30 +1625,37 @@ public class GLProfile {
if (DEBUG) {
System.err.println("GLProfile.init map "+device.getConnection()+", desktopCtxUndef "+desktopCtxUndef+", esCtxUndef "+esCtxUndef);
}
- GLProfile defaultGLProfile = null;
+ final boolean isHardwareRasterizer[] = new boolean[1];
+ GLProfile defaultGLProfileAny = null;
+ GLProfile defaultGLProfileHW = null;
HashMap<String, GLProfile> _mappedProfiles = new HashMap<String, GLProfile>(GL_PROFILE_LIST_ALL.length + 1 /* default */);
for(int i=0; i<GL_PROFILE_LIST_ALL.length; i++) {
String profile = GL_PROFILE_LIST_ALL[i];
- String profileImpl = computeProfileImpl(device, profile, desktopCtxUndef, esCtxUndef);
+ String profileImpl = computeProfileImpl(device, profile, desktopCtxUndef, esCtxUndef, isHardwareRasterizer);
if(null!=profileImpl) {
final GLProfile glProfile;
if(profile.equals(profileImpl)) {
- glProfile = new GLProfile(profile, null);
+ glProfile = new GLProfile(profile, null, isHardwareRasterizer[0]);
} else {
final GLProfile _mglp = _mappedProfiles.get(profileImpl);
if(null == _mglp) {
throw new InternalError("XXX0");
}
- glProfile = new GLProfile(profile, _mglp);
+ glProfile = new GLProfile(profile, _mglp, isHardwareRasterizer[0]);
}
_mappedProfiles.put(profile, glProfile);
if (DEBUG) {
System.err.println("GLProfile.init map "+glProfile+" on devide "+device.getConnection());
}
- if(null==defaultGLProfile) {
- defaultGLProfile=glProfile;
+ if(null==defaultGLProfileHW && isHardwareRasterizer[0]) {
+ defaultGLProfileHW=glProfile;
+ if (DEBUG) {
+ System.err.println("GLProfile.init map defaultHW "+glProfile+" on device "+device.getConnection());
+ }
+ } else if(null==defaultGLProfileAny) {
+ defaultGLProfileAny=glProfile;
if (DEBUG) {
- System.err.println("GLProfile.init map default "+glProfile+" on device "+device.getConnection());
+ System.err.println("GLProfile.init map defaultAny "+glProfile+" on device "+device.getConnection());
}
}
} else {
@@ -1628,8 +1664,10 @@ public class GLProfile {
}
}
}
- if(null!=defaultGLProfile) {
- _mappedProfiles.put(GL_DEFAULT, defaultGLProfile);
+ if(null!=defaultGLProfileHW) {
+ _mappedProfiles.put(GL_DEFAULT, defaultGLProfileHW);
+ } else if(null!=defaultGLProfileAny) {
+ _mappedProfiles.put(GL_DEFAULT, defaultGLProfileAny);
}
setProfileMap(device, _mappedProfiles);
return _mappedProfiles.size() > 0;
@@ -1638,66 +1676,98 @@ public class GLProfile {
/**
* Returns the profile implementation
*/
- private static String computeProfileImpl(AbstractGraphicsDevice device, String profile, boolean desktopCtxUndef, boolean esCtxUndef) {
+ private static String computeProfileImpl(AbstractGraphicsDevice device, String profile, boolean desktopCtxUndef, boolean esCtxUndef, boolean isHardwareRasterizer[]) {
// OSX GL3.. doesn't support GLSL<150,
// hence GL2ES2 and GL2GL3 need to be mapped on GL2 on OSX for GLSL compatibility.
final boolean isOSX = Platform.OS_TYPE == Platform.OSType.MACOS;
if (GL2ES1.equals(profile)) {
+ final boolean es1HardwareRasterizer[] = new boolean[1];
+ final boolean gles1Available = hasGLES1Impl && ( esCtxUndef || GLContext.isGLES1Available(device, es1HardwareRasterizer) );
+ final boolean gles1HWAvailable = gles1Available && es1HardwareRasterizer[0] ;
if(hasGL234Impl) {
- if(GLContext.isGL4bcAvailable(device)) {
- return GL4bc;
- } else if(GLContext.isGL3bcAvailable(device)) {
- return GL3bc;
- } else if(desktopCtxUndef || GLContext.isGL2Available(device)) {
- return GL2;
+ if(GLContext.isGL4bcAvailable(device, isHardwareRasterizer)) {
+ if(!gles1HWAvailable || isHardwareRasterizer[0]) {
+ return GL4bc;
+ }
+ }
+ if(GLContext.isGL3bcAvailable(device, isHardwareRasterizer)) {
+ if(!gles1HWAvailable || isHardwareRasterizer[0]) {
+ return GL3bc;
+ }
+ }
+ if(desktopCtxUndef || GLContext.isGL2Available(device, isHardwareRasterizer)) {
+ if(!gles1HWAvailable || isHardwareRasterizer[0]) {
+ return GL2;
+ }
}
}
- if(hasGLES1Impl && ( esCtxUndef || GLContext.isGLES1Available(device))) {
+ if(gles1Available) {
+ isHardwareRasterizer[0] = es1HardwareRasterizer[0];
return GLES1;
}
} else if (GL2ES2.equals(profile)) {
+ final boolean es2HardwareRasterizer[] = new boolean[1];
+ final boolean gles2Available = hasGLES2Impl && ( esCtxUndef || GLContext.isGLES2Available(device, es2HardwareRasterizer) );
+ final boolean gles2HWAvailable = gles2Available && es2HardwareRasterizer[0] ;
if(hasGL234Impl) {
- if(!isOSX && GLContext.isGL4bcAvailable(device)) {
- return GL4bc;
- } else if(!isOSX && GLContext.isGL4Available(device)) {
- return GL4;
- } else if(!isOSX && GLContext.isGL3bcAvailable(device)) {
- return GL3bc;
- } else if(!isOSX && GLContext.isGL3Available(device)) {
- return GL3;
- } else if(desktopCtxUndef || GLContext.isGL2Available(device)) {
- return GL2;
+ if(!isOSX) {
+ if(GLContext.isGL4bcAvailable(device, isHardwareRasterizer)) {
+ if(!gles2HWAvailable || isHardwareRasterizer[0]) {
+ return GL4bc;
+ }
+ }
+ if(GLContext.isGL4Available(device, isHardwareRasterizer)) {
+ if(!gles2HWAvailable || isHardwareRasterizer[0]) {
+ return GL4;
+ }
+ }
+ if(GLContext.isGL3bcAvailable(device, isHardwareRasterizer)) {
+ if(!gles2HWAvailable || isHardwareRasterizer[0]) {
+ return GL3bc;
+ }
+ }
+ if(GLContext.isGL3Available(device, isHardwareRasterizer)) {
+ if(!gles2HWAvailable || isHardwareRasterizer[0]) {
+ return GL3;
+ }
+ }
+ }
+ if(desktopCtxUndef || GLContext.isGL2Available(device, isHardwareRasterizer)) {
+ if(!gles2HWAvailable || isHardwareRasterizer[0]) {
+ return GL2;
+ }
}
}
- if(hasGLES2Impl && ( esCtxUndef || GLContext.isGLES2Available(device))) {
+ if(gles2Available) {
+ isHardwareRasterizer[0] = es2HardwareRasterizer[0];
return GLES2;
}
} else if(GL2GL3.equals(profile)) {
if(hasGL234Impl) {
- if(!isOSX && GLContext.isGL4bcAvailable(device)) {
+ if(!isOSX && GLContext.isGL4bcAvailable(device, isHardwareRasterizer)) {
return GL4bc;
- } else if(!isOSX && GLContext.isGL4Available(device)) {
+ } else if(!isOSX && GLContext.isGL4Available(device, isHardwareRasterizer)) {
return GL4;
- } else if(!isOSX && GLContext.isGL3bcAvailable(device)) {
+ } else if(!isOSX && GLContext.isGL3bcAvailable(device, isHardwareRasterizer)) {
return GL3bc;
- } else if(!isOSX && GLContext.isGL3Available(device)) {
+ } else if(!isOSX && GLContext.isGL3Available(device, isHardwareRasterizer)) {
return GL3;
- } else if(desktopCtxUndef || GLContext.isGL2Available(device)) {
+ } else if(desktopCtxUndef || GLContext.isGL2Available(device, isHardwareRasterizer)) {
return GL2;
}
}
- } else if(GL4bc.equals(profile) && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL4bcAvailable(device))) {
+ } else if(GL4bc.equals(profile) && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL4bcAvailable(device, isHardwareRasterizer))) {
return GL4bc;
- } else if(GL4.equals(profile) && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL4Available(device))) {
+ } else if(GL4.equals(profile) && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL4Available(device, isHardwareRasterizer))) {
return GL4;
- } else if(GL3bc.equals(profile) && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL3bcAvailable(device))) {
+ } else if(GL3bc.equals(profile) && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL3bcAvailable(device, isHardwareRasterizer))) {
return GL3bc;
- } else if(GL3.equals(profile) && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL3Available(device))) {
+ } else if(GL3.equals(profile) && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL3Available(device, isHardwareRasterizer))) {
return GL3;
- } else if(GL2.equals(profile) && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL2Available(device))) {
+ } else if(GL2.equals(profile) && hasGL234Impl && ( desktopCtxUndef || GLContext.isGL2Available(device, isHardwareRasterizer))) {
return GL2;
- } else if(GLES2.equals(profile) && hasGLES2Impl && ( esCtxUndef || GLContext.isGLES2Available(device))) {
+ } else if(GLES2.equals(profile) && hasGLES2Impl && ( esCtxUndef || GLContext.isGLES2Available(device, isHardwareRasterizer))) {
return GLES2;
/**
* TODO: GLES2_TRUE_DESKTOP (see: GLContextImpl, GLProfile)
@@ -1713,7 +1783,7 @@ public class GLProfile {
return GLContext.getAvailableGLProfile(device, 2, GLContext.CTX_PROFILE_ES);
}
*/
- } else if(GLES1.equals(profile) && hasGLES1Impl && ( esCtxUndef || GLContext.isGLES1Available(device))) {
+ } else if(GLES1.equals(profile) && hasGLES1Impl && ( esCtxUndef || GLContext.isGLES1Available(device, isHardwareRasterizer))) {
return GLES1;
}
return null;
@@ -1782,11 +1852,13 @@ public class GLProfile {
}
}
- private GLProfile(String profile, GLProfile profileImpl) {
+ private GLProfile(String profile, GLProfile profileImpl, boolean isHardwareRasterizer) {
this.profile = profile;
this.profileImpl = profileImpl;
+ this.isHardwareRasterizer = isHardwareRasterizer;
}
- private GLProfile profileImpl = null;
- private String profile = null;
+ private GLProfile profileImpl;
+ private String profile;
+ private boolean isHardwareRasterizer;
}
diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
index 1924ba409..08a9baeb9 100644
--- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
@@ -514,14 +514,43 @@ public abstract class GLContextImpl extends GLContext {
}
if (DEBUG) {
if(created) {
- System.err.println(getThreadName() + ": !!! Create GL context OK: " + toHexString(contextHandle) + " for " + getClass().getName());
+ System.err.println(getThreadName() + ": !!! Create GL context OK: " + toHexString(contextHandle) + " for " + getClass().getName()+" - "+getGLVersion());
} else {
System.err.println(getThreadName() + ": !!! Create GL context FAILED for " + getClass().getName());
}
- }
+ }
if(!created) {
return CONTEXT_NOT_CURRENT;
}
+
+ // finalize mapping the available GLVersions, in case it's not done yet
+ {
+ final AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration();
+ final AbstractGraphicsDevice device = config.getScreen().getDevice();
+
+ if( !GLContext.getAvailableGLVersionsSet(device) ) {
+ final int reqMajor;
+ final int reqProfile;
+ if( 0 != ( ctxOptions & GLContext.CTX_PROFILE_ES) ) {
+ // ES1 or ES2
+ reqMajor = ctxMajorVersion;
+ reqProfile = GLContext.CTX_PROFILE_ES;
+ } else {
+ // Only GL2 actually
+ if(ctxMajorVersion>2 || 0 != ( ctxOptions & GLContext.CTX_PROFILE_CORE)) {
+ throw new InternalError("XXX: "+getGLVersion());
+ }
+ reqMajor = 2;
+ reqProfile = GLContext.CTX_PROFILE_COMPAT;
+ }
+ GLContext.mapAvailableGLVersion(device, reqMajor, reqProfile,
+ ctxMajorVersion, ctxMinorVersion, ctxOptions);
+ GLContext.setAvailableGLVersionsSet(device);
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! createContextOLD-MapVersionsAvailable HAVE: " +reqMajor+"."+reqProfile+ " -> "+getGLVersion());
+ }
+ }
+ }
GLContextShareSet.contextCreated(this);
return CONTEXT_CURRENT_NEW;
}
@@ -714,7 +743,7 @@ public abstract class GLContextImpl extends GLContext {
}
}
if(0!=_context) {
- AbstractGraphicsDevice device = drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice();
+ AbstractGraphicsDevice device = drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice();
// ctxMajorVersion, ctxMinorVersion, ctxOptions is being set by
// createContextARBVersions(..) -> setGLFunctionAvailbility(..) -> setContextVersion(..)
GLContext.mapAvailableGLVersion(device, reqMajor, reqProfile, ctxMajorVersion, ctxMinorVersion, ctxOptions);
@@ -729,10 +758,10 @@ public abstract class GLContextImpl extends GLContext {
}*/
destroyContextARBImpl(_context);
if (DEBUG) {
- System.err.println(getThreadName() + ": !!! createContextARBMapVersionsAvailable HAVE: " + getGLVersion());
+ System.err.println(getThreadName() + ": !!! createContextARB-MapVersionsAvailable HAVE: " +reqMajor+"."+reqProfile+ " -> "+getGLVersion());
}
} else if (DEBUG) {
- System.err.println(getThreadName() + ": !!! createContextARBMapVersionsAvailable NOPE: "+reqMajor+"."+reqProfile);
+ System.err.println(getThreadName() + ": !!! createContextARB-MapVersionsAvailable NOPE: "+reqMajor+"."+reqProfile);
}
resetStates();
}
@@ -951,11 +980,12 @@ public abstract class GLContextImpl extends GLContext {
}
updateGLXProcAddressTable();
- AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration();
- AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
- if(!drawable.getChosenGLCapabilities().getHardwareAccelerated()) {
+ if(!isCurrentContextHardwareRasterizer()) {
ctxProfileBits |= GLContext.CTX_IMPL_ACCEL_SOFT;
- }
+ }
+ final AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration();
+ final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
+
contextFQN = getContextFQN(adevice, major, minor, ctxProfileBits);
if (DEBUG) {
System.err.println(getThreadName() + ": !!! Context FQN: "+contextFQN+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, null));
@@ -1024,11 +1054,12 @@ public abstract class GLContextImpl extends GLContext {
}
protected final void removeCachedVersion(int major, int minor, int ctxProfileBits) {
- AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration();
- AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
- if(!drawable.getChosenGLCapabilities().getHardwareAccelerated()) {
+ if(!isCurrentContextHardwareRasterizer()) {
ctxProfileBits |= GLContext.CTX_IMPL_ACCEL_SOFT;
}
+ final AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration();
+ final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
+
contextFQN = getContextFQN(adevice, major, minor, ctxProfileBits);
if (DEBUG) {
System.err.println(getThreadName() + ": !!! RM Context FQN: "+contextFQN+" - "+GLContext.getGLVersion(major, minor, ctxProfileBits, null));
@@ -1049,6 +1080,21 @@ public abstract class GLContextImpl extends GLContext {
}
}
+ private final boolean isCurrentContextHardwareRasterizer() {
+ boolean isHardwareRasterizer = true;
+
+ if(!drawable.getChosenGLCapabilities().getHardwareAccelerated()) {
+ isHardwareRasterizer = false;
+ } else {
+ // On some platforms (eg. X11), a software GL impl. does not properly declare itself properly.
+ final GLDynamicLookupHelper glDynLookupHelper = getDrawableImpl().getGLDynamicLookupHelper();
+ final long _glGetString = glDynLookupHelper.dynamicLookupFunction("glGetString");
+ final String glRenderer = glGetStringInt(GL.GL_RENDERER, _glGetString).toLowerCase();
+ isHardwareRasterizer = !glRenderer.contains("software");
+ }
+ return isHardwareRasterizer;
+ }
+
/**
* Updates the platform's 'GLX' function cache
*/
@@ -1259,4 +1305,7 @@ public abstract class GLContextImpl extends GLContext {
gl.getGL2GL3().glDebugMessageInsertAMD(GLDebugMessage.translateARB2AMDCategory(source, type), severity, id, len, buf);
}
}
+
+ /** Internal bootstraping glGetString(GL_RENDERER) */
+ protected static native String glGetStringInt(int name, long procAddress);
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
index c412bbe1d..91d05f945 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
@@ -205,7 +205,7 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
boolean hasRECTTextures = false;
boolean hasAppleFloatPixels = false;
{
- GLProfile glp = GLProfile.get(sharedDevice, GLProfile.GL_PROFILE_LIST_MIN_DESKTOP);
+ GLProfile glp = GLProfile.get(sharedDevice, GLProfile.GL_PROFILE_LIST_MIN_DESKTOP, false);
if (null == glp) {
throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice);
}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
index f40a5f0bf..5eafebc11 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
@@ -292,7 +292,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
sharedDevice.lock();
try {
AbstractGraphicsScreen absScreen = new DefaultGraphicsScreen(sharedDevice, 0);
- GLProfile glp = GLProfile.get(sharedDevice, GLProfile.GL_PROFILE_LIST_MIN_DESKTOP);
+ GLProfile glp = GLProfile.get(sharedDevice, GLProfile.GL_PROFILE_LIST_MIN_DESKTOP, false);
if (null == glp) {
throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice);
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
index 4e8a35fa5..70e22476b 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
@@ -229,7 +229,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
}
X11GraphicsScreen sharedScreen = new X11GraphicsScreen(sharedDevice, 0);
- GLProfile glp = GLProfile.get(sharedDevice, GLProfile.GL_PROFILE_LIST_MIN_DESKTOP);
+ GLProfile glp = GLProfile.get(sharedDevice, GLProfile.GL_PROFILE_LIST_MIN_DESKTOP, false);
if (null == glp) {
throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice);
}
diff --git a/src/jogl/native/JoglCommon.c b/src/jogl/native/JoglCommon.c
index 16f60e4e7..c1d6ad181 100644
--- a/src/jogl/native/JoglCommon.c
+++ b/src/jogl/native/JoglCommon.c
@@ -1,6 +1,10 @@
+#include "jogamp_opengl_GLContextImpl.h"
#include "JoglCommon.h"
+#include <assert.h>
+#include <KHR/khrplatform.h>
+
static const char * const ClazzNameRuntimeException = "java/lang/RuntimeException";
static jclass runtimeExceptionClz=NULL;
@@ -53,3 +57,20 @@ jchar* JoglCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str)
return strChars;
}
+/*
+ * Class: jogamp_opengl_GLContextImpl
+ * Method: glGetStringInt
+ * Signature: (IJ)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL
+Java_jogamp_opengl_GLContextImpl_glGetStringInt(JNIEnv *env, jclass _unused, jint name, jlong procAddress) {
+ typedef const khronos_uint8_t * (KHRONOS_APIENTRY*_local_PFNGLGETSTRINGPROC)(unsigned int name);
+ _local_PFNGLGETSTRINGPROC ptr_glGetString;
+ const khronos_uint8_t * _res;
+ ptr_glGetString = (_local_PFNGLGETSTRINGPROC) (intptr_t) procAddress;
+ assert(ptr_glGetString != NULL);
+ _res = (* ptr_glGetString) ((unsigned int) name);
+ if (NULL == _res) return NULL;
+ return (*env)->NewStringUTF(env, _res);
+}
+
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLProfile01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLProfile01NEWT.java
index a30171f0d..2c89ec7f6 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLProfile01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLProfile01NEWT.java
@@ -87,7 +87,7 @@ public class TestGLProfile01NEWT extends UITestCase {
@Test
public void testGLProfileMaxProgrammable() throws InterruptedException {
// Assuming at least one programmable profile is available
- GLProfile glp = GLProfile.getMaxProgrammable();
+ GLProfile glp = GLProfile.getMaxProgrammable(true);
System.out.println("GLProfile.getMaxProgrammable(): "+glp);
if(glp.getName().equals(GLProfile.GL4)) {
Assert.assertTrue(GLProfile.isAvailable(GLProfile.GL4));
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestTransformFeedbackVaryingsBug407NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestTransformFeedbackVaryingsBug407NEWT.java
index 904fdc7f6..2f6025a63 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestTransformFeedbackVaryingsBug407NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestTransformFeedbackVaryingsBug407NEWT.java
@@ -83,7 +83,7 @@ public class TestTransformFeedbackVaryingsBug407NEWT extends UITestCase {
final static String glps = GLProfile.GL3;
private NEWTGLContext.WindowContext prepareTest() throws GLException, InterruptedException {
- final NEWTGLContext.WindowContext winctx = NEWTGLContext.createOnscreenWindow(GLProfile.getMaxProgrammable(), 480, 480, debugGL);
+ final NEWTGLContext.WindowContext winctx = NEWTGLContext.createOnscreenWindow(GLProfile.getMaxProgrammable(true), 480, 480, debugGL);
if(!winctx.context.getGL().isGL3()) {
System.err.println("GL3 not available");
cleanupTest(winctx);