-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Defer reflow for rows above viewport to idle callbacks #4232
Comments
Will the deferred array buffer resizes in #4115 already do here? They give me ~4 times faster resize runtime. But there is still some work needed over there (got some errors on the |
Delaying the resizing of the buffer would help a lot, combining that with also only resizing/reflowing until either it's needed or an idle callback would speed things up even more. I had a look at this and it's quite a bit more difficult than I initially anticipated, I think a pre-requisite to this is simplifying reflow to be able to run on a range of rows and changing that code always scares me 😅 |
Hmm reflowing only the viewport (in a sense of currently visible area) when resizing occurs, and postponing everything else should remove most of main thread stalls from resizing. The ugly part would be the state holding and dealing with different resize states on the ringbuffer. I wonder if it would be possible to keep the current logic as it is, but just shard the reflow into smaller buffer pieces backwards on the scrollbuffer - by decorating the buffer with a helper structure that maintains the reflow state? Well postponing reflow will introduce several awkward situations, where reflow has to be realized immediately:
As shrinking reflow always removes data from the top of the buffer, we cannot do partial reflow in the middle, but always have to progress sequentially backwards. It gets interesting when several reflows come in in short progression - I think here it would be possible to skip finishing earlier reflows, and just jump to the new sizes. To put this all together, would something like this work? Schematically:
While writing this down I kinda spotted, that we will get issues with our |
That's basically I was thinking but wrapping all access of buffer lines in a check that ensures the reflow state, so whenever they're accessed that would need the reflow to be done it's performed then.
This is the part I can't really get my head around currently since reflow shifts rows around in the buffer as 1 may become n when reflowing smaller and n may become 1 when reflowing larger. |
I'm hoping to do lazy reflow in conjunction with the For what it's worth, I've already implemented this logic in DomTerm. (Necessary because DomTerm reflow is quite expensive, involving DOM updates and handling pretty-printing, and optionally variable-width fonts.) |
@PerBothner Yes your line rewrite also sounds like it makes the reflow itself much more light-weighted - isnt that just a recalc of the soft-wrap "stops" in the end (thus saving the annoying and exp. data moving part)? |
@jerch While in the re-write figuring out where the soft-breaks may require a linear search, that should be more than made up by reduced coping. Partly because the length of the |
I hope we can get away with a simple divmod calc here on the logical length w'o introspection of all cells - here the constant part of the O(n) search would be really tiny. But I'm not quite sure, if thats feasible, because of the ugly wider clusters forcing earlier soft-wrapping with follow-up offsets. A solution to that might be to use a skiplist or a binary tree with a certain width/pos resolution to find the cells at the breaks faster. |
I implemented lazy reflow in my LineBuffer-rewrite fork. |
Resize is one of the bigger bottlenecks, especially in an embedder that has many terminal tabs or when terminal columns is high. We could use a task queue to defer any pending resize operations and either drop or flush when the row is actually needed.
The text was updated successfully, but these errors were encountered: