Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple windows / buffers per cache #97

Open
dhardy opened this issue Mar 3, 2020 · 5 comments
Open

Multiple windows / buffers per cache #97

dhardy opened this issue Mar 3, 2020 · 5 comments

Comments

@dhardy
Copy link
Contributor

dhardy commented Mar 3, 2020

So, for any application / library using multiple windows / render targets, it makes sense to track the draw queue and cache validation status per window, but it may still make sense to share the actual cache across windows. Lets consider introducing GlyphBrushBuffer to track a per-window/target queue.

The motivation is better resource-sharing across windows and better cache management. Additionally, a separate buffer could be used per clip-region (see kas-gui/kas#20: currently KAS does not clip fonts within a scroll-region, while last I checked Iced does but with sub-optimal cache behaviour) — although since drawing fonts amounts to copying a rect from a texture, it may be easier to solve this by specifying more explicit boundaries within the Section — I'll probably open a separate issue/PR about this.

Investigation

I took a look at the GlyphBrush type, and it looks like everything besides fonts, texture_cache and cache_glyph_drawing should belong to GlyphBrushBuffer (except that frame_seq_id_sections may no longer have a reason to exist if users can use a separate buffer for each "similar frame").

But, there's a problem: texture_cache considers any glyph not queued since the last cache update to be ripe-for-removal, when it may still be in use by a different buffer. So, the gpu_cache code also needs updating — I see you already have plans here.

Waffling on about caches ...

It may seem like there's an easy answer to cache validation: draw each window in order, then clear anything not used since the last draw cycle, but this assumes that each window/target gets drawn in sequence. In a general UI system a window may only get redrawn when its contents change, so this assumption doesn't hold.

The best option for cache-removal may then be to clear not-recently-used items, where "recently" means "in the last N queues" or some such. (Each buffer could track and remove unwanted sections it has added, but this doesn't deal with shared glyphs, and any method for calculating exactly which of those are wanted requires a holistic list of all active buffers — complicated and difficult to use.)

@alexheretic
Copy link
Owner

rusttype's gpu_cache API is modelled on a single cache_queued call each frame. This sets the agenda for glyph_brush's API and is the reason we can't currently share a draw-cache texture between multiple glyph_brush instances.

I am aiming to design a new draw cache with a different use style that's more flexible.

For now I'd just use multiple glyph_brush instances each with their own cache. The positioning & vertex caches aren't very useful to share between different sections anyway. If gpu memory is the issue, fair enough. But the rusttype gpu_cache module is already quite heavy on memory usage and, I think, has lower hanging fruit there.

currently KAS does not clip fonts within a scroll-region, while last I checked Iced does but with sub-optimal cache behaviour

I don't understand this, does this mean ensuring that the fonts don't draw past their bounds? They already do that in all glyph_brush examples. It's done by simply respecting the bounds in the vertex generation function. So take the paragraph example using height / 2.0 bounds.

@dhardy
Copy link
Contributor Author

dhardy commented Mar 3, 2020

Yes; however, the bounds in a Section are used to calculate glyph positions by the layout. I think a supplemental draw_bounds rect is needed here. Since the draw bounds may not be aligned with the text position and may have nothing to do with the bounds used for layout control, I think the whole rect must be specified too. Looks like the pre-positioned glyph API is already sufficient.

@dhardy
Copy link
Contributor Author

dhardy commented Mar 3, 2020

I was just looking at GlyphPositioner::bounds_rect: this calculates bounds based on glyph geometry. I'd like to use the intersection of this rect with user-provided draw_bounds.

@alexheretic
Copy link
Owner

alexheretic commented Mar 3, 2020 via email

@dhardy
Copy link
Contributor Author

dhardy commented Jul 31, 2020

I'm now moving to using the prepositioned_glyphs API with my own caching, so don't really care about the cache management aspect of this issue any more (and clipping I solved via a depth buffer instead).

I still have this comment in KAS: that ideally the glyph cache should only once for the application (while the render surface is per-window in a multi-window GUI). I leave it to you whether you wish to do this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants