diff --git a/packages/react-native/ReactAndroid/gradle.properties b/packages/react-native/ReactAndroid/gradle.properties index a672aedd0839..126f0d0d231c 100644 --- a/packages/react-native/ReactAndroid/gradle.properties +++ b/packages/react-native/ReactAndroid/gradle.properties @@ -1,4 +1,4 @@ -VERSION_NAME=0.86.0-discord-31 +VERSION_NAME=0.86.0-kosmydel-yoga-setsize react.internal.publishingGroup=com.facebook.react react.internal.hermesPublishingGroup=com.facebook.hermes diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt index 4cdc98f29d6d..007ef02d27c0 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<652b195c21ffe47263fcfbe77a898aa1>> + * @generated SignedSource<<8004c71ad564ff4bfb2766ad3665c2e5>> */ /** @@ -90,6 +90,12 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun disableViewPreallocationAndroid(): Boolean = accessor.disableViewPreallocationAndroid() + /** + * Skip dirtying Yoga nodes in setSize/setPositionType when the value is unchanged (react-native#59101). + */ + @JvmStatic + public fun discordSkipUnchangedYogaDirty(): Boolean = accessor.discordSkipUnchangedYogaDirty() + /** * Select UIManager optimizations: 0 = none, 1 = preserve lazy properties, 2 = load view manager constants on demand. */ diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt index d86c4d22365e..54bed019b903 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<10c483c7007076bb3c1cee1197c20c89>> + * @generated SignedSource<<2f795a10a9de5d60ddf07671aa7b7c9d>> */ /** @@ -30,6 +30,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces private var disableSubviewClippingAndroidCache: Boolean? = null private var disableTextLayoutManagerCacheAndroidCache: Boolean? = null private var disableViewPreallocationAndroidCache: Boolean? = null + private var discordSkipUnchangedYogaDirtyCache: Boolean? = null private var discordUiManagerOptimizationCache: Double? = null private var enableAccessibilityOrderCache: Boolean? = null private var enableAccumulatedUpdatesInRawPropsAndroidCache: Boolean? = null @@ -210,6 +211,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun discordSkipUnchangedYogaDirty(): Boolean { + var cached = discordSkipUnchangedYogaDirtyCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.discordSkipUnchangedYogaDirty() + discordSkipUnchangedYogaDirtyCache = cached + } + return cached + } + override fun discordUiManagerOptimization(): Double { var cached = discordUiManagerOptimizationCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt index 40bd79a50391..c95500f21300 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<1492421cd4b9bca791ee9ad5f87507a3>> + * @generated SignedSource<<6f18835027df02bd21bdd2fb295d6c6d>> */ /** @@ -48,6 +48,8 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun disableViewPreallocationAndroid(): Boolean + @DoNotStrip @JvmStatic public external fun discordSkipUnchangedYogaDirty(): Boolean + @DoNotStrip @JvmStatic public external fun discordUiManagerOptimization(): Double @DoNotStrip @JvmStatic public external fun enableAccessibilityOrder(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt index dc51cbe04a22..c61dfb46c650 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<462ac270e53d73922c29341d2bf557cc>> + * @generated SignedSource<<3237443af97e85729b05a4ce9774ec3a>> */ /** @@ -43,6 +43,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun disableViewPreallocationAndroid(): Boolean = false + override fun discordSkipUnchangedYogaDirty(): Boolean = false + override fun discordUiManagerOptimization(): Double = 0.0 override fun enableAccessibilityOrder(): Boolean = false diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt index 2e25e6b8118f..451ec646cb34 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<5883ee9dd871db6518eeabe40983feab>> */ /** @@ -34,6 +34,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc private var disableSubviewClippingAndroidCache: Boolean? = null private var disableTextLayoutManagerCacheAndroidCache: Boolean? = null private var disableViewPreallocationAndroidCache: Boolean? = null + private var discordSkipUnchangedYogaDirtyCache: Boolean? = null private var discordUiManagerOptimizationCache: Double? = null private var enableAccessibilityOrderCache: Boolean? = null private var enableAccumulatedUpdatesInRawPropsAndroidCache: Boolean? = null @@ -224,6 +225,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc return cached } + override fun discordSkipUnchangedYogaDirty(): Boolean { + var cached = discordSkipUnchangedYogaDirtyCache + if (cached == null) { + cached = currentProvider.discordSkipUnchangedYogaDirty() + accessedFeatureFlags.add("discordSkipUnchangedYogaDirty") + discordSkipUnchangedYogaDirtyCache = cached + } + return cached + } + override fun discordUiManagerOptimization(): Double { var cached = discordUiManagerOptimizationCache if (cached == null) { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt index c988df91b592..85b983bf1402 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -43,6 +43,8 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun disableViewPreallocationAndroid(): Boolean + @DoNotStrip public fun discordSkipUnchangedYogaDirty(): Boolean + @DoNotStrip public fun discordUiManagerOptimization(): Double @DoNotStrip public fun enableAccessibilityOrder(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp index 26ac3a63c5dd..dc08ed29f1da 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<79f454a4ac0fe044f40517855ba49deb>> */ /** @@ -99,6 +99,12 @@ class ReactNativeFeatureFlagsJavaProvider return method(javaProvider_); } + bool discordSkipUnchangedYogaDirty() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("discordSkipUnchangedYogaDirty"); + return method(javaProvider_); + } + double discordUiManagerOptimization() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("discordUiManagerOptimization"); @@ -687,6 +693,11 @@ bool JReactNativeFeatureFlagsCxxInterop::disableViewPreallocationAndroid( return ReactNativeFeatureFlags::disableViewPreallocationAndroid(); } +bool JReactNativeFeatureFlagsCxxInterop::discordSkipUnchangedYogaDirty( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::discordSkipUnchangedYogaDirty(); +} + double JReactNativeFeatureFlagsCxxInterop::discordUiManagerOptimization( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::discordUiManagerOptimization(); @@ -1193,6 +1204,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "disableViewPreallocationAndroid", JReactNativeFeatureFlagsCxxInterop::disableViewPreallocationAndroid), + makeNativeMethod( + "discordSkipUnchangedYogaDirty", + JReactNativeFeatureFlagsCxxInterop::discordSkipUnchangedYogaDirty), makeNativeMethod( "discordUiManagerOptimization", JReactNativeFeatureFlagsCxxInterop::discordUiManagerOptimization), diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h index 16bd68e9c28a..c761e072da10 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<584ebd805c4a72383eb1e07ef28d490b>> + * @generated SignedSource<<49862609637dde695866d149949bcc3a>> */ /** @@ -60,6 +60,9 @@ class JReactNativeFeatureFlagsCxxInterop static bool disableViewPreallocationAndroid( facebook::jni::alias_ref); + static bool discordSkipUnchangedYogaDirty( + facebook::jni::alias_ref); + static double discordUiManagerOptimization( facebook::jni::alias_ref); diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp index 16a8faf3033e..96d116eff68c 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<8a37279e2d9a281cdeb43356993ec0a9>> + * @generated SignedSource<> */ /** @@ -66,6 +66,10 @@ bool ReactNativeFeatureFlags::disableViewPreallocationAndroid() { return getAccessor().disableViewPreallocationAndroid(); } +bool ReactNativeFeatureFlags::discordSkipUnchangedYogaDirty() { + return getAccessor().discordSkipUnchangedYogaDirty(); +} + double ReactNativeFeatureFlags::discordUiManagerOptimization() { return getAccessor().discordUiManagerOptimization(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index 3c4c8d10d271..96b8fb56414d 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<01cfdab8946e251169d6a69ed712d57e>> + * @generated SignedSource<<096729bde9a4580be6756ff8f7bb5045>> */ /** @@ -89,6 +89,11 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool disableViewPreallocationAndroid(); + /** + * Skip dirtying Yoga nodes in setSize/setPositionType when the value is unchanged (react-native#59101). + */ + RN_EXPORT static bool discordSkipUnchangedYogaDirty(); + /** * Select UIManager optimizations: 0 = none, 1 = preserve lazy properties, 2 = load view manager constants on demand. */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index 231a308c61e1..1881d30acd9b 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<3af59bc31ba9f14a2b9d5e8ef2422c00>> */ /** @@ -209,6 +209,24 @@ bool ReactNativeFeatureFlagsAccessor::disableViewPreallocationAndroid() { return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::discordSkipUnchangedYogaDirty() { + auto flagValue = discordSkipUnchangedYogaDirty_.load(); + + if (!flagValue.has_value()) { + // This block is not exclusive but it is not necessary. + // If multiple threads try to initialize the feature flag, we would only + // be accessing the provider multiple times but the end state of this + // instance and the returned flag value would be the same. + + markFlagAsAccessed(10, "discordSkipUnchangedYogaDirty"); + + flagValue = currentProvider_->discordSkipUnchangedYogaDirty(); + discordSkipUnchangedYogaDirty_ = flagValue; + } + + return flagValue.value(); +} + double ReactNativeFeatureFlagsAccessor::discordUiManagerOptimization() { auto flagValue = discordUiManagerOptimization_.load(); @@ -218,7 +236,7 @@ double ReactNativeFeatureFlagsAccessor::discordUiManagerOptimization() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(10, "discordUiManagerOptimization"); + markFlagAsAccessed(11, "discordUiManagerOptimization"); flagValue = currentProvider_->discordUiManagerOptimization(); discordUiManagerOptimization_ = flagValue; @@ -236,7 +254,7 @@ bool ReactNativeFeatureFlagsAccessor::enableAccessibilityOrder() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(11, "enableAccessibilityOrder"); + markFlagAsAccessed(12, "enableAccessibilityOrder"); flagValue = currentProvider_->enableAccessibilityOrder(); enableAccessibilityOrder_ = flagValue; @@ -254,7 +272,7 @@ bool ReactNativeFeatureFlagsAccessor::enableAccumulatedUpdatesInRawPropsAndroid( // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(12, "enableAccumulatedUpdatesInRawPropsAndroid"); + markFlagAsAccessed(13, "enableAccumulatedUpdatesInRawPropsAndroid"); flagValue = currentProvider_->enableAccumulatedUpdatesInRawPropsAndroid(); enableAccumulatedUpdatesInRawPropsAndroid_ = flagValue; @@ -272,7 +290,7 @@ bool ReactNativeFeatureFlagsAccessor::enableAndroidTextMeasurementOptimizations( // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(13, "enableAndroidTextMeasurementOptimizations"); + markFlagAsAccessed(14, "enableAndroidTextMeasurementOptimizations"); flagValue = currentProvider_->enableAndroidTextMeasurementOptimizations(); enableAndroidTextMeasurementOptimizations_ = flagValue; @@ -290,7 +308,7 @@ bool ReactNativeFeatureFlagsAccessor::enableBridgelessArchitecture() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(14, "enableBridgelessArchitecture"); + markFlagAsAccessed(15, "enableBridgelessArchitecture"); flagValue = currentProvider_->enableBridgelessArchitecture(); enableBridgelessArchitecture_ = flagValue; @@ -308,7 +326,7 @@ bool ReactNativeFeatureFlagsAccessor::enableCppPropsIteratorSetter() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(15, "enableCppPropsIteratorSetter"); + markFlagAsAccessed(16, "enableCppPropsIteratorSetter"); flagValue = currentProvider_->enableCppPropsIteratorSetter(); enableCppPropsIteratorSetter_ = flagValue; @@ -326,7 +344,7 @@ bool ReactNativeFeatureFlagsAccessor::enableCustomFocusSearchOnClippedElementsAn // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(16, "enableCustomFocusSearchOnClippedElementsAndroid"); + markFlagAsAccessed(17, "enableCustomFocusSearchOnClippedElementsAndroid"); flagValue = currentProvider_->enableCustomFocusSearchOnClippedElementsAndroid(); enableCustomFocusSearchOnClippedElementsAndroid_ = flagValue; @@ -344,7 +362,7 @@ bool ReactNativeFeatureFlagsAccessor::enableDestroyShadowTreeRevisionAsync() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(17, "enableDestroyShadowTreeRevisionAsync"); + markFlagAsAccessed(18, "enableDestroyShadowTreeRevisionAsync"); flagValue = currentProvider_->enableDestroyShadowTreeRevisionAsync(); enableDestroyShadowTreeRevisionAsync_ = flagValue; @@ -362,7 +380,7 @@ bool ReactNativeFeatureFlagsAccessor::enableDifferentiatorMutationVectorPrealloc // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(18, "enableDifferentiatorMutationVectorPreallocation"); + markFlagAsAccessed(19, "enableDifferentiatorMutationVectorPreallocation"); flagValue = currentProvider_->enableDifferentiatorMutationVectorPreallocation(); enableDifferentiatorMutationVectorPreallocation_ = flagValue; @@ -380,7 +398,7 @@ bool ReactNativeFeatureFlagsAccessor::enableDoubleMeasurementFixAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(19, "enableDoubleMeasurementFixAndroid"); + markFlagAsAccessed(20, "enableDoubleMeasurementFixAndroid"); flagValue = currentProvider_->enableDoubleMeasurementFixAndroid(); enableDoubleMeasurementFixAndroid_ = flagValue; @@ -398,7 +416,7 @@ bool ReactNativeFeatureFlagsAccessor::enableEagerMainQueueModulesOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(20, "enableEagerMainQueueModulesOnIOS"); + markFlagAsAccessed(21, "enableEagerMainQueueModulesOnIOS"); flagValue = currentProvider_->enableEagerMainQueueModulesOnIOS(); enableEagerMainQueueModulesOnIOS_ = flagValue; @@ -416,7 +434,7 @@ bool ReactNativeFeatureFlagsAccessor::enableEagerRootViewAttachment() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(21, "enableEagerRootViewAttachment"); + markFlagAsAccessed(22, "enableEagerRootViewAttachment"); flagValue = currentProvider_->enableEagerRootViewAttachment(); enableEagerRootViewAttachment_ = flagValue; @@ -434,7 +452,7 @@ bool ReactNativeFeatureFlagsAccessor::enableExclusivePropsUpdateAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(22, "enableExclusivePropsUpdateAndroid"); + markFlagAsAccessed(23, "enableExclusivePropsUpdateAndroid"); flagValue = currentProvider_->enableExclusivePropsUpdateAndroid(); enableExclusivePropsUpdateAndroid_ = flagValue; @@ -452,7 +470,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricCommitBranching() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(23, "enableFabricCommitBranching"); + markFlagAsAccessed(24, "enableFabricCommitBranching"); flagValue = currentProvider_->enableFabricCommitBranching(); enableFabricCommitBranching_ = flagValue; @@ -470,7 +488,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricLogs() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(24, "enableFabricLogs"); + markFlagAsAccessed(25, "enableFabricLogs"); flagValue = currentProvider_->enableFabricLogs(); enableFabricLogs_ = flagValue; @@ -488,7 +506,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricRenderer() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(25, "enableFabricRenderer"); + markFlagAsAccessed(26, "enableFabricRenderer"); flagValue = currentProvider_->enableFabricRenderer(); enableFabricRenderer_ = flagValue; @@ -506,7 +524,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFixForParentTagDuringReparenting() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(26, "enableFixForParentTagDuringReparenting"); + markFlagAsAccessed(27, "enableFixForParentTagDuringReparenting"); flagValue = currentProvider_->enableFixForParentTagDuringReparenting(); enableFixForParentTagDuringReparenting_ = flagValue; @@ -524,7 +542,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFontScaleChangesUpdatingLayout() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(27, "enableFontScaleChangesUpdatingLayout"); + markFlagAsAccessed(28, "enableFontScaleChangesUpdatingLayout"); flagValue = currentProvider_->enableFontScaleChangesUpdatingLayout(); enableFontScaleChangesUpdatingLayout_ = flagValue; @@ -542,7 +560,7 @@ bool ReactNativeFeatureFlagsAccessor::enableIOSExperimentalAutoFocusImplementati // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(28, "enableIOSExperimentalAutoFocusImplementation"); + markFlagAsAccessed(29, "enableIOSExperimentalAutoFocusImplementation"); flagValue = currentProvider_->enableIOSExperimentalAutoFocusImplementation(); enableIOSExperimentalAutoFocusImplementation_ = flagValue; @@ -560,7 +578,7 @@ bool ReactNativeFeatureFlagsAccessor::enableIOSTextBaselineOffsetPerLine() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(29, "enableIOSTextBaselineOffsetPerLine"); + markFlagAsAccessed(30, "enableIOSTextBaselineOffsetPerLine"); flagValue = currentProvider_->enableIOSTextBaselineOffsetPerLine(); enableIOSTextBaselineOffsetPerLine_ = flagValue; @@ -578,7 +596,7 @@ bool ReactNativeFeatureFlagsAccessor::enableIOSViewClipToPaddingBox() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(30, "enableIOSViewClipToPaddingBox"); + markFlagAsAccessed(31, "enableIOSViewClipToPaddingBox"); flagValue = currentProvider_->enableIOSViewClipToPaddingBox(); enableIOSViewClipToPaddingBox_ = flagValue; @@ -596,7 +614,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImagePrefetchingAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(31, "enableImagePrefetchingAndroid"); + markFlagAsAccessed(32, "enableImagePrefetchingAndroid"); flagValue = currentProvider_->enableImagePrefetchingAndroid(); enableImagePrefetchingAndroid_ = flagValue; @@ -614,7 +632,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImmediateUpdateModeForContentOffsetC // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(32, "enableImmediateUpdateModeForContentOffsetChanges"); + markFlagAsAccessed(33, "enableImmediateUpdateModeForContentOffsetChanges"); flagValue = currentProvider_->enableImmediateUpdateModeForContentOffsetChanges(); enableImmediateUpdateModeForContentOffsetChanges_ = flagValue; @@ -632,7 +650,7 @@ bool ReactNativeFeatureFlagsAccessor::enableImperativeFocus() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(33, "enableImperativeFocus"); + markFlagAsAccessed(34, "enableImperativeFocus"); flagValue = currentProvider_->enableImperativeFocus(); enableImperativeFocus_ = flagValue; @@ -650,7 +668,7 @@ bool ReactNativeFeatureFlagsAccessor::enableInteropViewManagerClassLookUpOptimiz // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(34, "enableInteropViewManagerClassLookUpOptimizationIOS"); + markFlagAsAccessed(35, "enableInteropViewManagerClassLookUpOptimizationIOS"); flagValue = currentProvider_->enableInteropViewManagerClassLookUpOptimizationIOS(); enableInteropViewManagerClassLookUpOptimizationIOS_ = flagValue; @@ -668,7 +686,7 @@ bool ReactNativeFeatureFlagsAccessor::enableIntersectionObserverByDefault() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(35, "enableIntersectionObserverByDefault"); + markFlagAsAccessed(36, "enableIntersectionObserverByDefault"); flagValue = currentProvider_->enableIntersectionObserverByDefault(); enableIntersectionObserverByDefault_ = flagValue; @@ -686,7 +704,7 @@ bool ReactNativeFeatureFlagsAccessor::enableKeyEvents() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(36, "enableKeyEvents"); + markFlagAsAccessed(37, "enableKeyEvents"); flagValue = currentProvider_->enableKeyEvents(); enableKeyEvents_ = flagValue; @@ -704,7 +722,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(37, "enableLayoutAnimationsOnAndroid"); + markFlagAsAccessed(38, "enableLayoutAnimationsOnAndroid"); flagValue = currentProvider_->enableLayoutAnimationsOnAndroid(); enableLayoutAnimationsOnAndroid_ = flagValue; @@ -722,7 +740,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(38, "enableLayoutAnimationsOnIOS"); + markFlagAsAccessed(39, "enableLayoutAnimationsOnIOS"); flagValue = currentProvider_->enableLayoutAnimationsOnIOS(); enableLayoutAnimationsOnIOS_ = flagValue; @@ -740,7 +758,7 @@ bool ReactNativeFeatureFlagsAccessor::enableMainQueueCoordinatorOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(39, "enableMainQueueCoordinatorOnIOS"); + markFlagAsAccessed(40, "enableMainQueueCoordinatorOnIOS"); flagValue = currentProvider_->enableMainQueueCoordinatorOnIOS(); enableMainQueueCoordinatorOnIOS_ = flagValue; @@ -758,7 +776,7 @@ bool ReactNativeFeatureFlagsAccessor::enableModuleArgumentNSNullConversionIOS() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(40, "enableModuleArgumentNSNullConversionIOS"); + markFlagAsAccessed(41, "enableModuleArgumentNSNullConversionIOS"); flagValue = currentProvider_->enableModuleArgumentNSNullConversionIOS(); enableModuleArgumentNSNullConversionIOS_ = flagValue; @@ -776,7 +794,7 @@ bool ReactNativeFeatureFlagsAccessor::enableMutationObserverByDefault() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(41, "enableMutationObserverByDefault"); + markFlagAsAccessed(42, "enableMutationObserverByDefault"); flagValue = currentProvider_->enableMutationObserverByDefault(); enableMutationObserverByDefault_ = flagValue; @@ -794,7 +812,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNativeCSSParsing() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(42, "enableNativeCSSParsing"); + markFlagAsAccessed(43, "enableNativeCSSParsing"); flagValue = currentProvider_->enableNativeCSSParsing(); enableNativeCSSParsing_ = flagValue; @@ -812,7 +830,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNativeViewPropTransformations() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(43, "enableNativeViewPropTransformations"); + markFlagAsAccessed(44, "enableNativeViewPropTransformations"); flagValue = currentProvider_->enableNativeViewPropTransformations(); enableNativeViewPropTransformations_ = flagValue; @@ -830,7 +848,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNetworkEventReporting() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(44, "enableNetworkEventReporting"); + markFlagAsAccessed(45, "enableNetworkEventReporting"); flagValue = currentProvider_->enableNetworkEventReporting(); enableNetworkEventReporting_ = flagValue; @@ -848,7 +866,7 @@ bool ReactNativeFeatureFlagsAccessor::enablePreparedTextLayout() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(45, "enablePreparedTextLayout"); + markFlagAsAccessed(46, "enablePreparedTextLayout"); flagValue = currentProvider_->enablePreparedTextLayout(); enablePreparedTextLayout_ = flagValue; @@ -866,7 +884,7 @@ bool ReactNativeFeatureFlagsAccessor::enablePropsUpdateReconciliationAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(46, "enablePropsUpdateReconciliationAndroid"); + markFlagAsAccessed(47, "enablePropsUpdateReconciliationAndroid"); flagValue = currentProvider_->enablePropsUpdateReconciliationAndroid(); enablePropsUpdateReconciliationAndroid_ = flagValue; @@ -884,7 +902,7 @@ bool ReactNativeFeatureFlagsAccessor::enableSchedulerDelegateInvalidation() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(47, "enableSchedulerDelegateInvalidation"); + markFlagAsAccessed(48, "enableSchedulerDelegateInvalidation"); flagValue = currentProvider_->enableSchedulerDelegateInvalidation(); enableSchedulerDelegateInvalidation_ = flagValue; @@ -902,7 +920,7 @@ bool ReactNativeFeatureFlagsAccessor::enableSwiftUIBasedFilters() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(48, "enableSwiftUIBasedFilters"); + markFlagAsAccessed(49, "enableSwiftUIBasedFilters"); flagValue = currentProvider_->enableSwiftUIBasedFilters(); enableSwiftUIBasedFilters_ = flagValue; @@ -920,7 +938,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewCulling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(49, "enableViewCulling"); + markFlagAsAccessed(50, "enableViewCulling"); flagValue = currentProvider_->enableViewCulling(); enableViewCulling_ = flagValue; @@ -938,7 +956,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecycling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(50, "enableViewRecycling"); + markFlagAsAccessed(51, "enableViewRecycling"); flagValue = currentProvider_->enableViewRecycling(); enableViewRecycling_ = flagValue; @@ -956,7 +974,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForImage() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(51, "enableViewRecyclingForImage"); + markFlagAsAccessed(52, "enableViewRecyclingForImage"); flagValue = currentProvider_->enableViewRecyclingForImage(); enableViewRecyclingForImage_ = flagValue; @@ -974,7 +992,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForScrollView() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(52, "enableViewRecyclingForScrollView"); + markFlagAsAccessed(53, "enableViewRecyclingForScrollView"); flagValue = currentProvider_->enableViewRecyclingForScrollView(); enableViewRecyclingForScrollView_ = flagValue; @@ -992,7 +1010,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForText() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(53, "enableViewRecyclingForText"); + markFlagAsAccessed(54, "enableViewRecyclingForText"); flagValue = currentProvider_->enableViewRecyclingForText(); enableViewRecyclingForText_ = flagValue; @@ -1010,7 +1028,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForView() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(54, "enableViewRecyclingForView"); + markFlagAsAccessed(55, "enableViewRecyclingForView"); flagValue = currentProvider_->enableViewRecyclingForView(); enableViewRecyclingForView_ = flagValue; @@ -1028,7 +1046,7 @@ bool ReactNativeFeatureFlagsAccessor::enableVirtualViewContainerStateExperimenta // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(55, "enableVirtualViewContainerStateExperimental"); + markFlagAsAccessed(56, "enableVirtualViewContainerStateExperimental"); flagValue = currentProvider_->enableVirtualViewContainerStateExperimental(); enableVirtualViewContainerStateExperimental_ = flagValue; @@ -1046,7 +1064,7 @@ bool ReactNativeFeatureFlagsAccessor::enableVirtualViewDebugFeatures() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(56, "enableVirtualViewDebugFeatures"); + markFlagAsAccessed(57, "enableVirtualViewDebugFeatures"); flagValue = currentProvider_->enableVirtualViewDebugFeatures(); enableVirtualViewDebugFeatures_ = flagValue; @@ -1064,7 +1082,7 @@ bool ReactNativeFeatureFlagsAccessor::fixDifferentiatorParentTagForUnflattenCase // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(57, "fixDifferentiatorParentTagForUnflattenCase"); + markFlagAsAccessed(58, "fixDifferentiatorParentTagForUnflattenCase"); flagValue = currentProvider_->fixDifferentiatorParentTagForUnflattenCase(); fixDifferentiatorParentTagForUnflattenCase_ = flagValue; @@ -1082,7 +1100,7 @@ bool ReactNativeFeatureFlagsAccessor::fixFindShadowNodeByTagRaceCondition() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(58, "fixFindShadowNodeByTagRaceCondition"); + markFlagAsAccessed(59, "fixFindShadowNodeByTagRaceCondition"); flagValue = currentProvider_->fixFindShadowNodeByTagRaceCondition(); fixFindShadowNodeByTagRaceCondition_ = flagValue; @@ -1100,7 +1118,7 @@ bool ReactNativeFeatureFlagsAccessor::fixMappingOfEventPrioritiesBetweenFabricAn // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(59, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); + markFlagAsAccessed(60, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); flagValue = currentProvider_->fixMappingOfEventPrioritiesBetweenFabricAndReact(); fixMappingOfEventPrioritiesBetweenFabricAndReact_ = flagValue; @@ -1118,7 +1136,7 @@ bool ReactNativeFeatureFlagsAccessor::fixYogaFlexBasisFitContentInMainAxis() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(60, "fixYogaFlexBasisFitContentInMainAxis"); + markFlagAsAccessed(61, "fixYogaFlexBasisFitContentInMainAxis"); flagValue = currentProvider_->fixYogaFlexBasisFitContentInMainAxis(); fixYogaFlexBasisFitContentInMainAxis_ = flagValue; @@ -1136,7 +1154,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxAssertSingleHostState() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(61, "fuseboxAssertSingleHostState"); + markFlagAsAccessed(62, "fuseboxAssertSingleHostState"); flagValue = currentProvider_->fuseboxAssertSingleHostState(); fuseboxAssertSingleHostState_ = flagValue; @@ -1154,7 +1172,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxEnabledRelease() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(62, "fuseboxEnabledRelease"); + markFlagAsAccessed(63, "fuseboxEnabledRelease"); flagValue = currentProvider_->fuseboxEnabledRelease(); fuseboxEnabledRelease_ = flagValue; @@ -1172,7 +1190,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxFrameRecordingEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(63, "fuseboxFrameRecordingEnabled"); + markFlagAsAccessed(64, "fuseboxFrameRecordingEnabled"); flagValue = currentProvider_->fuseboxFrameRecordingEnabled(); fuseboxFrameRecordingEnabled_ = flagValue; @@ -1190,7 +1208,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxNetworkInspectionEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(64, "fuseboxNetworkInspectionEnabled"); + markFlagAsAccessed(65, "fuseboxNetworkInspectionEnabled"); flagValue = currentProvider_->fuseboxNetworkInspectionEnabled(); fuseboxNetworkInspectionEnabled_ = flagValue; @@ -1208,7 +1226,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxScreenshotCaptureEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(65, "fuseboxScreenshotCaptureEnabled"); + markFlagAsAccessed(66, "fuseboxScreenshotCaptureEnabled"); flagValue = currentProvider_->fuseboxScreenshotCaptureEnabled(); fuseboxScreenshotCaptureEnabled_ = flagValue; @@ -1226,7 +1244,7 @@ bool ReactNativeFeatureFlagsAccessor::hideOffscreenVirtualViewsOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(66, "hideOffscreenVirtualViewsOnIOS"); + markFlagAsAccessed(67, "hideOffscreenVirtualViewsOnIOS"); flagValue = currentProvider_->hideOffscreenVirtualViewsOnIOS(); hideOffscreenVirtualViewsOnIOS_ = flagValue; @@ -1244,7 +1262,7 @@ bool ReactNativeFeatureFlagsAccessor::overrideBySynchronousMountPropsAtMountingA // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(67, "overrideBySynchronousMountPropsAtMountingAndroid"); + markFlagAsAccessed(68, "overrideBySynchronousMountPropsAtMountingAndroid"); flagValue = currentProvider_->overrideBySynchronousMountPropsAtMountingAndroid(); overrideBySynchronousMountPropsAtMountingAndroid_ = flagValue; @@ -1262,7 +1280,7 @@ bool ReactNativeFeatureFlagsAccessor::perfIssuesEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(68, "perfIssuesEnabled"); + markFlagAsAccessed(69, "perfIssuesEnabled"); flagValue = currentProvider_->perfIssuesEnabled(); perfIssuesEnabled_ = flagValue; @@ -1280,7 +1298,7 @@ bool ReactNativeFeatureFlagsAccessor::perfMonitorV2Enabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(69, "perfMonitorV2Enabled"); + markFlagAsAccessed(70, "perfMonitorV2Enabled"); flagValue = currentProvider_->perfMonitorV2Enabled(); perfMonitorV2Enabled_ = flagValue; @@ -1298,7 +1316,7 @@ double ReactNativeFeatureFlagsAccessor::preparedTextCacheSize() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(70, "preparedTextCacheSize"); + markFlagAsAccessed(71, "preparedTextCacheSize"); flagValue = currentProvider_->preparedTextCacheSize(); preparedTextCacheSize_ = flagValue; @@ -1316,7 +1334,7 @@ bool ReactNativeFeatureFlagsAccessor::preventShadowTreeCommitExhaustion() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(71, "preventShadowTreeCommitExhaustion"); + markFlagAsAccessed(72, "preventShadowTreeCommitExhaustion"); flagValue = currentProvider_->preventShadowTreeCommitExhaustion(); preventShadowTreeCommitExhaustion_ = flagValue; @@ -1334,7 +1352,7 @@ bool ReactNativeFeatureFlagsAccessor::redBoxV2Android() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(72, "redBoxV2Android"); + markFlagAsAccessed(73, "redBoxV2Android"); flagValue = currentProvider_->redBoxV2Android(); redBoxV2Android_ = flagValue; @@ -1352,7 +1370,7 @@ bool ReactNativeFeatureFlagsAccessor::redBoxV2IOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(73, "redBoxV2IOS"); + markFlagAsAccessed(74, "redBoxV2IOS"); flagValue = currentProvider_->redBoxV2IOS(); redBoxV2IOS_ = flagValue; @@ -1370,7 +1388,7 @@ bool ReactNativeFeatureFlagsAccessor::shouldPressibilityUseW3CPointerEventsForHo // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(74, "shouldPressibilityUseW3CPointerEventsForHover"); + markFlagAsAccessed(75, "shouldPressibilityUseW3CPointerEventsForHover"); flagValue = currentProvider_->shouldPressibilityUseW3CPointerEventsForHover(); shouldPressibilityUseW3CPointerEventsForHover_ = flagValue; @@ -1388,7 +1406,7 @@ bool ReactNativeFeatureFlagsAccessor::runtimeCrashUiThreadUtils() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(75, "runtimeCrashUiThreadUtils"); + markFlagAsAccessed(76, "runtimeCrashUiThreadUtils"); flagValue = currentProvider_->runtimeCrashUiThreadUtils(); runtimeCrashUiThreadUtils_ = flagValue; @@ -1406,7 +1424,7 @@ bool ReactNativeFeatureFlagsAccessor::shouldTriggerResponderTransferOnScrollAndr // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(76, "shouldTriggerResponderTransferOnScrollAndroid"); + markFlagAsAccessed(77, "shouldTriggerResponderTransferOnScrollAndroid"); flagValue = currentProvider_->shouldTriggerResponderTransferOnScrollAndroid(); shouldTriggerResponderTransferOnScrollAndroid_ = flagValue; @@ -1424,7 +1442,7 @@ bool ReactNativeFeatureFlagsAccessor::skipActivityIdentityAssertionOnHostPause() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(77, "skipActivityIdentityAssertionOnHostPause"); + markFlagAsAccessed(78, "skipActivityIdentityAssertionOnHostPause"); flagValue = currentProvider_->skipActivityIdentityAssertionOnHostPause(); skipActivityIdentityAssertionOnHostPause_ = flagValue; @@ -1442,7 +1460,7 @@ bool ReactNativeFeatureFlagsAccessor::syncAndroidClipBoundsWithOverflow() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(78, "syncAndroidClipBoundsWithOverflow"); + markFlagAsAccessed(79, "syncAndroidClipBoundsWithOverflow"); flagValue = currentProvider_->syncAndroidClipBoundsWithOverflow(); syncAndroidClipBoundsWithOverflow_ = flagValue; @@ -1460,7 +1478,7 @@ bool ReactNativeFeatureFlagsAccessor::traceTurboModulePromiseRejectionsOnAndroid // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(79, "traceTurboModulePromiseRejectionsOnAndroid"); + markFlagAsAccessed(80, "traceTurboModulePromiseRejectionsOnAndroid"); flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid(); traceTurboModulePromiseRejectionsOnAndroid_ = flagValue; @@ -1478,7 +1496,7 @@ bool ReactNativeFeatureFlagsAccessor::updateRuntimeShadowNodeReferencesOnCommit( // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(80, "updateRuntimeShadowNodeReferencesOnCommit"); + markFlagAsAccessed(81, "updateRuntimeShadowNodeReferencesOnCommit"); flagValue = currentProvider_->updateRuntimeShadowNodeReferencesOnCommit(); updateRuntimeShadowNodeReferencesOnCommit_ = flagValue; @@ -1496,7 +1514,7 @@ bool ReactNativeFeatureFlagsAccessor::updateRuntimeShadowNodeReferencesOnCommitT // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(81, "updateRuntimeShadowNodeReferencesOnCommitThread"); + markFlagAsAccessed(82, "updateRuntimeShadowNodeReferencesOnCommitThread"); flagValue = currentProvider_->updateRuntimeShadowNodeReferencesOnCommitThread(); updateRuntimeShadowNodeReferencesOnCommitThread_ = flagValue; @@ -1514,7 +1532,7 @@ bool ReactNativeFeatureFlagsAccessor::useAlwaysAvailableJSErrorHandling() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(82, "useAlwaysAvailableJSErrorHandling"); + markFlagAsAccessed(83, "useAlwaysAvailableJSErrorHandling"); flagValue = currentProvider_->useAlwaysAvailableJSErrorHandling(); useAlwaysAvailableJSErrorHandling_ = flagValue; @@ -1532,7 +1550,7 @@ bool ReactNativeFeatureFlagsAccessor::useFabricInterop() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(83, "useFabricInterop"); + markFlagAsAccessed(84, "useFabricInterop"); flagValue = currentProvider_->useFabricInterop(); useFabricInterop_ = flagValue; @@ -1550,7 +1568,7 @@ bool ReactNativeFeatureFlagsAccessor::useLISAlgorithmInDifferentiator() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(84, "useLISAlgorithmInDifferentiator"); + markFlagAsAccessed(85, "useLISAlgorithmInDifferentiator"); flagValue = currentProvider_->useLISAlgorithmInDifferentiator(); useLISAlgorithmInDifferentiator_ = flagValue; @@ -1568,7 +1586,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeViewConfigsInBridgelessMode() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(85, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(86, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -1586,7 +1604,7 @@ bool ReactNativeFeatureFlagsAccessor::useNestedScrollViewAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(86, "useNestedScrollViewAndroid"); + markFlagAsAccessed(87, "useNestedScrollViewAndroid"); flagValue = currentProvider_->useNestedScrollViewAndroid(); useNestedScrollViewAndroid_ = flagValue; @@ -1604,7 +1622,7 @@ bool ReactNativeFeatureFlagsAccessor::useOptimizedViewRegistryOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(87, "useOptimizedViewRegistryOnAndroid"); + markFlagAsAccessed(88, "useOptimizedViewRegistryOnAndroid"); flagValue = currentProvider_->useOptimizedViewRegistryOnAndroid(); useOptimizedViewRegistryOnAndroid_ = flagValue; @@ -1622,7 +1640,7 @@ bool ReactNativeFeatureFlagsAccessor::usePullModelOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(88, "usePullModelOnAndroid"); + markFlagAsAccessed(89, "usePullModelOnAndroid"); flagValue = currentProvider_->usePullModelOnAndroid(); usePullModelOnAndroid_ = flagValue; @@ -1640,7 +1658,7 @@ bool ReactNativeFeatureFlagsAccessor::useSharedAnimatedBackend() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(89, "useSharedAnimatedBackend"); + markFlagAsAccessed(90, "useSharedAnimatedBackend"); flagValue = currentProvider_->useSharedAnimatedBackend(); useSharedAnimatedBackend_ = flagValue; @@ -1658,7 +1676,7 @@ bool ReactNativeFeatureFlagsAccessor::useSilenceErrorSMMViewNotFound() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(90, "useSilenceErrorSMMViewNotFound"); + markFlagAsAccessed(91, "useSilenceErrorSMMViewNotFound"); flagValue = currentProvider_->useSilenceErrorSMMViewNotFound(); useSilenceErrorSMMViewNotFound_ = flagValue; @@ -1676,7 +1694,7 @@ bool ReactNativeFeatureFlagsAccessor::useTraitHiddenOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(91, "useTraitHiddenOnAndroid"); + markFlagAsAccessed(92, "useTraitHiddenOnAndroid"); flagValue = currentProvider_->useTraitHiddenOnAndroid(); useTraitHiddenOnAndroid_ = flagValue; @@ -1694,7 +1712,7 @@ bool ReactNativeFeatureFlagsAccessor::useTraitHiddenOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(92, "useTraitHiddenOnIOS"); + markFlagAsAccessed(93, "useTraitHiddenOnIOS"); flagValue = currentProvider_->useTraitHiddenOnIOS(); useTraitHiddenOnIOS_ = flagValue; @@ -1712,7 +1730,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModuleInterop() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(93, "useTurboModuleInterop"); + markFlagAsAccessed(94, "useTurboModuleInterop"); flagValue = currentProvider_->useTurboModuleInterop(); useTurboModuleInterop_ = flagValue; @@ -1730,7 +1748,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModules() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(94, "useTurboModules"); + markFlagAsAccessed(95, "useTurboModules"); flagValue = currentProvider_->useTurboModules(); useTurboModules_ = flagValue; @@ -1748,7 +1766,7 @@ bool ReactNativeFeatureFlagsAccessor::useUnorderedMapInDifferentiator() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(95, "useUnorderedMapInDifferentiator"); + markFlagAsAccessed(96, "useUnorderedMapInDifferentiator"); flagValue = currentProvider_->useUnorderedMapInDifferentiator(); useUnorderedMapInDifferentiator_ = flagValue; @@ -1766,7 +1784,7 @@ double ReactNativeFeatureFlagsAccessor::viewCullingOutsetRatio() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(96, "viewCullingOutsetRatio"); + markFlagAsAccessed(97, "viewCullingOutsetRatio"); flagValue = currentProvider_->viewCullingOutsetRatio(); viewCullingOutsetRatio_ = flagValue; @@ -1784,7 +1802,7 @@ bool ReactNativeFeatureFlagsAccessor::viewTransitionEnabled() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(97, "viewTransitionEnabled"); + markFlagAsAccessed(98, "viewTransitionEnabled"); flagValue = currentProvider_->viewTransitionEnabled(); viewTransitionEnabled_ = flagValue; @@ -1802,7 +1820,7 @@ double ReactNativeFeatureFlagsAccessor::virtualViewPrerenderRatio() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(98, "virtualViewPrerenderRatio"); + markFlagAsAccessed(99, "virtualViewPrerenderRatio"); flagValue = currentProvider_->virtualViewPrerenderRatio(); virtualViewPrerenderRatio_ = flagValue; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index da03826909f6..acd711a54c56 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<4d3705bd5161ff7635e97ae248c74868>> + * @generated SignedSource<<77156155e45df4293e9168e4bb7d853c>> */ /** @@ -42,6 +42,7 @@ class ReactNativeFeatureFlagsAccessor { bool disableSubviewClippingAndroid(); bool disableTextLayoutManagerCacheAndroid(); bool disableViewPreallocationAndroid(); + bool discordSkipUnchangedYogaDirty(); double discordUiManagerOptimization(); bool enableAccessibilityOrder(); bool enableAccumulatedUpdatesInRawPropsAndroid(); @@ -142,7 +143,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 99> accessedFeatureFlags_; + std::array, 100> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> cdpInteractionMetricsEnabled_; @@ -154,6 +155,7 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> disableSubviewClippingAndroid_; std::atomic> disableTextLayoutManagerCacheAndroid_; std::atomic> disableViewPreallocationAndroid_; + std::atomic> discordSkipUnchangedYogaDirty_; std::atomic> discordUiManagerOptimization_; std::atomic> enableAccessibilityOrder_; std::atomic> enableAccumulatedUpdatesInRawPropsAndroid_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index bb7a36bc0125..f36f4528e2e2 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<5e62b8c1a5b6edbd80276ece225c0439>> */ /** @@ -67,6 +67,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } + bool discordSkipUnchangedYogaDirty() override { + return false; + } + double discordUiManagerOptimization() override { return 0.0; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h index 4d215ccd3a15..3765d56302a0 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<0ce2303f050c763a34ac4998192c78af>> + * @generated SignedSource<<1d3efb9471bb29056e72abbc69cfd4c9>> */ /** @@ -135,6 +135,15 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef return ReactNativeFeatureFlagsDefaults::disableViewPreallocationAndroid(); } + bool discordSkipUnchangedYogaDirty() override { + auto value = values_["discordSkipUnchangedYogaDirty"]; + if (!value.isNull()) { + return value.getBool(); + } + + return ReactNativeFeatureFlagsDefaults::discordSkipUnchangedYogaDirty(); + } + double discordUiManagerOptimization() override { auto value = values_["discordUiManagerOptimization"]; if (!value.isNull()) { diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index e7c2fc710792..d5047264399f 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<4386eff150cd9570d98c0ca4fe9a90ac>> + * @generated SignedSource<<51ebb831ed1eb7749c34ec71f5a6c8ec>> */ /** @@ -35,6 +35,7 @@ class ReactNativeFeatureFlagsProvider { virtual bool disableSubviewClippingAndroid() = 0; virtual bool disableTextLayoutManagerCacheAndroid() = 0; virtual bool disableViewPreallocationAndroid() = 0; + virtual bool discordSkipUnchangedYogaDirty() = 0; virtual double discordUiManagerOptimization() = 0; virtual bool enableAccessibilityOrder() = 0; virtual bool enableAccumulatedUpdatesInRawPropsAndroid() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index b2048a2ce519..a55cb5db7a34 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<6e3d7aa0a7bbccd61549ca3e5dd26020>> + * @generated SignedSource<<70c28021a82adee268309af69f45c382>> */ /** @@ -94,6 +94,11 @@ bool NativeReactNativeFeatureFlags::disableViewPreallocationAndroid( return ReactNativeFeatureFlags::disableViewPreallocationAndroid(); } +bool NativeReactNativeFeatureFlags::discordSkipUnchangedYogaDirty( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::discordSkipUnchangedYogaDirty(); +} + double NativeReactNativeFeatureFlags::discordUiManagerOptimization( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::discordUiManagerOptimization(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index 21bda15bca87..f1fa97adc373 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<380250279c76aca0f139fdd0eac141db>> + * @generated SignedSource<<7ac7e91352386b1142c738083df9c9e8>> */ /** @@ -56,6 +56,8 @@ class NativeReactNativeFeatureFlags bool disableViewPreallocationAndroid(jsi::Runtime& runtime); + bool discordSkipUnchangedYogaDirty(jsi::Runtime& runtime); + double discordUiManagerOptimization(jsi::Runtime& runtime); bool enableAccessibilityOrder(jsi::Runtime& runtime); 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 c630cb420188..bd03f31562b1 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp @@ -543,11 +543,21 @@ YogaLayoutableShadowNode& YogaLayoutableShadowNode::cloneChildInPlace( void YogaLayoutableShadowNode::setSize(Size size) const { ensureUnsealed(); + auto width = yoga::StyleSizeLength::points(size.width); + auto height = yoga::StyleSizeLength::points(size.height); + + // Component descriptors call this from `adopt`, which runs on every clone. + // Dirtying the node when nothing changed would make every commit that clones + // it re-run layout over the whole tree. auto style = yogaNode_.style(); - style.setDimension( - yoga::Dimension::Width, yoga::StyleSizeLength::points(size.width)); - style.setDimension( - yoga::Dimension::Height, yoga::StyleSizeLength::points(size.height)); + if (ReactNativeFeatureFlags::discordSkipUnchangedYogaDirty() && + width == style.dimension(yoga::Dimension::Width) && + height == style.dimension(yoga::Dimension::Height)) { + return; + } + + style.setDimension(yoga::Dimension::Width, width); + style.setDimension(yoga::Dimension::Height, height); yogaNode_.setStyle(style); yogaNode_.setDirty(true); } @@ -582,6 +592,11 @@ void YogaLayoutableShadowNode::setPositionType( ensureUnsealed(); auto style = yogaNode_.style(); + if (ReactNativeFeatureFlags::discordSkipUnchangedYogaDirty() && + style.positionType() == yoga::scopedEnum(positionType)) { + return; + } + style.setPositionType(yoga::scopedEnum(positionType)); yogaNode_.setStyle(style); yogaNode_.setDirty(true); diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/tests/ViewTest.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/tests/ViewTest.cpp index 82c363b8d792..757b5c6b0dc9 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/tests/ViewTest.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/tests/ViewTest.cpp @@ -10,6 +10,8 @@ #include +#include +#include #include #include #include @@ -23,6 +25,14 @@ namespace facebook::react { +class SkipUnchangedYogaDirtyFeatureFlags + : public ReactNativeFeatureFlagsDefaults { + public: + bool discordSkipUnchangedYogaDirty() override { + return true; + } +}; + class YogaDirtyFlagTest : public ::testing::Test { protected: ComponentBuilder builder_; @@ -84,6 +94,18 @@ class YogaDirtyFlagTest : public ::testing::Test { */ EXPECT_FALSE(rootShadowNode_->layoutIfNeeded()); } + + void TearDown() override { + ReactNativeFeatureFlags::dangerouslyReset(); + } + + static void enableSkipUnchangedYogaDirty() { + // The fixture constructor already read the flags, so reset before + // overriding. + ReactNativeFeatureFlags::dangerouslyReset(); + ReactNativeFeatureFlags::override( + std::make_unique()); + } }; TEST_F(YogaDirtyFlagTest, cloningPropsWithoutChangingThem) { @@ -230,6 +252,67 @@ TEST_F(YogaDirtyFlagTest, updatingStateForScrollViewMistNotDirtyYogaNode) { static_cast(*newRootShadowNode).layoutIfNeeded()); } +TEST_F(YogaDirtyFlagTest, settingUnchangedSizeMustNotDirtyYogaNode) { + enableSkipUnchangedYogaDirty(); + + /* + * Component descriptors call `setSize` from `adopt`, which runs on every + * clone. Setting the size a node already has must *not* dirty its Yoga node, + * otherwise every commit that clones it re-runs layout. + */ + auto setSize = [](const ShadowNode& oldShadowNode) { + auto newShadowNode = oldShadowNode.clone({}); + static_cast(*newShadowNode) + .setSize({.width = 100, .height = 200}); + return newShadowNode; + }; + + auto sizedRootShadowNode = + rootShadowNode_->cloneTree(innerShadowNode_->getFamily(), setSize); + + /* + * Changing the size *must* dirty the Yoga node. + */ + EXPECT_TRUE( + static_cast(*sizedRootShadowNode).layoutIfNeeded()); + + auto newRootShadowNode = + sizedRootShadowNode->cloneTree(innerShadowNode_->getFamily(), setSize); + + EXPECT_FALSE( + static_cast(*newRootShadowNode).layoutIfNeeded()); +} + +TEST_F(YogaDirtyFlagTest, settingUnchangedPositionTypeMustNotDirtyYogaNode) { + enableSkipUnchangedYogaDirty(); + + /* + * Setting the position type a node already has must *not* dirty its Yoga + * node. + */ + auto setPositionType = [](const ShadowNode& oldShadowNode) { + auto newShadowNode = oldShadowNode.clone({}); + static_cast(*newShadowNode) + .setPositionType(YGPositionTypeAbsolute); + return newShadowNode; + }; + + auto absoluteRootShadowNode = rootShadowNode_->cloneTree( + innerShadowNode_->getFamily(), setPositionType); + + /* + * Changing the position type *must* dirty the Yoga node. + */ + EXPECT_TRUE( + static_cast(*absoluteRootShadowNode).layoutIfNeeded()); + + auto newRootShadowNode = absoluteRootShadowNode->cloneTree( + innerShadowNode_->getFamily(), setPositionType); + + EXPECT_FALSE( + static_cast(*newRootShadowNode).layoutIfNeeded()); +} + TEST_F(YogaDirtyFlagTest, clonedPropsPreserveAspectRatio) { ContextContainer contextContainer{}; PropsParserContext parserContext{-1, contextContainer}; diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index 15646b06830a..f25de7005783 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -158,6 +158,17 @@ const definitions: FeatureFlagDefinitions = { }, ossReleaseStage: 'none', }, + discordSkipUnchangedYogaDirty: { + defaultValue: false, + metadata: { + dateAdded: '2026-10-16', + description: + 'Skip dirtying Yoga nodes in setSize/setPositionType when the value is unchanged (react-native#59101).', + expectedReleaseValue: true, + purpose: 'experimentation', + }, + ossReleaseStage: 'none', + }, discordUiManagerOptimization: { defaultValue: 0, metadata: { diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index a632cb0a4eb1..063cd8f765d4 100644 --- a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<91aeb0b626fa2146487c73d4cc2d9d82>> * @flow strict * @noformat */ @@ -57,6 +57,7 @@ export type ReactNativeFeatureFlags = $ReadOnly<{ disableSubviewClippingAndroid: Getter, disableTextLayoutManagerCacheAndroid: Getter, disableViewPreallocationAndroid: Getter, + discordSkipUnchangedYogaDirty: Getter, discordUiManagerOptimization: Getter, enableAccessibilityOrder: Getter, enableAccumulatedUpdatesInRawPropsAndroid: Getter, @@ -252,6 +253,10 @@ export const disableTextLayoutManagerCacheAndroid: Getter = createNativ * Force disable view preallocation triggered from createNode off the main thread on Android */ export const disableViewPreallocationAndroid: Getter = createNativeFlagGetter('disableViewPreallocationAndroid', false); +/** + * Skip dirtying Yoga nodes in setSize/setPositionType when the value is unchanged (react-native#59101). + */ +export const discordSkipUnchangedYogaDirty: Getter = createNativeFlagGetter('discordSkipUnchangedYogaDirty', false); /** * Select UIManager optimizations: 0 = none, 1 = preserve lazy properties, 2 = load view manager constants on demand. */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index 94154d6cd621..8624f706d453 100644 --- a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<0bf19d4c28b5951ae76777bf6df1228c>> * @flow strict * @noformat */ @@ -35,6 +35,7 @@ export interface Spec extends TurboModule { +disableSubviewClippingAndroid?: () => boolean; +disableTextLayoutManagerCacheAndroid?: () => boolean; +disableViewPreallocationAndroid?: () => boolean; + +discordSkipUnchangedYogaDirty?: () => boolean; +discordUiManagerOptimization?: () => number; +enableAccessibilityOrder?: () => boolean; +enableAccumulatedUpdatesInRawPropsAndroid?: () => boolean;