Merge "Add Material 3 Benchmarks for Chip" into androidx-main
diff --git a/compose/material3/benchmark/build.gradle b/compose/material3/benchmark/build.gradle
index c21a27e..df3e144 100644
--- a/compose/material3/benchmark/build.gradle
+++ b/compose/material3/benchmark/build.gradle
@@ -24,6 +24,7 @@
dependencies {
+ androidTestImplementation(project(":compose:material:material-icons-core"))
androidTestImplementation(project(":compose:material3:material3"))
androidTestImplementation(project(":benchmark:benchmark-junit4"))
androidTestImplementation(project(":compose:runtime:runtime"))
diff --git a/compose/material3/benchmark/src/androidTest/java/androidx/compose/material3/benchmark/ChipBenchmark.kt b/compose/material3/benchmark/src/androidTest/java/androidx/compose/material3/benchmark/ChipBenchmark.kt
new file mode 100644
index 0000000..d190cbf
--- /dev/null
+++ b/compose/material3/benchmark/src/androidTest/java/androidx/compose/material3/benchmark/ChipBenchmark.kt
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.material3.benchmark
+
+import androidx.compose.foundation.layout.size
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Settings
+import androidx.compose.material3.AssistChip
+import androidx.compose.material3.AssistChipDefaults
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.Icon
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.testutils.LayeredComposeTestCase
+import androidx.compose.testutils.benchmark.ComposeBenchmarkRule
+import androidx.compose.testutils.benchmark.benchmarkFirstCompose
+import androidx.compose.testutils.benchmark.benchmarkFirstDraw
+import androidx.compose.testutils.benchmark.benchmarkFirstLayout
+import androidx.compose.testutils.benchmark.benchmarkFirstMeasure
+import androidx.compose.ui.Modifier
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.LargeTest
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@LargeTest
+@RunWith(AndroidJUnit4::class)
+class ChipBenchmark {
+
+ @get:Rule
+ val benchmarkRule = ComposeBenchmarkRule()
+
+ private val chipTestCaseFactory = { ChipTestCase() }
+
+ @Test
+ fun first_compose() {
+ benchmarkRule.benchmarkFirstCompose(chipTestCaseFactory)
+ }
+
+ @Test
+ fun chip_measure() {
+ benchmarkRule.benchmarkFirstMeasure(chipTestCaseFactory)
+ }
+
+ @Test
+ fun chip_layout() {
+ benchmarkRule.benchmarkFirstLayout(chipTestCaseFactory)
+ }
+
+ @Test
+ fun chip_draw() {
+ benchmarkRule.benchmarkFirstDraw(chipTestCaseFactory)
+ }
+}
+
+internal class ChipTestCase : LayeredComposeTestCase() {
+
+ @OptIn(ExperimentalMaterial3Api::class)
+ @Composable
+ override fun MeasuredContent() {
+ AssistChip(
+ onClick = { /* Do something! */ },
+ label = { Text("Assist Chip") },
+ leadingIcon = {
+ Icon(
+ Icons.Filled.Settings,
+ contentDescription = "Localized description",
+ Modifier.size(AssistChipDefaults.IconSize)
+ )
+ }
+ )
+ }
+
+ @Composable
+ override fun ContentWrappers(content: @Composable () -> Unit) {
+ MaterialTheme {
+ content()
+ }
+ }
+}
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Chip.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Chip.kt
index 1c5ef84..b2c7357 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Chip.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Chip.kt
@@ -43,12 +43,14 @@
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.State
+import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
+import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.graphicsLayer
@@ -1493,6 +1495,7 @@
interactionSource: InteractionSource
): State<Dp> {
val interactions = remember { mutableStateListOf<Interaction>() }
+ var lastInteraction by remember { mutableStateOf<Interaction?>(null) }
LaunchedEffect(interactionSource) {
interactionSource.interactions.collect { interaction ->
when (interaction) {
@@ -1546,22 +1549,16 @@
val animatable = remember { Animatable(target, Dp.VectorConverter) }
- if (!enabled) {
- // No transition when moving to a disabled state
- LaunchedEffect(target) { animatable.snapTo(target) }
- } else {
- LaunchedEffect(target) {
- val lastInteraction = when (animatable.targetValue) {
- pressedElevation -> PressInteraction.Press(Offset.Zero)
- hoveredElevation -> HoverInteraction.Enter()
- focusedElevation -> FocusInteraction.Focus()
- draggedElevation -> DragInteraction.Start()
- else -> null
- }
+ LaunchedEffect(target) {
+ if (!enabled) {
+ // No transition when moving to a disabled state
+ animatable.snapTo(target)
+ } else {
animatable.animateElevation(
from = lastInteraction, to = interaction, target = target
)
}
+ lastInteraction = interaction
}
return animatable.asState()
@@ -1653,6 +1650,7 @@
interactionSource: InteractionSource
): State<Dp> {
val interactions = remember { mutableStateListOf<Interaction>() }
+ var lastInteraction by remember { mutableStateOf<Interaction?>(null) }
LaunchedEffect(interactionSource) {
interactionSource.interactions.collect { interaction ->
when (interaction) {
@@ -1706,22 +1704,16 @@
val animatable = remember { Animatable(target, Dp.VectorConverter) }
- if (!enabled) {
- // No transition when moving to a disabled state
- LaunchedEffect(target) { animatable.snapTo(target) }
- } else {
- LaunchedEffect(target) {
- val lastInteraction = when (animatable.targetValue) {
- pressedElevation -> PressInteraction.Press(Offset.Zero)
- hoveredElevation -> HoverInteraction.Enter()
- focusedElevation -> FocusInteraction.Focus()
- draggedElevation -> DragInteraction.Start()
- else -> null
- }
+ LaunchedEffect(target) {
+ if (!enabled) {
+ // No transition when moving to a disabled state
+ animatable.snapTo(target)
+ } else {
animatable.animateElevation(
from = lastInteraction, to = interaction, target = target
)
}
+ lastInteraction = interaction
}
return animatable.asState()