aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl/classes')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/GLBase.java60
-rw-r--r--src/jogl/classes/com/jogamp/opengl/GLContext.java63
-rw-r--r--src/jogl/classes/jogamp/opengl/GLContextImpl.java31
-rw-r--r--src/jogl/classes/jogamp/opengl/GLXExtensions.java6
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLContext.java16
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java13
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java45
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java77
8 files changed, 208 insertions, 103 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/GLBase.java b/src/jogl/classes/com/jogamp/opengl/GLBase.java
index dee5f1488..e0c784398 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLBase.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLBase.java
@@ -446,29 +446,43 @@ public interface GLBase {
public boolean isTextureFormatBGRA8888Available();
- /** Provides a platform-independent way to specify the minimum swap
- interval for buffer swaps. An argument of 0 disables
- sync-to-vertical-refresh completely, while an argument of 1
- causes the application to wait until the next vertical refresh
- until swapping buffers. The default, which is platform-specific,
- is usually either 0 or 1. This function is not guaranteed to
- have an effect, and in particular only affects heavyweight
- onscreen components.
-
- @see #getSwapInterval
- @throws GLException if this context is not the current
+ /**
+ * Set the swap interval of the current context and attached <i>onscreen {@link GLDrawable}</i>.
+ * <p>
+ * <i>offscreen {@link GLDrawable}</i> are ignored and {@code false} is returned.
+ * </p>
+ * <p>
+ * The {@code interval} semantics:
+ * <ul>
+ * <li><i>0</i> disables the vertical synchronization</li>
+ * <li><i>&ge;1</i> is the number of vertical refreshes before a swap buffer occurs</li>
+ * <li><i>&lt;0</i> enables <i>late swaps to occur without synchronization to the video frame</i>, a.k.a <i>EXT_swap_control_tear</i>.
+ * If supported, the absolute value is the minimum number of
+ * video frames between buffer swaps. If not supported, the absolute value is being used, see above.
+ * </li>
+ * </ul>
+ * </p>
+ * @param interval see above
+ * @return true if the operation was successful, otherwise false
+ * @throws GLException if the context is not current.
+ * @see GLContext#setSwapInterval(int)
+ * @see #getSwapInterval()
*/
- public void setSwapInterval(int interval);
-
- /** Provides a platform-independent way to get the swap
- interval set by {@link #setSwapInterval}. <br>
+ public void setSwapInterval(int interval) throws GLException;
- If the interval is not set by {@link #setSwapInterval} yet,
- -1 is returned, indicating that the platforms default
- is being used.
-
- @see #setSwapInterval
- */
+ /**
+ * Return the current swap interval.
+ * <p>
+ * If the context has not been made current at all,
+ * the default value {@code 0} is returned.
+ * </p>
+ * <p>
+ * For a valid context w/ an <o>onscreen {@link GLDrawable}</i> the default value is {@code 1},
+ * otherwise the default value is {@code 0}.
+ * </p>
+ * @see GLContext#getSwapInterval()
+ * @see #setSwapInterval(int)
+ */
public int getSwapInterval();
/**
@@ -494,12 +508,12 @@ public interface GLBase {
* for accessing it, including which class or interface contains the
* functions.
*
- * <P>
- *
+ * <p>
* Note: it is the intent to add new extensions as quickly as possible
* to the core GL API. Therefore it is unlikely that most vendors will
* use this extension mechanism, but it is being provided for
* completeness.
+ * </p>
*/
public Object getExtension(String extensionName);
diff --git a/src/jogl/classes/com/jogamp/opengl/GLContext.java b/src/jogl/classes/com/jogamp/opengl/GLContext.java
index f68c029df..3ac5df7d4 100644
--- a/src/jogl/classes/com/jogamp/opengl/GLContext.java
+++ b/src/jogl/classes/com/jogamp/opengl/GLContext.java
@@ -237,7 +237,6 @@ public abstract class GLContext {
protected String ctxVersionString;
protected VersionNumberString ctxVendorVersion;
protected VersionNumber ctxGLSLVersion;
- private int currentSwapInterval;
protected GLRendererQuirks glRendererQuirks;
/** Did the drawable association changed ? see {@link GLRendererQuirks#NoSetSwapIntervalPostRetarget} */
@@ -258,7 +257,6 @@ public abstract class GLContext {
ctxGLSLVersion = VersionNumber.zeroVersion;
attachedObjects.clear();
contextHandle=0;
- currentSwapInterval = -1;
glRendererQuirks = null;
drawableRetargeted = false;
}
@@ -1246,50 +1244,41 @@ public abstract class GLContext {
}
/**
- * Set the swap interval of the current context and attached drawable.
- * @param interval Should be &ge; 0. 0 disables the vertical synchronization,
- * where &ge; 1 is the number of vertical refreshes before a swap buffer occurs.
- * A value &lt; 0 is ignored.
+ * Set the swap interval of the current context and attached <i>onscreen {@link GLDrawable}</i>.
+ * <p>
+ * <i>offscreen {@link GLDrawable}</i> are ignored and {@code false} is returned.
+ * </p>
+ * <p>
+ * The {@code interval} semantics:
+ * <ul>
+ * <li><i>0</i> disables the vertical synchronization</li>
+ * <li><i>&ge;1</i> is the number of vertical refreshes before a swap buffer occurs</li>
+ * <li><i>&lt;0</i> enables <i>late swaps to occur without synchronization to the video frame</i>, a.k.a <i>EXT_swap_control_tear</i>.
+ * If supported, the absolute value is the minimum number of
+ * video frames between buffer swaps. If not supported, the absolute value is being used, see above.
+ * </li>
+ * </ul>
+ * </p>
+ * @param interval see above
* @return true if the operation was successful, otherwise false
- *
* @throws GLException if the context is not current.
+ * @see #getSwapInterval()
*/
- public final boolean setSwapInterval(final int interval) throws GLException {
- validateCurrent();
- if(0<=interval) {
- if( !drawableRetargeted || !hasRendererQuirk(GLRendererQuirks.NoSetSwapIntervalPostRetarget) ) {
- if( setSwapIntervalImpl(interval) ) {
- currentSwapInterval = interval;
- return true;
- }
- }
- }
- return false;
- }
- protected boolean setSwapIntervalImpl(final int interval) {
- return false;
- }
- /** Return the current swap interval.
+ public abstract boolean setSwapInterval(final int interval) throws GLException;
+
+ /**
+ * Return the current swap interval.
* <p>
* If the context has not been made current at all,
- * the default value <code>-1</code> is returned.
+ * the default value {@code 0} is returned.
* </p>
* <p>
- * For a valid context the default value is <code>1</code>
- * in case of an EGL based profile (ES1 or ES2) and <code>-1</code>
- * (undefined) for desktop.
+ * For a valid context w/ an <o>onscreen {@link GLDrawable}</i> the default value is {@code 1},
+ * otherwise the default value is {@code 0}.
* </p>
+ * @see #setSwapInterval(int)
*/
- public final int getSwapInterval() {
- return currentSwapInterval;
- }
- protected final void setDefaultSwapInterval() {
- if(this.isGLES()) {
- currentSwapInterval = 1;
- } else {
- currentSwapInterval = -1;
- }
- }
+ public abstract int getSwapInterval();
public final boolean queryMaxSwapGroups(final int[] maxGroups, final int maxGroups_offset,
final int[] maxBarriers, final int maxBarriers_offset) {
diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
index fa7aeaff8..39c5796f3 100644
--- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
@@ -131,6 +131,8 @@ public abstract class GLContextImpl extends GLContext {
private boolean pixelDataEvaluated;
private int /* pixelDataInternalFormat, */ pixelDataFormat, pixelDataType;
+ private int currentSwapInterval;
+
protected GL gl;
protected static final Object mappedContextTypeObjectLock;
@@ -209,6 +211,7 @@ public abstract class GLContextImpl extends GLContext {
surfacelessOK = false;
pixelDataEvaluated = false;
+ currentSwapInterval = 0;
super.resetStates(isInit);
}
@@ -1110,6 +1113,34 @@ public abstract class GLContextImpl extends GLContext {
}
}
+ @Override
+ public final boolean setSwapInterval(final int interval) throws GLException {
+ validateCurrent();
+ return setSwapIntervalNC(interval);
+ }
+ protected final boolean setSwapIntervalNC(final int interval) throws GLException {
+ if( drawable.getChosenGLCapabilities().isOnscreen() &&
+ ( !drawableRetargeted || !hasRendererQuirk(GLRendererQuirks.NoSetSwapIntervalPostRetarget) )
+ )
+ {
+ final Integer usedInterval = setSwapIntervalImpl(interval);
+ if( null != usedInterval ) {
+ currentSwapInterval = usedInterval.intValue();
+ return true;
+ }
+ }
+ return false;
+ }
+ protected abstract Integer setSwapIntervalImpl(final int interval);
+
+ public final int getSwapInterval() {
+ return currentSwapInterval;
+ }
+ protected final void setDefaultSwapInterval() {
+ currentSwapInterval = 0;
+ setSwapIntervalNC(1);
+ }
+
/**
* Note: Since context creation is temporary, caller need to issue {@link #resetStates(boolean)}, if creation was successful, i.e. returns true.
* This method does not reset the states, allowing the caller to utilize the state variables.
diff --git a/src/jogl/classes/jogamp/opengl/GLXExtensions.java b/src/jogl/classes/jogamp/opengl/GLXExtensions.java
index 9325c6f68..db4757e4d 100644
--- a/src/jogl/classes/jogamp/opengl/GLXExtensions.java
+++ b/src/jogl/classes/jogamp/opengl/GLXExtensions.java
@@ -34,4 +34,10 @@ public class GLXExtensions {
public static final String GLX_MESA_swap_control = "GLX_MESA_swap_control";
public static final String GLX_SGI_swap_control = "GLX_SGI_swap_control";
public static final String GLX_NV_swap_group = "GLX_NV_swap_group";
+
+ public static final String GLX_EXT_swap_control = "GLX_EXT_swap_control";
+ public static final String GLX_EXT_swap_control_tear = "GLX_EXT_swap_control_tear";
+
+ public static final String WGL_EXT_swap_control = "WGL_EXT_swap_control";
+ public static final String WGL_EXT_swap_control_tear = "WGL_EXT_swap_control_tear";
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
index b6a05aeeb..b64bb375a 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
@@ -51,7 +51,6 @@ import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableImpl;
import jogamp.opengl.egl.EGLExtImpl;
import jogamp.opengl.egl.EGLExtProcAddressTable;
-import jogamp.opengl.windows.wgl.WindowsWGLContext;
import com.jogamp.common.ExceptionUtils;
import com.jogamp.common.nio.Buffers;
@@ -432,11 +431,20 @@ public class EGLContext extends GLContextImpl {
}
@Override
- protected boolean setSwapIntervalImpl(final int interval) {
+ protected final Integer setSwapIntervalImpl(final int interval) {
if( hasRendererQuirk(GLRendererQuirks.NoSetSwapInterval) ) {
- return false;
+ return null;
}
- return EGL.eglSwapInterval(drawable.getNativeSurface().getDisplayHandle(), interval);
+ final int useInterval;
+ if( 0 > interval ) {
+ useInterval = Math.abs(interval);
+ } else {
+ useInterval = interval;
+ }
+ if( EGL.eglSwapInterval(drawable.getNativeSurface().getDisplayHandle(), useInterval) ) {
+ return Integer.valueOf(useInterval);
+ }
+ return null;
}
static long eglGetProcAddress(final long eglGetProcAddressHandle, final String procname)
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
index d4fc0b005..2f88e7619 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
@@ -423,8 +423,17 @@ public class MacOSXCGLContext extends GLContextImpl
}
@Override
- protected boolean setSwapIntervalImpl(final int interval) {
- return impl.setSwapInterval(interval);
+ protected final Integer setSwapIntervalImpl(final int interval) {
+ final int useInterval;
+ if( 0 > interval ) {
+ useInterval = Math.abs(interval);
+ } else {
+ useInterval = interval;
+ }
+ if( impl.setSwapInterval(useInterval) ) {
+ return Integer.valueOf(useInterval);
+ }
+ return null;
}
@Override
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
index a8269ad5c..6ff8c57c8 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
@@ -50,6 +50,7 @@ import com.jogamp.nativewindow.NativeSurface;
import com.jogamp.opengl.GLContext;
import com.jogamp.opengl.GLException;
import com.jogamp.opengl.GLCapabilitiesImmutable;
+import com.jogamp.common.ExceptionUtils;
import com.jogamp.common.nio.Buffers;
import com.jogamp.gluegen.runtime.ProcAddressTable;
import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
@@ -59,6 +60,7 @@ import com.jogamp.opengl.GLRendererQuirks;
import jogamp.nativewindow.windows.GDI;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableImpl;
+import jogamp.opengl.GLXExtensions;
public class WindowsWGLContext extends GLContextImpl {
static final Map<String, String> extensionNameMap;
@@ -70,7 +72,8 @@ public class WindowsWGLContext extends GLContextImpl {
// Table that holds the addresses of the native C-language entry points for
// WGL extension functions.
private WGLExtProcAddressTable wglExtProcAddressTable;
- private int hasSwapIntervalSGI = 0;
+ /** 2 WGL_EXT_swap_control_tear, 1 WGL_EXT_swap_control, 0 undefined, -1 none */
+ private int hasSwapInterval = 0;
private int hasSwapGroupNV = 0;
static {
@@ -93,7 +96,7 @@ public class WindowsWGLContext extends GLContextImpl {
wglGLReadDrawableAvailable=false;
// no inner state _wglExt=null;
wglExtProcAddressTable=null;
- hasSwapIntervalSGI = 0;
+ hasSwapInterval = 0;
hasSwapGroupNV = 0;
super.resetStates(isInit);
}
@@ -487,19 +490,39 @@ public class WindowsWGLContext extends GLContextImpl {
}
@Override
- protected boolean setSwapIntervalImpl(final int interval) {
- final WGLExt wglExt = getWGLExt();
- if(0==hasSwapIntervalSGI) {
+ protected final Integer setSwapIntervalImpl(final int interval) {
+ if( 0 == hasSwapInterval ) {
try {
- hasSwapIntervalSGI = wglExt.isExtensionAvailable("WGL_EXT_swap_control")?1:-1;
- } catch (final Throwable t) { hasSwapIntervalSGI=1; }
+ if ( isExtensionAvailable(GLXExtensions.WGL_EXT_swap_control) ) {
+ hasSwapInterval = 1;
+ if ( isExtensionAvailable(GLXExtensions.WGL_EXT_swap_control_tear) ) {
+ hasSwapInterval = 2;
+ if(DEBUG) { System.err.println("WGLContext.setSwapInterval.2 using: "+GLXExtensions.WGL_EXT_swap_control_tear + ", " + GLXExtensions.WGL_EXT_swap_control_tear); }
+ } else {
+ hasSwapInterval = 1;
+ if(DEBUG) { System.err.println("WGLContext.setSwapInterval.1 using: "+GLXExtensions.WGL_EXT_swap_control); }
+ }
+ } else {
+ hasSwapInterval = -1;
+ if(DEBUG) { System.err.println("WGLContext.setSwapInterval.0 N/A"); }
+ }
+ } catch (final Throwable t) { hasSwapInterval=-1; if(DEBUG) { ExceptionUtils.dumpThrowable("", t); } }
}
- if (hasSwapIntervalSGI>0) {
+ if ( 0 < hasSwapInterval ) { // 2 || 1
+ final int useInterval;
+ if( 1 == hasSwapInterval && 0 > interval ) {
+ useInterval = Math.abs(interval);
+ } else {
+ useInterval = interval;
+ }
try {
- return wglExt.wglSwapIntervalEXT(interval);
- } catch (final Throwable t) { hasSwapIntervalSGI=-1; }
+ final WGLExt wglExt = getWGLExt();
+ if( wglExt.wglSwapIntervalEXT(useInterval) ) {
+ return Integer.valueOf(useInterval);
+ }
+ } catch (final Throwable t) { hasSwapInterval=-1; if(DEBUG) { ExceptionUtils.dumpThrowable("", t); } }
}
- return false;
+ return null;
}
private final int initSwapGroupImpl(final WGLExt wglExt) {
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
index 63b0b35c0..3f856e4f8 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
@@ -72,7 +72,7 @@ public class X11GLXContext extends GLContextImpl {
// Table that holds the addresses of the native C-language entry points for
// GLX extension functions.
private GLXExtProcAddressTable glXExtProcAddressTable;
- /** 1 MESA, 2 SGI, 0 undefined, -1 none */
+ /** 3 SGI, 2 GLX_EXT_swap_control_tear, 1 GLX_EXT_swap_control, 0 undefined, -1 none */
private int hasSwapInterval = 0;
private int hasSwapGroupNV = 0;
@@ -549,39 +549,64 @@ public class X11GLXContext extends GLContextImpl {
}
@Override
- protected boolean setSwapIntervalImpl(final int interval) {
- if( !drawable.getChosenGLCapabilities().isOnscreen() ) { return false; }
-
- final GLXExt glXExt = getGLXExt();
- if(0==hasSwapInterval) {
+ protected final Integer setSwapIntervalImpl(final int interval) {
+ final long displayHandle = drawable.getNativeSurface().getDisplayHandle();
+ if( 0 == hasSwapInterval ) {
try {
- /** Same impl. ..
- if( glXExt.isExtensionAvailable(GLXExtensions.GLX_MESA_swap_control) ) {
- if(DEBUG) { System.err.println("X11GLXContext.setSwapInterval using: "+GLXExtensions.GLX_MESA_swap_control); }
- hasSwapInterval = 1;
- } else */
- if ( glXExt.isExtensionAvailable(GLXExtensions.GLX_SGI_swap_control) ) {
- if(DEBUG) { System.err.println("X11GLXContext.setSwapInterval using: "+GLXExtensions.GLX_SGI_swap_control); }
- hasSwapInterval = 2;
+ if ( isExtensionAvailable(GLXExtensions.GLX_EXT_swap_control) ) {
+ hasSwapInterval = 1;
+ if ( isExtensionAvailable(GLXExtensions.GLX_EXT_swap_control_tear) ) {
+ try {
+ final IntBuffer val = Buffers.newDirectIntBuffer(1);
+ GLX.glXQueryDrawable(displayHandle, drawable.getHandle(), GLX.GLX_LATE_SWAPS_TEAR_EXT, val);
+ if( 1 == val.get(0) ) {
+ hasSwapInterval = 2;
+ if(DEBUG) { System.err.println("X11GLXContext.setSwapInterval.2 using: "+GLXExtensions.GLX_EXT_swap_control_tear + ", " + GLXExtensions.GLX_EXT_swap_control_tear); }
+ } else if(DEBUG) {
+ System.err.println("X11GLXContext.setSwapInterval.2 n/a: "+GLXExtensions.GLX_EXT_swap_control_tear+", query: "+val.get(0));
+ }
+ } catch (final Throwable t) { if(DEBUG) { ExceptionUtils.dumpThrowable("", t); } }
+ }
+ if(DEBUG) {
+ if( 1 == hasSwapInterval ) {
+ System.err.println("X11GLXContext.setSwapInterval.1 using: "+GLXExtensions.GLX_EXT_swap_control);
+ }
+ }
+ } else if ( isExtensionAvailable(GLXExtensions.GLX_SGI_swap_control) ) {
+ hasSwapInterval = 3;
+ if(DEBUG) { System.err.println("X11GLXContext.setSwapInterval.3 using: "+GLXExtensions.GLX_SGI_swap_control); }
} else {
hasSwapInterval = -1;
+ if(DEBUG) { System.err.println("X11GLXContext.setSwapInterval.0 N/A"); }
}
- } catch (final Throwable t) { hasSwapInterval=-1; }
+ } catch (final Throwable t) { hasSwapInterval=-1; if(DEBUG) { ExceptionUtils.dumpThrowable("", t); } }
}
- /* try {
- switch( hasSwapInterval ) {
- case 1:
- return 0 == glXExt.glXSwapIntervalMESA(interval);
- case 2:
- return 0 == glXExt.glXSwapIntervalSGI(interval);
+ if (3 == hasSwapInterval) {
+ final int useInterval;
+ if( 0 > interval ) {
+ useInterval = Math.abs(interval);
+ } else {
+ useInterval = interval;
+ }
+ try {
+ final GLXExt glXExt = getGLXExt();
+ if( 0 == glXExt.glXSwapIntervalSGI(useInterval) ) {
+ return Integer.valueOf(useInterval);
+ }
+ } catch (final Throwable t) { hasSwapInterval=-1; if(DEBUG) { ExceptionUtils.dumpThrowable("", t); } }
+ } else if ( 0 < hasSwapInterval ) { // 2 || 1
+ final int useInterval;
+ if( 1 == hasSwapInterval && 0 > interval ) {
+ useInterval = Math.abs(interval);
+ } else {
+ useInterval = interval;
}
- } catch (Throwable t) { hasSwapInterval = -1; } */
- if (2 == hasSwapInterval) {
try {
- return 0 == glXExt.glXSwapIntervalSGI(interval);
- } catch (final Throwable t) { hasSwapInterval=-1; }
+ GLX.glXSwapIntervalEXT(displayHandle, drawable.getHandle(), useInterval);
+ return Integer.valueOf(useInterval);
+ } catch (final Throwable t) { hasSwapInterval=-1; if(DEBUG) { ExceptionUtils.dumpThrowable("", t); } }
}
- return false;
+ return null;
}
private final int initSwapGroupImpl(final GLXExt glXExt) {