How to asynchronously upload images from the CPU to the GPU?

180 views
Skip to first unread message

Daljit

unread,
Mar 5, 2023, 7:07:07 PM3/5/23
to skia-discuss
I'm trying to render a large image (using SkImage created from disk data) using the GPU and it's taking a little longer than I need to draw (OpenGL backend). I know that the first time an SkImage is drawn, Skia makes a copy of the pixel data so that it can be uploaded into GPU memory and then it caches the result on subsequent calls.

Now, I would like the pixel data upload to happen asynchronously so my render thread doesn't block when doing so. I can see that SkImage has an asyncRescaleAndReadPixels() method, but I couldn't exactly figure out if this is what I need (and there don't seem to be any examples on how to use it).
Is there a way for doing this? Say, I have a CPU-backed SkImage, how to do I create the equivalent GPU-backed SkImage in an asynchronous manner? If yes, is there an example that shows how to do this?

I can do this using multiple shared OpenGL contexts, but I would like to avoid that because it introduces a lot of complexity. Alternatively, using something like PBOs could be an option, but I would still prefer a built-in Skia solution if available.

Chinmay Garde

unread,
Mar 6, 2023, 9:08:26 AM3/6/23
to skia-d...@googlegroups.com
For texture uploads, Flutter uses SkImage::MakeCrossContextFromPixmap on a different thread with a separate OpenGL context in the same sharegroup as the main context. Flutter only has one of these IO contexts so it also decompresses the images on worker pool before uploading on the IO contexts thread.

Chinmay

--
You received this message because you are subscribed to the Google Groups "skia-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to skia-discuss...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/skia-discuss/5c3e2543-ca4c-4829-838a-84c97074b2fen%40googlegroups.com.

Greg Daniel

unread,
Mar 6, 2023, 9:56:30 AM3/6/23
to skia-d...@googlegroups.com
So if you're trying to avoid using multiple OpenGL contexts, then GL does essentially force you to be single threaded and things can't truly be asynchronous. Now one thing you can control is exactly when to create the GPU backend SkImage. Instead of having Skia do the upload behind the scenes when you draw a raster SkImage, you can use SkImage::makeTextureImage to get a new SkImage that is texture backend. This well at least allow you to control when the upload to the GPU happens and then you just hold on to the new GPU SkImage and use that for your drawing.

Daljit Singh

unread,
Mar 6, 2023, 1:25:17 PM3/6/23
to skia-d...@googlegroups.com
Thanks for the information. That's quite helpful, I wasn't aware of SkImage::MakeCrossContextFromPixmap. I guess I could attempt to use multiple OpenGL contexts in separate threads. I was reluctant because in the past I've had a lot of trouble with OpenGL drivers when using them (especially on Windows) and I can't really use Angle to solve that problem, but since this is a relatively simple use case there may be no trouble.

@Greg thanks, indeed that's probably going to be my short term strategy to achieve higher frame rates (another possibility might be to use some sort of tile rendering mechanism so that texture uploads can be chunked in smaller bits)

You received this message because you are subscribed to a topic in the Google Groups "skia-discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/skia-discuss/MYSRgImCakw/unsubscribe.
To unsubscribe from this group and all its topics, send an email to skia-discuss...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/skia-discuss/CAL_WtP6crL7q8EJpg8K0JLHn5h_z%3DGgwy8tW%3DC3%2Byz%3DdOuUGjg%40mail.gmail.com.

craste...@gmail.com

unread,
Mar 6, 2023, 3:28:27 PM3/6/23
to skia-discuss
I was thinking that you might consider a tile-loading/rendering implementation too.
I am doing something similar for images larger than X by X. (where X is a multiple of 2) I have that working without multi-threading at the moment. As the data is being read, the tiles start popping in.

I am also thinking of including a low-res thumbnail of the image (if it is really large) that can be drawn behind the tiles as they pop-in.  So that the user gets a sense of what is coming into focus, albeit however slowly.

Reply all
Reply to author
Forward
0 new messages