이전 글 : https://nanamare.tistory.com/170 와 관련이 있습니다.
몇일 전 아래와 같은 에러를 다시 만났습니다.
Software rendering doesn't support hardware bitmaps
해당 이슈는 아래와 같은 코드에서 발생했습니다.
canvas.drawBitmap(bitmap, width, height, paint);
결론적으로 "위 코드의 bitmap 이 하드웨어 비트맵이기 때문에, CPU 에 정보가 있지 않아 그려낼 수 없다." 가 원인이였는데,
이전글에서 bitmap 을 가져올 때, ALLOCATOR_SOFTWARE 옵션을 주기 때문에 아마 다른 원인이 있을 것이라고 생각하고 코드를 확인해봤습니다. uri 에서 bitmap 을 변환 시키는 것이 아닌 ImageView 에서 직접 bitmap 을 가져오고 있었는데, 안드로이드 3.0 부터 하드웨어 가속이 기본으로 on 되어 있고, 디바이스의 레벨이 8.0 이상이여서 하드웨어 비트맵의 타겟이 되었습니다 따라서 getBitmap 을 하면 hardware bitmap 으로 채워져 있게 됩니다.
val bitmap = imageView.getBitmap() // default value is hardware's bitmap
그리고 여기서 중요한 점은 hardware bitmap 은 프레임 버퍼(그래픽 메모리, GPU) 에 존재하기 때문에 CPU 가 쉽게 접근할수 없습니다. 따라서 Software rendering doesn't support hardware bitmaps 에러를 던지게 됩니다.
해결법으로는 CPU 메모리 영역에 있는 데이터를 그려내는 (software) Canvas 객체에게 해당 Bitmap 의 값을 복사해서 전달해줘야 합니다.
// 값 복사 Bitmap.Config.HARDWARE 는 사용 X
val softwareBitmap = hardwareBitmap.copy(Bitmap.Config.ARGB_8888, isMutable = true)
https://bumptech.github.io/glide/doc/hardwarebitmaps.html 링크에서
하드웨어 비트맵에 대해 더 자세히 알 수 있습니다.
What are hardware Bitmaps?
Bitmap.Config.HARDWARE is a new Bitmap format that was added in Android O. Hardware Bitmaps store pixel data only in graphics memory and are optimal for cases where the Bitmap is only drawn to the screen.
하드웨어 비트맵이란 무엇인가요 ?
안드로이드 O(8.0) 에서 추가된 새로운 비트맵 형식으로 오직 그래픽 메모리 영역에만 픽셀 데이터를 저장하고, 화면을 그려낼 때만 최적으로 사용할 수 있다. (그래픽 메모리라고 잘 설명이 되어 있었네요.!)
또한 저는 Canvas 에 그려낼 때 이슈가 생겼었는데, 이 밖에도 다양한 사례에서 해당 에러를 만날 수도 있습니다.
1. 아래 API 로 자바에서 픽셀 데이터를 읽고/쓸때
2. C 로 짜여진 Native 코드에서 픽셀 데이터를 읽고/쓸때
3. Software Canvas 에 Bitmap 들을 그려낼 때
Canvas canvas = new Canvas(normalBitmap)
canvas.drawBitmap(hardwareBitmap, 0, 0, new Paint()); // throw error
4. ImageView 에 하드웨어 비트맵을 전달하면서, layerType 으로는 SOFTWARE 를 명시적으로 선언할 때
ImageView imageView = …
imageView.setImageBitmap(hardwareBitmap);
imageView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
5. 너무 많은 파일 디스크립터를 열 때
6. ARGB_8888 Config 를 사용하는 경우
7. 코드를 사용하여 스크린샷을 찍어내는데 이때, Canvas 객체에 뷰를 계층적으로 그려내는 경우
등등이 있다.
더 궁금한 부분은 https://bumptech.github.io/glide/doc/hardwarebitmaps.html#whats-broken-when-we-use-hardware-bitmaps 를 참고하시면 됩니다.
Reference
- 회사 안드 개발자분의 의견
- https://developer.android.com/reference/android/graphics/ImageDecoder
- https://developer.android.com/reference/android/graphics/Bitmap.Config#HARDWARE
'Android > Development Tips' 카테고리의 다른 글
BroadcastReceiver 사용할 때 유의점 (0) | 2021.12.12 |
---|---|
Coil 썸네일 구현하기 (0) | 2021.11.23 |
ViewModel 에서 Fragment, Activity 로 콜백을 조심하자 (0) | 2021.11.18 |
Google login errorCode 12500 인 경우 (0) | 2021.06.07 |
Proguard 로 난독화 된 코드 복호화 (0) | 2021.05.31 |