diff --git a/backdrop/src/main/java/com/kyant/backdrop/Shaders.kt b/backdrop/src/main/java/com/kyant/backdrop/Shaders.kt index bdb9d1a..a8b9a68 100644 --- a/backdrop/src/main/java/com/kyant/backdrop/Shaders.kt +++ b/backdrop/src/main/java/com/kyant/backdrop/Shaders.kt @@ -166,8 +166,6 @@ half4 main(float2 coord) { @Language("AGSL") internal const val DefaultHighlightShaderString = """ -uniform shader content; - uniform float2 size; uniform float4 cornerRadii; uniform float angle; @@ -184,13 +182,11 @@ half4 main(float2 coord) { float2 grad = gradSdRoundedRectangle(centeredCoord, halfSize, gradRadius); float2 normal = float2(-cos(angle), -sin(angle)); float intensity = pow(abs(dot(normal, grad)), falloff); - return content.eval(coord) * intensity; + return half4(intensity); }""" @Language("AGSL") internal const val AmbientHighlightShaderString = """ -uniform shader content; - uniform float2 size; uniform float4 cornerRadii; uniform float angle; @@ -207,16 +203,13 @@ half4 main(float2 coord) { float2 grad = gradSdRoundedRectangle(centeredCoord, halfSize, gradRadius); float2 normal = float2(-cos(angle), -sin(angle)); float d = dot(normal, grad); - float alpha = content.eval(coord).a; float intensity = pow(abs(d), falloff); if (d > 0.0) { - return half4(0.0, 0.0, 0.0, 1.0) * intensity * alpha; + return half4(0.0, 0.0, 0.0, 1.0) * intensity; + } else { + return half4(1.0) * intensity; } - if (d < 0.0) { - return half4(1.0) * intensity * alpha; - } - return half4(0.0); }""" @Language("AGSL") diff --git a/backdrop/src/main/java/com/kyant/backdrop/highlight/HighlightModifier.kt b/backdrop/src/main/java/com/kyant/backdrop/highlight/HighlightModifier.kt index 67ec88d..fdd66fa 100644 --- a/backdrop/src/main/java/com/kyant/backdrop/highlight/HighlightModifier.kt +++ b/backdrop/src/main/java/com/kyant/backdrop/highlight/HighlightModifier.kt @@ -11,7 +11,6 @@ import androidx.compose.ui.graphics.drawOutline import androidx.compose.ui.graphics.drawscope.ContentDrawScope import androidx.compose.ui.graphics.drawscope.DrawScope import androidx.compose.ui.graphics.drawscope.translate -import androidx.compose.ui.graphics.layer.CompositingStrategy import androidx.compose.ui.graphics.layer.GraphicsLayer import androidx.compose.ui.graphics.layer.drawLayer import androidx.compose.ui.node.DrawModifierNode @@ -73,7 +72,6 @@ internal class HighlightNode( override val shouldAutoInvalidate: Boolean = false private var highlightLayer: GraphicsLayer? = null - private var maskLayer: GraphicsLayer? = null private val paint = Paint().apply { @@ -94,8 +92,7 @@ internal class HighlightNode( drawContent() val highlightLayer = highlightLayer - val maskLayer = maskLayer - if (highlightLayer != null && maskLayer != null) { + if (highlightLayer != null) { val size = size val density: Density = this val layoutDirection = layoutDirection @@ -116,18 +113,8 @@ internal class HighlightNode( configurePaint(highlight) - val style = highlight.style - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - if (prevStyle != style) { - highlightLayer.renderEffect = with(style) { - createRenderEffect( - shape = shapeProvider.shape, - runtimeShaderCache = runtimeShaderCache - ) - } - prevStyle = style - } - } + highlightLayer.alpha = highlight.alpha + highlightLayer.blendMode = highlight.style.blendMode highlightLayer.record(safeSize) { translate(1f, 1f) { val canvas = drawContext.canvas @@ -138,14 +125,8 @@ internal class HighlightNode( } } - maskLayer.alpha = highlight.alpha - maskLayer.blendMode = style.blendMode - maskLayer.record(safeSize) { - drawLayer(highlightLayer) - } - translate(-1f, -1f) { - drawLayer(maskLayer) + drawLayer(highlightLayer) } } } @@ -153,10 +134,6 @@ internal class HighlightNode( override fun onAttach() { val graphicsContext = requireGraphicsContext() highlightLayer = graphicsContext.createGraphicsLayer() - maskLayer = - graphicsContext.createGraphicsLayer().apply { - compositingStrategy = CompositingStrategy.Offscreen - } } override fun onDetach() { @@ -165,10 +142,6 @@ internal class HighlightNode( graphicsContext.releaseGraphicsLayer(layer) highlightLayer = null } - maskLayer?.let { layer -> - graphicsContext.releaseGraphicsLayer(layer) - maskLayer = null - } clipPath = null runtimeShaderCache.clear() prevStyle = null @@ -185,5 +158,13 @@ internal class HighlightNode( } else { null } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + paint.shader = with(highlight.style) { + createShader( + shape = shapeProvider.shape, + runtimeShaderCache = runtimeShaderCache + ) + } + } } } diff --git a/backdrop/src/main/java/com/kyant/backdrop/highlight/HighlightStyle.kt b/backdrop/src/main/java/com/kyant/backdrop/highlight/HighlightStyle.kt index 6a61de3..5992ece 100644 --- a/backdrop/src/main/java/com/kyant/backdrop/highlight/HighlightStyle.kt +++ b/backdrop/src/main/java/com/kyant/backdrop/highlight/HighlightStyle.kt @@ -8,9 +8,8 @@ import androidx.compose.runtime.Immutable import androidx.compose.runtime.Stable import androidx.compose.ui.graphics.BlendMode import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.RenderEffect +import androidx.compose.ui.graphics.Shader import androidx.compose.ui.graphics.Shape -import androidx.compose.ui.graphics.asComposeRenderEffect import androidx.compose.ui.graphics.drawscope.DrawScope import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.util.fastCoerceAtMost @@ -27,10 +26,10 @@ interface HighlightStyle { val blendMode: BlendMode @RequiresApi(Build.VERSION_CODES.S) - fun DrawScope.createRenderEffect( + fun DrawScope.createShader( shape: Shape, runtimeShaderCache: RuntimeShaderCache - ): RenderEffect? + ): Shader? @Immutable data class Plain( @@ -39,10 +38,10 @@ interface HighlightStyle { ) : HighlightStyle { @RequiresApi(Build.VERSION_CODES.S) - override fun DrawScope.createRenderEffect( + override fun DrawScope.createShader( shape: Shape, runtimeShaderCache: RuntimeShaderCache - ): RenderEffect? = null + ): Shader? = null } @Immutable @@ -57,20 +56,20 @@ interface HighlightStyle { override val blendMode: BlendMode = BlendMode.Plus @RequiresApi(Build.VERSION_CODES.S) - override fun DrawScope.createRenderEffect( + override fun DrawScope.createShader( shape: Shape, runtimeShaderCache: RuntimeShaderCache - ): RenderEffect? { + ): Shader? { return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - val shader = runtimeShaderCache.obtainRuntimeShader("Default", DefaultHighlightShaderString) - shader.apply { + runtimeShaderCache.obtainRuntimeShader( + "Default", + DefaultHighlightShaderString + ).apply { setFloatUniform("size", size.width, size.height) setFloatUniform("cornerRadii", getCornerRadii(shape)) setFloatUniform("angle", angle * (PI / 180f).toFloat()) setFloatUniform("falloff", falloff) } - android.graphics.RenderEffect.createRuntimeShaderEffect(shader, "content") - .asComposeRenderEffect() } else { null } @@ -87,20 +86,20 @@ interface HighlightStyle { override val blendMode: BlendMode = DrawScope.DefaultBlendMode @RequiresApi(Build.VERSION_CODES.S) - override fun DrawScope.createRenderEffect( + override fun DrawScope.createShader( shape: Shape, runtimeShaderCache: RuntimeShaderCache - ): RenderEffect? { + ): Shader? { return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - val shader = runtimeShaderCache.obtainRuntimeShader("Ambient", AmbientHighlightShaderString) - shader.apply { + runtimeShaderCache.obtainRuntimeShader( + "Ambient", + AmbientHighlightShaderString + ).apply { setFloatUniform("size", size.width, size.height) setFloatUniform("cornerRadii", getCornerRadii(shape)) setFloatUniform("angle", 45f * (PI / 180f).toFloat()) setFloatUniform("falloff", 1f) } - android.graphics.RenderEffect.createRuntimeShaderEffect(shader, "content") - .asComposeRenderEffect() } else { null } @@ -121,9 +120,9 @@ interface HighlightStyle { } private fun DrawScope.getCornerRadii(shape: Shape): FloatArray { - val shape = shape as? CornerBasedShape ?: return FloatArray(4) { size.minDimension / 2f } val size = size val maxRadius = size.minDimension / 2f + val shape = shape as? CornerBasedShape ?: return FloatArray(4) { maxRadius } val isLtr = layoutDirection == LayoutDirection.Ltr val topLeft = if (isLtr) shape.topStart.toPx(size, this)