KaustubhPatange / kapture

A small library for Jetpack Compose to capture Composable content to Android Bitmap.
Apache License 2.0
14 stars 0 forks source link

Software rendering doesn't support hardware bitmaps #2

Open zkvvoob opened 1 year ago

zkvvoob commented 1 year ago

Hello,

I realise it's been quite a long time since you released kapture and you probably don't intend to support it anymore, but on the off-chance that you still care, could you look into this exception that I keep getting, please?

FATAL EXCEPTION: main
Process: com.example.myapp, PID: 23210
java.lang.IllegalArgumentException: Software rendering doesn't support hardware bitmaps
at android.graphics.BaseCanvas.throwIfHwBitmapInSwMode(BaseCanvas.java:706)
at android.graphics.BaseCanvas.throwIfCannotDraw(BaseCanvas.java:81)
at android.graphics.BaseCanvas.drawBitmap(BaseCanvas.java:139)
at android.graphics.Canvas.drawBitmap(Canvas.java:1604)
at androidx.compose.ui.graphics.AndroidCanvas.drawImageRect-HPBpro0(AndroidCanvas.android.kt:271)
at androidx.compose.ui.graphics.drawscope.CanvasDrawScope.drawImage-AZ2fEMs(CanvasDrawScope.kt:263)
at androidx.compose.ui.node.LayoutNodeDrawScope.drawImage-AZ2fEMs(Unknown Source:40)
at androidx.compose.ui.graphics.drawscope.DrawScope.drawImage-AZ2fEMs$default(DrawScope.kt:510)
at androidx.compose.ui.graphics.painter.BitmapPainter.onDraw(BitmapPainter.kt:93)
at androidx.compose.ui.graphics.painter.Painter.draw-x_KDEd0(Painter.kt:212)
at coil.compose.AsyncImagePainter.onDraw(AsyncImagePainter.kt:210)
at androidx.compose.ui.graphics.painter.Painter.draw-x_KDEd0(Painter.kt:212)
at coil.compose.ContentPainterModifier.draw(ContentPainterModifier.kt:188)
at androidx.compose.ui.node.BackwardsCompatNode.draw(BackwardsCompatNode.kt:352)
at androidx.compose.ui.node.LayoutNodeDrawScope.drawDirect-x_KDEd0$ui_release(LayoutNodeDrawScope.kt:105)
at androidx.compose.ui.node.LayoutNodeDrawScope.draw-x_KDEd0$ui_release(LayoutNodeDrawScope.kt:86)
at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:342)
at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:331)
at androidx.compose.ui.node.LayoutModifierNodeCoordinator.performDraw(LayoutModifierNodeCoordinator.kt:182)
at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:339)
at androidx.compose.ui.node.NodeCoordinator.access$drawContainedDrawModifiers(NodeCoordinator.kt:57)
at androidx.compose.ui.node.NodeCoordinator$invoke$1.invoke(NodeCoordinator.kt:362)
at androidx.compose.ui.node.NodeCoordinator$invoke$1.invoke(NodeCoordinator.kt:361)
at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2254)
at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:460)
at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:230)
at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:120)
at androidx.compose.ui.node.NodeCoordinator.invoke(NodeCoordinator.kt:361)
at androidx.compose.ui.node.NodeCoordinator.invoke(NodeCoordinator.kt:57)
at androidx.compose.ui.platform.RenderNodeLayer.drawLayer(RenderNodeLayer.android.kt:276)
at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:326)
at androidx.compose.ui.node.LayoutModifierNodeCoordinator.performDraw(LayoutModifierNodeCoordinator.kt:182)
at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:339)
at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:331)
at androidx.compose.ui.node.LayoutModifierNodeCoordinator.performDraw(LayoutModifierNodeCoordinator.kt:182)
at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:339)
at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:331)
at androidx.compose.ui.node.LayoutModifierNodeCoordinator.performDraw(LayoutModifierNodeCoordinator.kt:182)
at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:339)
at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:331)
at androidx.compose.ui.node.LayoutNode.draw$ui_release(LayoutNode.kt:872)
at androidx.compose.ui.node.InnerNodeCoordinator.performDraw(InnerNodeCoordinator.kt:154)
at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:339)
at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:331)
at androidx.compose.ui.node.LayoutModifierNodeCoordinator.performDraw(LayoutModifierNodeCoordinator.kt:182)
at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:339)
at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:331)
at androidx.compose.ui.node.LayoutNode.draw$ui_release(LayoutNode.kt:872)
at androidx.compose.ui.node.InnerNodeCoordinator.performDraw(InnerNodeCoordinator.kt:154)
at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:339)
at androidx.compose.ui.node.NodeCoordinator.access$drawContainedDrawModifiers(NodeCoordinator.kt:57)
at androidx.compose.ui.node.NodeCoordinator$invoke$1.invoke(NodeCoordinator.kt:362)
at androidx.compose.ui.node.NodeCoordinator$invoke$1.invoke(NodeCoordinator.kt:361)
at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2254)
at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:460)
at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:230)
at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:120)
at androidx.compose.ui.node.NodeCoordinator.invoke(NodeCoordinator.kt:361)
at androidx.compose.ui.node.NodeCoordinator.invoke(NodeCoordinator.kt:57)
at androidx.compose.ui.platform.RenderNodeLayer.drawLayer(RenderNodeLayer.android.kt:276)
at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:326)
at androidx.compose.ui.node.LayoutModifierNodeCoordinator.performDraw(LayoutModifierNodeCoordinator.kt:182)
at androidx.compose.ui.node.LayoutNodeDrawScope.drawContent(LayoutNodeDrawScope.kt:66)
at androidx.compose.foundation.BackgroundNode.draw(Background.kt:154)
at androidx.compose.ui.node.LayoutNodeDrawScope.drawDirect-x_KDEd0$ui_release(LayoutNodeDrawScope.kt:105)
at androidx.compose.ui.node.LayoutNodeDrawScope.draw-x_KDEd0$ui_release(LayoutNodeDrawScope.kt:86)
at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:342)
at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:331)
at androidx.compose.ui.node.LayoutNode.draw$ui_release(LayoutNode.kt:872)
at androidx.compose.ui.node.InnerNodeCoordinator.performDraw(InnerNodeCoordinator.kt:154)
at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:339)
at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:331)
at androidx.compose.ui.node.LayoutNode.draw$ui_release(LayoutNode.kt:872)
at androidx.compose.ui.node.InnerNodeCoordinator.performDraw(InnerNodeCoordinator.kt:154)
at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:339)
at androidx.compose.ui.node.NodeCoordinator.access$drawContainedDrawModifiers(NodeCoordinator.kt:57)
at androidx.compose.ui.node.NodeCoordinator$invoke$1.invoke(NodeCoordinator.kt:362)
at androidx.compose.ui.node.NodeCoordinator$invoke$1.invoke(NodeCoordinator.kt:361)
at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2254)
at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:460)
at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:230)
at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:120)
at androidx.compose.ui.node.NodeCoordinator.invoke(NodeCoordinator.kt:361)
at androidx.compose.ui.node.NodeCoordinator.invoke(NodeCoordinator.kt:57)
at androidx.compose.ui.platform.RenderNodeLayer.drawLayer(RenderNodeLayer.android.kt:276)
at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:326)
at androidx.compose.ui.node.LayoutModifierNodeCoordinator.performDraw(LayoutModifierNodeCoordinator.kt:182)
at at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:331)
at androidx.compose.ui.node.LayoutModifierNodeCoordinator.performDraw(LayoutModifierNodeCoordinator.kt:182)
at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:339)
at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:331)
at androidx.compose.ui.node.LayoutNode.draw$ui_release(LayoutNode.kt:872)
at androidx.compose.ui.node.InnerNodeCoordinator.performDraw(InnerNodeCoordinator.kt:154)
at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:339)
at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:331)
at androidx.compose.ui.node.LayoutModifierNodeCoordinator.performDraw(LayoutModifierNodeCoordinator.kt:182)
at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:339)
at androidx.compose.ui.node.NodeCoordinator.access$drawContainedDrawModifiers(NodeCoordinator.kt:57)
at androidx.compose.ui.node.NodeCoordinator$invoke$1.invoke(NodeCoordinator.kt:362)
at androidx.compose.ui.node.NodeCoordinator$invoke$1.invoke(NodeCoordinator.kt:361)
at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2254)
at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:460)
at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:230)
at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:120)
at androidx.compose.ui.node.NodeCoordinator.invoke(NodeCoordinator.kt:361)
at androidx.compose.ui.node.NodeCoordinator.invoke(NodeCoordinator.kt:57)
at androidx.compose.ui.platform.RenderNodeLayer.drawLayer(RenderNodeLayer.android.kt:276)
at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:326)
at androidx.compose.ui.node.LayoutModifierNodeCoordinator.performDraw(LayoutModifierNodeCoordinator.kt:182)
at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:339)
at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:331)
at androidx.compose.ui.node.LayoutModifierNodeCoordinator.performDraw(LayoutModifierNodeCoordinator.kt:182)
at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:339)
at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:331)
at androidx.compose.ui.node.LayoutNode.draw$ui_release(LayoutNode.kt:872)
at androidx.compose.ui.node.InnerNodeCoordinator.performDraw(InnerNodeCoordinator.kt:154)
at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:339)
at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:331)
at androidx.compose.ui.node.LayoutNode.draw$ui_release(LayoutNode.kt:872)
at androidx.compose.ui.node.InnerNodeCoordinator.performDraw(InnerNodeCoordinator.kt:154)
at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:339)
at androidx.compose.ui.node.NodeCoordinator.access$drawContainedDrawModifiers(NodeCoordinator.kt:57)
at androidx.compose.ui.node.NodeCoordinator$invoke$1.invoke(NodeCoordinator.kt:362)
at androidx.compose.ui.node.NodeCoordinator$invoke$1.invoke(NodeCoordinator.kt:361)
at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2254)
at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:460)
at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:230)
at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:120)
at androidx.compose.ui.node.NodeCoordinator.invoke(NodeCoordinator.kt:361)
at androidx.compose.ui.node.NodeCoordinator.invoke(NodeCoordinator.kt:57)
at at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:326)
at androidx.compose.ui.node.LayoutModifierNodeCoordinator.performDraw(LayoutModifierNodeCoordinator.kt:182)
at androidx.compose.ui.node.LayoutNodeDrawScope.drawContent(LayoutNodeDrawScope.kt:66)
at androidx.compose.foundation.BackgroundNode.draw(Background.kt:154)
at androidx.compose.ui.node.LayoutNodeDrawScope.drawDirect-x_KDEd0$ui_release(LayoutNodeDrawScope.kt:105)
at androidx.compose.ui.node.LayoutNodeDrawScope.draw-x_KDEd0$ui_release(LayoutNodeDrawScope.kt:86)
at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:342)
at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:331)
at androidx.compose.ui.node.LayoutModifierNodeCoordinator.performDraw(LayoutModifierNodeCoordinator.kt:182)
at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:339)
at androidx.compose.ui.node.NodeCoordinator.access$drawContainedDrawModifiers(NodeCoordinator.kt:57)
at androidx.compose.ui.node.NodeCoordinator$invoke$1.invoke(NodeCoordinator.kt:362)
at androidx.compose.ui.node.NodeCoordinator$invoke$1.invoke(NodeCoordinator.kt:361)
at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2254)
at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:460)
at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:230)
at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:120)
at androidx.compose.ui.node.NodeCoordinator.invoke(NodeCoordinator.kt:361)
at androidx.compose.ui.node.NodeCoordinator.invoke(NodeCoordinator.kt:57)
at androidx.compose.ui.platform.RenderNodeLayer.drawLayer(RenderNodeLayer.android.kt:276)
at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:326)
at androidx.compose.ui.node.LayoutNode.draw$ui_release(LayoutNode.kt:872)
at androidx.compose.ui.node.InnerNodeCoordinator.performDraw(InnerNodeCoordinator.kt:154)
at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:339)
at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:331)
at androidx.compose.ui.node.LayoutNode.draw$ui_release(LayoutNode.kt:872)
at androidx.compose.ui.platform.AndroidComposeView.dispatchDraw(AndroidComposeView.android.kt:1063)
at android.view.View.draw(View.java:23197)
at androidx.core.view.ViewKt.drawToBitmap(View.kt:240)
at com.kpstv.compose.kapture.ScreenshotController$captureToBitmap$2.invokeSuspend(Kapture.kt:71)
at com.kpstv.compose.kapture.ScreenshotController$captureToBitmap$2.invoke(Unknown Source:8)
at com.kpstv.compose.kapture.ScreenshotController$captureToBitmap$2.invoke(Unknown Source:4)
at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:89)
at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:169)
at kotlinx.coroutines.BuildersKt.withContext(Unknown Source:1)
at com.kpstv.compose.kapture.ScreenshotController.captureToBitmap-gIAlu-s(Kapture.kt:68)
at com.example.myapp.ui.screens.ShareImageScreenKt$ShareImageScreen$1.invokeSuspend(ShareImageScreen.kt:51)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at androidx.compose.ui.platform.AndroidUiDispatcher.performTrampolineDispatch(AndroidUiDispatcher.android.kt:81)
at androidx.compose.ui.platform.AndroidUiDispatcher.access$performTrampolineDispatch(AndroidUiDispatcher.android.kt:41)
at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.run(AndroidUiDispatcher.android.kt:57)
at android.os.Handler.handleCallback(Handler.java:942)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7872)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [androidx.compose.ui.platform.MotionDurationScaleImpl@ba0496, androidx.compose.runtime.BroadcastFrameClock@e9dd817, StandaloneCoroutine{Cancelling}@9d63404, AndroidUiDispatcher@3258ded]
KaustubhPatange commented 1 year ago

This is because you are loading bitmap in GPU, this has its own benefits like performance as each pixel will be stored independently. Since drawToBitmap() androidx utility needs these pixel data it has to be present in memory.

If you are loading an image in Glide, you can use disallowHardwareConfig() to load bitmaps in memory. I don't have any idea about coil if you are using so but I'm sure coil docs must have a mention for that.

5peak2me commented 1 year ago

Use coil's ImageRequest.allowHardware(false) method to solve the problem of java.lang.IllegalArgumentException: Software rendering doesn't support hardware bitmaps

AsyncImage(
    model = ImageRequest.Builder(LocalContext.current)
        .data("https://xxxx.png")
        .allowHardware(false)
        .crossfade(true)
        .build(),
    contentDescription = null,
    modifier = Modifier
        .size(200.dp)
        .clip(RoundedCornerShape(12.dp)),
    contentScale = ContentScale.Crop
)