diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
index d4b7accb..c224ad56 100644
--- a/.idea/kotlinc.xml
+++ b/.idea/kotlinc.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/haze/src/androidMain/generated/baselineProfiles/baseline-prof.txt b/haze/src/androidMain/generated/baselineProfiles/baseline-prof.txt
index 36cb03cd..1eaed273 100644
--- a/haze/src/androidMain/generated/baselineProfiles/baseline-prof.txt
+++ b/haze/src/androidMain/generated/baselineProfiles/baseline-prof.txt
@@ -4,221 +4,174 @@ Ldev/chrisbanes/haze/BlendModeKt$$ExternalSyntheticApiModelOutline0;
HSPLdev/chrisbanes/haze/BlendModeKt$$ExternalSyntheticApiModelOutline0;->m$24()Landroid/graphics/BlendMode;
HSPLdev/chrisbanes/haze/BlendModeKt$$ExternalSyntheticApiModelOutline0;->m$26()Landroid/graphics/BlendMode;
HSPLdev/chrisbanes/haze/BlendModeKt$$ExternalSyntheticApiModelOutline0;->m()V
+PLdev/chrisbanes/haze/BlendModeKt$$ExternalSyntheticApiModelOutline0;->m(FFLandroid/graphics/RenderEffect;)Landroid/graphics/RenderEffect;
HSPLdev/chrisbanes/haze/BlendModeKt$$ExternalSyntheticApiModelOutline0;->m(FFLandroid/graphics/Shader$TileMode;)Landroid/graphics/RenderEffect;
HSPLdev/chrisbanes/haze/BlendModeKt$$ExternalSyntheticApiModelOutline0;->m(ILandroid/graphics/BlendMode;)Landroid/graphics/BlendModeColorFilter;
HSPLdev/chrisbanes/haze/BlendModeKt$$ExternalSyntheticApiModelOutline0;->m(Landroid/graphics/ColorFilter;Landroid/graphics/RenderEffect;)Landroid/graphics/RenderEffect;
-Ldev/chrisbanes/haze/HazeArea;
-HSPLdev/chrisbanes/haze/HazeArea;->()V
-HSPLdev/chrisbanes/haze/HazeArea;->()V
-HSPLdev/chrisbanes/haze/HazeArea;->getMask()Lkotlin/jvm/functions/Function0;
-HSPLdev/chrisbanes/haze/HazeArea;->getPositionOnScreen-F1C5BW0()J
-HSPLdev/chrisbanes/haze/HazeArea;->getSize-NH-jbRc()J
-HSPLdev/chrisbanes/haze/HazeArea;->getStyle()Lkotlin/jvm/functions/Function0;
-HSPLdev/chrisbanes/haze/HazeArea;->isValid()Z
-HSPLdev/chrisbanes/haze/HazeArea;->reset$haze_release()V
-HSPLdev/chrisbanes/haze/HazeArea;->setMask$haze_release(Lkotlin/jvm/functions/Function0;)V
-HSPLdev/chrisbanes/haze/HazeArea;->setPositionOnScreen-k-4lQ0M$haze_release(J)V
-HSPLdev/chrisbanes/haze/HazeArea;->setSize-uvyYCjk$haze_release(J)V
-HSPLdev/chrisbanes/haze/HazeArea;->setStyle$haze_release(Lkotlin/jvm/functions/Function0;)V
-Ldev/chrisbanes/haze/HazeArea$$ExternalSyntheticLambda0;
-HSPLdev/chrisbanes/haze/HazeArea$$ExternalSyntheticLambda0;->()V
-Ldev/chrisbanes/haze/HazeArea$mask$1;
-HSPLdev/chrisbanes/haze/HazeArea$mask$1;->()V
-HSPLdev/chrisbanes/haze/HazeArea$mask$1;->()V
+PLdev/chrisbanes/haze/BlendModeKt$$ExternalSyntheticApiModelOutline0;->m(Landroid/graphics/RenderEffect;Landroid/graphics/RenderEffect;Landroid/graphics/BlendMode;)Landroid/graphics/RenderEffect;
+PLdev/chrisbanes/haze/BlendModeKt$$ExternalSyntheticApiModelOutline0;->m(Landroid/graphics/Shader;)Landroid/graphics/RenderEffect;
Ldev/chrisbanes/haze/HazeChildKt;
-HSPLdev/chrisbanes/haze/HazeChildKt;->$r8$lambda$Cfv4pX3Ar2fhrIW2zXilDymXOWo(Ldev/chrisbanes/haze/HazeStyle;)Ldev/chrisbanes/haze/HazeStyle;
-HSPLdev/chrisbanes/haze/HazeChildKt;->$r8$lambda$F-RQkrkWwdgvYKjPvJx0705viAw(Landroidx/compose/ui/graphics/Brush;)Landroidx/compose/ui/graphics/Brush;
-HSPLdev/chrisbanes/haze/HazeChildKt;->hazeChild$default(Landroidx/compose/ui/Modifier;Ldev/chrisbanes/haze/HazeState;Ldev/chrisbanes/haze/HazeStyle;Landroidx/compose/ui/graphics/Brush;ILjava/lang/Object;)Landroidx/compose/ui/Modifier;
-HSPLdev/chrisbanes/haze/HazeChildKt;->hazeChild$lambda$0(Landroidx/compose/ui/graphics/Brush;)Landroidx/compose/ui/graphics/Brush;
-HSPLdev/chrisbanes/haze/HazeChildKt;->hazeChild$lambda$1(Ldev/chrisbanes/haze/HazeStyle;)Ldev/chrisbanes/haze/HazeStyle;
-HSPLdev/chrisbanes/haze/HazeChildKt;->hazeChild(Landroidx/compose/ui/Modifier;Ldev/chrisbanes/haze/HazeState;Ldev/chrisbanes/haze/HazeStyle;Landroidx/compose/ui/graphics/Brush;)Landroidx/compose/ui/Modifier;
-HSPLdev/chrisbanes/haze/HazeChildKt;->hazeChild(Landroidx/compose/ui/Modifier;Ldev/chrisbanes/haze/HazeState;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)Landroidx/compose/ui/Modifier;
+HSPLdev/chrisbanes/haze/HazeChildKt;->$r8$lambda$RUMZ3jwY2AK94GufVmYRU2D3BV8(Ldev/chrisbanes/haze/HazeStyle;Ldev/chrisbanes/haze/HazeChildScope;)Lkotlin/Unit;
+HSPLdev/chrisbanes/haze/HazeChildKt;->hazeChild$lambda$0(Ldev/chrisbanes/haze/HazeStyle;Ldev/chrisbanes/haze/HazeChildScope;)Lkotlin/Unit;
+HSPLdev/chrisbanes/haze/HazeChildKt;->hazeChild(Landroidx/compose/ui/Modifier;Ldev/chrisbanes/haze/HazeState;Ldev/chrisbanes/haze/HazeStyle;)Landroidx/compose/ui/Modifier;
+HSPLdev/chrisbanes/haze/HazeChildKt;->hazeChild(Landroidx/compose/ui/Modifier;Ldev/chrisbanes/haze/HazeState;Lkotlin/jvm/functions/Function1;)Landroidx/compose/ui/Modifier;
Ldev/chrisbanes/haze/HazeChildKt$$ExternalSyntheticLambda0;
-HSPLdev/chrisbanes/haze/HazeChildKt$$ExternalSyntheticLambda0;->(Landroidx/compose/ui/graphics/Brush;)V
-HSPLdev/chrisbanes/haze/HazeChildKt$$ExternalSyntheticLambda0;->invoke()Ljava/lang/Object;
-Ldev/chrisbanes/haze/HazeChildKt$$ExternalSyntheticLambda1;
-HSPLdev/chrisbanes/haze/HazeChildKt$$ExternalSyntheticLambda1;->(Ldev/chrisbanes/haze/HazeStyle;)V
-HSPLdev/chrisbanes/haze/HazeChildKt$$ExternalSyntheticLambda1;->invoke()Ljava/lang/Object;
+HSPLdev/chrisbanes/haze/HazeChildKt$$ExternalSyntheticLambda0;->(Ldev/chrisbanes/haze/HazeStyle;)V
+HSPLdev/chrisbanes/haze/HazeChildKt$$ExternalSyntheticLambda0;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
Ldev/chrisbanes/haze/HazeChildNode;
-HSPLdev/chrisbanes/haze/HazeChildNode;->$r8$lambda$VIbvP3j28u0E8eGVT1GTHYOc0Ag()Ldev/chrisbanes/haze/HazeArea;
+PLdev/chrisbanes/haze/HazeChildNode;->$r8$lambda$KBVHyW0Fa_iPAdXCb7pSXOrOafY(Landroidx/compose/ui/graphics/layer/GraphicsLayer;Landroidx/compose/ui/graphics/drawscope/DrawScope;)Lkotlin/Unit;
+HSPLdev/chrisbanes/haze/HazeChildNode;->$r8$lambda$a14gtlAPqbHQS_Fxl2vWXRn7cdQ(Ldev/chrisbanes/haze/HazeChildNode;)Lkotlin/Unit;
+HSPLdev/chrisbanes/haze/HazeChildNode;->$r8$lambda$iLza8U6jk8SqjThbFtFgItaR2Xs(Ldev/chrisbanes/haze/HazeChildNode;JLandroidx/compose/ui/graphics/layer/GraphicsLayer;Landroidx/compose/ui/graphics/drawscope/DrawScope;)Lkotlin/Unit;
HSPLdev/chrisbanes/haze/HazeChildNode;->()V
-HSPLdev/chrisbanes/haze/HazeChildNode;->(Ldev/chrisbanes/haze/HazeState;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)V
-HSPLdev/chrisbanes/haze/HazeChildNode;->area_delegate$lambda$1()Ldev/chrisbanes/haze/HazeArea;
-HSPLdev/chrisbanes/haze/HazeChildNode;->calculateHazeAreas()Lkotlin/sequences/Sequence;
+HSPLdev/chrisbanes/haze/HazeChildNode;->(Ldev/chrisbanes/haze/HazeState;Lkotlin/jvm/functions/Function1;)V
+HSPLdev/chrisbanes/haze/HazeChildNode;->access$getPositionOnScreen-F1C5BW0(Ldev/chrisbanes/haze/HazeChildNode;)J
HSPLdev/chrisbanes/haze/HazeChildNode;->draw(Landroidx/compose/ui/graphics/drawscope/ContentDrawScope;)V
-HSPLdev/chrisbanes/haze/HazeChildNode;->getArea()Ldev/chrisbanes/haze/HazeArea;
-HSPLdev/chrisbanes/haze/HazeChildNode;->getState()Ldev/chrisbanes/haze/HazeState;
+HSPLdev/chrisbanes/haze/HazeChildNode;->drawEffectWithGraphicsLayer$lambda$7(Ldev/chrisbanes/haze/HazeChildNode;JLandroidx/compose/ui/graphics/layer/GraphicsLayer;Landroidx/compose/ui/graphics/drawscope/DrawScope;)Lkotlin/Unit;
+HSPLdev/chrisbanes/haze/HazeChildNode;->drawEffectWithGraphicsLayer(Landroidx/compose/ui/graphics/drawscope/DrawScope;Landroidx/compose/ui/graphics/layer/GraphicsLayer;)V
+HSPLdev/chrisbanes/haze/HazeChildNode;->drawEffectWithScrim(Landroidx/compose/ui/graphics/drawscope/DrawScope;)V
+PLdev/chrisbanes/haze/HazeChildNode;->drawLinearGradientProgressiveEffect-Fgt4K4Q(Landroidx/compose/ui/graphics/drawscope/DrawScope;Ldev/chrisbanes/haze/ReusableHazeEffect;Ldev/chrisbanes/haze/HazeProgressive$LinearGradient;JLandroidx/compose/ui/graphics/layer/GraphicsLayer;)V
+PLdev/chrisbanes/haze/HazeChildNode;->drawLinearGradientProgressiveEffect_Fgt4K4Q$lambda$11(Landroidx/compose/ui/graphics/layer/GraphicsLayer;Landroidx/compose/ui/graphics/drawscope/DrawScope;)Lkotlin/Unit;
+HSPLdev/chrisbanes/haze/HazeChildNode;->getEffect()Ldev/chrisbanes/haze/ReusableHazeEffect;
+HSPLdev/chrisbanes/haze/HazeChildNode;->getPositionOnScreen-F1C5BW0()J
+HSPLdev/chrisbanes/haze/HazeChildNode;->getShouldAutoInvalidate()Z
+HSPLdev/chrisbanes/haze/HazeChildNode;->onAttach()V
+HSPLdev/chrisbanes/haze/HazeChildNode;->onGloballyPositioned(Landroidx/compose/ui/layout/LayoutCoordinates;)V
+HSPLdev/chrisbanes/haze/HazeChildNode;->onMeasureResultChanged()V
+HSPLdev/chrisbanes/haze/HazeChildNode;->onObservedReadsChanged$lambda$0(Ldev/chrisbanes/haze/HazeChildNode;)Lkotlin/Unit;
+HSPLdev/chrisbanes/haze/HazeChildNode;->onObservedReadsChanged()V
HSPLdev/chrisbanes/haze/HazeChildNode;->onPlaced(Landroidx/compose/ui/layout/LayoutCoordinates;)V
-HSPLdev/chrisbanes/haze/HazeChildNode;->onReset()V
-HSPLdev/chrisbanes/haze/HazeChildNode;->setMask(Lkotlin/jvm/functions/Function0;)V
+HSPLdev/chrisbanes/haze/HazeChildNode;->onPostDraw(Ldev/chrisbanes/haze/ReusableHazeEffect;)V
+HSPLdev/chrisbanes/haze/HazeChildNode;->onPreDraw(Ldev/chrisbanes/haze/ReusableHazeEffect;Landroidx/compose/ui/unit/Density;)V
+HSPLdev/chrisbanes/haze/HazeChildNode;->onRemeasured-ozmzZPI(J)V
+HSPLdev/chrisbanes/haze/HazeChildNode;->setBlock(Lkotlin/jvm/functions/Function1;)V
HSPLdev/chrisbanes/haze/HazeChildNode;->setState(Ldev/chrisbanes/haze/HazeState;)V
-HSPLdev/chrisbanes/haze/HazeChildNode;->setStyle(Lkotlin/jvm/functions/Function0;)V
HSPLdev/chrisbanes/haze/HazeChildNode;->update()V
+HSPLdev/chrisbanes/haze/HazeChildNode;->updateEffect()V
Ldev/chrisbanes/haze/HazeChildNode$$ExternalSyntheticLambda0;
HSPLdev/chrisbanes/haze/HazeChildNode$$ExternalSyntheticLambda0;->()V
Ldev/chrisbanes/haze/HazeChildNode$$ExternalSyntheticLambda1;
Ldev/chrisbanes/haze/HazeChildNode$$ExternalSyntheticLambda2;
HSPLdev/chrisbanes/haze/HazeChildNode$$ExternalSyntheticLambda2;->()V
Ldev/chrisbanes/haze/HazeChildNode$$ExternalSyntheticLambda3;
-HSPLdev/chrisbanes/haze/HazeChildNode$$ExternalSyntheticLambda3;->()V
+HSPLdev/chrisbanes/haze/HazeChildNode$$ExternalSyntheticLambda3;->(Ldev/chrisbanes/haze/HazeChildNode;)V
HSPLdev/chrisbanes/haze/HazeChildNode$$ExternalSyntheticLambda3;->invoke()Ljava/lang/Object;
+PLdev/chrisbanes/haze/HazeChildNode$$ExternalSyntheticLambda4;->(Landroidx/compose/ui/graphics/layer/GraphicsLayer;)V
+PLdev/chrisbanes/haze/HazeChildNode$$ExternalSyntheticLambda4;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
+PLdev/chrisbanes/haze/HazeChildNode$$ExternalSyntheticLambda5;->(IFFLjava/util/List;)V
+Ldev/chrisbanes/haze/HazeChildNode$$ExternalSyntheticLambda6;
+HSPLdev/chrisbanes/haze/HazeChildNode$$ExternalSyntheticLambda6;->(Ldev/chrisbanes/haze/HazeChildNode;JLandroidx/compose/ui/graphics/layer/GraphicsLayer;)V
+HSPLdev/chrisbanes/haze/HazeChildNode$$ExternalSyntheticLambda6;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
Ldev/chrisbanes/haze/HazeChildNode$Companion;
HSPLdev/chrisbanes/haze/HazeChildNode$Companion;->()V
HSPLdev/chrisbanes/haze/HazeChildNode$Companion;->(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
+Ldev/chrisbanes/haze/HazeChildNode$effect$2;
+HSPLdev/chrisbanes/haze/HazeChildNode$effect$2;->()V
+HSPLdev/chrisbanes/haze/HazeChildNode$effect$2;->()V
+HSPLdev/chrisbanes/haze/HazeChildNode$effect$2;->invoke()Ldev/chrisbanes/haze/ReusableHazeEffect;
+HSPLdev/chrisbanes/haze/HazeChildNode$effect$2;->invoke()Ljava/lang/Object;
Ldev/chrisbanes/haze/HazeChildNodeElement;
-HSPLdev/chrisbanes/haze/HazeChildNodeElement;->(Ldev/chrisbanes/haze/HazeState;Lkotlin/jvm/functions/Function0;Lkotlin/jvm/functions/Function0;)V
+HSPLdev/chrisbanes/haze/HazeChildNodeElement;->(Ldev/chrisbanes/haze/HazeState;Lkotlin/jvm/functions/Function1;)V
HSPLdev/chrisbanes/haze/HazeChildNodeElement;->create()Landroidx/compose/ui/Modifier$Node;
HSPLdev/chrisbanes/haze/HazeChildNodeElement;->create()Ldev/chrisbanes/haze/HazeChildNode;
HSPLdev/chrisbanes/haze/HazeChildNodeElement;->equals(Ljava/lang/Object;)Z
HSPLdev/chrisbanes/haze/HazeChildNodeElement;->update(Landroidx/compose/ui/Modifier$Node;)V
HSPLdev/chrisbanes/haze/HazeChildNodeElement;->update(Ldev/chrisbanes/haze/HazeChildNode;)V
-Ldev/chrisbanes/haze/HazeEffect;
-HSPLdev/chrisbanes/haze/HazeEffect;->()V
-HSPLdev/chrisbanes/haze/HazeEffect;->(Ldev/chrisbanes/haze/HazeArea;)V
-HSPLdev/chrisbanes/haze/HazeEffect;->getArea()Ldev/chrisbanes/haze/HazeArea;
-HSPLdev/chrisbanes/haze/HazeEffect;->getBackgroundColor-0d7_KjU()J
-HSPLdev/chrisbanes/haze/HazeEffect;->getBlurRadius-D9Ej5fM()F
-HSPLdev/chrisbanes/haze/HazeEffect;->getFallbackTint()Ldev/chrisbanes/haze/HazeTint;
-HSPLdev/chrisbanes/haze/HazeEffect;->getLayerOffset-F1C5BW0()J
-HSPLdev/chrisbanes/haze/HazeEffect;->getLayerSize-NH-jbRc()J
-HSPLdev/chrisbanes/haze/HazeEffect;->getMask()Landroidx/compose/ui/graphics/Brush;
-HSPLdev/chrisbanes/haze/HazeEffect;->getNoiseFactor()F
-HSPLdev/chrisbanes/haze/HazeEffect;->getPositionOnScreen-F1C5BW0()J
-HSPLdev/chrisbanes/haze/HazeEffect;->getRenderEffect()Landroidx/compose/ui/graphics/RenderEffect;
-HSPLdev/chrisbanes/haze/HazeEffect;->getRenderEffectDirty()Z
-HSPLdev/chrisbanes/haze/HazeEffect;->getSize-NH-jbRc()J
-HSPLdev/chrisbanes/haze/HazeEffect;->getTints()Ljava/util/List;
-HSPLdev/chrisbanes/haze/HazeEffect;->setBackgroundColor-8_81llA(J)V
-HSPLdev/chrisbanes/haze/HazeEffect;->setBlurRadius-0680j_4(F)V
-HSPLdev/chrisbanes/haze/HazeEffect;->setFallbackTint(Ldev/chrisbanes/haze/HazeTint;)V
-HSPLdev/chrisbanes/haze/HazeEffect;->setLayerSize-uvyYCjk(J)V
-HSPLdev/chrisbanes/haze/HazeEffect;->setMask(Landroidx/compose/ui/graphics/Brush;)V
-HSPLdev/chrisbanes/haze/HazeEffect;->setNoiseFactor(F)V
-HSPLdev/chrisbanes/haze/HazeEffect;->setPositionOnScreen-k-4lQ0M(J)V
-HSPLdev/chrisbanes/haze/HazeEffect;->setRenderEffect(Landroidx/compose/ui/graphics/RenderEffect;)V
-HSPLdev/chrisbanes/haze/HazeEffect;->setRenderEffectDirty(Z)V
-HSPLdev/chrisbanes/haze/HazeEffect;->setSize-uvyYCjk(J)V
-HSPLdev/chrisbanes/haze/HazeEffect;->setTints(Ljava/util/List;)V
-Ldev/chrisbanes/haze/HazeEffectKt;
-HSPLdev/chrisbanes/haze/HazeEffectKt;->getBlurRadiusOrZero(Ldev/chrisbanes/haze/HazeEffect;)F
-HSPLdev/chrisbanes/haze/HazeEffectKt;->getNeedInvalidation(Ldev/chrisbanes/haze/HazeEffect;)Z
-Ldev/chrisbanes/haze/HazeEffectNode;
-HSPLdev/chrisbanes/haze/HazeEffectNode;->$r8$lambda$1xK0Q6UYaGNPerjewHv82vZr1pw(Ldev/chrisbanes/haze/HazeEffectNode;Landroidx/compose/ui/unit/Density;Ldev/chrisbanes/haze/HazeEffect;)Lkotlin/Unit;
-HSPLdev/chrisbanes/haze/HazeEffectNode;->$r8$lambda$2rOhtcrH86tgcRPpfAKerON-RJM(Ljava/util/Map;Ldev/chrisbanes/haze/HazeArea;)Ldev/chrisbanes/haze/HazeEffect;
-HSPLdev/chrisbanes/haze/HazeEffectNode;->$r8$lambda$TMiUDV1itjrEZWGcGXbTZbaTyv0(Ldev/chrisbanes/haze/HazeEffectNode;)Lkotlin/Unit;
-HSPLdev/chrisbanes/haze/HazeEffectNode;->$r8$lambda$Tc2swJu8TLb3sC-irz36XXNQLT4(Ldev/chrisbanes/haze/HazeArea;)Z
-HSPLdev/chrisbanes/haze/HazeEffectNode;->$r8$lambda$ahGLdlD8SE0EwtiS7eUcEblAxnQ(Ldev/chrisbanes/haze/HazeEffect;Ldev/chrisbanes/haze/HazeEffectNode;JLandroidx/compose/ui/graphics/layer/GraphicsLayer;Landroidx/compose/ui/graphics/drawscope/DrawScope;)Lkotlin/Unit;
-HSPLdev/chrisbanes/haze/HazeEffectNode;->()V
-HSPLdev/chrisbanes/haze/HazeEffectNode;->()V
-HSPLdev/chrisbanes/haze/HazeEffectNode;->drawEffect-Rg1IO4c$default(Ldev/chrisbanes/haze/HazeEffectNode;Landroidx/compose/ui/graphics/drawscope/DrawScope;Ldev/chrisbanes/haze/HazeEffect;JLandroidx/compose/ui/graphics/layer/GraphicsLayer;ILjava/lang/Object;)V
-HSPLdev/chrisbanes/haze/HazeEffectNode;->drawEffect-Rg1IO4c(Landroidx/compose/ui/graphics/drawscope/DrawScope;Ldev/chrisbanes/haze/HazeEffect;JLandroidx/compose/ui/graphics/layer/GraphicsLayer;)V
-HSPLdev/chrisbanes/haze/HazeEffectNode;->drawEffectsWithGraphicsLayer$lambda$8$lambda$7(Ldev/chrisbanes/haze/HazeEffect;Ldev/chrisbanes/haze/HazeEffectNode;JLandroidx/compose/ui/graphics/layer/GraphicsLayer;Landroidx/compose/ui/graphics/drawscope/DrawScope;)Lkotlin/Unit;
-HSPLdev/chrisbanes/haze/HazeEffectNode;->drawEffectsWithGraphicsLayer(Landroidx/compose/ui/graphics/drawscope/DrawScope;Landroidx/compose/ui/graphics/layer/GraphicsLayer;)V
-HSPLdev/chrisbanes/haze/HazeEffectNode;->drawEffectsWithScrim(Landroidx/compose/ui/graphics/drawscope/DrawScope;)V
-HSPLdev/chrisbanes/haze/HazeEffectNode;->getEffects()Ljava/util/List;
-HSPLdev/chrisbanes/haze/HazeEffectNode;->getPositionOnScreen-F1C5BW0()J
-HSPLdev/chrisbanes/haze/HazeEffectNode;->getShouldAutoInvalidate()Z
-HSPLdev/chrisbanes/haze/HazeEffectNode;->onAttach()V
-HSPLdev/chrisbanes/haze/HazeEffectNode;->onGloballyPositioned(Landroidx/compose/ui/layout/LayoutCoordinates;)V
-HSPLdev/chrisbanes/haze/HazeEffectNode;->onMeasureResultChanged()V
-HSPLdev/chrisbanes/haze/HazeEffectNode;->onObservedReadsChanged$lambda$0(Ldev/chrisbanes/haze/HazeEffectNode;)Lkotlin/Unit;
-HSPLdev/chrisbanes/haze/HazeEffectNode;->onObservedReadsChanged()V
-HSPLdev/chrisbanes/haze/HazeEffectNode;->onPlaced(Landroidx/compose/ui/layout/LayoutCoordinates;)V
-HSPLdev/chrisbanes/haze/HazeEffectNode;->onPreDraw(Ldev/chrisbanes/haze/HazeEffect;Landroidx/compose/ui/unit/Density;)V
-HSPLdev/chrisbanes/haze/HazeEffectNode;->onRemeasured-ozmzZPI(J)V
-HSPLdev/chrisbanes/haze/HazeEffectNode;->setPositionOnScreen-k-4lQ0M(J)V
-HSPLdev/chrisbanes/haze/HazeEffectNode;->update()V
-HSPLdev/chrisbanes/haze/HazeEffectNode;->updateEffects$lambda$1(Ldev/chrisbanes/haze/HazeArea;)Z
-HSPLdev/chrisbanes/haze/HazeEffectNode;->updateEffects$lambda$2(Ljava/util/Map;Ldev/chrisbanes/haze/HazeArea;)Ldev/chrisbanes/haze/HazeEffect;
-HSPLdev/chrisbanes/haze/HazeEffectNode;->updateEffects$lambda$4(Ldev/chrisbanes/haze/HazeEffectNode;Landroidx/compose/ui/unit/Density;Ldev/chrisbanes/haze/HazeEffect;)Lkotlin/Unit;
-HSPLdev/chrisbanes/haze/HazeEffectNode;->updateEffects()V
-Ldev/chrisbanes/haze/HazeEffectNode$$ExternalSyntheticLambda0;
-HSPLdev/chrisbanes/haze/HazeEffectNode$$ExternalSyntheticLambda0;->(Ldev/chrisbanes/haze/HazeEffectNode;)V
-HSPLdev/chrisbanes/haze/HazeEffectNode$$ExternalSyntheticLambda0;->invoke()Ljava/lang/Object;
-Ldev/chrisbanes/haze/HazeEffectNode$$ExternalSyntheticLambda1;
-HSPLdev/chrisbanes/haze/HazeEffectNode$$ExternalSyntheticLambda1;->()V
-HSPLdev/chrisbanes/haze/HazeEffectNode$$ExternalSyntheticLambda1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
-Ldev/chrisbanes/haze/HazeEffectNode$$ExternalSyntheticLambda2;
-HSPLdev/chrisbanes/haze/HazeEffectNode$$ExternalSyntheticLambda2;->(Ljava/util/Map;)V
-HSPLdev/chrisbanes/haze/HazeEffectNode$$ExternalSyntheticLambda2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
-Ldev/chrisbanes/haze/HazeEffectNode$$ExternalSyntheticLambda3;
-HSPLdev/chrisbanes/haze/HazeEffectNode$$ExternalSyntheticLambda3;->(Ldev/chrisbanes/haze/HazeEffectNode;Landroidx/compose/ui/unit/Density;)V
-HSPLdev/chrisbanes/haze/HazeEffectNode$$ExternalSyntheticLambda3;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
-Ldev/chrisbanes/haze/HazeEffectNode$$ExternalSyntheticLambda4;
-HSPLdev/chrisbanes/haze/HazeEffectNode$$ExternalSyntheticLambda4;->(Ldev/chrisbanes/haze/HazeEffect;Ldev/chrisbanes/haze/HazeEffectNode;JLandroidx/compose/ui/graphics/layer/GraphicsLayer;)V
-HSPLdev/chrisbanes/haze/HazeEffectNode$$ExternalSyntheticLambda4;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
-Ldev/chrisbanes/haze/HazeEffect_androidKt;
-HSPLdev/chrisbanes/haze/HazeEffect_androidKt;->observeInvalidationTick(Ldev/chrisbanes/haze/HazeEffectNode;)V
+Ldev/chrisbanes/haze/HazeChildNodeKt;
+PLdev/chrisbanes/haze/HazeChildNodeKt;->access$calculateLength-wtYxqtY(JJJ)F
+HSPLdev/chrisbanes/haze/HazeChildNodeKt;->access$drawFallbackEffect-6a0pyJM(Landroidx/compose/ui/graphics/drawscope/DrawScope;FFLjava/util/List;Ldev/chrisbanes/haze/HazeTint;Landroidx/compose/ui/graphics/Brush;)V
+HSPLdev/chrisbanes/haze/HazeChildNodeKt;->access$expand-TmRCtEA(JF)J
+PLdev/chrisbanes/haze/HazeChildNodeKt;->access$lerp(FFF)F
+PLdev/chrisbanes/haze/HazeChildNodeKt;->calculateLength-wtYxqtY(JJJ)F
+HSPLdev/chrisbanes/haze/HazeChildNodeKt;->drawFallbackEffect-6a0pyJM(Landroidx/compose/ui/graphics/drawscope/DrawScope;FFLjava/util/List;Ldev/chrisbanes/haze/HazeTint;Landroidx/compose/ui/graphics/Brush;)V
+HSPLdev/chrisbanes/haze/HazeChildNodeKt;->drawFallbackEffect_6a0pyJM$scrim(Ldev/chrisbanes/haze/HazeTint;Landroidx/compose/ui/graphics/Brush;Landroidx/compose/ui/graphics/drawscope/DrawScope;)V
+HSPLdev/chrisbanes/haze/HazeChildNodeKt;->expand-TmRCtEA(JF)J
+HSPLdev/chrisbanes/haze/HazeChildNodeKt;->getBlurRadiusOrZero(Ldev/chrisbanes/haze/ReusableHazeEffect;)F
+HSPLdev/chrisbanes/haze/HazeChildNodeKt;->getNeedInvalidation(Ldev/chrisbanes/haze/ReusableHazeEffect;)Z
+PLdev/chrisbanes/haze/HazeChildNodeKt;->lerp(FFF)F
+Ldev/chrisbanes/haze/HazeChildNodeKt$$ExternalSyntheticLambda0;
+HSPLdev/chrisbanes/haze/HazeChildNodeKt$$ExternalSyntheticLambda0;->(Ldev/chrisbanes/haze/HazeTint;Landroidx/compose/ui/graphics/Brush;F)V
+Ldev/chrisbanes/haze/HazeChildScope;
+Ldev/chrisbanes/haze/HazeDefaults;
+HSPLdev/chrisbanes/haze/HazeDefaults;->()V
+HSPLdev/chrisbanes/haze/HazeDefaults;->()V
+HSPLdev/chrisbanes/haze/HazeDefaults;->getBlurRadius-D9Ej5fM()F
Ldev/chrisbanes/haze/HazeKt;
-HSPLdev/chrisbanes/haze/HazeKt;->access$boostTintForFallback-3ABfNKs(Ldev/chrisbanes/haze/HazeTint;F)Ldev/chrisbanes/haze/HazeTint;
-HSPLdev/chrisbanes/haze/HazeKt;->boostAlphaForBlurRadius-l07J4OM(JF)J
-HSPLdev/chrisbanes/haze/HazeKt;->boostTintForFallback-3ABfNKs(Ldev/chrisbanes/haze/HazeTint;F)Ldev/chrisbanes/haze/HazeTint;
-HSPLdev/chrisbanes/haze/HazeKt;->haze(Landroidx/compose/ui/Modifier;Ldev/chrisbanes/haze/HazeState;Ldev/chrisbanes/haze/HazeStyle;)Landroidx/compose/ui/Modifier;
-HSPLdev/chrisbanes/haze/HazeKt;->resolveStyle(Ldev/chrisbanes/haze/HazeStyle;Ldev/chrisbanes/haze/HazeStyle;)Ldev/chrisbanes/haze/HazeStyle;
+HSPLdev/chrisbanes/haze/HazeKt;->haze(Landroidx/compose/ui/Modifier;Ldev/chrisbanes/haze/HazeState;)Landroidx/compose/ui/Modifier;
Ldev/chrisbanes/haze/HazeNode;
-HSPLdev/chrisbanes/haze/HazeNode;->$r8$lambda$-CzCB03VEdD1kta4WTg4u494RoA(Landroidx/compose/ui/graphics/drawscope/ContentDrawScope;Landroidx/compose/ui/graphics/drawscope/DrawScope;)Lkotlin/Unit;
-HSPLdev/chrisbanes/haze/HazeNode;->$r8$lambda$YPx_mXKDPp0SRYkuNC0oTdC059c(Ldev/chrisbanes/haze/HazeNode;)Ldev/chrisbanes/haze/HazeStyle;
+HSPLdev/chrisbanes/haze/HazeNode;->$r8$lambda$ZAFTqbULq_DcmjZSqRUARRZ_3DY(Landroidx/compose/ui/graphics/drawscope/ContentDrawScope;Landroidx/compose/ui/graphics/drawscope/DrawScope;)Lkotlin/Unit;
HSPLdev/chrisbanes/haze/HazeNode;->()V
-HSPLdev/chrisbanes/haze/HazeNode;->(Ldev/chrisbanes/haze/HazeState;Ldev/chrisbanes/haze/HazeStyle;)V
-HSPLdev/chrisbanes/haze/HazeNode;->draw$lambda$6(Landroidx/compose/ui/graphics/drawscope/ContentDrawScope;Landroidx/compose/ui/graphics/drawscope/DrawScope;)Lkotlin/Unit;
+HSPLdev/chrisbanes/haze/HazeNode;->(Ldev/chrisbanes/haze/HazeState;)V
+HSPLdev/chrisbanes/haze/HazeNode;->draw$lambda$3(Landroidx/compose/ui/graphics/drawscope/ContentDrawScope;Landroidx/compose/ui/graphics/drawscope/DrawScope;)Lkotlin/Unit;
HSPLdev/chrisbanes/haze/HazeNode;->draw(Landroidx/compose/ui/graphics/drawscope/ContentDrawScope;)V
HSPLdev/chrisbanes/haze/HazeNode;->getShouldAutoInvalidate()Z
-HSPLdev/chrisbanes/haze/HazeNode;->onAttach()V
HSPLdev/chrisbanes/haze/HazeNode;->onDetach()V
HSPLdev/chrisbanes/haze/HazeNode;->onGloballyPositioned(Landroidx/compose/ui/layout/LayoutCoordinates;)V
HSPLdev/chrisbanes/haze/HazeNode;->onMeasureResultChanged()V
HSPLdev/chrisbanes/haze/HazeNode;->onPlaced(Landroidx/compose/ui/layout/LayoutCoordinates;)V
HSPLdev/chrisbanes/haze/HazeNode;->onRemeasured-ozmzZPI(J)V
-HSPLdev/chrisbanes/haze/HazeNode;->setDefaultStyle(Ldev/chrisbanes/haze/HazeStyle;)V
HSPLdev/chrisbanes/haze/HazeNode;->setState(Ldev/chrisbanes/haze/HazeState;)V
-HSPLdev/chrisbanes/haze/HazeNode;->update$lambda$0(Ldev/chrisbanes/haze/HazeNode;)Ldev/chrisbanes/haze/HazeStyle;
-HSPLdev/chrisbanes/haze/HazeNode;->update()V
Ldev/chrisbanes/haze/HazeNode$$ExternalSyntheticLambda0;
-HSPLdev/chrisbanes/haze/HazeNode$$ExternalSyntheticLambda0;->(Ldev/chrisbanes/haze/HazeNode;)V
-HSPLdev/chrisbanes/haze/HazeNode$$ExternalSyntheticLambda0;->invoke()Ljava/lang/Object;
+HSPLdev/chrisbanes/haze/HazeNode$$ExternalSyntheticLambda0;->()V
Ldev/chrisbanes/haze/HazeNode$$ExternalSyntheticLambda1;
-HSPLdev/chrisbanes/haze/HazeNode$$ExternalSyntheticLambda1;->()V
+HSPLdev/chrisbanes/haze/HazeNode$$ExternalSyntheticLambda1;->(Landroidx/compose/ui/graphics/drawscope/ContentDrawScope;)V
+HSPLdev/chrisbanes/haze/HazeNode$$ExternalSyntheticLambda1;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
Ldev/chrisbanes/haze/HazeNode$$ExternalSyntheticLambda2;
-HSPLdev/chrisbanes/haze/HazeNode$$ExternalSyntheticLambda2;->(Landroidx/compose/ui/graphics/drawscope/ContentDrawScope;)V
-HSPLdev/chrisbanes/haze/HazeNode$$ExternalSyntheticLambda2;->invoke(Ljava/lang/Object;)Ljava/lang/Object;
-Ldev/chrisbanes/haze/HazeNode$$ExternalSyntheticLambda3;
-HSPLdev/chrisbanes/haze/HazeNode$$ExternalSyntheticLambda3;->()V
+HSPLdev/chrisbanes/haze/HazeNode$$ExternalSyntheticLambda2;->()V
Ldev/chrisbanes/haze/HazeNode$Companion;
HSPLdev/chrisbanes/haze/HazeNode$Companion;->()V
HSPLdev/chrisbanes/haze/HazeNode$Companion;->(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
Ldev/chrisbanes/haze/HazeNodeElement;
HSPLdev/chrisbanes/haze/HazeNodeElement;->()V
-HSPLdev/chrisbanes/haze/HazeNodeElement;->(Ldev/chrisbanes/haze/HazeState;Ldev/chrisbanes/haze/HazeStyle;)V
+HSPLdev/chrisbanes/haze/HazeNodeElement;->(Ldev/chrisbanes/haze/HazeState;)V
HSPLdev/chrisbanes/haze/HazeNodeElement;->create()Landroidx/compose/ui/Modifier$Node;
HSPLdev/chrisbanes/haze/HazeNodeElement;->create()Ldev/chrisbanes/haze/HazeNode;
HSPLdev/chrisbanes/haze/HazeNodeElement;->equals(Ljava/lang/Object;)Z
HSPLdev/chrisbanes/haze/HazeNodeElement;->update(Landroidx/compose/ui/Modifier$Node;)V
HSPLdev/chrisbanes/haze/HazeNodeElement;->update(Ldev/chrisbanes/haze/HazeNode;)V
+Ldev/chrisbanes/haze/HazeNodeKt;
+HSPLdev/chrisbanes/haze/HazeNodeKt;->boostAlphaForBlurRadius-l07J4OM(JF)J
+HSPLdev/chrisbanes/haze/HazeNodeKt;->boostForFallback-3ABfNKs(Ldev/chrisbanes/haze/HazeTint;F)Ldev/chrisbanes/haze/HazeTint;
Ldev/chrisbanes/haze/HazeNode_androidKt;
HSPLdev/chrisbanes/haze/HazeNode_androidKt;->()V
-HSPLdev/chrisbanes/haze/HazeNode_androidKt;->createRenderEffect(Ldev/chrisbanes/haze/HazeEffectNode;Ldev/chrisbanes/haze/HazeEffect;Landroidx/compose/ui/unit/Density;)Landroidx/compose/ui/graphics/RenderEffect;
-HSPLdev/chrisbanes/haze/HazeNode_androidKt;->drawEffect(Ldev/chrisbanes/haze/HazeEffectNode;Landroidx/compose/ui/graphics/drawscope/DrawScope;Ldev/chrisbanes/haze/HazeEffect;Landroidx/compose/ui/graphics/layer/GraphicsLayer;)V
-HSPLdev/chrisbanes/haze/HazeNode_androidKt;->getUSE_GRAPHICS_LAYERS()Z
+HSPLdev/chrisbanes/haze/HazeNode_androidKt;->createRenderEffect-XOOFMZI$default(Ldev/chrisbanes/haze/HazeChildNode;FFLjava/util/List;FLandroidx/compose/ui/geometry/Rect;JLandroidx/compose/ui/graphics/Brush;ILjava/lang/Object;)Landroidx/compose/ui/graphics/RenderEffect;
+HSPLdev/chrisbanes/haze/HazeNode_androidKt;->createRenderEffect-XOOFMZI(Ldev/chrisbanes/haze/HazeChildNode;FFLjava/util/List;FLandroidx/compose/ui/geometry/Rect;JLandroidx/compose/ui/graphics/Brush;)Landroidx/compose/ui/graphics/RenderEffect;
+PLdev/chrisbanes/haze/HazeNode_androidKt;->toShader-d16Qtg0(Landroidx/compose/ui/graphics/Brush;J)Landroid/graphics/Shader;
+HSPLdev/chrisbanes/haze/HazeNode_androidKt;->useGraphicLayers(Landroidx/compose/ui/graphics/drawscope/DrawScope;)Z
HSPLdev/chrisbanes/haze/HazeNode_androidKt;->withBrush(Landroid/graphics/RenderEffect;Landroidx/compose/ui/graphics/Brush;Landroidx/compose/ui/geometry/Rect;Landroid/graphics/BlendMode;)Landroid/graphics/RenderEffect;
HSPLdev/chrisbanes/haze/HazeNode_androidKt;->withMask(Landroid/graphics/RenderEffect;Landroidx/compose/ui/graphics/Brush;Landroidx/compose/ui/geometry/Rect;)Landroid/graphics/RenderEffect;
HSPLdev/chrisbanes/haze/HazeNode_androidKt;->withNoise(Landroidx/compose/ui/node/CompositionLocalConsumerModifierNode;Landroid/graphics/RenderEffect;F)Landroid/graphics/RenderEffect;
-HSPLdev/chrisbanes/haze/HazeNode_androidKt;->withTint(Landroid/graphics/RenderEffect;Ldev/chrisbanes/haze/HazeTint;Landroidx/compose/ui/geometry/Rect;)Landroid/graphics/RenderEffect;
-HSPLdev/chrisbanes/haze/HazeNode_androidKt;->withTints(Landroid/graphics/RenderEffect;Ljava/util/List;Landroidx/compose/ui/geometry/Rect;)Landroid/graphics/RenderEffect;
+HSPLdev/chrisbanes/haze/HazeNode_androidKt;->withTint(Landroid/graphics/RenderEffect;Ldev/chrisbanes/haze/HazeTint;F)Landroid/graphics/RenderEffect;
+HSPLdev/chrisbanes/haze/HazeNode_androidKt;->withTints(Landroid/graphics/RenderEffect;Ljava/util/List;F)Landroid/graphics/RenderEffect;
+Ldev/chrisbanes/haze/HazeNode_androidKt$$ExternalSyntheticLambda7;
+HSPLdev/chrisbanes/haze/HazeNode_androidKt$$ExternalSyntheticLambda7;->(FFLjava/util/List;Landroidx/compose/ui/geometry/Rect;)V
Ldev/chrisbanes/haze/HazeNode_androidKt$special$$inlined$lruCache$default$1;
HSPLdev/chrisbanes/haze/HazeNode_androidKt$special$$inlined$lruCache$default$1;->(I)V
+Ldev/chrisbanes/haze/HazeProgressive;
+PLdev/chrisbanes/haze/HazeProgressive;->()V
+PLdev/chrisbanes/haze/HazeProgressive$Companion;->()V
+PLdev/chrisbanes/haze/HazeProgressive$Companion;->()V
+PLdev/chrisbanes/haze/HazeProgressive$Companion;->verticalGradient$default(Ldev/chrisbanes/haze/HazeProgressive$Companion;ILandroidx/compose/animation/core/Easing;FFFFILjava/lang/Object;)Ldev/chrisbanes/haze/HazeProgressive$LinearGradient;
+PLdev/chrisbanes/haze/HazeProgressive$Companion;->verticalGradient(ILandroidx/compose/animation/core/Easing;FFFF)Ldev/chrisbanes/haze/HazeProgressive$LinearGradient;
+Ldev/chrisbanes/haze/HazeProgressive$LinearGradient;
+PLdev/chrisbanes/haze/HazeProgressive$LinearGradient;->()V
+PLdev/chrisbanes/haze/HazeProgressive$LinearGradient;->(ILandroidx/compose/animation/core/Easing;JFJF)V
+PLdev/chrisbanes/haze/HazeProgressive$LinearGradient;->(ILandroidx/compose/animation/core/Easing;JFJFLkotlin/jvm/internal/DefaultConstructorMarker;)V
+PLdev/chrisbanes/haze/HazeProgressive$LinearGradient;->equals(Ljava/lang/Object;)Z
+PLdev/chrisbanes/haze/HazeProgressive$LinearGradient;->getEasing()Landroidx/compose/animation/core/Easing;
+PLdev/chrisbanes/haze/HazeProgressive$LinearGradient;->getEnd-F1C5BW0()J
+PLdev/chrisbanes/haze/HazeProgressive$LinearGradient;->getEndIntensity()F
+PLdev/chrisbanes/haze/HazeProgressive$LinearGradient;->getStart-F1C5BW0()J
+PLdev/chrisbanes/haze/HazeProgressive$LinearGradient;->getStartIntensity()F
+PLdev/chrisbanes/haze/HazeProgressive$LinearGradient;->getSteps()I
Ldev/chrisbanes/haze/HazeState;
-HSPLdev/chrisbanes/haze/HazeState;->$r8$lambda$5yHbMAZZnQWsJ3oK80ae8m1tnxc()Ldev/chrisbanes/haze/HazeArea;
HSPLdev/chrisbanes/haze/HazeState;->()V
HSPLdev/chrisbanes/haze/HazeState;->()V
-HSPLdev/chrisbanes/haze/HazeState;->contentArea_delegate$lambda$0()Ldev/chrisbanes/haze/HazeArea;
-HSPLdev/chrisbanes/haze/HazeState;->getContentArea()Ldev/chrisbanes/haze/HazeArea;
HSPLdev/chrisbanes/haze/HazeState;->getContentLayer()Landroidx/compose/ui/graphics/layer/GraphicsLayer;
-HSPLdev/chrisbanes/haze/HazeState;->getInvalidateTick$haze_release()I
+HSPLdev/chrisbanes/haze/HazeState;->getPositionOnScreen-F1C5BW0()J
HSPLdev/chrisbanes/haze/HazeState;->setContentLayer$haze_release(Landroidx/compose/ui/graphics/layer/GraphicsLayer;)V
-HSPLdev/chrisbanes/haze/HazeState;->setInvalidateTick$haze_release(I)V
+HSPLdev/chrisbanes/haze/HazeState;->setPositionOnScreen-k-4lQ0M$haze_release(J)V
Ldev/chrisbanes/haze/HazeState$$ExternalSyntheticLambda0;
HSPLdev/chrisbanes/haze/HazeState$$ExternalSyntheticLambda0;->()V
-HSPLdev/chrisbanes/haze/HazeState$$ExternalSyntheticLambda0;->invoke()Ljava/lang/Object;
Ldev/chrisbanes/haze/HazeStyle;
HSPLdev/chrisbanes/haze/HazeStyle;->()V
HSPLdev/chrisbanes/haze/HazeStyle;->(JLdev/chrisbanes/haze/HazeTint;FFLdev/chrisbanes/haze/HazeTint;)V
@@ -227,7 +180,6 @@ HSPLdev/chrisbanes/haze/HazeStyle;->(JLdev/chrisbanes/haze/HazeTint;FFLdev
HSPLdev/chrisbanes/haze/HazeStyle;->(JLjava/util/List;FFLdev/chrisbanes/haze/HazeTint;)V
HSPLdev/chrisbanes/haze/HazeStyle;->(JLjava/util/List;FFLdev/chrisbanes/haze/HazeTint;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
HSPLdev/chrisbanes/haze/HazeStyle;->(JLjava/util/List;FFLdev/chrisbanes/haze/HazeTint;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
-HSPLdev/chrisbanes/haze/HazeStyle;->access$getUnspecified$cp()Ldev/chrisbanes/haze/HazeStyle;
HSPLdev/chrisbanes/haze/HazeStyle;->getBackgroundColor-0d7_KjU()J
HSPLdev/chrisbanes/haze/HazeStyle;->getBlurRadius-D9Ej5fM()F
HSPLdev/chrisbanes/haze/HazeStyle;->getFallbackTint()Ldev/chrisbanes/haze/HazeTint;
@@ -236,22 +188,51 @@ HSPLdev/chrisbanes/haze/HazeStyle;->getTints()Ljava/util/List;
Ldev/chrisbanes/haze/HazeStyle$Companion;
HSPLdev/chrisbanes/haze/HazeStyle$Companion;->()V
HSPLdev/chrisbanes/haze/HazeStyle$Companion;->(Lkotlin/jvm/internal/DefaultConstructorMarker;)V
-HSPLdev/chrisbanes/haze/HazeStyle$Companion;->getUnspecified()Ldev/chrisbanes/haze/HazeStyle;
Ldev/chrisbanes/haze/HazeTint;
-Ldev/chrisbanes/haze/HazeTint$Brush;
-Ldev/chrisbanes/haze/HazeTint$Color;
-HSPLdev/chrisbanes/haze/HazeTint$Color;->()V
-HSPLdev/chrisbanes/haze/HazeTint$Color;->(JI)V
-HSPLdev/chrisbanes/haze/HazeTint$Color;->(JIILkotlin/jvm/internal/DefaultConstructorMarker;)V
-HSPLdev/chrisbanes/haze/HazeTint$Color;->(JILkotlin/jvm/internal/DefaultConstructorMarker;)V
-HSPLdev/chrisbanes/haze/HazeTint$Color;->copy-xETnrds$default(Ldev/chrisbanes/haze/HazeTint$Color;JIILjava/lang/Object;)Ldev/chrisbanes/haze/HazeTint$Color;
-HSPLdev/chrisbanes/haze/HazeTint$Color;->copy-xETnrds(JI)Ldev/chrisbanes/haze/HazeTint$Color;
-HSPLdev/chrisbanes/haze/HazeTint$Color;->equals(Ljava/lang/Object;)Z
-HSPLdev/chrisbanes/haze/HazeTint$Color;->getBlendMode-0nO6VwU()I
-HSPLdev/chrisbanes/haze/HazeTint$Color;->getColor-0d7_KjU()J
-HSPLdev/chrisbanes/haze/HazeTint$Color;->toString()Ljava/lang/String;
+HSPLdev/chrisbanes/haze/HazeTint;->()V
+HSPLdev/chrisbanes/haze/HazeTint;->(JI)V
+HSPLdev/chrisbanes/haze/HazeTint;->(JIILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLdev/chrisbanes/haze/HazeTint;->(JILkotlin/jvm/internal/DefaultConstructorMarker;)V
+HSPLdev/chrisbanes/haze/HazeTint;->copy-xETnrds$default(Ldev/chrisbanes/haze/HazeTint;JIILjava/lang/Object;)Ldev/chrisbanes/haze/HazeTint;
+HSPLdev/chrisbanes/haze/HazeTint;->copy-xETnrds(JI)Ldev/chrisbanes/haze/HazeTint;
+HSPLdev/chrisbanes/haze/HazeTint;->equals(Ljava/lang/Object;)Z
+HSPLdev/chrisbanes/haze/HazeTint;->getBlendMode-0nO6VwU()I
+HSPLdev/chrisbanes/haze/HazeTint;->getColor-0d7_KjU()J
Ldev/chrisbanes/haze/Log_androidKt;
HSPLdev/chrisbanes/haze/Log_androidKt;->log(Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
+Ldev/chrisbanes/haze/ReusableHazeEffect;
+HSPLdev/chrisbanes/haze/ReusableHazeEffect;->()V
+HSPLdev/chrisbanes/haze/ReusableHazeEffect;->()V
+HSPLdev/chrisbanes/haze/ReusableHazeEffect;->applyStyle(Ldev/chrisbanes/haze/HazeStyle;)V
+HSPLdev/chrisbanes/haze/ReusableHazeEffect;->getAlpha()F
+HSPLdev/chrisbanes/haze/ReusableHazeEffect;->getBackgroundColor-0d7_KjU()J
+HSPLdev/chrisbanes/haze/ReusableHazeEffect;->getBlurRadius-D9Ej5fM()F
+HSPLdev/chrisbanes/haze/ReusableHazeEffect;->getDrawParametersDirty()Z
+HSPLdev/chrisbanes/haze/ReusableHazeEffect;->getFallbackTint()Ldev/chrisbanes/haze/HazeTint;
+HSPLdev/chrisbanes/haze/ReusableHazeEffect;->getLayerOffset-F1C5BW0()J
+HSPLdev/chrisbanes/haze/ReusableHazeEffect;->getLayerSize-NH-jbRc()J
+HSPLdev/chrisbanes/haze/ReusableHazeEffect;->getMask()Landroidx/compose/ui/graphics/Brush;
+HSPLdev/chrisbanes/haze/ReusableHazeEffect;->getNoiseFactor()F
+HSPLdev/chrisbanes/haze/ReusableHazeEffect;->getPositionOnScreen-F1C5BW0()J
+HSPLdev/chrisbanes/haze/ReusableHazeEffect;->getProgressive()Ldev/chrisbanes/haze/HazeProgressive;
+HSPLdev/chrisbanes/haze/ReusableHazeEffect;->getProgressiveDirty()Z
+HSPLdev/chrisbanes/haze/ReusableHazeEffect;->getRenderEffect()Landroidx/compose/ui/graphics/RenderEffect;
+HSPLdev/chrisbanes/haze/ReusableHazeEffect;->getRenderEffectDirty()Z
+HSPLdev/chrisbanes/haze/ReusableHazeEffect;->getSize-NH-jbRc()J
+HSPLdev/chrisbanes/haze/ReusableHazeEffect;->getTints()Ljava/util/List;
+HSPLdev/chrisbanes/haze/ReusableHazeEffect;->isValid()Z
+HSPLdev/chrisbanes/haze/ReusableHazeEffect;->setBackgroundColor-8_81llA(J)V
+HSPLdev/chrisbanes/haze/ReusableHazeEffect;->setBlurRadius-0680j_4(F)V
+HSPLdev/chrisbanes/haze/ReusableHazeEffect;->setDrawParametersDirty(Z)V
+HSPLdev/chrisbanes/haze/ReusableHazeEffect;->setFallbackTint(Ldev/chrisbanes/haze/HazeTint;)V
+HSPLdev/chrisbanes/haze/ReusableHazeEffect;->setLayerSize-uvyYCjk(J)V
+HSPLdev/chrisbanes/haze/ReusableHazeEffect;->setNoiseFactor(F)V
+HSPLdev/chrisbanes/haze/ReusableHazeEffect;->setPositionOnScreen-k-4lQ0M(J)V
+PLdev/chrisbanes/haze/ReusableHazeEffect;->setProgressive(Ldev/chrisbanes/haze/HazeProgressive;)V
+HSPLdev/chrisbanes/haze/ReusableHazeEffect;->setRenderEffect(Landroidx/compose/ui/graphics/RenderEffect;)V
+HSPLdev/chrisbanes/haze/ReusableHazeEffect;->setRenderEffectDirty(Z)V
+HSPLdev/chrisbanes/haze/ReusableHazeEffect;->setSize-uvyYCjk(J)V
+HSPLdev/chrisbanes/haze/ReusableHazeEffect;->setTints(Ljava/util/List;)V
Ldev/chrisbanes/haze/Window_androidKt;
HSPLdev/chrisbanes/haze/Window_androidKt;->()V
HSPLdev/chrisbanes/haze/Window_androidKt;->calculateWindowOffset(Landroidx/compose/ui/node/CompositionLocalConsumerModifierNode;)J
\ No newline at end of file
diff --git a/haze/src/commonMain/kotlin/dev/chrisbanes/haze/Canvas.kt b/haze/src/commonMain/kotlin/dev/chrisbanes/haze/Canvas.kt
index dd7d3c8a..ddad1498 100644
--- a/haze/src/commonMain/kotlin/dev/chrisbanes/haze/Canvas.kt
+++ b/haze/src/commonMain/kotlin/dev/chrisbanes/haze/Canvas.kt
@@ -5,19 +5,8 @@ package dev.chrisbanes.haze
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.isFinite
-import androidx.compose.ui.graphics.GraphicsContext
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.graphics.drawscope.translate
-import androidx.compose.ui.graphics.layer.GraphicsLayer
-
-internal inline fun GraphicsContext.useGraphicsLayer(block: (GraphicsLayer) -> Unit) {
- val layer = createGraphicsLayer()
- try {
- block(layer)
- } finally {
- releaseGraphicsLayer(layer)
- }
-}
internal inline fun DrawScope.translate(
offset: Offset,
diff --git a/haze/src/commonMain/kotlin/dev/chrisbanes/haze/HazeChildNode.kt b/haze/src/commonMain/kotlin/dev/chrisbanes/haze/HazeChildNode.kt
index 7a587f61..5cd7b022 100644
--- a/haze/src/commonMain/kotlin/dev/chrisbanes/haze/HazeChildNode.kt
+++ b/haze/src/commonMain/kotlin/dev/chrisbanes/haze/HazeChildNode.kt
@@ -5,15 +5,11 @@ package dev.chrisbanes.haze
import androidx.compose.animation.core.EaseIn
import androidx.compose.animation.core.Easing
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.geometry.isSpecified
-import androidx.compose.ui.geometry.takeOrElse
import androidx.compose.ui.geometry.toRect
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
@@ -32,7 +28,6 @@ import androidx.compose.ui.layout.positionInWindow
import androidx.compose.ui.node.CompositionLocalConsumerModifierNode
import androidx.compose.ui.node.DrawModifierNode
import androidx.compose.ui.node.GlobalPositionAwareModifierNode
-import androidx.compose.ui.node.LayoutAwareModifierNode
import androidx.compose.ui.node.ObserverModifierNode
import androidx.compose.ui.node.currentValueOf
import androidx.compose.ui.node.invalidateDraw
@@ -55,13 +50,10 @@ internal class HazeChildNode(
var block: HazeChildScope.() -> Unit,
) : Modifier.Node(),
CompositionLocalConsumerModifierNode,
- LayoutAwareModifierNode,
GlobalPositionAwareModifierNode,
ObserverModifierNode,
DrawModifierNode {
- private var positionOnScreen by mutableStateOf(Offset.Unspecified)
-
private val effect by lazy(::ReusableHazeEffect)
override val shouldAutoInvalidate: Boolean = false
@@ -80,8 +72,10 @@ internal class HazeChildNode(
}
}
- override fun onPlaced(coordinates: LayoutCoordinates) {
- effect.positionOnScreen = coordinates.positionInWindow() + calculateWindowOffset()
+ override fun onGloballyPositioned(coordinates: LayoutCoordinates) {
+ log(TAG) { "onGloballyPositioned: positionInWindow=${coordinates.positionInWindow()}" }
+ effect.positionInContent = coordinates.positionInWindow() +
+ calculateWindowOffset() - state.positionOnScreen
effect.size = coordinates.size.toSize()
val blurRadiusPx = with(currentValueOf(LocalDensity)) { effect.blurRadius.toPx() }
@@ -90,8 +84,6 @@ internal class HazeChildNode(
updateEffect()
}
- override fun onGloballyPositioned(coordinates: LayoutCoordinates) = onPlaced(coordinates)
-
override fun ContentDrawScope.draw() {
log(TAG) { "-> HazeChild. start draw()" }
@@ -128,6 +120,7 @@ internal class HazeChildNode(
block(effect)
if (effect.needInvalidation) {
+ log(TAG) { "invalidateDraw called, due to effect needing invalidation" }
invalidateDraw()
}
}
@@ -151,7 +144,7 @@ internal class HazeChildNode(
}
drawRect(effect.backgroundColor)
- translate(inflatedOffset + state.positionOnScreen - effect.positionOnScreen) {
+ translate(inflatedOffset - effect.positionInContent) {
// Draw the content into our effect layer
drawLayer(contentLayer)
}
@@ -169,12 +162,12 @@ internal class HazeChildNode(
clippedContentLayer.renderEffect = effect.renderEffect
clippedContentLayer.alpha = effect.alpha
- withPositionAndClip(
- effectPositionOnScreen = effect.positionOnScreen,
- size = effect.size,
- innerDrawOffset = -inflatedOffset,
- ) {
- drawLayer(clippedContentLayer)
+ clipRect(right = size.width, bottom = size.height) {
+ translate(-inflatedOffset) {
+ // Since we included a border around the content, we need to translate so that
+ // we don't see it (but it still affects the RenderEffect)
+ drawLayer(clippedContentLayer)
+ }
}
}
@@ -243,7 +236,7 @@ internal class HazeChildNode(
add(lerp(min, max, (i + 1f) / steps) to Color.Transparent)
}
- log("HazeChildNode") {
+ log(TAG) {
"drawProgressiveEffect. " +
"step=$i, " +
"fraction=$fraction, " +
@@ -269,30 +262,15 @@ internal class HazeChildNode(
),
)
- withPositionAndClip(
- effectPositionOnScreen = effect.positionOnScreen,
- size = effect.size,
- innerDrawOffset = innerDrawOffset,
- block = { drawLayer(layer) },
- )
-
- graphicsContext.releaseGraphicsLayer(layer)
- }
- }
-
- private inline fun DrawScope.withPositionAndClip(
- effectPositionOnScreen: Offset,
- size: Size,
- innerDrawOffset: Offset = Offset.Zero,
- block: DrawScope.() -> Unit,
- ) {
- val drawOffset = (effectPositionOnScreen - positionOnScreen).takeOrElse { Offset.Zero }
- translate(drawOffset) {
clipRect(right = size.width, bottom = size.height) {
- // Since we included a border around the content, we need to translate so that
- // we don't see it (but it still affects the RenderEffect)
- translate(innerDrawOffset, block)
+ translate(innerDrawOffset) {
+ // Since we included a border around the content, we need to translate so that
+ // we don't see it (but it still affects the RenderEffect)
+ drawLayer(layer)
+ }
}
+
+ graphicsContext.releaseGraphicsLayer(layer)
}
}
@@ -314,9 +292,11 @@ internal class HazeChildNode(
private fun ReusableHazeEffect.onPostDraw() {
drawParametersDirty = false
+ progressiveDirty = false
+ positionChanged = false
}
- private companion object {
+ internal companion object {
const val TAG = "HazeChild"
}
}
@@ -443,10 +423,18 @@ internal expect fun HazeChildNode.createRenderEffect(
internal class ReusableHazeEffect : HazeChildScope {
var renderEffect: RenderEffect? = null
var renderEffectDirty: Boolean = true
+ var positionChanged: Boolean = true
var drawParametersDirty: Boolean = true
var progressiveDirty: Boolean = true
- var positionOnScreen: Offset by mutableStateOf(Offset.Unspecified)
+ var positionInContent: Offset = Offset.Unspecified
+ set(value) {
+ if (value != field) {
+ log("ReusableHazeEffect") { "positionInContent changed. Current: $field. New: $value" }
+ positionChanged = true
+ field = value
+ }
+ }
val isValid: Boolean
get() = size.isSpecified && layerSize.isSpecified
@@ -454,6 +442,7 @@ internal class ReusableHazeEffect : HazeChildScope {
var size: Size = Size.Unspecified
set(value) {
if (value != field) {
+ log("ReusableHazeEffect") { "size changed. Current: $field. New: $value" }
// We use the size for crop rects/brush sizing
renderEffectDirty = true
field = value
@@ -463,6 +452,7 @@ internal class ReusableHazeEffect : HazeChildScope {
var layerSize: Size = Size.Unspecified
set(value) {
if (value != field) {
+ log("ReusableHazeEffect") { "layerSize changed. Current: $field. New: $value" }
renderEffectDirty = true
field = value
}
@@ -483,6 +473,7 @@ internal class ReusableHazeEffect : HazeChildScope {
override var blurRadius: Dp = HazeDefaults.blurRadius
set(value) {
if (value != field) {
+ log("ReusableHazeEffect") { "blurRadius changed. Current: $field. New: $value" }
renderEffectDirty = true
field = value
}
@@ -491,6 +482,7 @@ internal class ReusableHazeEffect : HazeChildScope {
override var noiseFactor: Float = HazeDefaults.noiseFactor
set(value) {
if (value != field) {
+ log("ReusableHazeEffect") { "noiseFactor changed. Current: $field. New: $value" }
renderEffectDirty = true
field = value
}
@@ -499,6 +491,7 @@ internal class ReusableHazeEffect : HazeChildScope {
override var mask: Brush? = null
set(value) {
if (value != field) {
+ log("ReusableHazeEffect") { "mask changed. Current: $field. New: $value" }
renderEffectDirty = true
field = value
}
@@ -509,6 +502,7 @@ internal class ReusableHazeEffect : HazeChildScope {
override var tints: List = emptyList()
set(value) {
if (value != field) {
+ log("ReusableHazeEffect") { "tints changed. Current: $field. New: $value" }
renderEffectDirty = true
field = value
}
@@ -517,6 +511,7 @@ internal class ReusableHazeEffect : HazeChildScope {
override var fallbackTint: HazeTint? = null
set(value) {
if (value != field) {
+ log("ReusableHazeEffect") { "fallbackTint changed. Current: $field. New: $value" }
renderEffectDirty = true
field = value
}
@@ -525,6 +520,7 @@ internal class ReusableHazeEffect : HazeChildScope {
override var alpha: Float = 1f
set(value) {
if (value != field) {
+ log("ReusableHazeEffect") { "alpha changed. Current $field. New: $value" }
drawParametersDirty = true
field = value
}
@@ -533,6 +529,7 @@ internal class ReusableHazeEffect : HazeChildScope {
override var progressive: HazeProgressive? = null
set(value) {
if (value != field) {
+ log("ReusableHazeEffect") { "progressive changed. Current $field. New: $value" }
progressiveDirty = true
field = value
}
@@ -551,7 +548,15 @@ internal val ReusableHazeEffect.blurRadiusOrZero: Dp
get() = blurRadius.takeOrElse { 0.dp }
internal val ReusableHazeEffect.needInvalidation: Boolean
- get() = renderEffectDirty || drawParametersDirty || progressiveDirty
+ get() {
+ log("ReusableHazeEffect") {
+ "needInvalidation. renderEffectDirty=$renderEffectDirty, " +
+ "drawParametersDirty=$drawParametersDirty, " +
+ "progressiveDirty=$progressiveDirty" +
+ "positionChanged=$positionChanged"
+ }
+ return renderEffectDirty || drawParametersDirty || progressiveDirty || positionChanged
+ }
private fun Size.expand(expansion: Float): Size {
return Size(width = width + expansion, height = height + expansion)
@@ -568,7 +573,7 @@ private fun DrawScope.drawFallbackEffect(
?.takeIf { it.color.isSpecified }
?: tints.firstOrNull()?.boostForFallback(blurRadius.takeOrElse { 0.dp })
- log("HazeChildNode") { "drawEffect. Drawing effect with scrim: tint=$tint, mask=$mask, alpha=$alpha" }
+ log(HazeChildNode.TAG) { "drawEffect. Drawing effect with scrim: tint=$tint, mask=$mask, alpha=$alpha" }
fun scrim() {
if (tint != null) {
diff --git a/haze/src/commonMain/kotlin/dev/chrisbanes/haze/HazeNode.kt b/haze/src/commonMain/kotlin/dev/chrisbanes/haze/HazeNode.kt
index f5541ddf..40097b92 100644
--- a/haze/src/commonMain/kotlin/dev/chrisbanes/haze/HazeNode.kt
+++ b/haze/src/commonMain/kotlin/dev/chrisbanes/haze/HazeNode.kt
@@ -13,7 +13,6 @@ import androidx.compose.ui.layout.positionInWindow
import androidx.compose.ui.node.CompositionLocalConsumerModifierNode
import androidx.compose.ui.node.DrawModifierNode
import androidx.compose.ui.node.GlobalPositionAwareModifierNode
-import androidx.compose.ui.node.LayoutAwareModifierNode
import androidx.compose.ui.node.currentValueOf
import androidx.compose.ui.platform.LocalGraphicsContext
import androidx.compose.ui.unit.Dp
@@ -23,13 +22,13 @@ internal class HazeNode(
var state: HazeState,
) : Modifier.Node(),
CompositionLocalConsumerModifierNode,
- LayoutAwareModifierNode,
GlobalPositionAwareModifierNode,
DrawModifierNode {
- override fun onGloballyPositioned(coordinates: LayoutCoordinates) = onPlaced(coordinates)
-
- override fun onPlaced(coordinates: LayoutCoordinates) {
+ override fun onGloballyPositioned(coordinates: LayoutCoordinates) {
+ log("HazeNode") {
+ "onPlaced: positionInWindow=${coordinates.positionInWindow()}"
+ }
state.positionOnScreen = coordinates.positionInWindow() + calculateWindowOffset()
}
diff --git a/internal/benchmark/build.gradle.kts b/internal/benchmark/build.gradle.kts
index 8879bb90..329aafb2 100644
--- a/internal/benchmark/build.gradle.kts
+++ b/internal/benchmark/build.gradle.kts
@@ -44,7 +44,7 @@ baselineProfile {
managedDevices += "pixel5Api30"
managedDevices += "pixel5Api34"
useConnectedDevices = false
- enableEmulatorDisplay = true
+ enableEmulatorDisplay = false
}
dependencies {
diff --git a/internal/benchmark/src/main/kotlin/dev/chrisbanes/haze/baselineprofile/BaselineProfileGenerator.kt b/internal/benchmark/src/main/kotlin/dev/chrisbanes/haze/baselineprofile/BaselineProfileGenerator.kt
index 1781cfcb..e3ff912a 100644
--- a/internal/benchmark/src/main/kotlin/dev/chrisbanes/haze/baselineprofile/BaselineProfileGenerator.kt
+++ b/internal/benchmark/src/main/kotlin/dev/chrisbanes/haze/baselineprofile/BaselineProfileGenerator.kt
@@ -3,12 +3,13 @@
package dev.chrisbanes.haze.baselineprofile
-import android.graphics.Point
import androidx.benchmark.macro.junit4.BaselineProfileRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.uiautomator.By
import dev.chrisbanes.haze.testutils.navigateToImagesList
-import dev.chrisbanes.haze.testutils.waitForObject
+import dev.chrisbanes.haze.testutils.navigateToScaffold
+import dev.chrisbanes.haze.testutils.navigateToScaffoldWithProgressive
+import dev.chrisbanes.haze.testutils.scroll
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -25,12 +26,20 @@ class BaselineProfileGenerator {
pressHome()
startActivityAndWait()
+ // Scroll down several times
device.navigateToImagesList()
+ device.scroll("lazy_column")
- // Scroll down several times
- repeat(5) {
- val column = device.waitForObject(By.res("lazy_column"))
- column.drag(Point(column.visibleCenter.x, column.visibleBounds.top))
- }
+ device.findObject(By.res("back")).click()
+ device.waitForIdle()
+
+ device.navigateToScaffoldWithProgressive()
+ device.scroll("lazy_grid")
+
+ device.findObject(By.res("back")).click()
+ device.waitForIdle()
+
+ device.navigateToScaffold()
+ device.scroll("lazy_grid")
}
}
diff --git a/internal/benchmark/src/main/kotlin/dev/chrisbanes/haze/benchmark/BenchmarkTest.kt b/internal/benchmark/src/main/kotlin/dev/chrisbanes/haze/benchmark/BenchmarkTest.kt
index b0775228..5d4101f2 100644
--- a/internal/benchmark/src/main/kotlin/dev/chrisbanes/haze/benchmark/BenchmarkTest.kt
+++ b/internal/benchmark/src/main/kotlin/dev/chrisbanes/haze/benchmark/BenchmarkTest.kt
@@ -12,6 +12,8 @@ import androidx.test.uiautomator.By
import dev.chrisbanes.haze.testutils.navigateToCreditCard
import dev.chrisbanes.haze.testutils.navigateToImagesList
import dev.chrisbanes.haze.testutils.navigateToScaffold
+import dev.chrisbanes.haze.testutils.navigateToScaffoldWithProgressive
+import dev.chrisbanes.haze.testutils.scroll
import dev.chrisbanes.haze.testutils.waitForObject
import org.junit.Rule
import org.junit.Test
@@ -37,16 +39,7 @@ class BenchmarkTest {
device.navigateToImagesList()
},
) {
- val column = device.waitForObject(By.res("lazy_column"))
-
- // Set gesture margin to avoid triggering gesture navigation
- // with input events from automation.
- column.setGestureMargin(device.displayWidth / 5)
-
- // Scroll down several times
- repeat(5) {
- column.drag(Point(column.visibleCenter.x, column.visibleBounds.top))
- }
+ device.scroll("lazy_column")
}
}
@@ -62,16 +55,23 @@ class BenchmarkTest {
device.navigateToScaffold()
},
) {
- val grid = device.waitForObject(By.res("lazy_grid"))
-
- // Set gesture margin to avoid triggering gesture navigation
- // with input events from automation.
- grid.setGestureMargin(device.displayWidth / 5)
+ device.scroll("lazy_grid")
+ }
+ }
- // Scroll down several times
- repeat(5) {
- grid.drag(Point(grid.visibleCenter.x, grid.visibleBounds.top))
- }
+ @Test
+ fun scaffoldProgressive() {
+ benchmarkRule.measureRepeated(
+ packageName = APP_PACKAGE,
+ metrics = listOf(FrameTimingMetric()),
+ startupMode = StartupMode.WARM,
+ iterations = DEFAULT_ITERATIONS,
+ setupBlock = {
+ startActivityAndWait()
+ device.navigateToScaffoldWithProgressive()
+ },
+ ) {
+ device.scroll("lazy_grid")
}
}
diff --git a/internal/benchmark/src/main/kotlin/dev/chrisbanes/haze/testutils/UiAutomator.kt b/internal/benchmark/src/main/kotlin/dev/chrisbanes/haze/testutils/UiAutomator.kt
index c45affd3..f2f3803b 100644
--- a/internal/benchmark/src/main/kotlin/dev/chrisbanes/haze/testutils/UiAutomator.kt
+++ b/internal/benchmark/src/main/kotlin/dev/chrisbanes/haze/testutils/UiAutomator.kt
@@ -3,6 +3,7 @@
package dev.chrisbanes.haze.testutils
+import android.graphics.Point
import androidx.test.uiautomator.By
import androidx.test.uiautomator.BySelector
import androidx.test.uiautomator.SearchCondition
@@ -44,7 +45,23 @@ internal fun UiDevice.navigateToScaffold() {
waitForIdle()
}
+internal fun UiDevice.navigateToScaffoldWithProgressive() {
+ waitForObject(By.res("Scaffold (with progressive blur)")).click()
+ waitForIdle()
+}
+
internal fun UiDevice.navigateToCreditCard() {
waitForObject(By.res("Credit Card")).click()
waitForIdle()
}
+
+internal fun UiDevice.scroll(tag: String, scrolls: Int = 5) {
+ val grid = waitForObject(By.res(tag))
+ // Set gesture margin to avoid triggering gesture navigation
+ // with input events from automation.
+ grid.setGestureMargin(displayWidth / 5)
+ // Scroll down several times
+ repeat(scrolls) {
+ grid.drag(Point(grid.visibleCenter.x, grid.visibleBounds.top))
+ }
+}
diff --git a/sample/shared/src/commonMain/kotlin/dev/chrisbanes/haze/sample/ImagesList.kt b/sample/shared/src/commonMain/kotlin/dev/chrisbanes/haze/sample/ImagesList.kt
index 4bbef68a..c6d41f0b 100644
--- a/sample/shared/src/commonMain/kotlin/dev/chrisbanes/haze/sample/ImagesList.kt
+++ b/sample/shared/src/commonMain/kotlin/dev/chrisbanes/haze/sample/ImagesList.kt
@@ -11,7 +11,7 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.ArrowBack
+import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
@@ -43,9 +43,11 @@ fun ImagesList(navigator: Navigator) {
LargeTopAppBar(
title = { Text(text = "Images") },
navigationIcon = {
- IconButton(onClick = navigator::navigateUp) {
- @Suppress("DEPRECATION")
- Icon(Icons.Default.ArrowBack, null)
+ IconButton(
+ onClick = navigator::navigateUp,
+ modifier = Modifier.testTag("back"),
+ ) {
+ Icon(Icons.AutoMirrored.Filled.ArrowBack, null)
}
},
modifier = Modifier.fillMaxWidth(),
diff --git a/sample/shared/src/commonMain/kotlin/dev/chrisbanes/haze/sample/Samples.kt b/sample/shared/src/commonMain/kotlin/dev/chrisbanes/haze/sample/Samples.kt
index 8cd78560..8ea92b73 100644
--- a/sample/shared/src/commonMain/kotlin/dev/chrisbanes/haze/sample/Samples.kt
+++ b/sample/shared/src/commonMain/kotlin/dev/chrisbanes/haze/sample/Samples.kt
@@ -31,7 +31,8 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
val Samples = listOf(
- Sample("Scaffold") { ScaffoldSample(it) },
+ Sample("Scaffold") { ScaffoldSample(it, false) },
+ Sample("Scaffold (with progressive blur)") { ScaffoldSample(it, true) },
Sample("Credit Card") { CreditCardSample(it) },
Sample("Images List") { ImagesList(it) },
Sample("List over Image") { ListOverImage(it) },
diff --git a/sample/shared/src/commonMain/kotlin/dev/chrisbanes/haze/sample/ScaffoldSample.kt b/sample/shared/src/commonMain/kotlin/dev/chrisbanes/haze/sample/ScaffoldSample.kt
index 84ceb59a..3c488b12 100644
--- a/sample/shared/src/commonMain/kotlin/dev/chrisbanes/haze/sample/ScaffoldSample.kt
+++ b/sample/shared/src/commonMain/kotlin/dev/chrisbanes/haze/sample/ScaffoldSample.kt
@@ -47,7 +47,7 @@ import dev.chrisbanes.haze.materials.HazeMaterials
@OptIn(ExperimentalMaterial3Api::class, ExperimentalHazeMaterialsApi::class)
@Composable
-fun ScaffoldSample(navigator: Navigator) {
+fun ScaffoldSample(navigator: Navigator, useProgressive: Boolean) {
val hazeState = remember { HazeState() }
val gridState = rememberLazyGridState()
val showNavigationBar by remember(gridState) {
@@ -61,7 +61,10 @@ fun ScaffoldSample(navigator: Navigator) {
LargeTopAppBar(
title = { Text(text = "Haze Scaffold sample") },
navigationIcon = {
- IconButton(onClick = navigator::navigateUp) {
+ IconButton(
+ onClick = navigator::navigateUp,
+ modifier = Modifier.testTag("back"),
+ ) {
Icon(Icons.AutoMirrored.Default.ArrowBack, null)
}
},
@@ -72,7 +75,9 @@ fun ScaffoldSample(navigator: Navigator) {
modifier = Modifier
.hazeChild(hazeState) {
applyStyle(style)
- progressive = HazeProgressive.verticalGradient(startIntensity = 1f, endIntensity = 0f)
+ if (useProgressive) {
+ progressive = HazeProgressive.verticalGradient(startIntensity = 1f, endIntensity = 0f)
+ }
}
.fillMaxWidth(),
)