diff options
author | Steve Kondik <steve@cyngn.com> | 2016-07-18 02:36:42 -0700 |
---|---|---|
committer | Steve Kondik <steve@cyngn.com> | 2016-07-20 10:07:31 -0700 |
commit | 86cae92291f728d0eca637573ecbe6e0a53ccf1a (patch) | |
tree | 577cc188e1b9fc69b006135fbb480b1848a29e1d /cm | |
parent | 25d708141814289067587e504a0bb33a76c28a78 (diff) | |
download | vendor_cmsdk-86cae92291f728d0eca637573ecbe6e0a53ccf1a.zip vendor_cmsdk-86cae92291f728d0eca637573ecbe6e0a53ccf1a.tar.gz vendor_cmsdk-86cae92291f728d0eca637573ecbe6e0a53ccf1a.tar.bz2 |
livedisplay: Add support for direct color balance control
* We currently use the DisplayColorCalibration API for setting display
temperature which makes a lot of guesses about what temperature
the display really is. Some devices will support the new ColorBalance
API (via QDCM or other mechanism), which offers a calibrated
alternative. Add support for this, which will supercede DCC if
available.
* Additionally, define the available color temperature range as a
set of overlayable values so this can be specified per-device.
This range will be mapped to balance values using the power curve
calculations in the new MathUtils class.
Change-Id: I99608c09807b747d962680293c7b0cee8d669003
Diffstat (limited to 'cm')
5 files changed, 189 insertions, 6 deletions
diff --git a/cm/lib/main/java/org/cyanogenmod/platform/internal/CMHardwareService.java b/cm/lib/main/java/org/cyanogenmod/platform/internal/CMHardwareService.java index 7e79de4..6052383 100644 --- a/cm/lib/main/java/org/cyanogenmod/platform/internal/CMHardwareService.java +++ b/cm/lib/main/java/org/cyanogenmod/platform/internal/CMHardwareService.java @@ -36,6 +36,7 @@ import java.util.Arrays; import org.cyanogenmod.hardware.AdaptiveBacklight; import org.cyanogenmod.hardware.AutoContrast; +import org.cyanogenmod.hardware.ColorBalance; import org.cyanogenmod.hardware.ColorEnhancement; import org.cyanogenmod.hardware.DisplayColorCalibration; import org.cyanogenmod.hardware.DisplayGammaCalibration; @@ -96,6 +97,11 @@ public class CMHardwareService extends CMSystemService implements ThermalUpdateC public boolean writePersistentBytes(String key, byte[] value); public byte[] readPersistentBytes(String key); + + public int getColorBalanceMin(); + public int getColorBalanceMax(); + public int getColorBalance(); + public boolean setColorBalance(int value); } private class LegacyCMHardware implements CMHardwareInterface { @@ -137,6 +143,8 @@ public class CMHardwareService extends CMSystemService implements ThermalUpdateC mSupportedFeatures |= CMHardwareManager.FEATURE_THERMAL_MONITOR; if (UniqueDeviceId.isSupported()) mSupportedFeatures |= CMHardwareManager.FEATURE_UNIQUE_DEVICE_ID; + if (ColorBalance.isSupported()) + mSupportedFeatures |= CMHardwareManager.FEATURE_COLOR_BALANCE; } public int getSupportedFeatures() { @@ -334,6 +342,22 @@ public class CMHardwareService extends CMSystemService implements ThermalUpdateC public byte[] readPersistentBytes(String key) { return PersistentStorage.get(key); } + + public int getColorBalanceMin() { + return ColorBalance.getMinValue(); + } + + public int getColorBalanceMax() { + return ColorBalance.getMaxValue(); + } + + public int getColorBalance() { + return ColorBalance.getValue(); + } + + public boolean setColorBalance(int value) { + return ColorBalance.setValue(value); + } } private CMHardwareInterface getImpl(Context context) { @@ -687,5 +711,45 @@ public class CMHardwareService extends CMSystemService implements ThermalUpdateC } return false; } + + @Override + public int getColorBalanceMin() { + mContext.enforceCallingOrSelfPermission( + cyanogenmod.platform.Manifest.permission.HARDWARE_ABSTRACTION_ACCESS, null); + if (isSupported(CMHardwareManager.FEATURE_COLOR_BALANCE)) { + return mCmHwImpl.getColorBalanceMin(); + } + return 0; + } + + @Override + public int getColorBalanceMax() { + mContext.enforceCallingOrSelfPermission( + cyanogenmod.platform.Manifest.permission.HARDWARE_ABSTRACTION_ACCESS, null); + if (isSupported(CMHardwareManager.FEATURE_COLOR_BALANCE)) { + return mCmHwImpl.getColorBalanceMax(); + } + return 0; + } + + @Override + public int getColorBalance() { + mContext.enforceCallingOrSelfPermission( + cyanogenmod.platform.Manifest.permission.HARDWARE_ABSTRACTION_ACCESS, null); + if (isSupported(CMHardwareManager.FEATURE_COLOR_BALANCE)) { + return mCmHwImpl.getColorBalance(); + } + return 0; + } + + @Override + public boolean setColorBalance(int value) { + mContext.enforceCallingOrSelfPermission( + cyanogenmod.platform.Manifest.permission.HARDWARE_ABSTRACTION_ACCESS, null); + if (isSupported(CMHardwareManager.FEATURE_COLOR_BALANCE)) { + return mCmHwImpl.setColorBalance(value); + } + return false; + } }; } diff --git a/cm/lib/main/java/org/cyanogenmod/platform/internal/display/ColorTemperatureController.java b/cm/lib/main/java/org/cyanogenmod/platform/internal/display/ColorTemperatureController.java index 3184d71..a72c3a2 100644 --- a/cm/lib/main/java/org/cyanogenmod/platform/internal/display/ColorTemperatureController.java +++ b/cm/lib/main/java/org/cyanogenmod/platform/internal/display/ColorTemperatureController.java @@ -20,18 +20,24 @@ import static cyanogenmod.hardware.LiveDisplayManager.MODE_DAY; import static cyanogenmod.hardware.LiveDisplayManager.MODE_NIGHT; import static cyanogenmod.hardware.LiveDisplayManager.MODE_OFF; +import android.animation.ValueAnimator; +import android.animation.ValueAnimator.AnimatorUpdateListener; import android.content.Context; import android.net.Uri; import android.os.Handler; import android.text.format.DateUtils; import android.util.MathUtils; +import android.util.Range; import android.util.Slog; +import android.view.animation.LinearInterpolator; import com.android.server.twilight.TwilightState; import java.io.PrintWriter; import java.util.BitSet; +import cyanogenmod.hardware.CMHardwareManager; +import cyanogenmod.hardware.LiveDisplayManager; import cyanogenmod.providers.CMSettings; import cyanogenmod.util.ColorUtils; @@ -40,6 +46,10 @@ public class ColorTemperatureController extends LiveDisplayFeature { private final DisplayHardwareController mDisplayHardware; private final boolean mUseTemperatureAdjustment; + private final boolean mUseColorBalance; + private final Range<Integer> mColorBalanceRange; + private final Range<Integer> mColorTemperatureRange; + private final double[] mColorBalanceCurve; private final int mDefaultDayTemperature; private final int mDefaultNightTemperature; @@ -48,6 +58,10 @@ public class ColorTemperatureController extends LiveDisplayFeature { private int mDayTemperature; private int mNightTemperature; + private ValueAnimator mAnimator; + + private final CMHardwareManager mHardware; + private static final long TWILIGHT_ADJUSTMENT_TIME = DateUtils.HOUR_IN_MILLIS * 1; private static final Uri DISPLAY_TEMPERATURE_DAY = @@ -59,12 +73,30 @@ public class ColorTemperatureController extends LiveDisplayFeature { Handler handler, DisplayHardwareController displayHardware) { super(context, handler); mDisplayHardware = displayHardware; - mUseTemperatureAdjustment = mDisplayHardware.hasColorAdjustment(); + mHardware = CMHardwareManager.getInstance(mContext); + + mUseColorBalance = mHardware + .isSupported(CMHardwareManager.FEATURE_COLOR_BALANCE); + mColorBalanceRange = mHardware.getColorBalanceRange(); + + mUseTemperatureAdjustment = mUseColorBalance || + mDisplayHardware.hasColorAdjustment(); mDefaultDayTemperature = mContext.getResources().getInteger( org.cyanogenmod.platform.internal.R.integer.config_dayColorTemperature); mDefaultNightTemperature = mContext.getResources().getInteger( org.cyanogenmod.platform.internal.R.integer.config_nightColorTemperature); + + mColorTemperatureRange = Range.create( + mContext.getResources().getInteger( + org.cyanogenmod.platform.internal.R.integer.config_minColorTemperature), + mContext.getResources().getInteger( + org.cyanogenmod.platform.internal.R.integer.config_maxColorTemperature)); + + mColorBalanceCurve = org.cyanogenmod.internal.util.MathUtils.powerCurve( + mColorTemperatureRange.getLower(), + mDefaultDayTemperature, + mColorTemperatureRange.getUpper()); } @Override @@ -85,6 +117,9 @@ public class ColorTemperatureController extends LiveDisplayFeature { caps.set(MODE_AUTO); caps.set(MODE_DAY); caps.set(MODE_NIGHT); + if (mUseColorBalance) { + caps.set(LiveDisplayManager.FEATURE_COLOR_BALANCE); + } } return mUseTemperatureAdjustment; } @@ -96,7 +131,11 @@ public class ColorTemperatureController extends LiveDisplayFeature { @Override protected void onScreenStateChanged() { - updateColorTemperature(); + if (mAnimator != null && mAnimator.isRunning() && !isScreenOn()) { + mAnimator.cancel(); + } else { + updateColorTemperature(); + } } @Override @@ -168,17 +207,79 @@ public class ColorTemperatureController extends LiveDisplayFeature { } } + /** + * Smoothly animate the current display color balance + */ + private synchronized void animateColorBalance(int balance) { + + // always start with the current values in the hardware + int current = mHardware.getColorBalance(); + + if (current == balance) { + return; + } + + long duration = (long)(5 * Math.abs(current - balance)); + + + if (DEBUG) { + Slog.d(TAG, "animateDisplayColor current=" + current + + " target=" + balance + " duration=" + duration); + } + + if (mAnimator != null) { + mAnimator.cancel(); + mAnimator.removeAllUpdateListeners(); + } + + mAnimator = ValueAnimator.ofInt(current, balance); + mAnimator.setDuration(duration); + mAnimator.setInterpolator(new LinearInterpolator()); + mAnimator.addUpdateListener(new AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(final ValueAnimator animation) { + synchronized (ColorTemperatureController.this) { + if (isScreenOn()) { + int value = (int) animation.getAnimatedValue(); + mHardware.setColorBalance(value); + } + } + } + }); + mAnimator.start(); + } + + /* + * Map the color temperature to a color balance value using a power curve. This assumes the + * correct configuration at the device level! + */ + private int mapColorTemperatureToBalance(int temperature) { + double z = org.cyanogenmod.internal.util.MathUtils.powerCurveToLinear(mColorBalanceCurve, temperature); + return Math.round(MathUtils.lerp((float)mColorBalanceRange.getLower(), + (float)mColorBalanceRange.getUpper(), (float)z)); + } private synchronized void setDisplayTemperature(int temperature) { + if (!mColorTemperatureRange.contains(temperature)) { + Slog.e(TAG, "Color temperature out of range: " + temperature); + return; + } + mColorTemperature = temperature; + if (mUseColorBalance) { + int balance = mapColorTemperatureToBalance(temperature); + Slog.d(TAG, "Set color balance = " + balance + " (temperature=" + temperature + ")"); + animateColorBalance(balance); + return; + } + final float[] rgb = ColorUtils.temperatureToRGB(temperature); if (mDisplayHardware.setAdditionalAdjustment(rgb)) { if (DEBUG) { Slog.d(TAG, "Adjust display temperature to " + temperature + "K"); } } - } /** @@ -257,4 +358,12 @@ public class ColorTemperatureController extends LiveDisplayFeature { void setNightColorTemperature(int temperature) { putInt(CMSettings.System.DISPLAY_TEMPERATURE_NIGHT, temperature); } + + Range<Integer> getColorTemperatureRange() { + return mColorTemperatureRange; + } + + Range<Integer> getColorBalanceRange() { + return mColorBalanceRange; + } } diff --git a/cm/lib/main/java/org/cyanogenmod/platform/internal/display/LiveDisplayService.java b/cm/lib/main/java/org/cyanogenmod/platform/internal/display/LiveDisplayService.java index db2b1a6..129983b 100644 --- a/cm/lib/main/java/org/cyanogenmod/platform/internal/display/LiveDisplayService.java +++ b/cm/lib/main/java/org/cyanogenmod/platform/internal/display/LiveDisplayService.java @@ -40,13 +40,11 @@ import android.os.IBinder; import android.os.PowerManagerInternal; import android.os.Process; import android.os.UserHandle; -import android.util.Log; import android.view.Display; import com.android.internal.util.ArrayUtils; import com.android.server.LocalServices; import com.android.server.ServiceThread; -import com.android.server.SystemService; import com.android.server.pm.UserContentObserver; import com.android.server.twilight.TwilightListener; import com.android.server.twilight.TwilightManager; @@ -188,7 +186,8 @@ public class LiveDisplayService extends CMSystemService { mConfig = new LiveDisplayConfig(capabilities, defaultMode, mCTC.getDefaultDayTemperature(), mCTC.getDefaultNightTemperature(), mOMC.getDefaultAutoOutdoorMode(), mDHC.getDefaultAutoContrast(), - mDHC.getDefaultCABC(), mDHC.getDefaultColorEnhancement()); + mDHC.getDefaultCABC(), mDHC.getDefaultColorEnhancement(), + mCTC.getColorTemperatureRange(), mCTC.getColorBalanceRange()); // listeners mDisplayManager = (DisplayManager) getContext().getSystemService( diff --git a/cm/res/res/values/config.xml b/cm/res/res/values/config.xml index f08a75f..9592bf1 100644 --- a/cm/res/res/values/config.xml +++ b/cm/res/res/values/config.xml @@ -57,6 +57,14 @@ <integer name="config_outdoorAmbientLux">9000</integer> <integer name="config_defaultLiveDisplayMode">0</integer> + <!-- These values should map to the true min and max + that the backend is capable of adjusting to. This + is more important when using the ColorBalance mode, + as the discrete adjustment is interpolated between + this range (with config_dayColorTemperature at zero) --> + <integer name="config_minColorTemperature">1000</integer> + <integer name="config_maxColorTemperature">10000</integer> + <bool name="config_defaultAutoContrast">false</bool> <bool name="config_defaultAutoOutdoorMode">true</bool> <bool name="config_defaultColorEnhancement">true</bool> diff --git a/cm/res/res/values/symbols.xml b/cm/res/res/values/symbols.xml index 0e7143c..e79570b 100644 --- a/cm/res/res/values/symbols.xml +++ b/cm/res/res/values/symbols.xml @@ -73,6 +73,9 @@ <java-symbol type="integer" name="config_nightColorTemperature" /> <java-symbol type="integer" name="config_outdoorAmbientLux" /> <java-symbol type="integer" name="config_defaultLiveDisplayMode" /> + <java-symbol type="integer" name="config_minColorTemperature" /> + <java-symbol type="integer" name="config_maxColorTemperature" /> + <java-symbol type="bool" name="config_defaultAutoContrast" /> <java-symbol type="bool" name="config_defaultAutoOutdoorMode" /> <java-symbol type="bool" name="config_defaultColorEnhancement" /> |