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

Support multiple textures in webgl and canvas renderer #4061

Closed
Tyriar opened this issue Aug 23, 2022 · 4 comments · Fixed by #4244
Closed

Support multiple textures in webgl and canvas renderer #4061

Tyriar opened this issue Aug 23, 2022 · 4 comments · Fixed by #4244
Assignees
Labels
area/addon/canvas area/addon/webgl type/enhancement Features or improvements to existing features
Milestone

Comments

@Tyriar
Copy link
Member

Tyriar commented Aug 23, 2022

VS Code issue: microsoft/vscode#158876

Currently we support a single 1024x1024 texture in the webgl renderer, when it gets filled we clear it and restart. Ideally we would support multiple textures (~4mb each) up to some maximum, this would let us support high dpi displays much better.

The canvas texture atlas has the same issue.

@Tyriar
Copy link
Member Author

Tyriar commented Aug 28, 2022

Can just increase the size of the atlas as well, up to gl.getParameter(gl.MAX_TEXTURE_SIZE) (16384 on my macbook). Perhaps increase the size only on reset to keep memory minimal?

@Tyriar
Copy link
Member Author

Tyriar commented Aug 28, 2022

Actually I think the reason the texture is small was to keep the uploads on new glyphs shorter.

@jerch
Copy link
Member

jerch commented Sep 3, 2022

Just some brainstorming on this (as I have lit. no clue how its organized currently on either webgl or canvas end):

  • Put standard glyphs (as of ASCII print range, maybe enhanced by some additional often occuring chars/interpunction) in a static texture calculated early on startup. This texture never gets altered, but only read from.
  • Put any other glyph in additional textures on the fly. In the beginning those textures are only filling up from more and more chars coming, once the total texture space is taken some eviction (by some "cache rules") takes place.
  • Possible eviction on non static textures:
    • first eviction run - drop all additional textures, recreate them with descending char likelihood (most likely in first non-static texture, least often seen go to last texture)
    • later eviction runs - on default drop and recreate only last texture, once in a while re-eval char-likelihoods (running counters?) and do recreation on earlier textures, if some threshold is hit

The "cache strategy" above would try to order chars on textures based on their occurrences in the past with the assumption, that often seen chars will be more likely in the future as well. This should get pretty stable over time at least for the first non-static textures, later textures will show more changes over time. Maybe this way texture can be kept pretty small to avoid costly recreation?

A slightly more advanced model would "overflow" into the next texture earlier (like when it is only halfway filled) and already re-eval char amounts during this step to get a better initial ordering with less full recreation steps.

@Tyriar
Copy link
Member Author

Tyriar commented Oct 24, 2022

Put standard glyphs (as of ASCII print range, maybe enhanced by some additional often occuring chars/interpunction) in a static texture calculated early on startup. This texture never gets altered, but only read from.

This is pretty much how it works, just we pack it in the single texture; we warm up the these standard glyphs (part of ascii range, default fg/bg) in idle callbacks. If we wanted to support more than 1 texture I think we should just make the whole system scale out dynamically to n textures. It looks possible, and it was one of my weekend projects a few weeks ago but I got distracted with other stuff 😄

There is also the option of just increasing the texture size which would fix the problem for most users easily, but I've been hesitant to do that since the larger the texture is, the longer it blocks the main thread to initialize and upload. Better might actually be to reduce the texture size when we move to supporting n of textures (from 1024x1024 to 512x512, possibly multiplying by devicePixelRatio?). I think reducing the texture size is a similar idea to your static texture idea by lowering the amount of effort it is to push new textures?

Here's an example of the demo starting up, showing the relative weight of the texture upload:

image

I think the getContext above will also scale depending on how large the texture is.

Possible eviction on non static textures

Eviction always seemed like more effort than it is worth to me, tracking it will end up eating more memory and cpu time and since we already pack the atlas pretty tight, the spots in between would be pretty small. In most real world use cases the user never hits the texture limit as well. The amount of GPU memory we end up consuming is also quite small which is another reason eviction feels like overkill, currently the texture takes 102410244 bytes = 4MB.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/addon/canvas area/addon/webgl type/enhancement Features or improvements to existing features
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants