Add compositingStrategy param for Modifier.liquidGlass

When using glass in a scrollable container #4, it's more efficient to use `Auto`. In most cases it's  more efficient to use `Offscreen`.
This commit is contained in:
Kyant0 committed 2025-07-28 14:10:56 +08:00
1 parent 1e9f309467
commit 2ffff6f519
9 files changed
+56 -42

No files matched your search

@@ -2,6 +2,7 @@ package com.kyant.liquidglass
import androidx.compose.foundation.shape.CornerBasedShape
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.CompositingStrategy
import androidx.compose.ui.graphics.GraphicsLayerScope
import androidx.compose.ui.layout.Measurable
import androidx.compose.ui.layout.MeasureResult
@@ -15,20 +16,22 @@ import androidx.compose.ui.platform.InspectorInfo
import androidx.compose.ui.unit.Constraints
internal class GlassShapeElement(
val style: () -> GlassStyle
val style: () -> GlassStyle,
val compositingStrategy: CompositingStrategy
) : ModifierNodeElement<GlassShapeNode>() {
override fun create(): GlassShapeNode {
return GlassShapeNode(style)
return GlassShapeNode(style, compositingStrategy)
}
override fun update(node: GlassShapeNode) {
node.update(style)
node.update(style, compositingStrategy)
}
override fun InspectorInfo.inspectableProperties() {
name = "glassShape"
properties["style"] = style
properties["compositingStrategy"] = compositingStrategy
}
override fun equals(other: Any?): Boolean {
@@ -36,17 +39,21 @@ internal class GlassShapeElement(
if (other !is GlassShapeElement) return false
if (style != other.style) return false
if (compositingStrategy != other.compositingStrategy) return false
return true
}
override fun hashCode(): Int {
return style.hashCode()
var result = style.hashCode()
result = 31 * result + compositingStrategy.hashCode()
return result
}
}
internal class GlassShapeNode(
var style: () -> GlassStyle
var style: () -> GlassStyle,
var compositingStrategy: CompositingStrategy
) : LayoutModifierNode, ObserverModifierNode, Modifier.Node() {
override val shouldAutoInvalidate: Boolean = false
@@ -62,6 +69,7 @@ internal class GlassShapeNode(
private val layerBlock: GraphicsLayerScope.() -> Unit = {
clip = true
shape = this@GlassShapeNode.shape
compositingStrategy = this@GlassShapeNode.compositingStrategy
}
override fun MeasureScope.measure(measurable: Measurable, constraints: Constraints): MeasureResult {
@@ -81,12 +89,17 @@ internal class GlassShapeNode(
}
fun update(
style: () -> GlassStyle
style: () -> GlassStyle,
compositingStrategy: CompositingStrategy
) {
if (this.style != style) {
this.style = style
updateShape()
}
if (this.compositingStrategy != compositingStrategy) {
this.compositingStrategy = compositingStrategy
invalidateLayer()
}
}
private fun updateShape() {
@@ -15,6 +15,7 @@ import androidx.compose.ui.draw.CacheDrawModifierNode
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.CompositingStrategy
import androidx.compose.ui.graphics.asAndroidColorFilter
import androidx.compose.ui.graphics.asComposeRenderEffect
import androidx.compose.ui.graphics.drawscope.translate
@@ -41,33 +42,39 @@ import kotlinx.coroutines.launch
fun Modifier.liquidGlass(
state: LiquidGlassProviderState,
style: () -> GlassStyle
): Modifier =
this
.then(GlassShapeElement(style = style))
.then(
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
LiquidGlassElement(
state = state,
style = style,
luminanceSampler = null
) then GlassBrushElement(
style = style
) then GlassHighlightElement(
style = style
)
} else {
Modifier
}
)
fun Modifier.liquidGlass(
state: LiquidGlassProviderState,
style: GlassStyle
style: GlassStyle,
compositingStrategy: CompositingStrategy = CompositingStrategy.Offscreen
): Modifier =
this.liquidGlass(
state = state,
luminanceSampler = null,
compositingStrategy = compositingStrategy,
style = { style }
)
fun Modifier.liquidGlass(
state: LiquidGlassProviderState,
compositingStrategy: CompositingStrategy = CompositingStrategy.Offscreen,
style: () -> GlassStyle
): Modifier =
this.liquidGlass(
state = state,
luminanceSampler = null,
compositingStrategy = compositingStrategy,
style = style
)
@ExperimentalLuminanceSamplerApi
fun Modifier.liquidGlass(
state: LiquidGlassProviderState,
style: GlassStyle,
compositingStrategy: CompositingStrategy = CompositingStrategy.Offscreen,
luminanceSampler: LuminanceSampler? = null
): Modifier =
this.liquidGlass(
state = state,
luminanceSampler = luminanceSampler,
compositingStrategy = compositingStrategy,
style = { style }
)
@@ -75,10 +82,16 @@ fun Modifier.liquidGlass(
fun Modifier.liquidGlass(
state: LiquidGlassProviderState,
luminanceSampler: LuminanceSampler? = null,
compositingStrategy: CompositingStrategy = CompositingStrategy.Offscreen,
style: () -> GlassStyle
): Modifier =
this
.then(GlassShapeElement(style = style))
.then(
GlassShapeElement(
style = style,
compositingStrategy = compositingStrategy
)
)
.then(
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
LiquidGlassElement(
@@ -95,18 +108,6 @@ fun Modifier.liquidGlass(
}
)
@ExperimentalLuminanceSamplerApi
fun Modifier.liquidGlass(
state: LiquidGlassProviderState,
style: GlassStyle,
luminanceSampler: LuminanceSampler? = null
): Modifier =
this.liquidGlass(
state = state,
luminanceSampler = luminanceSampler,
style = { style }
)
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
private class LiquidGlassElement(
val state: LiquidGlassProviderState,