Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ee707fbb authored by Yein Jo's avatar Yein Jo
Browse files

Update TurbulenceNoiseShader and the config.

Removed some unused or non shader related params from the config and
updated the Shader, View accordingly.

Test: MediaControlPanelTest, TurbulenceNoiseShaderTest,
TurbulenceNoiseViewTest, TurbulenceNoiseControllerTest, Inspect UMO and
wallpaper picker visually.
Bug: 282007590
Flag: NA

Change-Id: I477f1c07b683473a3a007ee8107b6c51f81f7f88
parent 4b6b9b8f
Loading
Loading
Loading
Loading
+11 −8
Original line number Diff line number Diff line
@@ -15,8 +15,8 @@
 */
package com.android.systemui.surfaceeffects.turbulencenoise

import android.graphics.BlendMode
import android.graphics.Color
import java.util.Random

/** Turbulence noise animation configuration. */
data class TurbulenceNoiseAnimationConfig(
@@ -26,6 +26,11 @@ data class TurbulenceNoiseAnimationConfig(
    /** Multiplier for the noise luma matte. Increase this for brighter effects. */
    val luminosityMultiplier: Float = DEFAULT_LUMINOSITY_MULTIPLIER,

    /** Initial noise offsets. */
    val noiseOffsetX: Float = random.nextFloat(),
    val noiseOffsetY: Float = random.nextFloat(),
    val noiseOffsetZ: Float = random.nextFloat(),

    /**
     * Noise move speed variables.
     *
@@ -45,18 +50,15 @@ data class TurbulenceNoiseAnimationConfig(
    val noiseMoveSpeedZ: Float = DEFAULT_NOISE_SPEED_Z,

    /** Color of the effect. */
    var color: Int = DEFAULT_COLOR,
    val color: Int = DEFAULT_COLOR,
    /** Background color of the effect. */
    val backgroundColor: Int = DEFAULT_BACKGROUND_COLOR,
    val opacity: Int = DEFAULT_OPACITY,
    val width: Float = 0f,
    val height: Float = 0f,
    val maxDuration: Float = DEFAULT_MAX_DURATION_IN_MILLIS,
    val easeInDuration: Float = DEFAULT_EASING_DURATION_IN_MILLIS,
    val easeOutDuration: Float = DEFAULT_EASING_DURATION_IN_MILLIS,
    val pixelDensity: Float = 1f,
    val blendMode: BlendMode = DEFAULT_BLEND_MODE,
    val onAnimationEnd: Runnable? = null,
    /**
     * Variants in noise. Higher number means more contrast; lower number means less contrast but
     * make the noise dimmed. You may want to increase the [lumaMatteBlendFactor] to compensate.
@@ -68,7 +70,9 @@ data class TurbulenceNoiseAnimationConfig(
     * want to use this if you have made the noise softer using [lumaMatteBlendFactor]. Expected
     * range [0, 1].
     */
    val lumaMatteOverallBrightness: Float = DEFAULT_LUMA_MATTE_OVERALL_BRIGHTNESS
    val lumaMatteOverallBrightness: Float = DEFAULT_LUMA_MATTE_OVERALL_BRIGHTNESS,
    /** Whether to flip the luma mask. */
    val shouldInverseNoiseLuminosity: Boolean = false
) {
    companion object {
        const val DEFAULT_MAX_DURATION_IN_MILLIS = 30_000f // Max 30 sec
@@ -76,11 +80,10 @@ data class TurbulenceNoiseAnimationConfig(
        const val DEFAULT_LUMINOSITY_MULTIPLIER = 1f
        const val DEFAULT_NOISE_GRID_COUNT = 1.2f
        const val DEFAULT_NOISE_SPEED_Z = 0.3f
        const val DEFAULT_OPACITY = 150 // full opacity is 255.
        const val DEFAULT_COLOR = Color.WHITE
        const val DEFAULT_LUMA_MATTE_BLEND_FACTOR = 1f
        const val DEFAULT_LUMA_MATTE_OVERALL_BRIGHTNESS = 0f
        const val DEFAULT_BACKGROUND_COLOR = Color.BLACK
        val DEFAULT_BLEND_MODE = BlendMode.SRC_OVER
        private val random = Random()
    }
}
+5 −2
Original line number Diff line number Diff line
@@ -69,12 +69,15 @@ class TurbulenceNoiseController(private val turbulenceNoiseView: TurbulenceNoise
     *
     * <p>It plays ease-in, main, and ease-out animations in sequence.
     */
    fun play(config: TurbulenceNoiseAnimationConfig) {
    fun play(
        baseType: TurbulenceNoiseShader.Companion.Type,
        config: TurbulenceNoiseAnimationConfig
    ) {
        if (state != AnimationState.NOT_PLAYING) {
            return // Ignore if any of the animation is playing.
        }

        turbulenceNoiseView.applyConfig(config)
        turbulenceNoiseView.initShader(baseType, config)
        playEaseInAnimation()
    }

+31 −7
Original line number Diff line number Diff line
@@ -22,10 +22,10 @@ import java.lang.Float.max
/**
 * Shader that renders turbulence simplex noise, by default no octave.
 *
 * @param useFractal whether to use fractal noise (4 octaves).
 * @param baseType the base [Type] of the shader.
 */
class TurbulenceNoiseShader(useFractal: Boolean = false) :
    RuntimeShader(if (useFractal) FRACTAL_NOISE_SHADER else SIMPLEX_NOISE_SHADER) {
class TurbulenceNoiseShader(val baseType: Type = Type.SIMPLEX_NOISE) :
    RuntimeShader(getShader(baseType)) {
    // language=AGSL
    companion object {
        private const val UNIFORMS =
@@ -86,11 +86,34 @@ class TurbulenceNoiseShader(useFractal: Boolean = false) :
                return vec4(color * in_opacity, in_opacity);
            }
        """

        private const val SIMPLEX_NOISE_SHADER =
            ShaderUtilLibrary.SHADER_LIB + UNIFORMS + SIMPLEX_SHADER
        private const val FRACTAL_NOISE_SHADER =
            ShaderUtilLibrary.SHADER_LIB + UNIFORMS + FRACTAL_SHADER
        // TODO (b/282007590): Add NOISE_WITH_SPARKLE

        enum class Type {
            SIMPLEX_NOISE,
            SIMPLEX_NOISE_FRACTAL,
        }

        fun getShader(type: Type): String {
            return when (type) {
                Type.SIMPLEX_NOISE -> SIMPLEX_NOISE_SHADER
                Type.SIMPLEX_NOISE_FRACTAL -> FRACTAL_NOISE_SHADER
            }
        }
    }

    /** Convenient way for updating multiple uniform values via config object. */
    fun applyConfig(config: TurbulenceNoiseAnimationConfig) {
        setGridCount(config.gridCount)
        setPixelDensity(config.pixelDensity)
        setColor(config.color)
        setBackgroundColor(config.backgroundColor)
        setSize(config.width, config.height)
        setLumaMatteFactors(config.lumaMatteBlendFactor, config.lumaMatteOverallBrightness)
        setInverseNoiseLuminosity(config.shouldInverseNoiseLuminosity)
    }

    /** Sets the number of grid for generating noise. */
@@ -107,18 +130,19 @@ class TurbulenceNoiseShader(useFractal: Boolean = false) :
        setFloatUniform("in_pixelDensity", pixelDensity)
    }

    /** Sets the noise color of the effect. */
    /** Sets the noise color of the effect. Alpha is ignored. */
    fun setColor(color: Int) {
        setColorUniform("in_color", color)
    }

    /** Sets the background color of the effect. */
    /** Sets the background color of the effect. Alpha is ignored. */
    fun setBackgroundColor(color: Int) {
        setColorUniform("in_backgroundColor", color)
    }

    /**
     * Sets the opacity to achieve fade in/ out of the animation.
     * Sets the opacity of the effect. Not intended to set by the client as it is used for
     * ease-in/out animations.
     *
     * Expected value range is [1, 0].
     */
+36 −31
Original line number Diff line number Diff line
@@ -19,12 +19,12 @@ import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.BlendMode
import android.graphics.Canvas
import android.graphics.Paint
import android.util.AttributeSet
import android.view.View
import androidx.annotation.VisibleForTesting
import androidx.core.graphics.ColorUtils

/**
 * View that renders turbulence noise effect.
@@ -44,8 +44,8 @@ class TurbulenceNoiseView(context: Context?, attrs: AttributeSet?) : View(contex
        private const val MS_TO_SEC = 0.001f
    }

    private val turbulenceNoiseShader = TurbulenceNoiseShader()
    private val paint = Paint().apply { this.shader = turbulenceNoiseShader }
    private val paint = Paint()
    @VisibleForTesting var turbulenceNoiseShader: TurbulenceNoiseShader? = null
    @VisibleForTesting var noiseConfig: TurbulenceNoiseAnimationConfig? = null
    @VisibleForTesting var currentAnimator: ValueAnimator? = null

@@ -61,9 +61,7 @@ class TurbulenceNoiseView(context: Context?, attrs: AttributeSet?) : View(contex

    /** Updates the color during the animation. No-op if there's no animation playing. */
    internal fun updateColor(color: Int) {
        noiseConfig?.let {
            turbulenceNoiseShader.setColor(ColorUtils.setAlphaComponent(color, it.opacity))
        }
        turbulenceNoiseShader?.setColor(color)
    }

    /** Plays the turbulence noise with no easing. */
@@ -73,24 +71,25 @@ class TurbulenceNoiseView(context: Context?, attrs: AttributeSet?) : View(contex
            return
        }
        val config = noiseConfig!!
        val shader = turbulenceNoiseShader!!

        val animator = ValueAnimator.ofFloat(0f, 1f)
        animator.duration = config.maxDuration.toLong()

        // Animation should start from the initial position to avoid abrupt transition.
        val initialX = turbulenceNoiseShader.noiseOffsetX
        val initialY = turbulenceNoiseShader.noiseOffsetY
        val initialZ = turbulenceNoiseShader.noiseOffsetZ
        val initialX = shader.noiseOffsetX
        val initialY = shader.noiseOffsetY
        val initialZ = shader.noiseOffsetZ

        animator.addUpdateListener { updateListener ->
            val timeInSec = updateListener.currentPlayTime * MS_TO_SEC
            turbulenceNoiseShader.setNoiseMove(
            shader.setNoiseMove(
                initialX + timeInSec * config.noiseMoveSpeedX,
                initialY + timeInSec * config.noiseMoveSpeedY,
                initialZ + timeInSec * config.noiseMoveSpeedZ
            )

            turbulenceNoiseShader.setOpacity(config.luminosityMultiplier)
            shader.setOpacity(config.luminosityMultiplier)

            invalidate()
        }
@@ -115,27 +114,28 @@ class TurbulenceNoiseView(context: Context?, attrs: AttributeSet?) : View(contex
            return
        }
        val config = noiseConfig!!
        val shader = turbulenceNoiseShader!!

        val animator = ValueAnimator.ofFloat(0f, 1f)
        animator.duration = config.easeInDuration.toLong()

        // Animation should start from the initial position to avoid abrupt transition.
        val initialX = turbulenceNoiseShader.noiseOffsetX
        val initialY = turbulenceNoiseShader.noiseOffsetY
        val initialZ = turbulenceNoiseShader.noiseOffsetZ
        val initialX = shader.noiseOffsetX
        val initialY = shader.noiseOffsetY
        val initialZ = shader.noiseOffsetZ

        animator.addUpdateListener { updateListener ->
            val timeInSec = updateListener.currentPlayTime * MS_TO_SEC
            val progress = updateListener.animatedValue as Float

            turbulenceNoiseShader.setNoiseMove(
            shader.setNoiseMove(
                offsetX + initialX + timeInSec * config.noiseMoveSpeedX,
                offsetY + initialY + timeInSec * config.noiseMoveSpeedY,
                initialZ + timeInSec * config.noiseMoveSpeedZ
            )

            // TODO: Replace it with a better curve.
            turbulenceNoiseShader.setOpacity(progress * config.luminosityMultiplier)
            shader.setOpacity(progress * config.luminosityMultiplier)

            invalidate()
        }
@@ -160,27 +160,28 @@ class TurbulenceNoiseView(context: Context?, attrs: AttributeSet?) : View(contex
            return
        }
        val config = noiseConfig!!
        val shader = turbulenceNoiseShader!!

        val animator = ValueAnimator.ofFloat(0f, 1f)
        animator.duration = config.easeOutDuration.toLong()

        // Animation should start from the initial position to avoid abrupt transition.
        val initialX = turbulenceNoiseShader.noiseOffsetX
        val initialY = turbulenceNoiseShader.noiseOffsetY
        val initialZ = turbulenceNoiseShader.noiseOffsetZ
        val initialX = shader.noiseOffsetX
        val initialY = shader.noiseOffsetY
        val initialZ = shader.noiseOffsetZ

        animator.addUpdateListener { updateListener ->
            val timeInSec = updateListener.currentPlayTime * MS_TO_SEC
            val progress = updateListener.animatedValue as Float

            turbulenceNoiseShader.setNoiseMove(
            shader.setNoiseMove(
                initialX + timeInSec * config.noiseMoveSpeedX,
                initialY + timeInSec * config.noiseMoveSpeedY,
                initialZ + timeInSec * config.noiseMoveSpeedZ
            )

            // TODO: Replace it with a better curve.
            turbulenceNoiseShader.setOpacity((1f - progress) * config.luminosityMultiplier)
            shader.setOpacity((1f - progress) * config.luminosityMultiplier)

            invalidate()
        }
@@ -211,18 +212,22 @@ class TurbulenceNoiseView(context: Context?, attrs: AttributeSet?) : View(contex

    /** Applies shader uniforms. Must be called before playing animation. */
    @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
    fun applyConfig(config: TurbulenceNoiseAnimationConfig) {
    fun initShader(
        baseType: TurbulenceNoiseShader.Companion.Type,
        config: TurbulenceNoiseAnimationConfig
    ) {
        noiseConfig = config
        with(turbulenceNoiseShader) {
            setGridCount(config.gridCount)
            setColor(config.color)
            setBackgroundColor(config.backgroundColor)
            setSize(config.width, config.height)
            setPixelDensity(config.pixelDensity)
            setInverseNoiseLuminosity(inverse = false)
            setLumaMatteFactors(config.lumaMatteBlendFactor, config.lumaMatteOverallBrightness)
        }
        paint.blendMode = config.blendMode
        if (turbulenceNoiseShader == null || turbulenceNoiseShader?.baseType != baseType) {
            turbulenceNoiseShader = TurbulenceNoiseShader(baseType)

            paint.shader = turbulenceNoiseShader!!
        }
        turbulenceNoiseShader!!.applyConfig(config)
    }

    /** Sets the blend mode of the View. */
    fun setBlendMode(blendMode: BlendMode) {
        paint.blendMode = blendMode
    }

    internal fun clearConfig() {
+15 −5
Original line number Diff line number Diff line
@@ -118,6 +118,8 @@ import com.android.systemui.surfaceeffects.ripple.RippleAnimationConfig;
import com.android.systemui.surfaceeffects.ripple.RippleShader;
import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseAnimationConfig;
import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseController;
import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseShader.Companion.Type;
import com.android.systemui.surfaceeffects.turbulencenoise.TurbulenceNoiseView;
import com.android.systemui.util.ColorUtilKt;
import com.android.systemui.util.animation.TransitionLayout;
import com.android.systemui.util.concurrency.DelayableExecutor;
@@ -132,6 +134,7 @@ import kotlin.Unit;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Executor;

import javax.inject.Inject;
@@ -251,6 +254,8 @@ public class MediaControlPanel {
    private boolean mWasPlaying = false;
    private boolean mButtonClicked = false;

    private final Random mRandom = new Random();

    /**
     * Initialize a new control panel
     *
@@ -448,7 +453,10 @@ public class MediaControlPanel {

        MultiRippleView multiRippleView = vh.getMultiRippleView();
        mMultiRippleController = new MultiRippleController(multiRippleView);
        mTurbulenceNoiseController = new TurbulenceNoiseController(vh.getTurbulenceNoiseView());

        TurbulenceNoiseView turbulenceNoiseView = vh.getTurbulenceNoiseView();
        turbulenceNoiseView.setBlendMode(BlendMode.SCREEN);
        mTurbulenceNoiseController = new TurbulenceNoiseController(turbulenceNoiseView);

        mColorSchemeTransition = new ColorSchemeTransition(
                mContext, mMediaViewHolder, mMultiRippleController, mTurbulenceNoiseController);
@@ -587,6 +595,7 @@ public class MediaControlPanel {
            }
            // Color will be correctly updated in ColorSchemeTransition.
            mTurbulenceNoiseController.play(
                    Type.SIMPLEX_NOISE,
                    mTurbulenceNoiseAnimationConfig
            );
            mMainExecutor.executeDelayed(
@@ -1227,22 +1236,23 @@ public class MediaControlPanel {
        return new TurbulenceNoiseAnimationConfig(
                /* gridCount= */ 2.14f,
                TurbulenceNoiseAnimationConfig.DEFAULT_LUMINOSITY_MULTIPLIER,
                /* noiseOffsetX= */ mRandom.nextFloat(),
                /* noiseOffsetY= */ mRandom.nextFloat(),
                /* noiseOffsetZ= */ mRandom.nextFloat(),
                /* noiseMoveSpeedX= */ 0.42f,
                /* noiseMoveSpeedY= */ 0f,
                TurbulenceNoiseAnimationConfig.DEFAULT_NOISE_SPEED_Z,
                /* color= */ mColorSchemeTransition.getAccentPrimary().getCurrentColor(),
                /* backgroundColor= */ Color.BLACK,
                /* opacity= */ 51,
                /* width= */ mMediaViewHolder.getTurbulenceNoiseView().getWidth(),
                /* height= */ mMediaViewHolder.getTurbulenceNoiseView().getHeight(),
                TurbulenceNoiseAnimationConfig.DEFAULT_MAX_DURATION_IN_MILLIS,
                /* easeInDuration= */ 1350f,
                /* easeOutDuration= */ 1350f,
                getContext().getResources().getDisplayMetrics().density,
                BlendMode.SCREEN,
                /* onAnimationEnd= */ null,
                /* lumaMatteBlendFactor= */ 0.26f,
                /* lumaMatteOverallBrightness= */ 0.09f
                /* lumaMatteOverallBrightness= */ 0.09f,
                /* shouldInverseNoiseLuminosity= */ false
        );
    }
    private void clearButton(final ImageButton button) {
Loading