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

Commit e37da217 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Reuse WeatherEffect in WeatherEffectFactory" into main

parents 92a43f73 6f467307
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.google.android.wallpaper.weathereffects.graphics

import android.graphics.Bitmap
import android.graphics.Canvas
import android.util.SizeF
import androidx.annotation.FloatRange
@@ -59,4 +60,16 @@ interface WeatherEffect {
     * @param intensity [0, 1] the intensity of the weather effect.
     */
    fun setIntensity(@FloatRange(from = 0.0, to = 1.0) intensity: Float)

    /**
     * Reuse current shader but change background, foreground
     *
     * @param foreground A bitmap containing the foreground of the image
     * @param background A bitmap containing the background of the image
     */
    fun setBitmaps(foreground: Bitmap, background: Bitmap)

    companion object {
        val DEFAULT_INTENSITY = 1f
    }
}
+28 −9
Original line number Diff line number Diff line
@@ -16,24 +16,28 @@

package com.google.android.wallpaper.weathereffects.graphics.fog

import android.graphics.Bitmap
import android.graphics.BitmapShader
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Shader
import android.util.SizeF
import com.google.android.wallpaper.weathereffects.graphics.WeatherEffect
import com.google.android.wallpaper.weathereffects.graphics.WeatherEffect.Companion.DEFAULT_INTENSITY
import com.google.android.wallpaper.weathereffects.graphics.utils.GraphicsUtils
import com.google.android.wallpaper.weathereffects.graphics.utils.ImageCrop
import com.google.android.wallpaper.weathereffects.graphics.utils.TimeUtils
import java.util.concurrent.TimeUnit
import kotlin.math.sin
import kotlin.random.Random

