From 95e7a74a50764920da95a531d3bf1641f7acea2f Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Wed, 2 Aug 2023 05:56:31 -0700 Subject: [PATCH] Do not swapLeftAnd right if not in RTL (#38748) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/38748 changelog: [internal] Android was setting flag `swapLeftAndRightInRTL` to true regardless if the context was RTL or LTR. This causes unnecessary tree traversal + invalidation of all yoga nodes. This is a completely unnecessary work when layout direction is left to right. To fix this, I made sure Android not longer sets `swapLeftAndRightInRTL` to true and in Fabric we only check the flag for RTL context. Reviewed By: NickGerleman Differential Revision: D47913605 fbshipit-source-id: 1d938b0dc9ba16a73b076f626055055162e3495f --- .../com/facebook/react/config/ReactFeatureFlags.java | 3 +++ .../src/main/jni/react/fabric/Binding.cpp | 2 ++ .../components/view/YogaLayoutableShadowNode.cpp | 12 ++++++++++-- .../ReactCommon/react/utils/CoreFeatures.cpp | 1 + .../ReactCommon/react/utils/CoreFeatures.h | 3 +++ 5 files changed, 19 insertions(+), 2 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java index 48771fd5cb6..82b05cec891 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java @@ -154,4 +154,7 @@ public class ReactFeatureFlags { /** Use native view configs in bridgeless mode. */ public static boolean useNativeViewConfigsInBridgelessMode = false; + + /** Only swap left and right on Android in RTL scripts. */ + public static boolean doNotSwapLeftAndRightOnAndroidInLTR = false; } diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.cpp index c23648f0ea0..65d6db392f8 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.cpp @@ -431,6 +431,8 @@ void Binding::installFabricUIManager( getFeatureFlagValue("enableCppPropsIteratorSetter"); CoreFeatures::useNativeState = getFeatureFlagValue("useNativeState"); CoreFeatures::enableMapBuffer = getFeatureFlagValue("useMapBufferProps"); + CoreFeatures::doNotSwapLeftAndRightOnAndroidInLTR = + getFeatureFlagValue("doNotSwapLeftAndRightOnAndroidInLTR"); // RemoveDelete mega-op ShadowViewMutation::PlatformSupportsRemoveDeleteTreeInstruction = diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp index fb4e57deaff..08f15ec203c 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -550,8 +551,15 @@ void YogaLayoutableShadowNode::layoutTree( threadLocalLayoutContext = layoutContext; - if (layoutContext.swapLeftAndRightInRTL) { - swapLeftAndRightInTree(*this); + if (CoreFeatures::doNotSwapLeftAndRightOnAndroidInLTR) { + if (layoutConstraints.layoutDirection == LayoutDirection::RightToLeft && + layoutContext.swapLeftAndRightInRTL) { + swapLeftAndRightInTree(*this); + } + } else { + if (layoutContext.swapLeftAndRightInRTL) { + swapLeftAndRightInTree(*this); + } } { diff --git a/packages/react-native/ReactCommon/react/utils/CoreFeatures.cpp b/packages/react-native/ReactCommon/react/utils/CoreFeatures.cpp index b23cdfbb125..2c3ce14e5ba 100644 --- a/packages/react-native/ReactCommon/react/utils/CoreFeatures.cpp +++ b/packages/react-native/ReactCommon/react/utils/CoreFeatures.cpp @@ -17,5 +17,6 @@ bool CoreFeatures::cacheLastTextMeasurement = false; bool CoreFeatures::cancelImageDownloadsOnRecycle = false; bool CoreFeatures::enableGranularScrollViewStateUpdatesIOS = false; bool CoreFeatures::enableMountHooks = false; +bool CoreFeatures::doNotSwapLeftAndRightOnAndroidInLTR = false; } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/utils/CoreFeatures.h b/packages/react-native/ReactCommon/react/utils/CoreFeatures.h index 84612fcfc97..8070cb4006f 100644 --- a/packages/react-native/ReactCommon/react/utils/CoreFeatures.h +++ b/packages/react-native/ReactCommon/react/utils/CoreFeatures.h @@ -50,6 +50,9 @@ class CoreFeatures { // Report mount operations from the host platform to notify mount hooks. static bool enableMountHooks; + + // Only swap left and right on Android in RTL scripts. + static bool doNotSwapLeftAndRightOnAndroidInLTR; }; } // namespace facebook::react