diff options
| -rw-r--r-- | services/core/java/com/android/server/display/RampAnimator.java | 35 | ||||
| -rw-r--r-- | services/tests/displayservicetests/src/com/android/server/display/RampAnimatorTest.java | 62 |
2 files changed, 85 insertions, 12 deletions
diff --git a/services/core/java/com/android/server/display/RampAnimator.java b/services/core/java/com/android/server/display/RampAnimator.java index 52b92c4c7ca6..378cdba09520 100644 --- a/services/core/java/com/android/server/display/RampAnimator.java +++ b/services/core/java/com/android/server/display/RampAnimator.java @@ -31,7 +31,12 @@ class RampAnimator<T> { private final FloatProperty<T> mProperty; private float mCurrentValue; - private float mTargetValue; + + // target in HLG space + private float mTargetHlgValue; + + // target in linear space + private float mTargetLinearValue; private float mRate; private float mAnimationIncreaseMaxTimeSecs; private float mAnimationDecreaseMaxTimeSecs; @@ -78,7 +83,8 @@ class RampAnimator<T> { if (mFirstTime || target != mCurrentValue) { mFirstTime = false; mRate = 0; - mTargetValue = target; + mTargetHlgValue = target; + mTargetLinearValue = targetLinear; mCurrentValue = target; setPropertyValue(target); mAnimating = false; @@ -105,13 +111,14 @@ class RampAnimator<T> { // Otherwise, continue at the previous rate. if (!mAnimating || rate > mRate - || (target <= mCurrentValue && mCurrentValue <= mTargetValue) - || (mTargetValue <= mCurrentValue && mCurrentValue <= target)) { + || (target <= mCurrentValue && mCurrentValue <= mTargetHlgValue) + || (mTargetHlgValue <= mCurrentValue && mCurrentValue <= target)) { mRate = rate; } - final boolean changed = (mTargetValue != target); - mTargetValue = target; + final boolean changed = (mTargetHlgValue != target); + mTargetHlgValue = target; + mTargetLinearValue = targetLinear; // Start animating. if (!mAnimating && target != mCurrentValue) { @@ -135,7 +142,11 @@ class RampAnimator<T> { * into linear space. */ private void setPropertyValue(float val) { - final float linearVal = BrightnessUtils.convertGammaToLinear(val); + // To avoid linearVal inconsistency when converting to HLG and back to linear space + // used original target linear value for final animation step + float linearVal = + val == mTargetHlgValue ? mTargetLinearValue : BrightnessUtils.convertGammaToLinear( + val); mProperty.setValue(mObject, linearVal); } @@ -150,13 +161,13 @@ class RampAnimator<T> { final float scale = ValueAnimator.getDurationScale(); if (scale == 0) { // Animation off. - mAnimatedValue = mTargetValue; + mAnimatedValue = mTargetHlgValue; } else { final float amount = timeDelta * mRate / scale; - if (mTargetValue > mCurrentValue) { - mAnimatedValue = Math.min(mAnimatedValue + amount, mTargetValue); + if (mTargetHlgValue > mCurrentValue) { + mAnimatedValue = Math.min(mAnimatedValue + amount, mTargetHlgValue); } else { - mAnimatedValue = Math.max(mAnimatedValue - amount, mTargetValue); + mAnimatedValue = Math.max(mAnimatedValue - amount, mTargetHlgValue); } } final float oldCurrentValue = mCurrentValue; @@ -164,7 +175,7 @@ class RampAnimator<T> { if (oldCurrentValue != mCurrentValue) { setPropertyValue(mCurrentValue); } - if (mTargetValue == mCurrentValue) { + if (mTargetHlgValue == mCurrentValue) { mAnimating = false; } } diff --git a/services/tests/displayservicetests/src/com/android/server/display/RampAnimatorTest.java b/services/tests/displayservicetests/src/com/android/server/display/RampAnimatorTest.java new file mode 100644 index 000000000000..2820da7c49c1 --- /dev/null +++ b/services/tests/displayservicetests/src/com/android/server/display/RampAnimatorTest.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.display; + +import static org.junit.Assert.assertEquals; + +import android.util.FloatProperty; + +import androidx.test.filters.SmallTest; + +import org.junit.Before; +import org.junit.Test; + +@SmallTest +public class RampAnimatorTest { + + private RampAnimator<TestObject> mRampAnimator; + + private final TestObject mTestObject = new TestObject(); + + private final FloatProperty<TestObject> mTestProperty = new FloatProperty<>("mValue") { + @Override + public void setValue(TestObject object, float value) { + object.mValue = value; + } + + @Override + public Float get(TestObject object) { + return object.mValue; + } + }; + + @Before + public void setUp() { + mRampAnimator = new RampAnimator<>(mTestObject, mTestProperty); + } + + @Test + public void testInitialValueUsedInLastAnimationStep() { + mRampAnimator.setAnimationTarget(0.67f, 0.1f); + + assertEquals(0.67f, mTestObject.mValue, 0); + } + + private static class TestObject { + private float mValue; + } +} |