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

Should skribo provide a shaping cache? #30

Closed
pcwalton opened this issue Feb 19, 2020 · 8 comments · Fixed by #33
Closed

Should skribo provide a shaping cache? #30

pcwalton opened this issue Feb 19, 2020 · 8 comments · Fixed by #33
Labels
question Further information is requested

Comments

@pcwalton
Copy link
Collaborator

pcwalton commented Feb 19, 2020

I'm finding that a lot of Pathfinder HTML canvas-like use cases end up slow for an annoying reason: they render the same text again and again, which ends up going through skribo and HarfBuzz to be shaped repeatedly. The solution is to cache on some level (per-word or per-run), but there's the question of who should be responsible for this caching. Should skribo offer this functionality, or should it be up to Pathfinder?

As detailed in #4, this is a difficult issue, and so it might be nice for skribo to implement per-word (or whatever) caching itself so that users of the crate don't have to implement it themselves. On the other hand, perhaps we don't intend skribo to have that many direct users, which would suggest that maybe caching should be handled at a higher level than skribo itself. I'm fine either way, but we should discuss and make a decision :)

@pcwalton pcwalton added the question Further information is requested label Feb 19, 2020
@raphlinus
Copy link
Contributor

It might be worth digging a little into why it's slow, as HarfBuzz tries to be pretty optimized. But if it's because HB is legitimately slow and that we would be able to go faster with a cache, then I think it's within the domain of skribo.

@raphlinus
Copy link
Contributor

You could of course cache the entire layout at a higher level, but that wouldn't give you the benefits of per-word caching; doing that more or less requires it to be done at this level. Note that Minikin implemented per-word caching for very similar reasons.

@pcwalton
Copy link
Collaborator Author

A profile suggests that it's actually HB's internal font sanitization which is slow. Curious as to why that's happening repeatedly.

@raphlinus
Copy link
Contributor

Yeah, we should be careful to retain whatever internal object HB derives after sanitization. I haven't dug deeply into that. Obviously it requires good-enough font identity (perhaps to drive an internal cache of HB font objects).

@RazrFalcon
Copy link

@pcwalton HB sanitizes the font only once. So unless you are creating a hb_font_t object each time it shouldn't be a problem.

@pcwalton
Copy link
Collaborator Author

@RazrFalcon Thanks, that points to the likely culprit: https://github.com/linebender/skribo/blob/master/src/hb_layout.rs#L65

I guess we should lazily instantiate and reuse the hb_font_t for each Font object.

@raphlinus
Copy link
Contributor

Yeah, I probably thought the font was relatively cheap to construct.

@Kethku
Copy link

Kethku commented Feb 23, 2020

I'm running into this with my neovim gui project. I attempt to cache the shaped text whenever possible, but definitely run into slowdowns. I'd be interested to see if this is the main issue

pcwalton added a commit to pcwalton/skribo that referenced this issue Mar 31, 2020
This drops the shaping time on the Pathfinder NanoVG demo from most of the
profile to nearly 0%.

This is not going to be very reliable until we have a global font ID in
`font-kit`.

Closes linebender#30.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants