Coil: Software rendering doesn't support hardware bitmaps

Created on 1 Nov 2019  路  15Comments  路  Source: coil-kt/coil

java.lang.IllegalArgumentException: Software rendering doesn't support hardware bitmaps
at android.graphics.BaseCanvas.onHwBitmapInSwMode(BaseCanvas.java:550)
at android.graphics.BaseCanvas.throwIfHwBitmapInSwMode(BaseCanvas.java:557)
at android.graphics.BaseCanvas.throwIfCannotDraw(BaseCanvas.java:69)
at android.graphics.BaseCanvas.drawBitmap(BaseCanvas.java:127)
at android.graphics.Canvas.drawBitmap(Canvas.java:1516)
at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:545)
at android.widget.ImageView.onDraw(ImageView.java:1360)
at android.view.View.draw(View.java:20332)
at android.view.View.draw(View.java:20194)
at android.view.ViewGroup.drawChild(ViewGroup.java:4395)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4174)
at androidx.constraintlayout.widget.ConstraintLayout.dispatchDraw(ConstraintLayout.java:1767)
at android.view.View.draw(View.java:20340)
at android.view.View.draw(View.java:20194)
at android.view.ViewGroup.drawChild(ViewGroup.java:4395)
at androidx.recyclerview.widget.RecyclerView.drawChild(RecyclerView.java:5030)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4174)
at android.view.View.draw(View.java:20340)
at androidx.recyclerview.widget.RecyclerView.draw(RecyclerView.java:4429)
at android.view.View.draw(View.java:20194)
at android.view.ViewGroup.drawChild(ViewGroup.java:4395)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4174)
at androidx.constraintlayout.widget.ConstraintLayout.dispatchDraw(ConstraintLayout.java:1767)
at android.view.View.draw(View.java:20340)
at android.view.View.draw(View.java:20194)
at android.view.ViewGroup.drawChild(ViewGroup.java:4395)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4174)
at android.view.View.draw(View.java:20192)
at android.view.ViewGroup.drawChild(ViewGroup.java:4395)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4174)
at androidx.constraintlayout.widget.ConstraintLayout.dispatchDraw(ConstraintLayout.java:1767)
at android.view.View.draw(View.java:20340)
at android.view.View.draw(View.java:20194)
at android.view.ViewGroup.drawChild(ViewGroup.java:4395)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4174)
at android.view.View.draw(View.java:20192)
at android.view.ViewGroup.drawChild(ViewGroup.java:4395)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4174)
at android.view.View.draw(View.java:20192)
at android.view.ViewGroup.drawChild(ViewGroup.java:4395)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4174)
at android.view.View.draw(View.java:20192)
at android.view.ViewGroup.drawChild(ViewGroup.java:4395)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4174)
at android.view.View.draw(View.java:20192)
at android.view.ViewGroup.drawChild(ViewGroup.java:4395)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4174)
at android.view.View.draw(View.java:20340)
at com.android.internal.policy.DecorView.draw(DecorView.java:781)
at android.view.ViewRootImpl.drawSoftware(ViewRootImpl.java:3582)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:3472)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:3244)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2598)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1521)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7437)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:965)
at android.view.Choreographer.doCallbacks(Choreographer.java:777)
at android.view.Choreographer.doFrame(Choreographer.java:709)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:951)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)

bug

Most helpful comment

If you're rendering on a software only canvas, you'll need to add allowHardware(false) to your request.

All 15 comments

If you're rendering on a software only canvas, you'll need to add allowHardware(false) to your request.

According to this information by Glide hardware bitmaps have a bug in Android Oreo (26) when used with shared element transitions that is fixed in Oreo 8.1.0 (27). Maybe hardware bitmaps should only be enabled by default for 27+?

I also receive crashes for devices with Android 8.1. Will enable hardware bitmaps for Android 9+ only.

@svenjacobs Hardware bitmaps are a pretty big optimization so I'd want to avoid disabling them. For the crashes, can you let me know if the devices you saw crashes for are in this list? There are a number of devices with hardware-specific issues that I'm working on blocking.

