You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[impeller] TextFrame::SetPerFrameData is weird and possibly buggy #177424
This is a brain dump of a potential problem I may have discovered in our text rendering.
I was looking through our text rendering code and I was looking at TextFrame::SetPerFrameData. This function is called in LazyGlyphAtlas::AddTextFrame, and that happens in FirstPassDispatcher::DrawText, which happens on the raster thread right before we render a displaylist to a target.
The frame data includes the matrix transform of the text, which is not actually specific to the text frame, but specific to that draw command of that text frame, so it seems wrong to attach it to the text frame itself. In addition, it seems at this point in the pipeline, the text frame itself being mutated feels a little wrong. I can imagine a scenario that leads wrong behavior:
Create a picture recorder
Draw a paragraph to that picture recorder and end recording, yielding a picture
Add this picture to multiple places in a single display list tree that have different matrix transforms on them
When we render this display list tree, the first pass dispatcher will run, and each time it encounters this picture it will set the matrix transform on the text frame based on the current transform, overwriting it multiple times.
When we actually get to rendering this info and populating the glyph atlas, it will use the last written transform for all of the instances of that text frame in the tree. (Which is wrong).
This might be a contrived example, but it sort of illustrates why this data shouldn't be mutated on the text frame itself. Ideally, the information attached to the text frame itself should be agnostic to the surrounding drawing context, and the lazy glyph atlas can store this extra information either in a wrapper object or in a sibling object to the text frame.
The description actually produces results, though they can be subtle. Run the following test case on Skia, note that it will randomize the scales of the individual cells on every repaint even if you are just mousing over the checkbox, but the text will look fine - reasonably well rendered whether the reuse checkbox is set or not.
Now run it with Impeller. It will look fine, like under Skia, if the reuse checkbox is off, but you can often see subtle mistakes in how it lays out and renders the text if reuse is on.
Test case of (optionally) reusing a DisplayList with text in a scene.
Output for the BigSmall variant (showing large hinting fringes on the Big text)Output for the BigSmall variant (showing lack of fringes on the Small text)
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.
Activity
flar commentedon Feb 4, 2026
The description actually produces results, though they can be subtle. Run the following test case on Skia, note that it will randomize the scales of the individual cells on every repaint even if you are just mousing over the checkbox, but the text will look fine - reasonably well rendered whether the reuse checkbox is set or not.
Now run it with Impeller. It will look fine, like under Skia, if the reuse checkbox is off, but you can often see subtle mistakes in how it lays out and renders the text if reuse is on.
Test case of (optionally) reusing a DisplayList with text in a scene.
Example output for Skia with or without the reuse flag
Example for Impeller not reusing the DisplayList
Example for Impeller reusing the DisplayList
flar commentedon Feb 4, 2026
The following Impeller playground test also exhibits the problem:
Unit test code for aiks_dl_text_unittests.cc
Output for the BigSmall variant (showing large hinting fringes on the Big text)
Output for the BigSmall variant (showing lack of fringes on the Small text)
[Impeller] Remove shared rendering data from TextFrame (#182886)
[Impeller] Remove shared rendering data from TextFrame (flutter#182886)
[Impeller] Remove shared rendering data from TextFrame (flutter#182886)
github-actions commentedon Mar 13, 2026
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of
flutter doctor -vand a minimal reproduction of the issue.[Impeller] Remove shared rendering data from TextFrame (flutter#182886)
[Impeller] Remove shared rendering data from TextFrame (#182886)