Skip to content

"IllegalArgumentException: Software rendering doesn't support drawRenderNode" caused by Modifier.animateItem() in compose 1.7.0-alpha06 #290

@alexjlockwood

Description

@alexjlockwood

I have a sample project (which you can download here in RoborazziSample.zip) that runs the following test:

@Test
fun lazyColumnTest() {
    composeTestRule.setContent {
        LazyColumn {
            item {
                Text(
                    modifier = Modifier.animateItem(),
                    text = "Text",
                )
            }
        }
    }
}

When I run this test, I get an exception:

java.lang.IllegalArgumentException: Software rendering doesn't support drawRenderNode

My sample project uses the following versions:

  • Compose 1.7.0-alpha06
  • Roborazzi 1.11.0
  • Robolectric 4.12.1

The issue seems to be related to Modifier.animateItem() in Compose 1.7.0-alpha06, as this test works fine if I downgrade to Compose 1.7.0-alpha05 and replace the modifier with the older Modifier.animateItemPlacement(). (If you are unfamiliar with these APIs, basically they allow for automatic fade in/out/reordering animations in a compose list).

I am uncertain of the details causing this exception, but I do notice that in the latest Compose changelog there is mention of changes to GraphicsLayer and I noticed that there's also mention of GraphicsLayer in the PR that introduced this new Modifier.animateLayer() API.

Full stack trace:

