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

Commit c5f264b8 authored by Yein Jo's avatar Yein Jo Committed by Android (Google) Code Review
Browse files

Revert "Extract GlowPie to avoid code repetition."

Revert submission 27073971

Reverted changes: /q/submissionid:27073971

Change-Id: I24386afb0c67c15bf6f0fc371314398be9467834
parent c2d9a4ad
Loading
Loading
Loading
Loading
+34 −136
Original line number Diff line number Diff line
@@ -44,31 +44,42 @@ class GlowPieEffect(
    fun play() {
        if (mainAnimator.isRunning) return

        baseGlow.resetProgress()
        firstGlowPie.resetProgress()
        secondGlowPie.resetProgress()

        mainAnimator.addUpdateListener { updateListener ->
            val time = updateListener.currentPlayTime.toFloat() % mainAnimator.duration

            // Remap each glow pie progress.
            baseGlow.updateProgress(time)
            firstGlowPie.updateProgress(time)
            secondGlowPie.updateProgress(time)
            // TODO(b/335315940): Extract the timestamps to config.
            val progress1 = MathUtils.constrainedMap(0f, 1f, 250f, 2500f, time)
            val progress2 = MathUtils.constrainedMap(0f, 1f, 350f, 2600f, time)

            // TODO(b/335315940): Consider passing in 2D Matrix.
            glowPieShader.setAngles(baseGlow.angle(), firstGlowPie.angle(), secondGlowPie.angle())
            val angle0 = 0f // No rotation for the base.
            // Negate the angle since we want clock-wise rotation.
            val angle1 =
                -(MathUtils.constrainedMap(-PI / 2f, 4f * PI, 0f, 1f, progress1) + progress1 * PI)
            val angle2 =
                -(MathUtils.constrainedMap(-PI / 2f, 3f * PI, 0f, 1f, progress2) + progress2 * PI)
            glowPieShader.setAngle(angle0, angle1, angle2)
            val bottomThreshold0 = 0f
            val topThreshold0 = 0f

            val bottomThreshold1 = MathUtils.lerp(1f, -FEATHER, progress1)
            val topThreshold1 = MathUtils.lerp(1f + FEATHER, 0f, progress1)

            val bottomThreshold2 = MathUtils.lerp(1f, -FEATHER, progress2)
            val topThreshold2 = MathUtils.lerp(1f + FEATHER, 0f, progress2)

            glowPieShader.setBottomAngleThresholds(
                baseGlow.bottomThreshold(),
                firstGlowPie.bottomThreshold(),
                secondGlowPie.bottomThreshold()
                bottomThreshold0,
                bottomThreshold1,
                bottomThreshold2
            )
            glowPieShader.setTopAngleThresholds(
                baseGlow.topThreshold(),
                firstGlowPie.topThreshold(),
                secondGlowPie.topThreshold()
            )
            glowPieShader.setAlphas(baseGlow.alpha(), firstGlowPie.alpha(), secondGlowPie.alpha())
            glowPieShader.setTopAngleThresholds(topThreshold0, topThreshold1, topThreshold2)

            // Remap timestamps (in MS) to alpha [0, 1].
            val alpha0 = MathUtils.constrainedMap(0f, 1f, 2250f, 2950f, time)
            val alpha1 = MathUtils.constrainedMap(1f, 0f, 2500f, 2750f, time)
            val alpha2 = MathUtils.constrainedMap(1f, 0f, 2600f, 2850f, time)
            glowPieShader.setAlphas(alpha0, alpha1, alpha2)

            // Finally trigger the draw callback.
            renderEffectDrawCallback.onDraw(
@@ -87,123 +98,10 @@ class GlowPieEffect(
        mainAnimator.cancel()
    }

    companion object {
        @VisibleForTesting const val PI = Math.PI.toFloat()
        @VisibleForTesting const val FEATHER = 0.3f
        @VisibleForTesting const val DURATION_MS = 3000L

        private val baseGlow = BaseGlow()
        private val firstGlowPie = FirstGlowPie()
        private val secondGlowPie = SecondGlowPie()
    }

    /** Contains animation parameters for each layer of glow pie. */
    interface GlowPie {
        /**
         * The start & end timestamps of the animation. Must be smaller than or equal to the full
         * [DURATION_MS].
         */
        val startMs: Float
        val endMs: Float
        /**
         * Start & end angles in radian. This determines how many cycles you want to rotate. e.g.
         * startAngle = 0f endAngle = 4f * PI, will give you the 2 cycles.
         */
        val startAngle: Float
        val endAngle: Float
        /**
         * Start & end timestamps of the fade out duration. You may want to override [alpha] if you
         * want to make it fade in. See [BaseGlow].
         */
        val alphaFadeStartMs: Float
        val alphaFadeEndMs: Float

        /** Below two values are expected to be updated through [updateProgress]. */
        /** Normalized progress. */
        var progress: Float
        /** current time of the animation in ms. */
        var time: Float

        // Must be called before retrieving angle, bottom & top thresholds, and alpha.
        // Otherwise the values would be stale.
        fun updateProgress(time: Float) {
            progress = MathUtils.constrainedMap(0f, 1f, startMs, endMs, time)
            this.time = time
        }

        fun resetProgress() {
            progress = 0f
            time = 0f
        }

        fun angle(): Float {
            // Negate the angle since we want clock-wise rotation.
            val angle =
                MathUtils.constrainedMap(startAngle, endAngle, 0f, 1f, progress) + progress * PI
            return -angle
    private companion object {
        private const val PI = Math.PI.toFloat()
        private const val FEATHER = 0.3f
        // This indicates a single loop of the animation.
        private const val DURATION_MS = 3000L
    }

        fun bottomThreshold(): Float {
            return MathUtils.lerp(1f, -FEATHER, progress)
        }

        fun topThreshold(): Float {
            return MathUtils.lerp(1f + FEATHER, 0f, progress)
        }

        // By default, it fades "out".
        fun alpha(): Float {
            // Remap timestamps (in MS) to alpha [0, 1].
            return MathUtils.constrainedMap(1f, 0f, alphaFadeStartMs, alphaFadeEndMs, time)
        }
    }

    data class BaseGlow(
        override val startMs: Float = 0f,
        override val endMs: Float = 0f,
        override val startAngle: Float = 0f,
        override val endAngle: Float = 0f,
        override val alphaFadeStartMs: Float = 2250f,
        override val alphaFadeEndMs: Float = 2950f,
    ) : GlowPie {

        override var progress: Float = 1f
        override var time: Float = 0f
        override fun updateProgress(time: Float) {}

        override fun resetProgress() {}

        override fun angle(): Float = 0f

        override fun bottomThreshold(): Float = 0f

        override fun topThreshold(): Float = 0f

        // Base glow fade "in" (i.e. reveals).
        override fun alpha(): Float {
            return MathUtils.constrainedMap(0f, 1f, alphaFadeStartMs, alphaFadeEndMs, time)
        }
    }

    data class FirstGlowPie(
        override val startMs: Float = 250f,
        override val endMs: Float = 2500f,
        override val startAngle: Float = -PI / 2f,
        override val endAngle: Float = 4f * PI,
        override val alphaFadeStartMs: Float = 2500f,
        override val alphaFadeEndMs: Float = 2750f,
        override var progress: Float = 0f,
        override var time: Float = 0f
    ) : GlowPie

    data class SecondGlowPie(
        override val startMs: Float = 350f,
        override val endMs: Float = 2600f,
        override val startAngle: Float = -PI / 2f,
        override val endAngle: Float = 3f * PI,
        override val alphaFadeStartMs: Float = 2600f,
        override val alphaFadeEndMs: Float = 2850f,
        override var progress: Float = 0f,
        override var time: Float = 0f
    ) : GlowPie
}
+1 −1
Original line number Diff line number Diff line
@@ -199,7 +199,7 @@ class GlowPieShader : RuntimeShader(GLOW_PIE_SHADER_COMP) {
        setColorUniform("in_colors2", colors[2])
    }

    fun setAngles(vararg angles: Float) {
    fun setAngle(vararg angles: Float) {
        if (angles.size != NUM_PIE) {
            Log.wtf(TAG, "The number of angles must be $NUM_PIE")
            return
+0 −35
Original line number Diff line number Diff line
@@ -91,39 +91,4 @@ class GlowPieEffectTest : SysUiStateTest() {

        assertThat(glowPieEffect.mainAnimator.isRunning).isFalse()
    }

    @Test
    fun glowPie_progress_computesProgressCorrectly() {
        val myGlowPieConfig =
            object : GlowPieEffect.GlowPie {
                override val startMs: Float = 0f
                override val endMs: Float = GlowPieEffect.DURATION_MS.toFloat()
                override val startAngle: Float = 0f
                override val endAngle: Float = 6f * GlowPieEffect.PI
                override val alphaFadeStartMs: Float = 0f
                override val alphaFadeEndMs: Float = GlowPieEffect.DURATION_MS.toFloat()
                override var progress: Float = 0f
                override var time: Float = 0f
            }

        val playTime = GlowPieEffect.DURATION_MS.toFloat() * 0.5f
        val tolerance = 1e-4f
        myGlowPieConfig.updateProgress(playTime)

        assertThat(myGlowPieConfig.time).isWithin(tolerance).of(playTime)
        assertThat(myGlowPieConfig.progress).isWithin(tolerance).of(0.5f)
        assertThat(myGlowPieConfig.angle()).isWithin(tolerance).of(-3.5f * GlowPieEffect.PI)
        assertThat(myGlowPieConfig.bottomThreshold())
            .isWithin(tolerance)
            .of((1f - GlowPieEffect.FEATHER) * 0.5f)
        assertThat(myGlowPieConfig.topThreshold())
            .isWithin(tolerance)
            .of((1f + GlowPieEffect.FEATHER) * 0.5f)
        assertThat(myGlowPieConfig.alpha()).isWithin(tolerance).of(0.5f)

        myGlowPieConfig.resetProgress()

        assertThat(myGlowPieConfig.time).isEqualTo(0f)
        assertThat(myGlowPieConfig.progress).isEqualTo(0f)
    }
}