/** Defines and generates the fog weather effect animation. */
class FogEffect(
    private val fogConfig: FogEffectConfig,
    private var foreground: Bitmap,
    private var background: Bitmap,
    private var intensity: Float = DEFAULT_INTENSITY,
    /** The initial size of the surface where the effect will be shown. */
    surfaceSize: SizeF
    private var surfaceSize: SizeF
) : WeatherEffect {

    private val fogPaint = Paint().also { it.shader = fogConfig.colorGradingShader }
@@ -44,12 +48,13 @@ class FogEffect(
        adjustCropping(surfaceSize)
        prepareColorGrading()
        updateFogGridSize(surfaceSize)
        setIntensity(fogConfig.intensity)
        setIntensity(intensity)
    }

    override fun resize(newSurfaceSize: SizeF) {
        adjustCropping(newSurfaceSize)
        updateFogGridSize(newSurfaceSize)
        surfaceSize = newSurfaceSize
    }

    override fun update(deltaMillis: Long, frameTimeNanos: Long) {
@@ -98,13 +103,27 @@ class FogEffect(
        )
    }

    override fun setBitmaps(foreground: Bitmap, background: Bitmap) {
        this.foreground = foreground
        this.background = background
        fogConfig.shader.setInputBuffer(
            "background",
            BitmapShader(background, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR)
        )
        fogConfig.shader.setInputBuffer(
            "foreground",
            BitmapShader(foreground, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR)
        )
        adjustCropping(surfaceSize)
    }

    private fun adjustCropping(surfaceSize: SizeF) {
        val imageCropFgd =
            ImageCrop.centerCoverCrop(
                surfaceSize.width,
                surfaceSize.height,
                fogConfig.foreground.width.toFloat(),
                fogConfig.foreground.height.toFloat()
                foreground.width.toFloat(),
                foreground.height.toFloat()
            )
        fogConfig.shader.setFloatUniform(
            "uvOffsetFgd",
@@ -120,8 +139,8 @@ class FogEffect(
            ImageCrop.centerCoverCrop(
                surfaceSize.width,
                surfaceSize.height,
                fogConfig.background.width.toFloat(),
                fogConfig.background.height.toFloat()
                background.width.toFloat(),
                background.height.toFloat()
            )
        fogConfig.shader.setFloatUniform(
            "uvOffsetBgd",
@@ -143,12 +162,12 @@ class FogEffect(
    private fun updateTextureUniforms() {
        fogConfig.shader.setInputBuffer(
            "foreground",
            BitmapShader(fogConfig.foreground, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR)
            BitmapShader(foreground, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR)
        )

        fogConfig.shader.setInputBuffer(
            "background",
            BitmapShader(fogConfig.background, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR)
            BitmapShader(background, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR)
        )

        fogConfig.shader.setInputBuffer(
+4 −19
Original line number Diff line number Diff line
@@ -40,14 +40,8 @@ data class FogEffectConfig(
     * tileable, and at least 16-bit per channel for render quality.
     */
    val fogTexture: Bitmap,
    /** A bitmap containing the foreground of the image. */
    val foreground: Bitmap,
    /** A bitmap containing the background of the image. */
    val background: Bitmap,
    /** Pixel density of the display. Used for dithering. */
    val pixelDensity: Float,
    /** The amount of the fog. This contributes to the color grading as well. */
    @FloatRange(from = 0.0, to = 1.0) val intensity: Float,
    /** The intensity of the color grading. 0: no color grading, 1: color grading in full effect. */
    @FloatRange(from = 0.0, to = 1.0) val colorGradingIntensity: Float,
) {
@@ -55,30 +49,22 @@ data class FogEffectConfig(
     * Constructor for [FogEffectConfig].
     *
     * @param assets the application [AssetManager].
     * @param foreground a bitmap containing the foreground of the image.
     * @param background a bitmap containing the background of the image.
     * @param pixelDensity pixel density of the display.
     * @param intensity initial intensity that affects the amount of fog and color grading. Expected
     *   range is [0, 1]. You can always change the intensity dynamically. Defaults to 1.
     */
    constructor(
        assets: AssetManager,
        foreground: Bitmap,
        background: Bitmap,
        pixelDensity: Float,
        intensity: Float = DEFAULT_INTENSITY,
    ) : this(
        shader = GraphicsUtils.loadShader(assets, SHADER_PATH),
        colorGradingShader = GraphicsUtils.loadShader(assets, COLOR_GRADING_SHADER_PATH),
        lut = GraphicsUtils.loadTexture(assets, LOOKUP_TABLE_TEXTURE_PATH),
        cloudsTexture = GraphicsUtils.loadTexture(assets, CLOUDS_TEXTURE_PATH)
        cloudsTexture =
            GraphicsUtils.loadTexture(assets, CLOUDS_TEXTURE_PATH)
                ?: throw RuntimeException("Clouds texture is missing."),
        fogTexture = GraphicsUtils.loadTexture(assets, FOG_TEXTURE_PATH)
        fogTexture =
            GraphicsUtils.loadTexture(assets, FOG_TEXTURE_PATH)
                ?: throw RuntimeException("Fog texture is missing."),
        foreground,
        background,
        pixelDensity,
        intensity,
        COLOR_GRADING_INTENSITY
    )

@@ -88,7 +74,6 @@ data class FogEffectConfig(
        private const val LOOKUP_TABLE_TEXTURE_PATH = "textures/lut_rain_and_fog.png"
        private const val CLOUDS_TEXTURE_PATH = "textures/clouds.png"
        private const val FOG_TEXTURE_PATH = "textures/fog.png"
        private const val DEFAULT_INTENSITY = 1f
        private const val COLOR_GRADING_INTENSITY = 0.7f
    }
}
+6 −2
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@ import com.google.android.wallpaper.weathereffects.graphics.WeatherEffect
import com.google.android.wallpaper.weathereffects.graphics.utils.MatrixUtils

/** Simply draws foreground and background images with no weather effect. */
class NoEffect(val foreground: Bitmap, val background: Bitmap, private var surfaceSize: SizeF) :
class NoEffect(var foreground: Bitmap, var background: Bitmap, private var surfaceSize: SizeF) :
    WeatherEffect {
    override fun resize(newSurfaceSize: SizeF) {
        surfaceSize = newSurfaceSize
@@ -40,7 +40,6 @@ class NoEffect(val foreground: Bitmap, val background: Bitmap, private var surfa
            ),
            null
        )

        canvas.drawBitmap(
            foreground,
            MatrixUtils.centerCropMatrix(
@@ -56,4 +55,9 @@ class NoEffect(val foreground: Bitmap, val background: Bitmap, private var surfa
    override fun release() {}

    override fun setIntensity(intensity: Float) {}

    override fun setBitmaps(foreground: Bitmap, background: Bitmap) {
        this.foreground = foreground
        this.background = background
    }
}
+32 −12
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.google.android.wallpaper.weathereffects.graphics.rain

import android.graphics.Bitmap
import android.graphics.BitmapShader
import android.graphics.Canvas
import android.graphics.Color
@@ -25,20 +26,23 @@ import android.graphics.Shader
import android.util.SizeF
import com.google.android.wallpaper.weathereffects.graphics.FrameBuffer
import com.google.android.wallpaper.weathereffects.graphics.WeatherEffect
import com.google.android.wallpaper.weathereffects.graphics.WeatherEffect.Companion.DEFAULT_INTENSITY
import com.google.android.wallpaper.weathereffects.graphics.utils.GraphicsUtils
import com.google.android.wallpaper.weathereffects.graphics.utils.ImageCrop
import com.google.android.wallpaper.weathereffects.graphics.utils.SolidColorShader
import com.google.android.wallpaper.weathereffects.graphics.utils.TimeUtils
import java.util.concurrent.Executor
import java.util.concurrent.TimeUnit
import kotlin.random.Random

/** Defines and generates the rain weather effect animation. */
class RainEffect(
    /** The config of the rain effect. */
    private val rainConfig: RainEffectConfig,
    private var foreground: Bitmap,
    private var background: Bitmap,
    private var intensity: Float = DEFAULT_INTENSITY,
    /** The initial size of the surface where the effect will be shown. */
    surfaceSize: SizeF,
    private var surfaceSize: SizeF,
    private val mainExecutor: Executor
) : WeatherEffect {

@@ -46,8 +50,8 @@ class RainEffect(

    // Set blur effect to reduce the outline noise. No need to set blur effect every time we
    // re-generate the outline buffer.
    private val outlineBuffer =
        FrameBuffer(rainConfig.background.width, rainConfig.background.height).apply {
    private var outlineBuffer =
        FrameBuffer(background.width, background.height).apply {
            setRenderEffect(RenderEffect.createBlurEffect(2f, 2f, Shader.TileMode.CLAMP))
        }
    private val outlineBufferPaint = Paint().also { it.shader = rainConfig.outlineShader }
@@ -59,12 +63,13 @@ class RainEffect(
        adjustCropping(surfaceSize)
        prepareColorGrading()
        updateRainGridSize(surfaceSize)
        setIntensity(rainConfig.intensity)
        setIntensity(intensity)
    }

    override fun resize(newSurfaceSize: SizeF) {
        adjustCropping(newSurfaceSize)
        updateRainGridSize(newSurfaceSize)
        surfaceSize = newSurfaceSize
    }

    override fun update(deltaMillis: Long, frameTimeNanos: Long) {
@@ -104,13 +109,27 @@ class RainEffect(
        createOutlineBuffer()
    }

    override fun setBitmaps(foreground: Bitmap, background: Bitmap) {
        this.foreground = foreground
        this.background = background
        outlineBuffer =
            FrameBuffer(background.width, background.height).apply {
                setRenderEffect(RenderEffect.createBlurEffect(2f, 2f, Shader.TileMode.CLAMP))
            }
        adjustCropping(surfaceSize)
        updateTextureUniforms()

        // Need to recreate the outline buffer as the outlineBuffer has changed due to background
        createOutlineBuffer()
    }

    private fun adjustCropping(surfaceSize: SizeF) {
        val imageCropFgd =
            ImageCrop.centerCoverCrop(
                surfaceSize.width,
                surfaceSize.height,
                rainConfig.foreground.width.toFloat(),
                rainConfig.foreground.height.toFloat()
                foreground.width.toFloat(),
                foreground.height.toFloat()
            )
        rainConfig.rainShowerShader.setFloatUniform(
            "uvOffsetFgd",
@@ -127,8 +146,8 @@ class RainEffect(
            ImageCrop.centerCoverCrop(
                surfaceSize.width,
                surfaceSize.height,
                rainConfig.background.width.toFloat(),
                rainConfig.background.height.toFloat()
                background.width.toFloat(),
                background.height.toFloat()
            )
        rainConfig.rainShowerShader.setFloatUniform(
            "uvOffsetBgd",
@@ -159,13 +178,13 @@ class RainEffect(

    private fun updateTextureUniforms() {
        val foregroundBuffer =
            BitmapShader(rainConfig.foreground, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR)
            BitmapShader(foreground, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR)
        rainConfig.rainShowerShader.setInputBuffer("foreground", foregroundBuffer)
        rainConfig.outlineShader.setInputBuffer("texture", foregroundBuffer)

        rainConfig.rainShowerShader.setInputBuffer(
            "background",
            BitmapShader(rainConfig.background, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR)
            BitmapShader(background, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR)
        )
    }

@@ -198,7 +217,8 @@ class RainEffect(
    }

    private fun updateRainGridSize(surfaceSize: SizeF) {
        val widthScreenScale = GraphicsUtils.computeDefaultGridSize(surfaceSize, rainConfig.pixelDensity)
        val widthScreenScale =
            GraphicsUtils.computeDefaultGridSize(surfaceSize, rainConfig.pixelDensity)
        rainConfig.rainShowerShader.setFloatUniform("gridScale", widthScreenScale)
        rainConfig.glassRainShader.setFloatUniform("gridScale", widthScreenScale)
    }
Loading