java.lang.IllegalArgumentException: Software rendering doesn't support drawRenderNode
	at android.graphics.Canvas.drawRenderNode(Canvas.java:2329)
	at androidx.compose.ui.graphics.layer.GraphicsLayerV29.draw(GraphicsLayerV29.android.kt:233)
	at androidx.compose.ui.graphics.layer.GraphicsLayer.draw$ui_graphics_release(AndroidGraphicsLayer.android.kt:510)
	at androidx.compose.ui.graphics.layer.GraphicsLayerKt.drawLayer(GraphicsLayer.kt:55)
	at androidx.compose.ui.platform.GraphicsLayerOwnerLayer.drawLayer(GraphicsLayerOwnerLayer.android.kt:107)
	at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:415)
	at androidx.compose.ui.node.LayoutNode.draw$ui_release(LayoutNode.kt:964)
	at androidx.compose.ui.node.InnerNodeCoordinator.performDraw(InnerNodeCoordinator.kt:196)
	at androidx.compose.ui.node.LayoutNodeDrawScope.drawContent(LayoutNodeDrawScope.kt:68)
	at androidx.compose.foundation.DrawStretchOverscrollModifier.draw(AndroidOverscroll.android.kt:156)
	at androidx.compose.ui.node.BackwardsCompatNode.draw(BackwardsCompatNode.kt:350)
	at androidx.compose.ui.node.LayoutNodeDrawScope.drawDirect-eZhPAX0$ui_release(LayoutNodeDrawScope.kt:110)
	at androidx.compose.ui.node.LayoutNodeDrawScope.draw-eZhPAX0$ui_release(LayoutNodeDrawScope.kt:89)
	at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:431)
	at androidx.compose.ui.node.NodeCoordinator.access$drawContainedDrawModifiers(NodeCoordinator.kt:58)
	at androidx.compose.ui.node.NodeCoordinator$drawBlock$1$1.invoke(NodeCoordinator.kt:450)
	at androidx.compose.ui.node.NodeCoordinator$drawBlock$1$1.invoke(NodeCoordinator.kt:449)
	at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:488)
	at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:502)
	at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:258)
	at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:133)
	at androidx.compose.ui.node.NodeCoordinator$drawBlock$1.invoke(NodeCoordinator.kt:449)
	at androidx.compose.ui.node.NodeCoordinator$drawBlock$1.invoke(NodeCoordinator.kt:447)
	at androidx.compose.ui.platform.RenderNodeLayer.drawLayer(RenderNodeLayer.android.kt:317)
	at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:415)
	at androidx.compose.ui.node.LayoutModifierNodeCoordinator.performDraw(LayoutModifierNodeCoordinator.kt:279)
	at androidx.compose.ui.node.LayoutNodeDrawScope.drawContent(LayoutNodeDrawScope.kt:68)
	at androidx.compose.foundation.lazy.LazyListItemAnimator$DisplayingDisappearingItemsNode.draw(LazyListItemAnimator.kt:447)
	at androidx.compose.ui.node.LayoutNodeDrawScope.drawDirect-eZhPAX0$ui_release(LayoutNodeDrawScope.kt:110)
	at androidx.compose.ui.node.LayoutNodeDrawScope.draw-eZhPAX0$ui_release(LayoutNodeDrawScope.kt:89)
	at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:431)
	at androidx.compose.ui.node.NodeCoordinator.access$drawContainedDrawModifiers(NodeCoordinator.kt:58)
	at androidx.compose.ui.node.NodeCoordinator$drawBlock$1$1.invoke(NodeCoordinator.kt:450)
	at androidx.compose.ui.node.NodeCoordinator$drawBlock$1$1.invoke(NodeCoordinator.kt:449)
	at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2408)
	at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:502)
	at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:258)
	at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:133)
	at androidx.compose.ui.node.NodeCoordinator$drawBlock$1.invoke(NodeCoordinator.kt:449)
	at androidx.compose.ui.node.NodeCoordinator$drawBlock$1.invoke(NodeCoordinator.kt:447)
	at androidx.compose.ui.platform.RenderNodeLayer.drawLayer(RenderNodeLayer.android.kt:317)
	at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:415)
	at androidx.compose.ui.node.LayoutNode.draw$ui_release(LayoutNode.kt:964)
	at androidx.compose.ui.node.InnerNodeCoordinator.performDraw(InnerNodeCoordinator.kt:196)
	at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:428)
	at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:420)
	at androidx.compose.ui.node.LayoutNode.draw$ui_release(LayoutNode.kt:964)
	at androidx.compose.ui.platform.AndroidComposeView.dispatchDraw(AndroidComposeView.android.kt:1505)
	at android.view.View.draw(View.java:23892)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at org.robolectric.shadows.ShadowView$_View_$$Reflector21.draw(Unknown Source)
	at org.robolectric.shadows.ShadowView.draw(ShadowView.java:261)
	at android.view.View.draw(View.java)
	at android.view.View.draw(View.java:23762)
	at android.view.ViewGroup.drawChild(ViewGroup.java:4556)
	at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4317)
	at android.view.View.draw(View.java:23760)
	at android.view.ViewGroup.drawChild(ViewGroup.java:4556)
	at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4317)
	at android.view.View.draw(View.java:23760)
	at android.view.ViewGroup.drawChild(ViewGroup.java:4556)
	at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4317)
	at android.view.View.draw(View.java:23760)
	at android.view.ViewGroup.drawChild(ViewGroup.java:4556)
	at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4317)
	at android.view.View.draw(View.java:23892)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at org.robolectric.shadows.ShadowView$_View_$$Reflector21.draw(Unknown Source)
	at org.robolectric.shadows.ShadowView.draw(ShadowView.java:261)
	at android.view.View.draw(View.java)
	at com.android.internal.policy.DecorView.draw(DecorView.java:809)
	at org.robolectric.shadows.ShadowPixelCopy.takeScreenshot(ShadowPixelCopy.java:169)
	at org.robolectric.shadows.ShadowPixelCopy.request(ShadowPixelCopy.java:96)
	at android.view.PixelCopy.request(PixelCopy.java)
	at com.github.takahirom.roborazzi.ViewScreenshotKt.generateBitmapFromPixelCopy(ViewScreenshot.kt:204)
	at com.github.takahirom.roborazzi.ViewScreenshotKt.generateBitmapFromPixelCopy(ViewScreenshot.kt:187)
	at com.github.takahirom.roborazzi.ViewScreenshotKt.generateBitmap(ViewScreenshot.kt:124)
	at com.github.takahirom.roborazzi.ViewScreenshotKt.fetchImage(ViewScreenshot.kt:23)
	at com.github.takahirom.roborazzi.ComposeScreenshotKt.fetchImage(ComposeScreenshot.kt:59)
	at com.github.takahirom.roborazzi.RoboComponent$Compose.<init>(capture.kt:184)
	at com.github.takahirom.roborazzi.RoboComponent$Compose.<init>(capture.kt:176)
	at com.github.takahirom.roborazzi.RoborazziKt.captureRoboImage(Roborazzi.kt:277)
	at com.github.takahirom.roborazzi.RoborazziRule.runTest(RoborazziRule.kt:225)
	at com.github.takahirom.roborazzi.RoborazziRule.access$runTest(RoborazziRule.kt:27)
	at com.github.takahirom.roborazzi.RoborazziRule$apply$1.evaluate(RoborazziRule.kt:132)
	at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:54)
	at androidx.compose.ui.test.junit4.AndroidComposeTestRule$apply$1$evaluate$1.invoke(AndroidComposeTestRule.android.kt:272)
	at androidx.compose.ui.test.junit4.AndroidComposeTestRule$apply$1$evaluate$1.invoke(AndroidComposeTestRule.android.kt:271)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment$AndroidComposeUiTestImpl.withDisposableContent(ComposeUiTest.android.kt:505)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment$runTest$1$1$1$1$1$1.invoke(ComposeUiTest.android.kt:333)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment.withComposeIdlingResource(ComposeUiTest.android.kt:385)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment.access$withComposeIdlingResource(ComposeUiTest.android.kt:219)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment$runTest$1$1$1$1$1.invoke(ComposeUiTest.android.kt:332)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment.withWindowRecomposer(ComposeUiTest.android.kt:359)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment.access$withWindowRecomposer(ComposeUiTest.android.kt:219)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment$runTest$1$1$1$1.invoke(ComposeUiTest.android.kt:331)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment.withTestCoroutines(ComposeUiTest.android.kt:372)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment.access$withTestCoroutines(ComposeUiTest.android.kt:219)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment$runTest$1$1$1.invoke(ComposeUiTest.android.kt:330)
	at androidx.compose.ui.test.IdlingStrategy.withStrategy(IdlingStrategy.android.kt:52)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment$runTest$1$1.invoke(ComposeUiTest.android.kt:329)
	at androidx.compose.ui.test.IdlingResourceRegistry.withRegistry(IdlingResourceRegistry.jvm.kt:155)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment$runTest$1.invoke(ComposeUiTest.android.kt:328)
	at androidx.compose.ui.test.ComposeRootRegistry.withRegistry(ComposeRootRegistry.android.kt:146)
	at androidx.compose.ui.test.AndroidComposeUiTestEnvironment.runTest(ComposeUiTest.android.kt:327)
	at androidx.compose.ui.test.junit4.AndroidComposeTestRule$apply$1.evaluate(AndroidComposeTestRule.android.kt:271)
	at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at org.robolectric.RobolectricTestRunner$HelperTestRunner$1.evaluate(RobolectricTestRunner.java:588)
	at org.robolectric.internal.SandboxTestRunner$2.lambda$evaluate$2(SandboxTestRunner.java:290)
	at org.robolectric.internal.bytecode.Sandbox.lambda$runOnMainThread$0(Sandbox.java:101)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at java.base/java.lang.Thread.run(Thread.java:833)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions