diff options
author | Sven Gothel <[email protected]> | 2014-07-27 23:23:15 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2014-07-27 23:23:15 +0200 |
commit | 15b9e36e80d6f62f7dfb5c45d00cd04de2007ee5 (patch) | |
tree | ee7b7e78e47ed9d2ea504b7232825b1d13a71071 /src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java | |
parent | 007f120cd8d33e4231ef4d207b85ed156d1e0c82 (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.java | 186 |
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>(); } |