I'm facing the same issue in two different devices that are not in the list
Devices:
One Plus 5: A5000 - Android 9
Pixel 2: walleye - Android 10

Code:

imageView.load(url)

url is a local image file, for example: file:///storage/emulated/0/DCIM/Camera/IMG_20200219_145106.jpg

The issue seems to be that i'm using a ShadowLayout as a parent of the image view

BTW: If I use allowHardware(false) the app works fine

Hmm that's interesting. What's the stacktrace you're seeing?

For the crashes, can you let me know if the devices you saw crashes for are in this list? There are a number of devices with hardware-specific issues that I'm working on blocking.

Here's a list of devices as reported by Firebase Crashlytics that crash with a "Software rendering doesn't support hardware bitmaps" during a shared element transition:

Android 8.1

A3
A60
Aquaris X
Aquaris X Pro
BlackBerry KEY2 LE
Blackview BV9500Pro
Cat S61
CUBOT_NOVA
CUBOT_POWER
Desire 12s
Galaxy J5
Galaxy J7 (2016)
Galaxy J7 Max
Galaxy J7 Prime
Galaxy Tab A (2016)
Gigaset GS270
Gigaset GS370
Gigaset GS370_Plus
GS280
K10
Lenovo TAB4 8 Plus
P1061X
Power 5
Redmi 5 Plus
Redmi Note 4
View2 Go
W_K400
Xperia XZ
ZenFone 4 Max (ZC520KL)

Android 8.0

Desire 12+
U Ultra
Xperia X Compact
Xperia XA1 Ultra
Xperia XZ

Hmm that's interesting. What's the stacktrace you're seeing?


Stacktrace

    java.lang.IllegalArgumentException: Software rendering doesn't support hardware bitmaps
        at android.graphics.BaseCanvas.onHwBitmapInSwMode(BaseCanvas.java:632)
        at android.graphics.BaseCanvas.throwIfHwBitmapInSwMode(BaseCanvas.java:639)
        at android.graphics.BaseCanvas.throwIfCannotDraw(BaseCanvas.java:73)
        at android.graphics.BaseCanvas.drawBitmap(BaseCanvas.java:131)
        at android.graphics.Canvas.drawBitmap(Canvas.java:1588)
        at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:548)
        at android.widget.ImageView.onDraw(ImageView.java:1436)
        at android.view.View.draw(View.java:21975)
        at android.view.View.draw(View.java:21849)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4432)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4193)
        at android.view.View.draw(View.java:21847)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4432)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4193)
        at android.view.View.draw(View.java:21978)
        at android.view.View.draw(View.java:21849)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4432)
        at androidx.recyclerview.widget.RecyclerView.drawChild(RecyclerView.java:5030)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4193)
        at android.view.View.draw(View.java:21978)
        at androidx.recyclerview.widget.RecyclerView.draw(RecyclerView.java:4429)
        at android.view.View.draw(View.java:21849)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4432)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4193)
        at android.view.View.draw(View.java:21978)
        at android.view.View.draw(View.java:21849)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4432)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4193)
        at com.gigamole.library.ShadowLayout.dispatchDraw(ShadowLayout.java:255)
        at android.view.View.draw(View.java:21978)
        at android.view.View.updateDisplayListIfDirty(View.java:20852)
        at android.view.View.draw(View.java:21707)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4432)
        at androidx.coordinatorlayout.widget.CoordinatorLayout.drawChild(CoordinatorLayout.java:1277)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4193)
        at android.view.View.draw(View.java:21978)
        at android.view.View.updateDisplayListIfDirty(View.java:20852)
        at android.view.View.draw(View.java:21707)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4432)
        at androidx.fragment.app.FragmentContainerView.drawChild(FragmentContainerView.java:235)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4193)
        at androidx.fragment.app.FragmentContainerView.dispatchDraw(FragmentContainerView.java:223)
        at android.view.View.updateDisplayListIfDirty(View.java:20843)
        at android.view.View.draw(View.java:21707)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4432)
        at androidx.coordinatorlayout.widget.CoordinatorLayout.drawChild(CoordinatorLayout.java:1277)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4193)
        at android.view.View.updateDisplayListIfDirty(View.java:20843)
        at android.view.View.draw(View.java:21707)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4432)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4193)
        at android.view.View.updateDisplayListIfDirty(View.java:20843)
        at android.view.View.draw(View.java:21707)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4432)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4193)
        at android.view.View.updateDisplayListIfDirty(View.java:20843)
        at android.view.View.draw(View.java:21707)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4432)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4193)
        at android.view.View.updateDisplayListIfDirty(View.java:20843)
        at android.view.View.draw(View.java:21707)
        at android.view.ViewGroup.drawChild(ViewGroup.java:4432)
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4193)
        at android.view.View.updateDisplayListIfDirty(View.java:20843)
        at android.view.View.draw(View.java:21707)

