Skip to content

Commit

Permalink
Add automatic HazeInputScale
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisbanes committed Dec 1, 2024
1 parent d41b8c7 commit 779b934
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 23 deletions.
14 changes: 10 additions & 4 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,19 @@ You can provide an input scale value which determines how much the content is sc
LargeTopAppBar(
// ...
modifier = Modifier.hazeChild(hazeState) {
inputScale = HazeInputScale.Fixed(0.5f)
inputScale = HazeInputScale.Auto
}
)
```

Using a value less than 1.0 **may** improve performance, at the sacrifice of quality and crispness. As always, run your own benchmarks as to whether this compromise is worth it.
`HazeInputScale` has a number of different options:

If you're looking for a good value to experiment with, `0.8` results in a reduction in total resolution of ~35%, while being visually imperceptible to most people (probably).
- `HazeInputScale.None`: Turns off input scaling (default)
- `HazeInputScale.Auto`: Turns on input scaling, with automatic values derived underneath.
- `HazeInputScale.Fixed(...)`: Turns on input scaling, using the value you pass in.

The minimum value I would realistically use is somewhere in the region of `0.5`, which results in the total pixel count of only 25% of the original content. This is likely to be visually different to no scaling, but depending on the styling parameters, it will be visually pleasing to the user.
When using a `Fixed` value, less than 1.0 **may** improve performance, at the sacrifice of quality and crispness. As always, run your own benchmarks as to whether this compromise is worth it.

If you're looking for a good value to experiment with, `0.66` results in a reduction in total resolution of ~55%, while being visually imperceptible to most people (probably).

The minimum value I would realistically use is somewhere in the region of `0.33`, which results in the total pixel count of only 11% of the original content. This is likely to be visually different to no scaling, but depending on the styling parameters, it will be visually pleasing to the user.
4 changes: 4 additions & 0 deletions haze/api/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ package dev.chrisbanes.haze {
field public static final dev.chrisbanes.haze.HazeInputScale.Companion Companion;
}

public static final class HazeInputScale.Auto implements dev.chrisbanes.haze.HazeInputScale {
field public static final dev.chrisbanes.haze.HazeInputScale.Auto INSTANCE;
}

public static final class HazeInputScale.Companion {
method public dev.chrisbanes.haze.HazeInputScale getDefault();
property @dev.chrisbanes.haze.ExperimentalHazeApi public final dev.chrisbanes.haze.HazeInputScale Default;
Expand Down
8 changes: 7 additions & 1 deletion haze/src/commonMain/kotlin/dev/chrisbanes/haze/HazeChild.kt
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,12 @@ sealed interface HazeInputScale {
*/
data object None : HazeInputScale

/**
* Automatic input scaling. Haze will attempt to use an appropriate input scale depending on
* the other settings which have been set. The values used underneath may change in the future.
*/
data object Auto : HazeInputScale

/**
* An input scale which uses a fixed scale factor.
*
Expand All @@ -175,7 +181,7 @@ sealed interface HazeInputScale {
companion object {
/**
* The default [HazeInputScale] value. Currently this resolves to [HazeInputScale.None] but
* this may change in the future.
* this may change in the future, probably to [HazeInputScale.Auto].
*/
@ExperimentalHazeApi
val Default: HazeInputScale get() = None
Expand Down
34 changes: 20 additions & 14 deletions haze/src/commonMain/kotlin/dev/chrisbanes/haze/HazeChildNode.kt
Original file line number Diff line number Diff line change
Expand Up @@ -259,24 +259,19 @@ class HazeChildNode(
}

override fun ContentDrawScope.draw() {
log(TAG) { "-> HazeChild. start draw()" }

require(!state.contentDrawing) {
"Layout nodes using Modifier.haze and Modifier.hazeChild can not be descendants of each other"
}

if (!isValid) {
// If we don't have any effects, just call drawContent and return early
drawContent()
log(TAG) { "-> HazeChild. end draw()" }
return
}
log(TAG) { "-> HazeChild. start draw()" }

val contentLayer = state.contentLayer
if (contentLayer != null && blurEnabled && canUseGraphicLayers()) {
drawEffectWithGraphicsLayer(contentLayer)
} else {
drawEffectWithScrim()
if (isValid) {
val contentLayer = state.contentLayer
if (contentLayer != null && blurEnabled && canUseGraphicLayers()) {
drawEffectWithGraphicsLayer(contentLayer)
} else {
drawEffectWithScrim()
}
}

// Finally we draw the content
Expand Down Expand Up @@ -535,9 +530,20 @@ internal data class RenderEffectParams(
)

@ExperimentalHazeApi
internal fun HazeChildNode.calculateInputScaleFactor(): Float = when (val s = inputScale) {
internal fun HazeChildNode.calculateInputScaleFactor(
blurRadius: Dp = resolveBlurRadius(),
): Float = when (val s = inputScale) {
HazeInputScale.None -> 1f
is HazeInputScale.Fixed -> s.scale
HazeInputScale.Auto -> {
when {
// For small blurRadius values, input scaling is very noticeable therefore we turn it off
blurRadius < 7.dp -> 1f
progressive != null -> 0.5f
mask != null -> 0.5f
else -> 0.3334f
}
}
}

@OptIn(ExperimentalHazeApi::class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,11 @@ import dev.chrisbanes.haze.HazeInputScale

val Samples = listOf(
Sample("Scaffold") { ScaffoldSample(it) },
Sample("Scaffold (input scaled)") { ScaffoldSample(it, inputScale = HazeInputScale.Fixed(0.5f)) },
Sample("Scaffold (input scaled)") { ScaffoldSample(it, inputScale = HazeInputScale.Auto) },
Sample("Scaffold (progressive blur)") { ScaffoldSample(it, ScaffoldSampleMode.Progressive) },
Sample("Scaffold (progressive blur, input scaled)") {
ScaffoldSample(it, ScaffoldSampleMode.Progressive, HazeInputScale.Fixed(0.5f))
},
Sample("Scaffold (progressive blur, input scaled)") { ScaffoldSample(it, ScaffoldSampleMode.Progressive, HazeInputScale.Auto) },
Sample("Scaffold (masked)") { ScaffoldSample(it, ScaffoldSampleMode.Mask) },
Sample("Scaffold (masked, input scaled)") { ScaffoldSample(it, ScaffoldSampleMode.Mask, HazeInputScale.Auto) },
Sample("Credit Card") { CreditCardSample(it) },
Sample("Images List") { ImagesList(it) },
Sample("List over Image") { ListOverImage(it) },
Expand Down

0 comments on commit 779b934

Please sign in to comment.