-
Notifications
You must be signed in to change notification settings - Fork 58
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
CATiledLayer for large chunks of text #14
Comments
Yeah, big fan of CATiledLayer for huge chunks of text. However, they are REALLY heavy weight on memory and bad for scroll perf if you have a bunch of them on the screen at once (I tested this awhile ago). In my other text impl I worked on in 2015 in my spare time I came up with the idea of a dual CALayer/CATiledLayer impl that basically uses the layers as stupid shells, and encapsulates logic in a layer render delegate. It's a kind of complicated dance that I'm sure could be simplified. I pulled the impl from my old project: https://gist.github.com/ocrickard/9892a28cfd733a84fed95b2a66f27615 Anyway, if you're looking for inspiration, that impl performs great both in tiny little labels, and in huuuge walls of text. |
TIL!! I've never used it before, spared me a lot of time figuring this out lol. I bet the async drawing will be a good quick win. Then if we (or someone else) is hitting huge perf issues from drawing giant bitmaps, then we can find a way to make this work. |
Summary: The current technique we use to draw text uses linear memory, which means that when text is too long the UIView layer is unable to draw it. This causes the issue described [here](#19453). On an iOS simulator the bug happens at around 500 lines which is quite annoying. It can also happen on a real device but requires a lot more text. To be more specific the amount of text doesn't actually matter, it is the size of the UIView that we use to draw the text. When we use `[drawRect:]` the view creates a bitmap to send to the gpu to render, if that bitmap is too big it cannot render. To fix this we can use `CATiledLayer` which will split drawing into smaller parts, that gets executed when the content is about to be visible. This drawing is also async which means the text can seem to appear during scroll. See https://developer.apple.com/documentation/quartzcore/calayer?language=objc. `CATiledLayer` also adds some overhead that we don't want when rendering small amount of text. To fix this we can use either a regular `CALayer` or a `CATiledLayer` depending on the size of the view containing the text. I picked 1024 as the threshold which is about 1 screen and a half, and is still smaller than the height needed for the bug to occur when using a regular `CALayer` on a iOS simulator. Also found this which addresses the problem in a similar manner and took some inspiration from the code linked there GitHawkApp/StyledTextKit#14 (comment) Fixes #19453 ## Changelog [iOS] [Fixed] - Use CALayers to draw text, fixes rendering for long text Pull Request resolved: #24387 Test Plan: - Added the example I was using to verify the fix to RNTester. - Made sure all other examples are still rendering properly. - Tested text selection Reviewed By: shergin Differential Revision: D15918277 Pulled By: sammy-SC fbshipit-source-id: c45409a8413e6e3ad272be39ba527a4e8d349e28
Summary: The current technique we use to draw text uses linear memory, which means that when text is too long the UIView layer is unable to draw it. This causes the issue described [here](#19453). On an iOS simulator the bug happens at around 500 lines which is quite annoying. It can also happen on a real device but requires a lot more text. To be more specific the amount of text doesn't actually matter, it is the size of the UIView that we use to draw the text. When we use `[drawRect:]` the view creates a bitmap to send to the gpu to render, if that bitmap is too big it cannot render. To fix this we can use `CATiledLayer` which will split drawing into smaller parts, that gets executed when the content is about to be visible. This drawing is also async which means the text can seem to appear during scroll. See https://developer.apple.com/documentation/quartzcore/calayer?language=objc. `CATiledLayer` also adds some overhead that we don't want when rendering small amount of text. To fix this we can use either a regular `CALayer` or a `CATiledLayer` depending on the size of the view containing the text. I picked 1024 as the threshold which is about 1 screen and a half, and is still smaller than the height needed for the bug to occur when using a regular `CALayer` on a iOS simulator. Also found this which addresses the problem in a similar manner and took some inspiration from the code linked there GitHawkApp/StyledTextKit#14 (comment) Fixes #19453 ## Changelog [iOS] [Fixed] - Use CALayers to draw text, fixes rendering for long text Pull Request resolved: #24387 Test Plan: - Added the example I was using to verify the fix to RNTester. - Made sure all other examples are still rendering properly. - Tested text selection Reviewed By: shergin Differential Revision: D15918277 Pulled By: sammy-SC fbshipit-source-id: c45409a8413e6e3ad272be39ba527a4e8d349e28
Summary: The current technique we use to draw text uses linear memory, which means that when text is too long the UIView layer is unable to draw it. This causes the issue described [here](facebook#19453). On an iOS simulator the bug happens at around 500 lines which is quite annoying. It can also happen on a real device but requires a lot more text. To be more specific the amount of text doesn't actually matter, it is the size of the UIView that we use to draw the text. When we use `[drawRect:]` the view creates a bitmap to send to the gpu to render, if that bitmap is too big it cannot render. To fix this we can use `CATiledLayer` which will split drawing into smaller parts, that gets executed when the content is about to be visible. This drawing is also async which means the text can seem to appear during scroll. See https://developer.apple.com/documentation/quartzcore/calayer?language=objc. `CATiledLayer` also adds some overhead that we don't want when rendering small amount of text. To fix this we can use either a regular `CALayer` or a `CATiledLayer` depending on the size of the view containing the text. I picked 1024 as the threshold which is about 1 screen and a half, and is still smaller than the height needed for the bug to occur when using a regular `CALayer` on a iOS simulator. Also found this which addresses the problem in a similar manner and took some inspiration from the code linked there GitHawkApp/StyledTextKit#14 (comment) Fixes facebook#19453 ## Changelog [iOS] [Fixed] - Use CALayers to draw text, fixes rendering for long text Pull Request resolved: facebook#24387 Test Plan: - Added the example I was using to verify the fix to RNTester. - Made sure all other examples are still rendering properly. - Tested text selection Reviewed By: shergin Differential Revision: D15918277 Pulled By: sammy-SC fbshipit-source-id: c45409a8413e6e3ad272be39ba527a4e8d349e28
Idk how best to combine these, but would improve rendering huge chunks of text.
mmap
bitmap from diskThe text was updated successfully, but these errors were encountered: