aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xmake/scripts/tests-win.bat4
-rw-r--r--make/scripts/tests.sh4
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/Gamma.java116
-rw-r--r--src/jogl/classes/javax/media/opengl/GLDrawableFactory.java67
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java186
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java18
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java44
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java127
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java13
9 files changed, 404 insertions, 175 deletions
diff --git a/make/scripts/tests-win.bat b/make/scripts/tests-win.bat
index 4161b534c..d4e10e889 100755
--- a/make/scripts/tests-win.bat
+++ b/make/scripts/tests-win.bat
@@ -2,12 +2,12 @@ REM scripts\java-win.bat jogamp.newt.awt.opengl.VersionApplet
REM scripts\java-win.bat com.jogamp.newt.opengl.GLWindow
REM scripts\java-win.bat javax.media.opengl.awt.GLCanvas
REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestMainVersionGLWindowNEWT %*
-scripts\java-win.bat com.jogamp.oculusvr.OVRVersion %*
+REM scripts\java-win.bat com.jogamp.oculusvr.OVRVersion %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNewtAWTWrapper %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNEWT -time 30000
REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es1.newt.TestGearsES1NEWT %*
-REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT %*
+scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT -vsync -time 4000 -x 10 -y 10 -width 100 -height 100 -screen 0
REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT -vsync -time 40000 -width 100 -height 100 -screen 0 %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.awt.TestGearsAWT -time 5000
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh
index 886d7c234..48538c2ee 100644
--- a/make/scripts/tests.sh
+++ b/make/scripts/tests.sh
@@ -399,7 +399,7 @@ function testawtswt() {
#testawt com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2GLJPanelsAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasAWT $*
#testawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestLandscapeES2NewtCanvasAWT $*
-#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $*
+testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestLandscapeES2NEWT $*
#testawtswt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasSWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestElektronenMultipliziererNEWT $*
@@ -533,7 +533,7 @@ function testawtswt() {
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.glels.TestGLContextDrawableSwitch01NEWT $*
#testnoawt com.jogamp.opengl.test.junit.jogl.acore.glels.TestGLContextDrawableSwitch10NEWT $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.glels.TestGLContextDrawableSwitch11NewtAWT $*
-testawt com.jogamp.opengl.test.junit.jogl.acore.glels.TestGLContextDrawableSwitch12AWT $*
+#testawt com.jogamp.opengl.test.junit.jogl.acore.glels.TestGLContextDrawableSwitch12AWT $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.glels.TestGLContextDrawableSwitch21Newt2AWT $*
#testawt com.jogamp.opengl.test.junit.jogl.acore.glels.TestBug722GLContextDrawableSwitchNewt2AWT $*
diff --git a/src/jogl/classes/com/jogamp/opengl/util/Gamma.java b/src/jogl/classes/com/jogamp/opengl/util/Gamma.java
index 4e44c997a..bab85e531 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/Gamma.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/Gamma.java
@@ -39,69 +39,79 @@
package com.jogamp.opengl.util;
-import javax.media.opengl.*;
-import jogamp.opengl.*;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
-/** Provides control over the primary display's gamma, brightness and
- contrast controls via the hardware gamma ramp tables. Not
- supported on all platforms or graphics hardware. <P>
-
- Thanks to the LWJGL project for illustrating how to access gamma
- control on the various platforms.
-*/
+import com.jogamp.common.util.locks.RecursiveLock;
+/**
+ * Provides convenient wrapper for {@link GLDrawableFactory} control over
+ * individual display's gamma, brightness and contrast values
+ * via the hardware gamma ramp tables.
+ * <p>
+ * Not supported on all platforms or graphics hardware.
+ * </p>
+ * <p>
+ * Thanks to the LWJGL project for illustrating how to access gamma
+ * control on the various platforms.
+ * </p>
+ */
public class Gamma {
private Gamma() {}
/**
- * Sets the gamma, brightness, and contrast of the current main
- * display. This functionality is not available on all platforms and
- * graphics hardware. Returns true if the settings were successfully
- * changed, false if not. This method may return false for some
- * values of the incoming arguments even on hardware which does
- * support the underlying functionality. <P>
- *
- * If this method returns true, the display settings will
- * automatically be reset to their original values upon JVM exit
- * (assuming the JVM does not crash); if the user wishes to change
- * the display settings back to normal ahead of time, use {@link
- * #resetDisplayGamma resetDisplayGamma}(). It is recommended to
- * call {@link #resetDisplayGamma resetDisplayGamma} before calling
- * e.g. <code>System.exit()</code> from the application rather than
- * rely on the shutdown hook functionality due to inevitable race
- * conditions and unspecified behavior during JVM teardown. <P>
- *
- * This method may be called multiple times during the application's
- * execution, but calling {@link #resetDisplayGamma
- * resetDisplayGamma} will only reset the settings to the values
- * before the first call to this method. <P>
- *
- * @param gamma The gamma value, typically > 1.0 (default values
- * vary, but typically roughly 1.0)
- * @param brightness The brightness value between -1.0 and 1.0,
- * inclusive (default values vary, but typically 0)
- * @param contrast The contrast, greater than 0.0 (default values
- * vary, but typically 1)
- * @return true if gamma settings were successfully changed, false
- * if not
- * @throws IllegalArgumentException if any of the parameters were
- * out-of-bounds
+ * Convenient wrapper for {@link GLDrawableFactory#setDisplayGamma(javax.media.nativewindow.NativeSurface, float, float, float)}.
+ * <p>
+ * Use {@link #setDisplayGamma(GLAutoDrawable, float, float, float)} in case of using an {#link GLAutoDrawable}.
+ * </p>
+ */
+ public static boolean setDisplayGamma(final GLDrawable drawable, final float gamma, final float brightness, final float contrast) throws IllegalArgumentException {
+ return GLDrawableFactory.getFactory(drawable.getGLProfile()).setDisplayGamma(drawable.getNativeSurface(), gamma, brightness, contrast);
+ }
+
+ /**
+ * Convenient wrapper for {@link GLDrawableFactory#setDisplayGamma(javax.media.nativewindow.NativeSurface, float, float, float)}
+ * locking {@link GLAutoDrawable#getUpstreamLock()} to ensure proper atomic operation.
+ */
+ public static boolean setDisplayGamma(final GLAutoDrawable drawable, final float gamma, final float brightness, final float contrast) throws IllegalArgumentException {
+ final RecursiveLock lock = drawable.getUpstreamLock();
+ lock.lock();
+ try {
+ return GLDrawableFactory.getFactory(drawable.getGLProfile()).setDisplayGamma(drawable.getNativeSurface(), gamma, brightness, contrast);
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ /**
+ * Convenient wrapper for {@link GLDrawableFactory#resetDisplayGamma(javax.media.nativewindow.NativeSurface)}.
+ * <p>
+ * Use {@link #resetDisplayGamma(GLAutoDrawable)} in case of using an {#link GLAutoDrawable}.
+ * </p>
+ */
+ public static void resetDisplayGamma(final GLDrawable drawable) {
+ GLDrawableFactory.getFactory(drawable.getGLProfile()).resetDisplayGamma(drawable.getNativeSurface());
+ }
+
+ /**
+ * Convenient wrapper for {@link GLDrawableFactory#resetDisplayGamma(javax.media.nativewindow.NativeSurface)}
+ * locking {@link GLAutoDrawable#getUpstreamLock()} to ensure proper atomic operation.
*/
- public static boolean setDisplayGamma(final GL gl, final float gamma, final float brightness, final float contrast) throws IllegalArgumentException {
- return GLDrawableFactoryImpl.getFactoryImpl(gl.getContext().getGLDrawable().getGLProfile()).setDisplayGamma(gamma, brightness, contrast);
+ public static void resetDisplayGamma(final GLAutoDrawable drawable) {
+ final RecursiveLock lock = drawable.getUpstreamLock();
+ lock.lock();
+ try {
+ GLDrawableFactory.getFactory(drawable.getGLProfile()).resetDisplayGamma(drawable.getNativeSurface());
+ } finally {
+ lock.unlock();
+ }
}
/**
- * Resets the gamma, brightness and contrast values for the primary
- * display to their original values before {@link #setDisplayGamma
- * setDisplayGamma} was called the first time. {@link
- * #setDisplayGamma setDisplayGamma} must be called before calling
- * this method or an unspecified exception will be thrown. While it
- * is not explicitly required that this method be called before
- * exiting, calling it is recommended because of the inevitable
- * unspecified behavior during JVM teardown.
+ * Convenient wrapper for {@link GLDrawableFactory#resetAllDisplayGamma()}.
*/
- public static void resetDisplayGamma(final GL gl) {
- GLDrawableFactoryImpl.getFactoryImpl(gl.getContext().getGLDrawable().getGLProfile()).resetDisplayGamma();
+ public static void resetAllDisplayGamma(final GLDrawable drawable) {
+ GLDrawableFactory.getFactory(drawable.getGLProfile()).resetAllDisplayGamma();
}
}
diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
index 82808a3cb..c11195c58 100644
--- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
+++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
@@ -222,7 +222,7 @@ public abstract class GLDrawableFactory {
System.err.println("GLDrawableFactory.shutdownAll["+(i+1)+"/"+gldfCount+"]: "+gldf.getClass().getName());
}
try {
- gldf.resetDisplayGamma();
+ gldf.resetAllDisplayGammaNoSync();
gldf.shutdownImpl();
} catch (final Throwable t) {
System.err.println("GLDrawableFactory.shutdownImpl: Caught "+t.getClass().getName()+" during factory shutdown #"+(i+1)+"/"+gldfCount+" "+gldf.getClass().getName());
@@ -259,7 +259,70 @@ public abstract class GLDrawableFactory {
protected abstract void shutdownImpl();
- public abstract void resetDisplayGamma();
+ /**
+ * Sets the gamma, brightness, and contrast of the display associated with the given <code>surface</code>.
+ * <p>
+ * This functionality is not available on all platforms and
+ * graphics hardware. Returns true if the settings were successfully
+ * changed, false if not. This method may return false for some
+ * values of the incoming arguments even on hardware which does
+ * support the underlying functionality. </p>
+ * <p>
+ * If this method returns true, the display settings will
+ * automatically be reset to their original values upon JVM exit
+ * (assuming the JVM does not crash); if the user wishes to change
+ * the display settings back to normal ahead of time,
+ * use {@link #resetDisplayGamma(NativeSurface)} or {@link #resetAllDisplayGamma()}.
+ * </p>
+ * <p>
+ * It is recommended to call {@link #resetDisplayGamma(NativeSurface)} or {@link #resetAllDisplayGamma()}
+ * before calling e.g. <code>System.exit()</code> from the application rather than
+ * rely on the shutdown hook functionality due to inevitable race
+ * conditions and unspecified behavior during JVM teardown.
+ * </p>
+ * <p>
+ * This method may be called multiple times during the application's
+ * execution, but calling {@link #resetDisplayGamma(NativeSurface)}
+ * will only reset the settings to the values
+ * before the first call to this method. </p>
+ *
+ * @param surface denominates the display device
+ * @param gamma The gamma value, typically > 1.0 (default values vary, but typically roughly 1.0)
+ * @param brightness The brightness value between -1.0 and 1.0, inclusive (default values vary, but typically 0)
+ * @param contrast The contrast, greater than 0.0 (default values vary, but typically 1)
+ *
+ * @return true if gamma settings were successfully changed, false if not
+ * @throws IllegalArgumentException if any of the parameters were out-of-bounds
+ * @see #resetDisplayGamma(NativeSurface)
+ * @see #resetAllDisplayGamma()
+ */
+ public abstract boolean setDisplayGamma(final NativeSurface surface, final float gamma, final float brightness, final float contrast) throws IllegalArgumentException;
+
+ /**
+ * Resets the gamma, brightness and contrast values of the display associated with the given <code>surface</code>
+ * to its original values before {@link #setDisplayGamma(NativeSurface, float, float, float) setDisplayGamma}
+ * was called the first time.
+ * <p>
+ * While it is not explicitly required that this method be called before
+ * exiting manually, calling it is recommended because of the inevitable
+ * unspecified behavior during JVM teardown.
+ * </p>
+ */
+ public abstract void resetDisplayGamma(final NativeSurface surface);
+
+ /**
+ * Resets the gamma, brightness and contrast values of all modified
+ * displays to their original values before {@link #setDisplayGamma(NativeSurface, float, float, float) setDisplayGamma}
+ * was called the first time.
+ * <p>
+ * While it is not explicitly required that this method be called before
+ * exiting manually, calling it is recommended because of the inevitable
+ * unspecified behavior during JVM teardown.
+ * </p>
+ */
+ public abstract void resetAllDisplayGamma();
+
+ protected abstract void resetAllDisplayGammaNoSync();
/**
* Retrieve the default <code>device</code> {@link AbstractGraphicsDevice#getConnection() connection},
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
index 0b119b50d..8d65f16d3 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
@@ -41,8 +41,14 @@
package jogamp.opengl;
import java.nio.Buffer;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.OffscreenLayerSurface;
@@ -516,64 +522,98 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
- /**
- * Sets the gamma, brightness, and contrast of the current main
- * display. Returns true if the settings were changed, false if
- * not. If this method returns true, the display settings will
- * automatically be reset upon JVM exit (assuming the JVM does not
- * crash); if the user wishes to change the display settings back to
- * normal ahead of time, use resetDisplayGamma(). Throws
- * IllegalArgumentException if any of the parameters were
- * out-of-bounds.
- *
- * @param gamma The gamma value, typically > 1.0 (default value is
- * 1.0)
- * @param brightness The brightness value between -1.0 and 1.0,
- * inclusive (default value is 0)
- * @param contrast The contrast, greater than 0.0 (default value is 1)
- * @throws IllegalArgumentException if any of the parameters were
- * out-of-bounds
- */
- public boolean setDisplayGamma(final float gamma, final float brightness, final float contrast) throws IllegalArgumentException {
+ @Override
+ public synchronized final boolean setDisplayGamma(final NativeSurface surface, final float gamma, final float brightness, final float contrast) throws IllegalArgumentException {
if ((brightness < -1.0f) || (brightness > 1.0f)) {
throw new IllegalArgumentException("Brightness must be between -1.0 and 1.0");
}
if (contrast < 0) {
throw new IllegalArgumentException("Contrast must be greater than 0.0");
}
- // FIXME: ensure gamma is > 1.0? Are smaller / negative values legal?
- final int rampLength = getGammaRampLength();
- if (rampLength == 0) {
- return false;
+ if( NativeSurface.LOCK_SURFACE_NOT_READY >= surface.lockSurface() ) {
+ return false;
+ }
+ try {
+ // FIXME: ensure gamma is > 1.0? Are smaller / negative values legal?
+ final int rampLength = getGammaRampLength(surface);
+ if (rampLength == 0) {
+ return false;
+ }
+ final float[] gammaRamp = new float[rampLength];
+ for (int i = 0; i < rampLength; i++) {
+ final float intensity = (float) i / (float) (rampLength - 1);
+ // apply gamma
+ float rampEntry = (float) java.lang.Math.pow(intensity, gamma);
+ // apply brightness
+ rampEntry += brightness;
+ // apply contrast
+ rampEntry = (rampEntry - 0.5f) * contrast + 0.5f;
+ // Clamp entry to [0, 1]
+ if (rampEntry > 1.0f)
+ rampEntry = 1.0f;
+ else if (rampEntry < 0.0f)
+ rampEntry = 0.0f;
+ gammaRamp[i] = rampEntry;
+ }
+ final AbstractGraphicsScreen screen = surface.getGraphicsConfiguration().getScreen();
+ final DeviceScreenID deviceScreenID = new DeviceScreenID(screen.getDevice().getConnection(), screen.getIndex());
+ if( null == screen2OrigGammaRamp.get(deviceScreenID) ) {
+ screen2OrigGammaRamp.put(deviceScreenID, getGammaRamp(surface)); // cache original gamma ramp once
+ if( DEBUG ) {
+ System.err.println("DisplayGamma: Stored: "+deviceScreenID);
+ dumpGammaStore();
+ }
+ }
+ return setGammaRamp(surface, gammaRamp);
+ } finally {
+ surface.unlockSurface();
}
- final float[] gammaRamp = new float[rampLength];
- for (int i = 0; i < rampLength; i++) {
- final float intensity = (float) i / (float) (rampLength - 1);
- // apply gamma
- float rampEntry = (float) java.lang.Math.pow(intensity, gamma);
- // apply brightness
- rampEntry += brightness;
- // apply contrast
- rampEntry = (rampEntry - 0.5f) * contrast + 0.5f;
- // Clamp entry to [0, 1]
- if (rampEntry > 1.0f)
- rampEntry = 1.0f;
- else if (rampEntry < 0.0f)
- rampEntry = 0.0f;
- gammaRamp[i] = rampEntry;
+ }
+
+ @Override
+ public synchronized final void resetDisplayGamma(final NativeSurface surface) {
+ if( NativeSurface.LOCK_SURFACE_NOT_READY >= surface.lockSurface() ) {
+ return;
}
- if( !needsGammaRampReset ) {
- originalGammaRamp = getGammaRamp();
- needsGammaRampReset = true;
+ try {
+ final AbstractGraphicsScreen screen = surface.getGraphicsConfiguration().getScreen();
+ final DeviceScreenID deviceScreenID = new DeviceScreenID(screen.getDevice().getConnection(), screen.getIndex());
+ final Buffer originalGammaRamp = screen2OrigGammaRamp.remove(deviceScreenID);
+ if( null != originalGammaRamp ) {
+ resetGammaRamp(surface, originalGammaRamp);
+ }
+ } finally {
+ surface.unlockSurface();
}
- return setGammaRamp(gammaRamp);
}
@Override
- public synchronized void resetDisplayGamma() {
- if( needsGammaRampReset ) {
- resetGammaRamp(originalGammaRamp);
- needsGammaRampReset = false;
+ public synchronized final void resetAllDisplayGamma() {
+ resetAllDisplayGammaNoSync();
+ }
+
+ @Override
+ protected final void resetAllDisplayGammaNoSync() {
+ if( DEBUG ) {
+ System.err.println("DisplayGamma: Reset");
+ dumpGammaStore();
+ }
+ final Set<DeviceScreenID> deviceScreenIDs = screen2OrigGammaRamp.keySet();
+ for( final Iterator<DeviceScreenID> i = deviceScreenIDs.iterator(); i.hasNext(); ) {
+ final DeviceScreenID deviceScreenID = i.next();
+ final Buffer originalGammaRamp = screen2OrigGammaRamp.remove(deviceScreenID);
+ if( null != originalGammaRamp ) {
+ resetGammaRamp(deviceScreenID, originalGammaRamp);
+ }
+ }
+ }
+ private void dumpGammaStore() {
+ final Set<DeviceScreenID> deviceScreenIDs = screen2OrigGammaRamp.keySet();
+ int count = 0;
+ for( final Iterator<DeviceScreenID> i = deviceScreenIDs.iterator(); i.hasNext(); count++) {
+ final DeviceScreenID deviceScreenID = i.next();
+ final Buffer originalGammaRamp = screen2OrigGammaRamp.get(deviceScreenID);
+ System.err.printf("%4d/%4d: %s -> %s%n", count, deviceScreenIDs.size(), deviceScreenID, originalGammaRamp);
}
}
@@ -582,30 +622,64 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
//
/** Returns the length of the computed gamma ramp for this OS and
- hardware. Returns 0 if gamma changes are not supported. */
- protected int getGammaRampLength() {
+ hardware. Returns 0 if gamma changes are not supported.
+ * @param surface TODO*/
+ protected int getGammaRampLength(final NativeSurface surface) {
return 0;
}
/** Sets the gamma ramp for the main screen. Returns false if gamma
- ramp changes were not supported. */
- protected boolean setGammaRamp(final float[] ramp) {
+ ramp changes were not supported.
+ * @param surface TODO*/
+ protected boolean setGammaRamp(final NativeSurface surface, final float[] ramp) {
return false;
}
/** Gets the current gamma ramp. This is basically an opaque value
used only on some platforms to reset the gamma ramp to its
- original settings. */
- protected Buffer getGammaRamp() {
+ original settings.
+ * @param surface TODO*/
+ protected Buffer getGammaRamp(final NativeSurface surface) {
return null;
}
/** Resets the gamma ramp, potentially using the specified Buffer as
- data to restore the original values. */
- protected void resetGammaRamp(final Buffer originalGammaRamp) {
+ data to restore the original values.
+ * @param surface TODO*/
+ protected void resetGammaRamp(final NativeSurface surface, final Buffer originalGammaRamp) {
+ }
+ protected void resetGammaRamp(final DeviceScreenID deviceScreenID, final Buffer originalGammaRamp) {
}
// Shutdown hook mechanism for resetting gamma
- private volatile Buffer originalGammaRamp;
- private volatile boolean needsGammaRampReset = false;
+ public final class DeviceScreenID {
+ public final String deviceConnection;
+ public final int screenIdx;
+ DeviceScreenID(final String deviceConnection, final int screenIdx) {
+ this.deviceConnection = deviceConnection;
+ this.screenIdx = screenIdx;
+ }
+ @Override
+ public int hashCode() {
+ // 31 * x == (x << 5) - x
+ int hash = 31 + deviceConnection.hashCode();
+ hash = ((hash << 5) - hash) + screenIdx;
+ return hash;
+ }
+ @Override
+ public boolean equals(final Object obj) {
+ if(this == obj) { return true; }
+ if (obj instanceof DeviceScreenID) {
+ final DeviceScreenID other = (DeviceScreenID)obj;
+ return this.deviceConnection.equals(other.deviceConnection) &&
+ this.screenIdx == other.screenIdx;
+ }
+ return false;
+ }
+ @Override
+ public String toString() {
+ return "DeviceScreenID[devCon "+deviceConnection+", screenIdx "+screenIdx+", hash 0x"+Integer.toHexString(hashCode())+"]";
+ }
+ }
+ private final Map<DeviceScreenID, Buffer> screen2OrigGammaRamp = new HashMap<DeviceScreenID, Buffer>();
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
index 7c05b8eab..045abca4c 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
@@ -42,6 +42,7 @@ package jogamp.opengl.macosx.cgl;
import java.nio.Buffer;
import java.nio.FloatBuffer;
+import java.nio.ShortBuffer;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -404,24 +405,29 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
/** Returns the length of the computed gamma ramp for this OS and
hardware. Returns 0 if gamma changes are not supported. */
@Override
- protected int getGammaRampLength() {
+ protected int getGammaRampLength(final NativeSurface surface) {
return GAMMA_RAMP_LENGTH;
}
@Override
- protected boolean setGammaRamp(final float[] ramp) {
+ protected boolean setGammaRamp(final NativeSurface surface, final float[] ramp) {
final FloatBuffer rampNIO = Buffers.newDirectFloatBuffer(ramp);
-
return CGL.setGammaRamp(ramp.length, rampNIO, rampNIO, rampNIO);
}
@Override
- protected Buffer getGammaRamp() {
- return null;
+ protected Buffer getGammaRamp(final NativeSurface surface) {
+ return ShortBuffer.allocate(0); // return a dummy gamma ramp default for reset
}
@Override
- protected void resetGammaRamp(final Buffer originalGammaRamp) {
+ protected void resetGammaRamp(final NativeSurface surface, final Buffer originalGammaRamp) {
CGL.resetGammaRamp();
}
+
+ @Override
+ protected final void resetGammaRamp(final DeviceScreenID deviceScreenID, final Buffer originalGammaRamp) {
+ CGL.resetGammaRamp();
+ }
+
}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
index 42e802a95..3daf6e1a8 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
@@ -559,12 +559,12 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
private static final int GAMMA_RAMP_LENGTH = 256;
@Override
- protected final int getGammaRampLength() {
+ protected final int getGammaRampLength(final NativeSurface surface) {
return GAMMA_RAMP_LENGTH;
}
@Override
- protected final boolean setGammaRamp(final float[] ramp) {
+ protected final boolean setGammaRamp(final NativeSurface surface, final float[] ramp) {
final short[] rampData = new short[3 * GAMMA_RAMP_LENGTH];
for (int i = 0; i < GAMMA_RAMP_LENGTH; i++) {
final short scaledValue = (short) (ramp[i] * 65535);
@@ -573,18 +573,26 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
rampData[i + 2 * GAMMA_RAMP_LENGTH] = scaledValue;
}
- final long screenDC = GDI.GetDC(0);
- final boolean res = GDI.SetDeviceGammaRamp(screenDC, ShortBuffer.wrap(rampData));
- GDI.ReleaseDC(0, screenDC);
+ final long hDC = surface.getSurfaceHandle();
+ if( 0 == hDC ) {
+ return false;
+ }
+ // final long screenDC = GDI.GetDC(0);
+ final boolean res = GDI.SetDeviceGammaRamp(hDC, ShortBuffer.wrap(rampData));
+ // GDI.ReleaseDC(0, screenDC);
return res;
}
@Override
- protected final Buffer getGammaRamp() {
+ protected final Buffer getGammaRamp(final NativeSurface surface) {
final ShortBuffer rampData = ShortBuffer.wrap(new short[3 * GAMMA_RAMP_LENGTH]);
- final long screenDC = GDI.GetDC(0);
- final boolean res = GDI.GetDeviceGammaRamp(screenDC, rampData);
- GDI.ReleaseDC(0, screenDC);
+ final long hDC = surface.getSurfaceHandle();
+ if( 0 == hDC ) {
+ return null;
+ }
+ // final long screenDC = GDI.GetDC(0);
+ final boolean res = GDI.GetDeviceGammaRamp(hDC, rampData);
+ // GDI.ReleaseDC(0, screenDC);
if (!res) {
return null;
}
@@ -592,7 +600,22 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
}
@Override
- protected final void resetGammaRamp(final Buffer originalGammaRamp) {
+ protected final void resetGammaRamp(final NativeSurface surface, final Buffer originalGammaRamp) {
+ if (originalGammaRamp == null) {
+ // getGammaRamp failed earlier
+ return;
+ }
+ final long hDC = surface.getSurfaceHandle();
+ if( 0 == hDC ) {
+ return;
+ }
+ // final long screenDC = GDI.GetDC(0);
+ GDI.SetDeviceGammaRamp(hDC, originalGammaRamp);
+ // GDI.ReleaseDC(0, hDC);
+ }
+
+ @Override
+ protected final void resetGammaRamp(final DeviceScreenID deviceScreenID, final Buffer originalGammaRamp) {
if (originalGammaRamp == null) {
// getGammaRamp failed earlier
return;
@@ -602,6 +625,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
GDI.ReleaseDC(0, screenDC);
}
+
static interface CPUAffinity {
boolean set(final int newAffinity);
boolean reset();
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
index fbab32963..60e4438d0 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
@@ -72,6 +72,7 @@ import jogamp.opengl.GLDynamicLookupHelper;
import jogamp.opengl.GLGraphicsConfigurationUtil;
import jogamp.opengl.SharedResourceRunner;
+import com.jogamp.common.nio.Buffers;
import com.jogamp.common.util.VersionNumber;
import com.jogamp.nativewindow.x11.X11GraphicsDevice;
import com.jogamp.nativewindow.x11.X11GraphicsScreen;
@@ -562,34 +563,34 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
private boolean gotGammaRampLength;
private int gammaRampLength;
@Override
- protected final synchronized int getGammaRampLength() {
+ protected final synchronized int getGammaRampLength(final NativeSurface surface) {
if (gotGammaRampLength) {
return gammaRampLength;
}
-
- final long display = getOrCreateSharedDpy(defaultDevice);
+ final long display = surface.getDisplayHandle();
if(0 == display) {
return 0;
}
+ final int screenIdx = surface.getScreenIndex();
final int[] size = new int[1];
- final boolean res = X11Lib.XF86VidModeGetGammaRampSize(display,
- X11Lib.DefaultScreen(display),
- size, 0);
+ final boolean res = X11Lib.XF86VidModeGetGammaRampSize(display, screenIdx, size, 0);
if (!res) {
return 0;
}
gotGammaRampLength = true;
gammaRampLength = size[0];
+ System.err.println("XXX: Gamma ramp size: "+gammaRampLength);
return gammaRampLength;
}
@Override
- protected final boolean setGammaRamp(final float[] ramp) {
- final long display = getOrCreateSharedDpy(defaultDevice);
+ protected final boolean setGammaRamp(final NativeSurface surface, final float[] ramp) {
+ final long display = surface.getDisplayHandle();
if(0 == display) {
return false;
}
+ final int screenIdx = surface.getScreenIndex();
final int len = ramp.length;
final short[] rampData = new short[len];
@@ -597,36 +598,52 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
rampData[i] = (short) (ramp[i] * 65535);
}
- final boolean res = X11Lib.XF86VidModeSetGammaRamp(display,
- X11Lib.DefaultScreen(display),
+ final boolean res = X11Lib.XF86VidModeSetGammaRamp(display, screenIdx,
rampData.length,
rampData, 0,
rampData, 0,
rampData, 0);
+ if( DEBUG ) {
+ dumpRamp("SET__", rampData.length, rampData, rampData, rampData);
+ }
return res;
}
+ private static void dumpRamp(final String prefix, final int size, final ShortBuffer r, final ShortBuffer g, final ShortBuffer b) {
+ for(int i=0; i<size; i++) {
+ if( 0 == i % 4 ) {
+ System.err.printf("%n%4d/%4d %s: ", i, size, prefix);
+ }
+ System.err.printf(" [%04X %04X %04X], ", r.get(i), g.get(i), b.get(i));
+ }
+ System.err.println();
+ }
+ private static void dumpRamp(final String prefix, final int size, final short[] r, final short[] g, final short[] b) {
+ for(int i=0; i<size; i++) {
+ if( 0 == i % 4 ) {
+ System.err.printf("%n%4d/%4d %s: ", i, size, prefix);
+ }
+ System.err.printf(" [%04X %04X %04X], ", r[i], g[i], b[i]);
+ }
+ System.err.println();
+ }
+
@Override
- protected final Buffer getGammaRamp() {
- final long display = getOrCreateSharedDpy(defaultDevice);
+ protected final Buffer getGammaRamp(final NativeSurface surface) {
+ final long display = surface.getDisplayHandle();
if(0 == display) {
return null;
}
+ final int screenIdx = surface.getScreenIndex();
+
+ final int size = getGammaRampLength(surface);
- final int size = getGammaRampLength();
- final ShortBuffer rampData = ShortBuffer.wrap(new short[3 * size]);
- rampData.position(0);
- rampData.limit(size);
- final ShortBuffer redRampData = rampData.slice();
- rampData.position(size);
- rampData.limit(2 * size);
- final ShortBuffer greenRampData = rampData.slice();
- rampData.position(2 * size);
- rampData.limit(3 * size);
- final ShortBuffer blueRampData = rampData.slice();
-
- final boolean res = X11Lib.XF86VidModeGetGammaRamp(display,
- X11Lib.DefaultScreen(display),
+ final ShortBuffer rampData = Buffers.newDirectShortBuffer(3 * size);
+ final ShortBuffer redRampData = Buffers.slice(rampData, 0 * size, size);
+ final ShortBuffer greenRampData = Buffers.slice(rampData, 1 * size, size);
+ final ShortBuffer blueRampData = Buffers.slice(rampData, 2 * size, size);
+
+ final boolean res = X11Lib.XF86VidModeGetGammaRamp(display, screenIdx,
size,
redRampData,
greenRampData,
@@ -634,40 +651,62 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
if (!res) {
return null;
}
+ if( DEBUG ) {
+ dumpRamp("GET__", size, redRampData, greenRampData, blueRampData);
+ }
return rampData;
}
@Override
- protected final void resetGammaRamp(final Buffer originalGammaRamp) {
+ protected final void resetGammaRamp(final NativeSurface surface, final Buffer originalGammaRamp) {
if (originalGammaRamp == null) {
return; // getGammaRamp failed originally
}
- final long display = getOrCreateSharedDpy(defaultDevice);
+ final long display = surface.getDisplayHandle();
if(0 == display) {
return;
}
+ final int screenIdx = surface.getScreenIndex();
+
+ resetGammaRamp(display, screenIdx, originalGammaRamp);
+ }
+
+ @Override
+ protected final void resetGammaRamp(final DeviceScreenID deviceScreenID, final Buffer originalGammaRamp) {
+ if (originalGammaRamp == null) {
+ return; // getGammaRamp failed originally
+ }
+ final long display = X11Util.openDisplay(deviceScreenID.deviceConnection);
+ if( 0 == display ) {
+ return;
+ }
+ try {
+ resetGammaRamp(display, deviceScreenID.screenIdx, originalGammaRamp);
+ } finally {
+ X11Util.closeDisplay(display);
+ }
+ }
+ private static final void resetGammaRamp(final long display, final int screenIdx, final Buffer originalGammaRamp) {
final ShortBuffer rampData = (ShortBuffer) originalGammaRamp;
final int capacity = rampData.capacity();
if ((capacity % 3) != 0) {
throw new IllegalArgumentException("Must not be the original gamma ramp");
}
final int size = capacity / 3;
- rampData.position(0);
- rampData.limit(size);
- final ShortBuffer redRampData = rampData.slice();
- rampData.position(size);
- rampData.limit(2 * size);
- final ShortBuffer greenRampData = rampData.slice();
- rampData.position(2 * size);
- rampData.limit(3 * size);
- final ShortBuffer blueRampData = rampData.slice();
-
- X11Lib.XF86VidModeSetGammaRamp(display,
- X11Lib.DefaultScreen(display),
- size,
- redRampData,
- greenRampData,
- blueRampData);
+
+ final ShortBuffer redRampData = Buffers.slice(rampData, 0 * size, size);
+ final ShortBuffer greenRampData = Buffers.slice(rampData, 1 * size, size);
+ final ShortBuffer blueRampData = Buffers.slice(rampData, 2 * size, size);
+ if( DEBUG ) {
+ dumpRamp("RESET", size, redRampData, greenRampData, blueRampData);
+ }
+
+ X11Lib.XF86VidModeSetGammaRamp(display, screenIdx,
+ size,
+ redRampData,
+ greenRampData,
+ blueRampData);
}
+
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java
index cd5e20c40..29c5aac70 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java
@@ -52,6 +52,7 @@ import com.jogamp.opengl.test.junit.util.UITestCase;
import com.jogamp.opengl.test.junit.util.QuitAdapter;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.AnimatorBase;
+import com.jogamp.opengl.util.Gamma;
import com.jogamp.opengl.util.PNGPixelRect;
import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
@@ -241,6 +242,9 @@ public class TestGearsES2NEWT extends UITestCase {
glWindow.addKeyListener(new KeyAdapter() {
int pointerIconIdx = 0;
+ float gamma = 1f;
+ float brightness = 0f;
+ float contrast = 1f;
@Override
public void keyPressed(final KeyEvent e) {
@@ -264,6 +268,15 @@ public class TestGearsES2NEWT extends UITestCase {
System.err.println("[set fullscreen post]: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getSurfaceWidth()+"x"+glWindow.getSurfaceHeight()+", f "+glWindow.isFullscreen()+", a "+glWindow.isAlwaysOnTop()+", "+glWindow.getInsets());
glWindow.setExclusiveContextThread(t);
} }.start();
+ } else if( e.getKeySymbol()== KeyEvent.VK_G ) {
+ new Thread() {
+ public void run() {
+ final float newGamma = gamma + ( e.isShiftDown() ? -0.1f : 0.1f );
+ System.err.println("[set gamma]: "+gamma+" -> "+newGamma);
+ if( Gamma.setDisplayGamma(glWindow, newGamma, brightness, contrast) ) {
+ gamma = newGamma;
+ }
+ } }.start();
} else if(e.getKeyChar()=='a') {
new Thread() {
public void run() {