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..ac8e617115e3 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<<67b631d02306806e8c7ffa8c975109a1>> */ /** @@ -96,6 +96,12 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun discordUiManagerOptimization(): Double = accessor.discordUiManagerOptimization() + /** + * Select text optimizations: 0 = none, 1 = keep paragraph content across unchanged clones, 2 = 1 + skip unused getDesiredWidth on Android. + */ + @JvmStatic + public fun discordTextOptimization(): Double = accessor.discordTextOptimization() + /** * When enabled, the accessibilityOrder prop will propagate to native platforms and define the accessibility order. */ 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..7f9d47722a31 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<> */ /** @@ -31,6 +31,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces private var disableTextLayoutManagerCacheAndroidCache: Boolean? = null private var disableViewPreallocationAndroidCache: Boolean? = null private var discordUiManagerOptimizationCache: Double? = null + private var discordTextOptimizationCache: Double? = null private var enableAccessibilityOrderCache: Boolean? = null private var enableAccumulatedUpdatesInRawPropsAndroidCache: Boolean? = null private var enableAndroidTextMeasurementOptimizationsCache: Boolean? = null @@ -219,6 +220,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun discordTextOptimization(): Double { + var cached = discordTextOptimizationCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.discordTextOptimization() + discordTextOptimizationCache = cached + } + return cached + } + override fun enableAccessibilityOrder(): Boolean { var cached = enableAccessibilityOrderCache 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..14258622e8f7 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<> */ /** @@ -50,6 +50,8 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun discordUiManagerOptimization(): Double + @DoNotStrip @JvmStatic public external fun discordTextOptimization(): Double + @DoNotStrip @JvmStatic public external fun enableAccessibilityOrder(): Boolean @DoNotStrip @JvmStatic public external fun enableAccumulatedUpdatesInRawPropsAndroid(): 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..e15d4ab63144 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<<1228bb8dec11c46e2c26b775ff45d7e2>> */ /** @@ -45,6 +45,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun discordUiManagerOptimization(): Double = 0.0 + override fun discordTextOptimization(): Double = 0.0 + override fun enableAccessibilityOrder(): Boolean = false override fun enableAccumulatedUpdatesInRawPropsAndroid(): Boolean = true 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..2088cd97372e 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<<5630bc94a28bed82e9246b5bd83eae2a>> */ /** @@ -35,6 +35,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc private var disableTextLayoutManagerCacheAndroidCache: Boolean? = null private var disableViewPreallocationAndroidCache: Boolean? = null private var discordUiManagerOptimizationCache: Double? = null + private var discordTextOptimizationCache: Double? = null private var enableAccessibilityOrderCache: Boolean? = null private var enableAccumulatedUpdatesInRawPropsAndroidCache: Boolean? = null private var enableAndroidTextMeasurementOptimizationsCache: Boolean? = null @@ -234,6 +235,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc return cached } + override fun discordTextOptimization(): Double { + var cached = discordTextOptimizationCache + if (cached == null) { + cached = currentProvider.discordTextOptimization() + accessedFeatureFlags.add("discordTextOptimization") + discordTextOptimizationCache = cached + } + return cached + } + override fun enableAccessibilityOrder(): Boolean { var cached = enableAccessibilityOrderCache 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..c14f5bbb5241 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<<7ab6e2389bd15ff296dc78a32a5d2e8d>> */ /** @@ -45,6 +45,8 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun discordUiManagerOptimization(): Double + @DoNotStrip public fun discordTextOptimization(): Double + @DoNotStrip public fun enableAccessibilityOrder(): Boolean @DoNotStrip public fun enableAccumulatedUpdatesInRawPropsAndroid(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.kt index 12e100a7f7c8..a4a0e2948bd1 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.kt @@ -731,13 +731,33 @@ internal object TextLayoutManager { ) } - val desiredWidth = ceil(Layout.getDesiredWidth(text, paint)).toInt() - val layoutWidth = - when (widthYogaMeasureMode) { - YogaMeasureMode.EXACTLY -> ceil(width).toInt() - YogaMeasureMode.AT_MOST -> min(desiredWidth, floor(width).toInt()) - else -> desiredWidth + if (ReactNativeFeatureFlags.discordTextOptimization() >= 2.0) { + // Layout.getDesiredWidth is a full measuring pass over the text, so only run it when its + // result can affect the layout width. It cannot when the width is EXACTLY, nor when the + // text was boring but did not fit: boring.width is the unwrapped width of the same text + // and we only get here if it exceeds floor(width), so min(desiredWidth, floor(width)) is + // floor(width). + when { + widthYogaMeasureMode == YogaMeasureMode.EXACTLY -> ceil(width).toInt() + widthYogaMeasureMode == YogaMeasureMode.AT_MOST && boring != null -> + floor(width).toInt() + else -> { + val desiredWidth = ceil(Layout.getDesiredWidth(text, paint)).toInt() + if (widthYogaMeasureMode == YogaMeasureMode.AT_MOST) { + min(desiredWidth, floor(width).toInt()) + } else { + desiredWidth + } + } + } + } else { + val desiredWidth = ceil(Layout.getDesiredWidth(text, paint)).toInt() + when (widthYogaMeasureMode) { + YogaMeasureMode.EXACTLY -> ceil(width).toInt() + YogaMeasureMode.AT_MOST -> min(desiredWidth, floor(width).toInt()) + else -> desiredWidth + } } return buildLayout( text, 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..59480eb1a498 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<<0be74c94405970ebed9a3deab3fe0a48>> */ /** @@ -105,6 +105,12 @@ class ReactNativeFeatureFlagsJavaProvider return method(javaProvider_); } + double discordTextOptimization() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("discordTextOptimization"); + return method(javaProvider_); + } + bool enableAccessibilityOrder() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableAccessibilityOrder"); @@ -692,6 +698,11 @@ double JReactNativeFeatureFlagsCxxInterop::discordUiManagerOptimization( return ReactNativeFeatureFlags::discordUiManagerOptimization(); } +double JReactNativeFeatureFlagsCxxInterop::discordTextOptimization( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::discordTextOptimization(); +} + bool JReactNativeFeatureFlagsCxxInterop::enableAccessibilityOrder( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::enableAccessibilityOrder(); @@ -1196,6 +1207,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "discordUiManagerOptimization", JReactNativeFeatureFlagsCxxInterop::discordUiManagerOptimization), + makeNativeMethod( + "discordTextOptimization", + JReactNativeFeatureFlagsCxxInterop::discordTextOptimization), makeNativeMethod( "enableAccessibilityOrder", JReactNativeFeatureFlagsCxxInterop::enableAccessibilityOrder), 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..5cf3a4ad0011 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<<974ffe0fc50bc5aa3d70fdc4a16c62ee>> */ /** @@ -63,6 +63,9 @@ class JReactNativeFeatureFlagsCxxInterop static double discordUiManagerOptimization( facebook::jni::alias_ref); + static double discordTextOptimization( + facebook::jni::alias_ref); + static bool enableAccessibilityOrder( facebook::jni::alias_ref); diff --git a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/text/TextLayoutManagerAbsoluteLayoutWithFractionalPixelTest.kt b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/text/TextLayoutManagerAbsoluteLayoutWithFractionalPixelTest.kt index 33e00f0af10c..0f4836f11368 100644 --- a/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/text/TextLayoutManagerAbsoluteLayoutWithFractionalPixelTest.kt +++ b/packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/text/TextLayoutManagerAbsoluteLayoutWithFractionalPixelTest.kt @@ -13,9 +13,11 @@ import android.text.Layout import android.text.SpannableString import android.text.TextPaint import android.text.TextUtils +import com.facebook.react.internal.featureflags.ReactNativeFeatureFlagsForTests import com.facebook.yoga.YogaMeasureMode import kotlin.math.ceil import org.assertj.core.api.Assertions.assertThat +import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner @@ -41,6 +43,11 @@ import org.robolectric.RobolectricTestRunner @RunWith(RobolectricTestRunner::class) class TextLayoutManagerAbsoluteLayoutWithFractionalPixelTest { + @Before + fun setUp() { + ReactNativeFeatureFlagsForTests.setUp() + } + @Test fun `EXACTLY mode with fractional width allocates a layout wide enough to fit its own text`() { val text = SpannableString("Keep watching") diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp index 16a8faf3033e..753f6bfda65a 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<> */ /** @@ -70,6 +70,10 @@ double ReactNativeFeatureFlags::discordUiManagerOptimization() { return getAccessor().discordUiManagerOptimization(); } +double ReactNativeFeatureFlags::discordTextOptimization() { + return getAccessor().discordTextOptimization(); +} + bool ReactNativeFeatureFlags::enableAccessibilityOrder() { return getAccessor().enableAccessibilityOrder(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index 3c4c8d10d271..68cead0ab757 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<> */ /** @@ -94,6 +94,11 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static double discordUiManagerOptimization(); + /** + * Select text optimizations: 0 = none, 1 = keep paragraph content across unchanged clones, 2 = 1 + skip unused getDesiredWidth on Android. + */ + RN_EXPORT static double discordTextOptimization(); + /** * When enabled, the accessibilityOrder prop will propagate to native platforms and define the accessibility order. */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index 231a308c61e1..228236d169ee 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<> */ /** @@ -227,6 +227,24 @@ double ReactNativeFeatureFlagsAccessor::discordUiManagerOptimization() { return flagValue.value(); } +double ReactNativeFeatureFlagsAccessor::discordTextOptimization() { + auto flagValue = discordTextOptimization_.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(11, "discordTextOptimization"); + + flagValue = currentProvider_->discordTextOptimization(); + discordTextOptimization_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::enableAccessibilityOrder() { auto flagValue = enableAccessibilityOrder_.load(); @@ -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..d09985b1c191 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<<9e33add4f9ea7ed16248e7ae0333b127>> */ /** @@ -43,6 +43,7 @@ class ReactNativeFeatureFlagsAccessor { bool disableTextLayoutManagerCacheAndroid(); bool disableViewPreallocationAndroid(); double discordUiManagerOptimization(); + double discordTextOptimization(); bool enableAccessibilityOrder(); bool enableAccumulatedUpdatesInRawPropsAndroid(); bool enableAndroidTextMeasurementOptimizations(); @@ -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_; @@ -155,6 +156,7 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> disableTextLayoutManagerCacheAndroid_; std::atomic> disableViewPreallocationAndroid_; std::atomic> discordUiManagerOptimization_; + std::atomic> discordTextOptimization_; std::atomic> enableAccessibilityOrder_; std::atomic> enableAccumulatedUpdatesInRawPropsAndroid_; std::atomic> enableAndroidTextMeasurementOptimizations_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index bb7a36bc0125..3b5e86e0700f 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<> */ /** @@ -71,6 +71,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return 0.0; } + double discordTextOptimization() override { + return 0.0; + } + bool enableAccessibilityOrder() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h index 4d215ccd3a15..16d00aaa4cf3 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<<9ca8b43afd60f17c21e1ac06fe9bb362>> */ /** @@ -144,6 +144,15 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef return ReactNativeFeatureFlagsDefaults::discordUiManagerOptimization(); } + double discordTextOptimization() override { + auto value = values_["discordTextOptimization"]; + if (!value.isNull()) { + return value.getDouble(); + } + + return ReactNativeFeatureFlagsDefaults::discordTextOptimization(); + } + bool enableAccessibilityOrder() override { auto value = values_["enableAccessibilityOrder"]; 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..fc753027de5d 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<<818815a80e5911d081089158dad07f48>> */ /** @@ -36,6 +36,7 @@ class ReactNativeFeatureFlagsProvider { virtual bool disableTextLayoutManagerCacheAndroid() = 0; virtual bool disableViewPreallocationAndroid() = 0; virtual double discordUiManagerOptimization() = 0; + virtual double discordTextOptimization() = 0; virtual bool enableAccessibilityOrder() = 0; virtual bool enableAccumulatedUpdatesInRawPropsAndroid() = 0; virtual bool enableAndroidTextMeasurementOptimizations() = 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..65b1898aa6b1 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<<424185ea967ff5fbd5c7fd43b0330237>> */ /** @@ -99,6 +99,11 @@ double NativeReactNativeFeatureFlags::discordUiManagerOptimization( return ReactNativeFeatureFlags::discordUiManagerOptimization(); } +double NativeReactNativeFeatureFlags::discordTextOptimization( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::discordTextOptimization(); +} + bool NativeReactNativeFeatureFlags::enableAccessibilityOrder( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::enableAccessibilityOrder(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index 21bda15bca87..3778c4f9500f 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<<707eb96a034a7d0b23263f583d0a363f>> */ /** @@ -58,6 +58,8 @@ class NativeReactNativeFeatureFlags double discordUiManagerOptimization(jsi::Runtime& runtime); + double discordTextOptimization(jsi::Runtime& runtime); + bool enableAccessibilityOrder(jsi::Runtime& runtime); bool enableAccumulatedUpdatesInRawPropsAndroid(jsi::Runtime& runtime); diff --git a/packages/react-native/ReactCommon/react/renderer/components/text/ParagraphShadowNode.cpp b/packages/react-native/ReactCommon/react/renderer/components/text/ParagraphShadowNode.cpp index 17b14c439f16..fa98d8c6a4f5 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/text/ParagraphShadowNode.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/text/ParagraphShadowNode.cpp @@ -59,6 +59,18 @@ ParagraphShadowNode::ParagraphShadowNode( const ShadowNodeFragment& fragment) : ConcreteViewShadowNode(sourceShadowNode, fragment) { initialize(); + // A revision with neither new props nor new children (e.g. one Yoga cloned + // because a sibling changed) renders the same content, so keep the + // attributed string and the layouts measured for it instead of rebuilding + // and re-measuring them. `getContent` drops both if the layout context they + // were built for no longer matches. + if (ReactNativeFeatureFlags::discordTextOptimization() >= 1 && + fragment.props == nullptr && fragment.children == nullptr) { + const auto& source = + static_cast(sourceShadowNode); + content_ = source.content_; + measuredLayouts_ = source.measuredLayouts_; + } } bool ParagraphShadowNode::shouldNewRevisionDirtyMeasurement( @@ -69,8 +81,20 @@ bool ParagraphShadowNode::shouldNewRevisionDirtyMeasurement( const Content& ParagraphShadowNode::getContent( const LayoutContext& layoutContext) const { + auto layoutDirection = YGNodeLayoutGetDirection(&yogaNode_) == YGDirectionRTL + ? LayoutDirection::RightToLeft + : LayoutDirection::LeftToRight; if (content_.has_value()) { - return content_.value(); + const auto& baseTextAttributes = + content_->attributedString.getBaseTextAttributes(); + if (baseTextAttributes.fontSizeMultiplier == + layoutContext.fontSizeMultiplier && + baseTextAttributes.layoutDirection == layoutDirection) { + return content_.value(); + } + // Carried over from a previous revision, but built for another context. + content_.reset(); + measuredLayouts_.clear(); } ensureUnsealed(); @@ -78,10 +102,7 @@ const Content& ParagraphShadowNode::getContent( auto textAttributes = TextAttributes::defaultTextAttributes(); textAttributes.fontSizeMultiplier = layoutContext.fontSizeMultiplier; textAttributes.apply(getConcreteProps().textAttributes); - textAttributes.layoutDirection = - YGNodeLayoutGetDirection(&yogaNode_) == YGDirectionRTL - ? LayoutDirection::RightToLeft - : LayoutDirection::LeftToRight; + textAttributes.layoutDirection = layoutDirection; auto attributedString = AttributedString{}; auto attachments = Attachments{}; buildAttributedString(textAttributes, *this, attributedString, attachments); diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index 15646b06830a..57e4ac0982b6 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -169,6 +169,17 @@ const definitions: FeatureFlagDefinitions = { }, ossReleaseStage: 'none', }, + discordTextOptimization: { + defaultValue: 0, + metadata: { + dateAdded: '2026-10-16', + description: + 'Select text optimizations: 0 = none, 1 = keep paragraph content across unchanged clones, 2 = 1 + skip unused getDesiredWidth on Android.', + expectedReleaseValue: 2, + purpose: 'experimentation', + }, + ossReleaseStage: 'none', + }, enableAccessibilityOrder: { defaultValue: false, metadata: { diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index a632cb0a4eb1..f59564b7416f 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<<22d010497ee09894e5d76890d0bd96af>> * @flow strict * @noformat */ @@ -58,6 +58,7 @@ export type ReactNativeFeatureFlags = $ReadOnly<{ disableTextLayoutManagerCacheAndroid: Getter, disableViewPreallocationAndroid: Getter, discordUiManagerOptimization: Getter, + discordTextOptimization: Getter, enableAccessibilityOrder: Getter, enableAccumulatedUpdatesInRawPropsAndroid: Getter, enableAndroidTextMeasurementOptimizations: Getter, @@ -256,6 +257,10 @@ export const disableViewPreallocationAndroid: Getter = createNativeFlag * Select UIManager optimizations: 0 = none, 1 = preserve lazy properties, 2 = load view manager constants on demand. */ export const discordUiManagerOptimization: Getter = createNativeFlagGetter('discordUiManagerOptimization', 0); +/** + * Select text optimizations: 0 = none, 1 = keep paragraph content across unchanged clones, 2 = 1 + skip unused getDesiredWidth on Android. + */ +export const discordTextOptimization: Getter = createNativeFlagGetter('discordTextOptimization', 0); /** * When enabled, the accessibilityOrder prop will propagate to native platforms and define the accessibility order. */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index 94154d6cd621..be549535622a 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<<3b5737cfb5f25f67ebf3f4c482e3c753>> * @flow strict * @noformat */ @@ -36,6 +36,7 @@ export interface Spec extends TurboModule { +disableTextLayoutManagerCacheAndroid?: () => boolean; +disableViewPreallocationAndroid?: () => boolean; +discordUiManagerOptimization?: () => number; + +discordTextOptimization?: () => number; +enableAccessibilityOrder?: () => boolean; +enableAccumulatedUpdatesInRawPropsAndroid?: () => boolean; +enableAndroidTextMeasurementOptimizations?: () => boolean;