Skip to content

Commit d61686c

Browse files
committed
Address feedback
1 parent 9134f35 commit d61686c

4 files changed

Lines changed: 27 additions & 11 deletions

File tree

compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import androidx.compose.ui.input.rotary.RotaryScrollEvent
3838
import androidx.compose.ui.platform.FrameRecomposer
3939
import androidx.compose.ui.platform.ProvidePlatformCompositionLocals
4040
import androidx.compose.ui.util.trace
41+
import kotlin.concurrent.Volatile
4142

4243
/**
4344
* BaseComposeScene is an internal abstract class that implements the ComposeScene interface.
@@ -82,15 +83,25 @@ internal abstract class BaseComposeScene(
8283
}
8384
}
8485

86+
@Volatile
87+
protected var hasForcedLayout: Boolean = false
88+
private set
89+
90+
@Volatile
91+
protected var hasForcedDraw: Boolean = false
92+
private set
93+
8594
protected fun invokeInvalidationCallbacks(
8695
forceLayout: Boolean = false,
8796
forceDraw: Boolean = false,
8897
) {
98+
hasForcedLayout = hasForcedLayout || forceLayout
99+
hasForcedDraw = hasForcedDraw || forceDraw
89100
if (isInvalidationDisabled || isClosed || composition == null) return
90-
if (forceLayout || hasPendingMeasureOrLayout) {
101+
if (hasForcedLayout || hasPendingMeasureOrLayout) {
91102
invalidateLayout()
92103
}
93-
if (forceDraw || hasPendingDraw) {
104+
if (hasForcedDraw || hasPendingDraw) {
94105
invalidateDraw()
95106
}
96107
}
@@ -142,6 +153,7 @@ internal abstract class BaseComposeScene(
142153

143154
override fun measureAndLayout() {
144155
if (isClosed) return
156+
hasForcedLayout = false
145157

146158
postponeInvalidation("BaseComposeScene:measureAndLayout") {
147159
doMeasureAndLayout()
@@ -157,6 +169,7 @@ internal abstract class BaseComposeScene(
157169

158170
override fun draw(canvas: Canvas) {
159171
if (isClosed) return
172+
hasForcedDraw = false
160173

161174
postponeInvalidation("BaseComposeScene:draw") {
162175
// FIXME: Remove applying the global snapshot here.

compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/CanvasLayersComposeScene.skiko.kt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -227,11 +227,11 @@ private class CanvasLayersComposeSceneImpl(
227227
}
228228

229229
override val hasPendingMeasureOrLayout: Boolean
230-
get() = mainOwner.hasPendingMeasureOrLayout
230+
get() = hasForcedLayout || mainOwner.hasPendingMeasureOrLayout
231231
|| layers.fastAny { it.owner.hasPendingMeasureOrLayout }
232232

233233
override val hasPendingDraw: Boolean
234-
get() = mainOwner.hasPendingDraw
234+
get() = hasForcedDraw || mainOwner.hasPendingDraw
235235
|| layers.fastAny { it.owner.hasPendingDraw }
236236

237237
override fun createComposition(
@@ -517,7 +517,7 @@ private class CanvasLayersComposeSceneImpl(
517517
onOwnerAppended(layer.owner)
518518

519519
inputHandler.onPointerUpdate()
520-
invokeInvalidationCallbacks()
520+
invokeInvalidationCallbacks(forceLayout = true, forceDraw = true)
521521
}
522522

523523
private fun detachLayer(layer: AttachedComposeSceneLayer) {
@@ -528,9 +528,9 @@ private class CanvasLayersComposeSceneImpl(
528528
onOwnerRemoved(layer.owner)
529529

530530
inputHandler.onPointerUpdate()
531-
// Removing a layer changes the scene's composited output (e.g. it removes a dialog scrim)
532-
// without dirtying any remaining owner, so force a draw pass to repaint without it.
533-
invokeInvalidationCallbacks(forceDraw = true)
531+
// A detached layer was composited onto this scene's canvas, so its removal changes
532+
// the scene's output even though no remaining owner is dirty.
533+
invokeInvalidationCallbacks(forceLayout = true, forceDraw = true)
534534
}
535535

536536
private fun requestFocus(layer: AttachedComposeSceneLayer) {

compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/PlatformLayersComposeScene.skiko.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,10 +162,10 @@ private class PlatformLayersComposeSceneImpl(
162162
}
163163

164164
override val hasPendingMeasureOrLayout: Boolean
165-
get() = mainOwner.hasPendingMeasureOrLayout
165+
get() = hasForcedLayout || mainOwner.hasPendingMeasureOrLayout
166166

167167
override val hasPendingDraw: Boolean
168-
get() = mainOwner.hasPendingDraw
168+
get() = hasForcedDraw || mainOwner.hasPendingDraw
169169

170170
override fun createComposition(
171171
parentCompositionContext: CompositionContext,

compose/ui/ui/src/skikoTest/kotlin/androidx/compose/ui/scene/CanvasLayersComposeSceneTest.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,14 @@ class CanvasLayersComposeSceneTest {
102102
// the close below would invalidate simply because an owner was still dirty.
103103
scene.measureAndLayout()
104104
scene.draw(surface.canvas.asComposeCanvas())
105-
assertFalse(scene.hasInvalidations())
105+
assertFalse(scene.hasPendingMeasureOrLayout)
106+
assertFalse(scene.hasPendingDraw)
106107

107108
val drawInvalidationsBeforeClose = drawInvalidations
108109
layer!!.close()
109110

111+
assertTrue(scene.hasPendingMeasureOrLayout)
112+
assertTrue(scene.hasPendingDraw)
110113
assertTrue(
111114
drawInvalidations > drawInvalidationsBeforeClose,
112115
"Detaching a layer must request a draw pass to repaint the scene without it",

0 commit comments

Comments
 (0)