mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Fix a crash in View Culling coming from unflattening/flattening algorith (#51907)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/51907 changelog: [internal] fixes a crash that is described by the two tests. The two tests cover both changes made to Differentiator.cpp. If you revert either of the change, a test will crash. Reviewed By: christophpurrer Differential Revision: D76231984 fbshipit-source-id: c32ab1851844121095f1dec953befb2e77c83fd4
This commit is contained in:
committed by
Facebook GitHub Bot
parent
38a4b62211
commit
84f9e48331
Vendored
+120
@@ -2327,6 +2327,126 @@ describe('reparenting', () => {
|
||||
'Insert {type: "View", parentNativeID: "grandchild", index: 0, nativeID: "grandgrandchild"}',
|
||||
]);
|
||||
});
|
||||
|
||||
test('parent-child flattening with deep hierarchy', () => {
|
||||
function renderTree(root: Fantom.Root, isFinal: boolean) {
|
||||
Fantom.runTask(() => {
|
||||
root.render(
|
||||
<ScrollView
|
||||
style={{height: 100, width: 100}}
|
||||
contentOffset={{x: 0, y: 52}}>
|
||||
<View
|
||||
style={{
|
||||
marginTop: isFinal ? 92 : 100,
|
||||
opacity: isFinal ? 0 : undefined,
|
||||
}}>
|
||||
<View
|
||||
style={{
|
||||
marginTop: 50,
|
||||
opacity: isFinal ? 0 : undefined,
|
||||
}}>
|
||||
<View collapsable={false} style={{height: 10, width: 10}}>
|
||||
<View
|
||||
collapsable={false}
|
||||
style={{height: 5, width: 5, marginTop: 5}}>
|
||||
<View
|
||||
nativeID="child"
|
||||
style={{height: 2.5, width: 2.5, marginTop: 2.5}}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</ScrollView>,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
const root = Fantom.createRoot({viewportWidth: 100, viewportHeight: 100});
|
||||
|
||||
renderTree(root, false);
|
||||
|
||||
expect(root.takeMountingManagerLogs()).not.toContain(
|
||||
'Create {type: "View", nativeID: "child"}',
|
||||
);
|
||||
|
||||
renderTree(root, true);
|
||||
|
||||
expect(root.takeMountingManagerLogs()).toContain(
|
||||
'Create {type: "View", nativeID: "child"}',
|
||||
);
|
||||
|
||||
const finalRoot = Fantom.createRoot({
|
||||
viewportWidth: 100,
|
||||
viewportHeight: 100,
|
||||
});
|
||||
|
||||
renderTree(finalRoot, true);
|
||||
|
||||
expect(root.getRenderedOutput().toJSON).toEqual(
|
||||
finalRoot.getRenderedOutput().toJSON,
|
||||
);
|
||||
});
|
||||
|
||||
test('parent-child unflattening with deep hierarchy', () => {
|
||||
function renderTree(root: Fantom.Root, isFinal: boolean) {
|
||||
Fantom.runTask(() => {
|
||||
root.render(
|
||||
<ScrollView
|
||||
style={{height: 100, width: 100}}
|
||||
contentOffset={{x: 0, y: 52}}>
|
||||
<View
|
||||
style={{
|
||||
marginTop: isFinal ? 92 : 100,
|
||||
opacity: isFinal ? undefined : 0,
|
||||
}}>
|
||||
<View
|
||||
style={{
|
||||
marginTop: 50,
|
||||
opacity: isFinal ? undefined : 0,
|
||||
}}>
|
||||
<View collapsable={false} style={{height: 10, width: 10}}>
|
||||
<View
|
||||
collapsable={false}
|
||||
style={{height: 5, width: 5, marginTop: 5}}>
|
||||
<View
|
||||
nativeID="child"
|
||||
style={{height: 2.5, width: 2.5, marginTop: 2.5}}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</ScrollView>,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
const root = Fantom.createRoot({viewportWidth: 100, viewportHeight: 100});
|
||||
|
||||
renderTree(root, false);
|
||||
|
||||
expect(root.takeMountingManagerLogs()).not.toContain(
|
||||
'Create {type: "View", nativeID: "child"}',
|
||||
);
|
||||
|
||||
renderTree(root, true);
|
||||
|
||||
expect(root.takeMountingManagerLogs()).toContain(
|
||||
'Create {type: "View", nativeID: "child"}',
|
||||
);
|
||||
|
||||
const finalRoot = Fantom.createRoot({
|
||||
viewportWidth: 100,
|
||||
viewportHeight: 100,
|
||||
});
|
||||
|
||||
renderTree(finalRoot, true);
|
||||
|
||||
expect(root.getRenderedOutput().toJSON).toEqual(
|
||||
finalRoot.getRenderedOutput().toJSON,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('opt out mechanism - Unstable_uncullableView & Unstable_uncullableTrace', () => {
|
||||
|
||||
@@ -630,7 +630,8 @@ static void calculateShadowViewMutationsFlattener(
|
||||
|
||||
// Update children if appropriate.
|
||||
if (!oldTreeNodePair.flattened && !newTreeNodePair.flattened) {
|
||||
if (oldTreeNodePair.shadowNode != newTreeNodePair.shadowNode) {
|
||||
if (oldTreeNodePair.shadowNode != newTreeNodePair.shadowNode ||
|
||||
adjustedOldCullingContext != adjustedNewCullingContext) {
|
||||
ViewNodePairScope innerScope{};
|
||||
auto oldGrandChildPairs =
|
||||
sliceChildShadowNodeViewPairsFromViewNodePair(
|
||||
@@ -678,7 +679,7 @@ static void calculateShadowViewMutationsFlattener(
|
||||
: parentTag),
|
||||
subVisitedNewMap,
|
||||
subVisitedOldMap,
|
||||
cullingContext,
|
||||
cullingContextForUnvisitedOtherNodes,
|
||||
cullingContext.adjustCullingContextIfNeeded(treeChildPair));
|
||||
} else {
|
||||
// Get flattened nodes from either new or old tree
|
||||
|
||||
Reference in New Issue
Block a user