Skip to content

Conversation

@jonahwilliams
Copy link
Contributor

Fixes #164606

When we preroll the text frame, we record the scale/transform used to compute the size and subpixel position. Use this same size + transform for the subsequent paint so that it is not possible for it to mismatch.

This is not really a fix for the underlying issue where the subpixel position may be mismatched.

@jonahwilliams jonahwilliams requested a review from gaaclarke March 10, 2025 20:08
@github-actions github-actions bot added a: text input Entering text in a text field or keyboard related problems engine flutter/engine related. See also e: labels. e: impeller Impeller rendering backend issues and features requests labels Mar 10, 2025
Copy link
Member

@gaaclarke gaaclarke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking good. This thing has been a bugger trying to track down. I wish we could come up with a better solution for the TextFrame PerFrameData. Keeping that state around is just asking for bugs.

Scalar rounded_scale = TextFrame::RoundScaledFontSize(scale);
Scalar rounded_scale = frame->GetScale();
const Matrix transform =
frame->GetTransform() * Matrix::MakeTranslation(offset);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be frame->offset to match TypographerContextSkia::CollectNewGlyphs?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

!TextPropertiesEquals(properties_, properties)) {
bound_values_.clear();
}
bound_values_.clear();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is this supposed to work? Should bounds_values_ just be added to SetFrameData?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Essentially what bound_values_ does is it lets us do a single lookup for the glyph locations of glyphs (instead of multiple). When we check if the glyph atlas is populated with a glyph, we stuff the resulting data into bound_values so that the text frame can re-use it without doing another slow hash lookup.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about the second question, should we just always be setting it at the same time instead of having a different method then?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't know the bound_values until after we populate the glyph atlas, which happens necessarily after preroll when this method is called.

Scalar rounded_scale = TextFrame::RoundScaledFontSize(scale);
Scalar rounded_scale = frame->GetScale();
const Matrix transform =
frame->GetTransform() * Matrix::MakeTranslation(offset);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we pull this out into a function that could be shared with TypographerContextSkia::CollectNewGlyphs?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@jonahwilliams
Copy link
Contributor Author

The per frame data is pretty important for performance, independent of bugs.

@jonahwilliams jonahwilliams requested a review from gaaclarke March 10, 2025 20:29
Comment on lines 109 to 110
const Matrix transform =
frame->GetTransform() * Matrix::MakeTranslation(frame->GetOffset());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

frame->GetOffsetTransform() right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Woops, fixed

Copy link
Member

@gaaclarke gaaclarke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! thanks

This is going to collide with my refactor of scale. You'll probably get this through first, but heads up.

@jonahwilliams jonahwilliams added the autosubmit Merge PR when tree becomes green via auto submit App label Mar 10, 2025
@auto-submit
Copy link
Contributor

auto-submit bot commented Mar 10, 2025

autosubmit label was removed for flutter/flutter/164931, because - The status or check suite Mac mac_unopt has failed. Please fix the issues identified (or deflake) before re-applying this label.

@auto-submit auto-submit bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Mar 10, 2025
@jonahwilliams
Copy link
Contributor Author

looks like a real test failure, need to investigate

@gaaclarke
Copy link
Member

So this is potentially drawing the text wrong though, right? We have competing ideas about what the subpixel alignment should be. This code considers the one calculated when creating the glyph atlas is the right one, and the one in TextContents is the wrong one. This will be very difficult to debug since there seems to be a race condition related to it and it will result in text being drawn a subpixel off.

I'm not saying we shouldn't have the workaround. I'm just trying to game out trying to track down the root cause.

@jonahwilliams
Copy link
Contributor Author

I don't agree that this is a race condition as this code is all single threaded, its more of a logical invariant error. Currently, we have a need to collect all glyphs (and as such all of their transforms/scales) before we start rasterization. And when we subsequently rasterize, we need the glyph data we ask for to match what is in the atlas.

The atlas is always the correct data, because we can't possibly support anything else - we can't on the fly add to the glyph atlas.

@gaaclarke
Copy link
Member

I don't agree that this is a race condition as this code is all single threaded

I don't understand it either but I don't think there is another valid explanation for the fact that if I start adding in print statements I can make the bug unable to be reproduced.

@jonahwilliams
Copy link
Contributor Author

When you added in print statements, were you running the application + interacting with it? If so, is it possible it changed the timing such that particular frames weren't rendered?

Imagine a scenario where we have some sort of rounding bug and a scale transform is computed as 0.23 in preroll and 0.24 in paint.

@gaaclarke
Copy link
Member

Yea, that's plausible. I can tell you it's not some rounding problem though. When the bug happens the offsets that are used to calculate the subpixel alignment are wildly different. Like 10s of pixels different, not some subpixel difference.

@flutter-dashboard
Copy link

Golden file changes have been found for this pull request. Click here to view and triage (e.g. because this is an intentional change).

If you are still iterating on this change and are not ready to resolve the images on the Flutter Gold dashboard, consider marking this PR as a draft pull request above. You will still be able to view image results on the dashboard, commenting will be silenced, and the check will not try to resolve itself until marked ready for review.

For more guidance, visit Writing a golden file test for package:flutter.

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

Changes reported for pull request #164931 at sha dd83bc7

@flutter-dashboard flutter-dashboard bot added the will affect goldens Changes to golden files label Mar 10, 2025
@gaaclarke
Copy link
Member

I wonder if this is a rotation thing. The matrix used in the TypographerContextSkia::CollectNewGlyphs is just the scale * translation. The matrix used in TextContents::Render is the entity.GetTransform().

@jonahwilliams jonahwilliams added the autosubmit Merge PR when tree becomes green via auto submit App label Mar 11, 2025
@auto-submit auto-submit bot added this pull request to the merge queue Mar 11, 2025
Merged via the queue into flutter:master with commit dbbfa2f Mar 11, 2025
177 checks passed
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 15, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 15, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 16, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 16, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 16, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 17, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 20, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 25, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 25, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 26, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 26, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 26, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 26, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 26, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 26, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 26, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 26, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 27, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 27, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 27, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 27, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 27, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 27, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 27, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 27, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 28, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request May 20, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request May 20, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request May 21, 2025
romanejaquez pushed a commit to romanejaquez/flutter that referenced this pull request Aug 14, 2025
…r text frames. (flutter#164931)

Fixes flutter#164606

When we preroll the text frame, we record the scale/transform used to
compute the size and subpixel position. Use this same size + transform
for the subsequent paint so that it is not possible for it to mismatch.

This is not really a fix for the underlying issue where the subpixel
position may be mismatched.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a: text input Entering text in a text field or keyboard related problems e: impeller Impeller rendering backend issues and features requests engine flutter/engine related. See also e: labels. will affect goldens Changes to golden files

Projects

None yet

2 participants