summaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2014-07-27 23:23:15 +0200
committerSven Gothel <[email protected]>2014-07-27 23:23:15 +0200
commit15b9e36e80d6f62f7dfb5c45d00cd04de2007ee5 (patch)
treeee7b7e78e47ed9d2ea504b7232825b1d13a71071 /src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
parent007f120cd8d33e4231ef4d207b85ed156d1e0c82 (diff)
Bug 1035 - Allow Gamma [Brightness, Contrast] settings to be performed on display/screen of a NativeSurface
Currently GLDrawableFactoryImpl's gamma settings are performed only on the main screen. Allow passing a NativeSurface, so it's display/screen gamma values will be changed. Further, promote low-level gamma settings to GLDrawableFactory for direct usage. Change com.jogamp.opengl.util.Gamma to use a GLDrawable instead of a GL object to clarify that we use the drawable. Also add a GLAutoDrawable variant, allowing proper locking of its 'upstream-lock' to guarantee atomicity. +++ Tested manually w/ TestGearsES2NEWT on X11 and Windows using the 'g' and 'G' to modify gamma. Value is properly reset on exit.
Diffstat (limited to 'src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java')
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java186
1 files changed, 130 insertions, 56 deletions
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>();
}