-
Notifications
You must be signed in to change notification settings - Fork 28.9k
Introduce caching mechanism during compile semantics tree monorepo and formatted version #161195
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
Conversation
f3d4d12
to
d8c7576
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some initial comments from my first read-through.
My first impression is that this approach seems more manageable and scalable than the previous one. 👍
if (!_isConfigWritable) { | ||
_config = _config.copy(); | ||
_isConfigWritable = true; | ||
void buildSemantics({required Set<int> usedSemanticsIds, required _SemanticsGeometry geometry}) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the difference between buildSemantics and buildSemanticsSubtree? Some documentation would be helpful.
required this.blocksUserActions, | ||
required this.explicitChildNodes, | ||
required this.tagsForChildren, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For my own understanding: Why are the geometrics not part of the parent data? I thought those are passed down from the parent as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
geometric can only be determined when we know the shape of semantics tree.
the parentData is used for determine the shape of semantics tree, e.g. explicitChildNode, blocksUseractions.
basically we can't determine both geometry, parentData, and semantics tree shape in one pass.
we could merge them and make parentData mutable and do a two pass to update the parentData, but i felt that is harder to manage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 to keeping parentData immutable. Maybe leave this as a comment here that geometrics are not included because we use parentData to determine the shape of the tree and geometrics can only be calculated after the shape of the tree is clear.
@Deprecated( | ||
'This was caches for internal calculation and is no longer needed. ' | ||
'This feature was deprecated after v3.27.0-0.0.pre.', | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, I think we should deprecate/remove the entire elevation/thickness feature from semantics. It's unused and has never been used.
explicitChildNodes: explicitChildNodesForChildren, | ||
tagsForChildren: tagsForChildren, | ||
); | ||
childSemantics.didUpdateParentData(childParentData); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if parent data should just be a getter/setter?
How good is our semantics test coverage? Did you do some manual testing on this (e.g. fire up a larger app and navigate around a bit / interact with it with a11y tools for a bit to see if everything works as expected and behaves?) |
Have you had a chance to look at the Google testing failures? Are we breaking something we shouldn't break? |
4f39357
to
86a2866
Compare
They are expected, either a color change due to more consistent id, and an actual bug fix where the test was expecting incorrect semantics tree |
I did do some manual test, but i think our test framework is quite good since it had caught a lot of corner cases |
3aa8c92
to
3322d3b
Compare
076a4f0
to
1b32144
Compare
31e4f89
to
a9f05bb
Compare
This is ready for review, the google test failure is due to RenderTable doesn't implment the redepthChildren method, so if two table are nested it won't be able to calculate the depth correct which lead to issues when calculate geometry transform in semantics, I will put up another pr to fix it. |
table redepth pr #162282 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@@ -2010,6 +2010,10 @@ class SemanticsNode with DiagnosticableTreeMixin { | |||
/// See also: | |||
/// | |||
/// * [elevation], the actual elevation of this [SemanticsNode]. | |||
@Deprecated( | |||
'This was caches for internal calculation and is no longer needed. ' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'This was caches for internal calculation and is no longer needed. ' | |
'This was a cache for internal calculations and is no longer needed. ' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we also slap a deprecation notice on the (related) elevation
and depth
property?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think depth is used in dirty node compilation, but sgtm to also deprecate elevation related API
@@ -1144,11 +1144,13 @@ class RenderParagraph extends RenderBox | |||
_semanticsInfo = text.getSemanticsInformation(); | |||
bool needsAssembleSemanticsNode = false; | |||
bool needsChildConfigurationsDelegate = false; | |||
bool hasTextSpan = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This appears to be unused?
if (!kReleaseMode) { | ||
FlutterTimeline.startSync('Semantics.updateChildren'); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just wondering: Is it useful that each node gets its own timeline event? They are just gonna be back-to-back in the timeline without a way to identify which node is getting processed. Should we instead just do one timeline event for the entire for loop?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah that sounds good
}()); | ||
|
||
for (final RenderObject node in nodesToProcess) { | ||
if (!kReleaseMode) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same question here and below.
} | ||
} | ||
|
||
for (final RenderObject node in nodesToProcess.reversed) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do the three for loops in this function correspond to the phases documented on _RenderObjectSemantics? If so, maybe leave a comment at the top of the function that links to that explanation there.
/// Walks the [_childrenAndElevationAdjustments] and produce semantics node for | ||
/// each [_RenderObjectSemantics] plus the sibling nodes. | ||
/// | ||
/// Since phase 2, 3, 4 each depends on previous step to finished updating the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// Since phase 2, 3, 4 each depends on previous step to finished updating the | |
/// Phase 2, 3, 4 each depends on previous step to finished updating |
/// Phase 1 and 2 are done in [updateChildren], Phase 3 is done in | ||
/// [ensureGeometry], and phase 4 is done in [ensureSemanticsNode]. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you move this sentence all the way to the beginning just after "The _RenderObjectSemantics tree is compiled in four phases."? This is the context I was missing and asking for in a previous comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Overall this is a great doc comment, though! Thank you for writing this up and providing context for future readers!)
// TODO(chunhtai): Figure out what to do when incomplete fragments are asked | ||
// to form a semantics node. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is that supposed to happen in a real app? Shouldn't it just throw/assert if that's illegal?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right now it is impossible that this can happen because i force them to merge into a _RenderObjectSemantics (by making the assumption in _collectChildMergeUpAndSiblingGroup). but that is not an ideal solution. The ideal solution is that they should form a semantics node if they are asked. but then we need a way for render object to assign geometry to those semantics node which is not possible in the current api
/// rendering subtree and forms a [_RenderObjectSemantics] tree where children | ||
/// are stored in [_childrenAndElevationAdjustments]. | ||
/// | ||
/// This method does the following: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe explicitly state again that it implements phase x of the four phases documented on [_RenderObjectSemantics]. (and also do this for the other methods that implement a phase)
/// This method will in turn call the [_buildSemanticsSubtree]. | ||
/// | ||
/// This method will short-circuit itself if the [cachedSemanticsNode] is |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// This method will in turn call the [_buildSemanticsSubtree]. | |
/// | |
/// This method will short-circuit itself if the [cachedSemanticsNode] is | |
/// This method will in turn call [_buildSemanticsSubtree]. | |
/// | |
/// This method will short-circuit itself if the [cachedSemanticsNode] |
…orepo and formatted version (flutter/flutter#161195)
…orepo and formatted version (flutter/flutter#161195)
…orepo and formatted version (flutter/flutter#161195)
…orepo and formatted version (flutter/flutter#161195)
…orepo and formatted version (flutter/flutter#161195)
…orepo and formatted version (flutter/flutter#161195)
…orepo and formatted version (flutter/flutter#161195)
…orepo and formatted version (flutter/flutter#161195)
…orepo and formatted version (flutter/flutter#161195)
…orepo and formatted version (flutter/flutter#161195)
…orepo and formatted version (flutter/flutter#161195)
…orepo and formatted version (flutter/flutter#161195)
…orepo and formatted version (flutter/flutter#161195)
…orepo and formatted version (flutter/flutter#161195)
…orepo and formatted version (flutter/flutter#161195)
…orepo and formatted version (flutter/flutter#161195)
…orepo and formatted version (flutter/flutter#161195)
old pr: #150394
Pre-launch Checklist
///
).If you need help, consider asking for advice on the #hackers-new channel on Discord.