Image caches that find an entry in O(log n), so drawing many small images no longer slows down as the caches fill
Prompt's window had come to spend 35 ms of CPU on every frame after some hours open, most of it in `GlesCanvas::draw_image_data`. Every cache hit looked its key up in the LRU order with `VecDeque::iter().position()` and moved it to the back with `remove`, both linear in the number of entries. A terminal draws each glyph as an image, one per colour it is drawn in, so the cache filled towards its 32 MiB with thousands of small textures, 7573 in the window measured, and every glyph of every frame walked all of them. The software canvas's premultiplied cache and the GLES surface cache did the same. `render/lru.rs` is a least-recently-used cache bounded by a byte budget. Each entry keeps the tick it was last used at and a `BTreeMap` orders the keys by it, so a hit, an insertion and an eviction cost O(log n). `insert` returns the values it evicted, for the GLES caches to delete their textures, and never evicts the one just inserted, so a value larger than the whole budget is still kept; inserting a key again returns its old value. Tests cover the eviction order, a value over the budget and a replaced key. `ImageCache` holds its images and its surfaces in one `Lru` each, with the same budgets of 32 and 16 MiB; `ImageCache::image` uploads a texture only when it is not cached, and `evict_overflow` and the two linear lookups are gone. The software canvas keeps its premultiplied images in an `Lru` in place of `PremulCache`. What is cached and evicted is unchanged.
This commit is contained in:
@@ -47,6 +47,7 @@ pub( crate ) mod primitives;
|
||||
pub( crate ) mod text;
|
||||
pub( crate ) mod image;
|
||||
pub( crate ) mod helpers;
|
||||
pub( crate ) mod lru;
|
||||
|
||||
// ─── Backend flag ────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
Reference in New Issue
Block a user