I've been testing a bit more. My app has a rv with some images (a photo gallery) and the crash happens when I call notifyDataSetChanged().

Hey @colinrtwhite I've tested it in the ShadowLayout library sample app and it's crashing, here is the example code, so you can try it.
I'm running basically this line:
(findViewById<ImageView>(R.id.imageView)) .load("https://github.com/xmartlabs/fountain/blob/master/images/banner.png?raw=true")
After a few seconds, the app crashes with the same issue.
I've used a Pixel 2 to test it

Maybe we can reopen the issue, what do you think?

@matir91 Ah thanks for the sample code - sorry missed the last message. I believe this is working as intended as ShadowLayout doesn't seem to support hardware acceleration. Here it's substituting the backing bitmap for the canvas with a software ARGB_8888 bitmap. This turns the canvas into a software canvas which is unable to render hardware bitmaps. Removing that line should allow the view to draw hardware bitmaps, however I'm not sure if it will break the shadow effect. Unfortunately, there's no way to work around this other than setting allowHardware(false) for your request.

Cool, thanks for explain me the cause of this issue! Yes, I can do it. I just wanted to be sure that this issue was not related to something wrong in this library. Thanks!

I recently had similar issue with 'Moto E5 play' during transitions, I see that on that list which @colinrtwhite shows it is, how should I know if I should enable allowHardware(false), HardwareBitmapService.kt has internal modifier, is there any better way than just copy it?

The hardware bitmap blacklist maintains a list of devices that have issues with hardware bitmaps in all cases. Coil will automatically never use hardware bitmaps on those devices. You shouldn't need to copy the list externally. For shared element transitions, check out this recipe.

I'm facing the same issue in two different devices that are not in the list
Devices:
One Plus 5: A5000 - Android 9
Pixel 2: walleye - Android 10

Code:

imageView.load(url)

url is a local image file, for example: file:///storage/emulated/0/DCIM/Camera/IMG_20200219_145106.jpg

The issue seems to be that i'm using a ShadowLayout as a parent of the image view

BTW: If I use allowHardware(false) the app works fine

Even I use ShadowLayout and got this same Crash,
However, below config seems to fix this :

thumbnail.load(path), imageLoader) {
    videoFrameMicros(2000)
    diskCachePolicy(CachePolicy.ENABLED)
    bitmapConfig(Bitmap.Config.ARGB_8888) // <-- specially this fixed my issue
}

I am also facing the same issue in two different devices that are not in the list;
Xiaomi Redmi Plus 5 - Android 8.1
General Mobile GM8 Go - Android 8

I use neither shadowLayout nor shared element transition, I just use recyclerview with grid layout manager. Error occurs when the user switches between bottom navigation tabs quickly.

I use the coil library with following code snippet

fun ImageView.loadWithCoil(imageUrl: String?) {
    this.load(imageUrl) {
        crossfade(true)
        allowHardware(false)
        bitmapConfig(Bitmap.Config.ARGB_8888)
        placeholder(R.drawable.img_placeholder)
        error(R.drawable.img_placeholder)
        transformations(RoundedCornersTransformation(36F))
    }
}

Should I add another configuration line to solve the issue?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

vegeta2102 picture vegeta2102  路  6Comments

RubenGonzalezGonzalez picture RubenGonzalezGonzalez  路  6Comments

ZacSweers picture ZacSweers  路  4Comments

adesamp picture adesamp  路  3Comments

doilio picture doilio  路  3Comments