iced-rs / iced

A cross-platform GUI library for Rust, inspired by Elm
https://iced.rs
MIT License
24.67k stars 1.15k forks source link

Rendering janks when large images are added to the layout #549

Open twitchyliquid64 opened 4 years ago

twitchyliquid64 commented 4 years ago

EG: The tour example, when you click Next to go to the page with the resizable rust logo.

~As far as I can tell, this is because upload of the raster data is synchronous in calls to iced_wgpu::image::Pipeline::draw(), and I think it takes a while (and hence blocks the event loop).~

A few ideas for improving this:

  1. Use a real cache (with a better eviction policy) in the raster cache. At a guess, I would use 2-queue or LRU. This won't fix the root cause, but will greatly improve cache efficiency in situations where images are re-used, but are not in every layout tree (for example, you experience jank on the tour example when going beyond the image page and then back again).

~2. Parallelize raster uploads across draw().

twitchyliquid64 commented 4 years ago

An interesting development: Its not the upload (only take 4ms for me) nor reading/allocating the image pixels (<1ms), but the conversion from raw pixel data using to_bgra() using this method which is super slow - over a second for the 1000x800 rust logo.

Because this conversion is done so late and is not cached once uploaded, we have to incur this cost every time the image leaves (and then enters) the layout.

Having an immediate-mode API like Image::new("kek.png") is nice, but because the only cached representation of the BGRA pixel data is all the way at the bottom of the stack (backend / image pipeline), we don't have any opportunity to cache the expensive BGRA data.

randall-coding commented 3 years ago

I just ran into this issue as well in my development process. Adding some caching here will be a great improvement. :+1: