facebook / facebook/fresco

Use Bitmap#prepareToDraw to upload Bitmaps to GPU in advance

Open
#1,756 5 comments 8 reactions 0 assignees View on GitHub
enhancement
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.