Use Bitmap#prepareToDraw to upload Bitmaps to GPU in advance
- Dominant language
- Kotlin
- Stars
- 17.2k
- Forks
- 3.7k
- PR merge metrics
- No merged PRs in 30d
Description
### Description
Hey, I work on UI Toolkit Graphics in Android. Wanted to pass on an optimization you can enable for displaying Bitmaps.
Android displays Bitmaps as OpenGL textures, and the first time a Bitmap is displayed in a frame, it’s uploaded to the GPU. That can take several milliseconds, but it’s necessary to display the image with the GPU.
In Android N, we added behavior to Bitmap#prepareToDraw() to send an async message to RenderThread to pre-upload. RenderThread uploads these to the GPU when it expects to be idle between frames, instead of while drawing the first frame that uses the Bitmap. If you can do this after decoding, you can make it much less likely that frames are dropped due to uploading.
### Reproduction
In Systrace, you can see the problem when any Bitmap is displayed by looking for sections labeled ‘Upload \x\ Texture’. If those are happening in ‘DrawFrame’ on the RenderThread, inside ‘syncFrameState,’ they haven’t been pre-uploaded, and are on the critical path for the frame.
### Solution
Call Bitmap#prepareToDraw as early as possible when you think a Bitmap will be displayed soon. The most aggressive way to do this is any time you decode an image (especially any immutable image).
The drawback is that if you call it on a bitmap before you modify it, or if it doesn’t get drawn, you’ll be wasting the time spent uploading. If you’re reasonably sure the Bitmap in question will be displayed, it’s still a great way to prefetch the upload work on RenderThread.
### Additional Information
Behavior added in Android N:
https://android.googlesource.com/platform/frameworks/base/+/4387190d8ec9fe4e953fcfeb093a644b82cf85ed
For reference, Glide implemented this here: https://github.com/bumptech/glide/commit/dce95506f138bd877aaed1183958f5e186a2bf
It's safe to call on older versions, so you don't need a version check. The method existed prior to N, but was a noop for normal Bitmaps.
Contributor guide
Assessment
This issue has not been assessed yet.