From 41938f8ca842dc39e45db125bc3b3e1876d3d6ed Mon Sep 17 00:00:00 2001 From: Zeya Peng Date: Tue, 17 Jun 2025 05:53:16 -0700 Subject: [PATCH 1/2] feature flag cxxNativeAnimatedRemoveJsSync Differential Revision: D76763197 --- .../featureflags/ReactNativeFeatureFlags.kt | 8 +- .../ReactNativeFeatureFlagsCxxAccessor.kt | 12 +- .../ReactNativeFeatureFlagsCxxInterop.kt | 4 +- .../ReactNativeFeatureFlagsDefaults.kt | 4 +- .../ReactNativeFeatureFlagsLocalAccessor.kt | 13 +- .../ReactNativeFeatureFlagsProvider.kt | 4 +- .../JReactNativeFeatureFlagsCxxInterop.cpp | 16 ++- .../JReactNativeFeatureFlagsCxxInterop.h | 5 +- .../featureflags/ReactNativeFeatureFlags.cpp | 6 +- .../featureflags/ReactNativeFeatureFlags.h | 7 +- .../ReactNativeFeatureFlagsAccessor.cpp | 118 ++++++++++-------- .../ReactNativeFeatureFlagsAccessor.h | 6 +- .../ReactNativeFeatureFlagsDefaults.h | 6 +- .../ReactNativeFeatureFlagsDynamicProvider.h | 11 +- .../ReactNativeFeatureFlagsProvider.h | 3 +- .../NativeReactNativeFeatureFlags.cpp | 7 +- .../NativeReactNativeFeatureFlags.h | 4 +- .../ReactNativeFeatureFlags.config.js | 10 ++ .../featureflags/ReactNativeFeatureFlags.js | 7 +- .../specs/NativeReactNativeFeatureFlags.js | 3 +- 20 files changed, 185 insertions(+), 69 deletions(-) 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 3e79735612f77c..83191b10c6b02f 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<<4c40e490481c50d2f19830366f50aad5>> + * @generated SignedSource<> */ /** @@ -48,6 +48,12 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun cxxNativeAnimatedEnabled(): Boolean = accessor.cxxNativeAnimatedEnabled() + /** + * Removes JS sync at end of native animation + */ + @JvmStatic + public fun cxxNativeAnimatedRemoveJsSync(): Boolean = accessor.cxxNativeAnimatedRemoveJsSync() + /** * Disable sync dispatch on the main queue on iOS */ 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 748e8c98b7dc96..7441b0bd1e001d 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<<8cb9eb082005be480c39272ffc7dde03>> + * @generated SignedSource<<15b001b69d9ea8bedbce2ce0f70bfa8e>> */ /** @@ -23,6 +23,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces private var commonTestFlagCache: Boolean? = null private var animatedShouldSignalBatchCache: Boolean? = null private var cxxNativeAnimatedEnabledCache: Boolean? = null + private var cxxNativeAnimatedRemoveJsSyncCache: Boolean? = null private var disableMainQueueSyncDispatchIOSCache: Boolean? = null private var disableMountItemReorderingAndroidCache: Boolean? = null private var disableTextLayoutManagerCacheAndroidCache: Boolean? = null @@ -100,6 +101,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun cxxNativeAnimatedRemoveJsSync(): Boolean { + var cached = cxxNativeAnimatedRemoveJsSyncCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.cxxNativeAnimatedRemoveJsSync() + cxxNativeAnimatedRemoveJsSyncCache = cached + } + return cached + } + override fun disableMainQueueSyncDispatchIOS(): Boolean { var cached = disableMainQueueSyncDispatchIOSCache 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 5fdafe52142fca..fc9d4df17fce82 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<> + * @generated SignedSource<> */ /** @@ -34,6 +34,8 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun cxxNativeAnimatedEnabled(): Boolean + @DoNotStrip @JvmStatic public external fun cxxNativeAnimatedRemoveJsSync(): Boolean + @DoNotStrip @JvmStatic public external fun disableMainQueueSyncDispatchIOS(): Boolean @DoNotStrip @JvmStatic public external fun disableMountItemReorderingAndroid(): 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 db24a967a13fc4..8e28aba6feafad 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<<76edde93369be682e837189f82871dfe>> + * @generated SignedSource<<56835f26710665a11a05879a0c90e577>> */ /** @@ -29,6 +29,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun cxxNativeAnimatedEnabled(): Boolean = false + override fun cxxNativeAnimatedRemoveJsSync(): Boolean = false + override fun disableMainQueueSyncDispatchIOS(): Boolean = false override fun disableMountItemReorderingAndroid(): 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 3aa1f6b31e3669..c111433f646894 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<> */ /** @@ -27,6 +27,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc private var commonTestFlagCache: Boolean? = null private var animatedShouldSignalBatchCache: Boolean? = null private var cxxNativeAnimatedEnabledCache: Boolean? = null + private var cxxNativeAnimatedRemoveJsSyncCache: Boolean? = null private var disableMainQueueSyncDispatchIOSCache: Boolean? = null private var disableMountItemReorderingAndroidCache: Boolean? = null private var disableTextLayoutManagerCacheAndroidCache: Boolean? = null @@ -107,6 +108,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc return cached } + override fun cxxNativeAnimatedRemoveJsSync(): Boolean { + var cached = cxxNativeAnimatedRemoveJsSyncCache + if (cached == null) { + cached = currentProvider.cxxNativeAnimatedRemoveJsSync() + accessedFeatureFlags.add("cxxNativeAnimatedRemoveJsSync") + cxxNativeAnimatedRemoveJsSyncCache = cached + } + return cached + } + override fun disableMainQueueSyncDispatchIOS(): Boolean { var cached = disableMainQueueSyncDispatchIOSCache 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 5dbf74e7293130..5f6814e10f1f44 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<<892db232156970e8241d1f1ddde3a745>> + * @generated SignedSource<> */ /** @@ -29,6 +29,8 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun cxxNativeAnimatedEnabled(): Boolean + @DoNotStrip public fun cxxNativeAnimatedRemoveJsSync(): Boolean + @DoNotStrip public fun disableMainQueueSyncDispatchIOS(): Boolean @DoNotStrip public fun disableMountItemReorderingAndroid(): 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 d5a92f445f9d1a..1ba9f43fafe975 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<> */ /** @@ -57,6 +57,12 @@ class ReactNativeFeatureFlagsJavaProvider return method(javaProvider_); } + bool cxxNativeAnimatedRemoveJsSync() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("cxxNativeAnimatedRemoveJsSync"); + return method(javaProvider_); + } + bool disableMainQueueSyncDispatchIOS() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("disableMainQueueSyncDispatchIOS"); @@ -370,6 +376,11 @@ bool JReactNativeFeatureFlagsCxxInterop::cxxNativeAnimatedEnabled( return ReactNativeFeatureFlags::cxxNativeAnimatedEnabled(); } +bool JReactNativeFeatureFlagsCxxInterop::cxxNativeAnimatedRemoveJsSync( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::cxxNativeAnimatedRemoveJsSync(); +} + bool JReactNativeFeatureFlagsCxxInterop::disableMainQueueSyncDispatchIOS( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::disableMainQueueSyncDispatchIOS(); @@ -655,6 +666,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "cxxNativeAnimatedEnabled", JReactNativeFeatureFlagsCxxInterop::cxxNativeAnimatedEnabled), + makeNativeMethod( + "cxxNativeAnimatedRemoveJsSync", + JReactNativeFeatureFlagsCxxInterop::cxxNativeAnimatedRemoveJsSync), makeNativeMethod( "disableMainQueueSyncDispatchIOS", JReactNativeFeatureFlagsCxxInterop::disableMainQueueSyncDispatchIOS), 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 d048d1338934a0..92ca846326e94c 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<<04986fa84ec60aa0816ee79ab68e56aa>> + * @generated SignedSource<> */ /** @@ -39,6 +39,9 @@ class JReactNativeFeatureFlagsCxxInterop static bool cxxNativeAnimatedEnabled( facebook::jni::alias_ref); + static bool cxxNativeAnimatedRemoveJsSync( + facebook::jni::alias_ref); + static bool disableMainQueueSyncDispatchIOS( 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 09d1f5842b7b4c..0cf66a4166e766 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<<96d8201a39879e04c384303d1087a0b0>> + * @generated SignedSource<> */ /** @@ -38,6 +38,10 @@ bool ReactNativeFeatureFlags::cxxNativeAnimatedEnabled() { return getAccessor().cxxNativeAnimatedEnabled(); } +bool ReactNativeFeatureFlags::cxxNativeAnimatedRemoveJsSync() { + return getAccessor().cxxNativeAnimatedRemoveJsSync(); +} + bool ReactNativeFeatureFlags::disableMainQueueSyncDispatchIOS() { return getAccessor().disableMainQueueSyncDispatchIOS(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index db3f16d41b2dfa..e8603638b8df8b 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<<25b3585f3648fe156fab4a5abbf32e60>> + * @generated SignedSource<<8112c62255be23bde3fc558953dc8b67>> */ /** @@ -54,6 +54,11 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool cxxNativeAnimatedEnabled(); + /** + * Removes JS sync at end of native animation + */ + RN_EXPORT static bool cxxNativeAnimatedRemoveJsSync(); + /** * Disable sync dispatch on the main queue on iOS */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index ddb4730218934a..f08fec85e3279a 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<<4ccd3294168a0c4f5d9916368db06d62>> */ /** @@ -83,6 +83,24 @@ bool ReactNativeFeatureFlagsAccessor::cxxNativeAnimatedEnabled() { return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::cxxNativeAnimatedRemoveJsSync() { + auto flagValue = cxxNativeAnimatedRemoveJsSync_.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(3, "cxxNativeAnimatedRemoveJsSync"); + + flagValue = currentProvider_->cxxNativeAnimatedRemoveJsSync(); + cxxNativeAnimatedRemoveJsSync_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::disableMainQueueSyncDispatchIOS() { auto flagValue = disableMainQueueSyncDispatchIOS_.load(); @@ -92,7 +110,7 @@ bool ReactNativeFeatureFlagsAccessor::disableMainQueueSyncDispatchIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(3, "disableMainQueueSyncDispatchIOS"); + markFlagAsAccessed(4, "disableMainQueueSyncDispatchIOS"); flagValue = currentProvider_->disableMainQueueSyncDispatchIOS(); disableMainQueueSyncDispatchIOS_ = flagValue; @@ -110,7 +128,7 @@ bool ReactNativeFeatureFlagsAccessor::disableMountItemReorderingAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(4, "disableMountItemReorderingAndroid"); + markFlagAsAccessed(5, "disableMountItemReorderingAndroid"); flagValue = currentProvider_->disableMountItemReorderingAndroid(); disableMountItemReorderingAndroid_ = flagValue; @@ -128,7 +146,7 @@ bool ReactNativeFeatureFlagsAccessor::disableTextLayoutManagerCacheAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(5, "disableTextLayoutManagerCacheAndroid"); + markFlagAsAccessed(6, "disableTextLayoutManagerCacheAndroid"); flagValue = currentProvider_->disableTextLayoutManagerCacheAndroid(); disableTextLayoutManagerCacheAndroid_ = flagValue; @@ -146,7 +164,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(6, "enableAccessibilityOrder"); + markFlagAsAccessed(7, "enableAccessibilityOrder"); flagValue = currentProvider_->enableAccessibilityOrder(); enableAccessibilityOrder_ = flagValue; @@ -164,7 +182,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(7, "enableAccumulatedUpdatesInRawPropsAndroid"); + markFlagAsAccessed(8, "enableAccumulatedUpdatesInRawPropsAndroid"); flagValue = currentProvider_->enableAccumulatedUpdatesInRawPropsAndroid(); enableAccumulatedUpdatesInRawPropsAndroid_ = flagValue; @@ -182,7 +200,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(8, "enableBridgelessArchitecture"); + markFlagAsAccessed(9, "enableBridgelessArchitecture"); flagValue = currentProvider_->enableBridgelessArchitecture(); enableBridgelessArchitecture_ = flagValue; @@ -200,7 +218,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(9, "enableCppPropsIteratorSetter"); + markFlagAsAccessed(10, "enableCppPropsIteratorSetter"); flagValue = currentProvider_->enableCppPropsIteratorSetter(); enableCppPropsIteratorSetter_ = flagValue; @@ -218,7 +236,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(10, "enableCustomFocusSearchOnClippedElementsAndroid"); + markFlagAsAccessed(11, "enableCustomFocusSearchOnClippedElementsAndroid"); flagValue = currentProvider_->enableCustomFocusSearchOnClippedElementsAndroid(); enableCustomFocusSearchOnClippedElementsAndroid_ = flagValue; @@ -236,7 +254,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(11, "enableDestroyShadowTreeRevisionAsync"); + markFlagAsAccessed(12, "enableDestroyShadowTreeRevisionAsync"); flagValue = currentProvider_->enableDestroyShadowTreeRevisionAsync(); enableDestroyShadowTreeRevisionAsync_ = flagValue; @@ -254,7 +272,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(12, "enableDoubleMeasurementFixAndroid"); + markFlagAsAccessed(13, "enableDoubleMeasurementFixAndroid"); flagValue = currentProvider_->enableDoubleMeasurementFixAndroid(); enableDoubleMeasurementFixAndroid_ = flagValue; @@ -272,7 +290,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(13, "enableEagerRootViewAttachment"); + markFlagAsAccessed(14, "enableEagerRootViewAttachment"); flagValue = currentProvider_->enableEagerRootViewAttachment(); enableEagerRootViewAttachment_ = flagValue; @@ -290,7 +308,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(14, "enableFabricLogs"); + markFlagAsAccessed(15, "enableFabricLogs"); flagValue = currentProvider_->enableFabricLogs(); enableFabricLogs_ = flagValue; @@ -308,7 +326,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(15, "enableFabricRenderer"); + markFlagAsAccessed(16, "enableFabricRenderer"); flagValue = currentProvider_->enableFabricRenderer(); enableFabricRenderer_ = flagValue; @@ -326,7 +344,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(16, "enableFixForParentTagDuringReparenting"); + markFlagAsAccessed(17, "enableFixForParentTagDuringReparenting"); flagValue = currentProvider_->enableFixForParentTagDuringReparenting(); enableFixForParentTagDuringReparenting_ = flagValue; @@ -344,7 +362,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(17, "enableFontScaleChangesUpdatingLayout"); + markFlagAsAccessed(18, "enableFontScaleChangesUpdatingLayout"); flagValue = currentProvider_->enableFontScaleChangesUpdatingLayout(); enableFontScaleChangesUpdatingLayout_ = flagValue; @@ -362,7 +380,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(18, "enableIOSTextBaselineOffsetPerLine"); + markFlagAsAccessed(19, "enableIOSTextBaselineOffsetPerLine"); flagValue = currentProvider_->enableIOSTextBaselineOffsetPerLine(); enableIOSTextBaselineOffsetPerLine_ = flagValue; @@ -380,7 +398,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(19, "enableIOSViewClipToPaddingBox"); + markFlagAsAccessed(20, "enableIOSViewClipToPaddingBox"); flagValue = currentProvider_->enableIOSViewClipToPaddingBox(); enableIOSViewClipToPaddingBox_ = flagValue; @@ -398,7 +416,7 @@ bool ReactNativeFeatureFlagsAccessor::enableIntersectionObserverEventLoopIntegra // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(20, "enableIntersectionObserverEventLoopIntegration"); + markFlagAsAccessed(21, "enableIntersectionObserverEventLoopIntegration"); flagValue = currentProvider_->enableIntersectionObserverEventLoopIntegration(); enableIntersectionObserverEventLoopIntegration_ = flagValue; @@ -416,7 +434,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(21, "enableLayoutAnimationsOnAndroid"); + markFlagAsAccessed(22, "enableLayoutAnimationsOnAndroid"); flagValue = currentProvider_->enableLayoutAnimationsOnAndroid(); enableLayoutAnimationsOnAndroid_ = flagValue; @@ -434,7 +452,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(22, "enableLayoutAnimationsOnIOS"); + markFlagAsAccessed(23, "enableLayoutAnimationsOnIOS"); flagValue = currentProvider_->enableLayoutAnimationsOnIOS(); enableLayoutAnimationsOnIOS_ = flagValue; @@ -452,7 +470,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(23, "enableMainQueueCoordinatorOnIOS"); + markFlagAsAccessed(24, "enableMainQueueCoordinatorOnIOS"); flagValue = currentProvider_->enableMainQueueCoordinatorOnIOS(); enableMainQueueCoordinatorOnIOS_ = flagValue; @@ -470,7 +488,7 @@ bool ReactNativeFeatureFlagsAccessor::enableMainQueueModulesOnIOS() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(24, "enableMainQueueModulesOnIOS"); + markFlagAsAccessed(25, "enableMainQueueModulesOnIOS"); flagValue = currentProvider_->enableMainQueueModulesOnIOS(); enableMainQueueModulesOnIOS_ = flagValue; @@ -488,7 +506,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(25, "enableModuleArgumentNSNullConversionIOS"); + markFlagAsAccessed(26, "enableModuleArgumentNSNullConversionIOS"); flagValue = currentProvider_->enableModuleArgumentNSNullConversionIOS(); enableModuleArgumentNSNullConversionIOS_ = flagValue; @@ -506,7 +524,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(26, "enableNativeCSSParsing"); + markFlagAsAccessed(27, "enableNativeCSSParsing"); flagValue = currentProvider_->enableNativeCSSParsing(); enableNativeCSSParsing_ = flagValue; @@ -524,7 +542,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(27, "enableNetworkEventReporting"); + markFlagAsAccessed(28, "enableNetworkEventReporting"); flagValue = currentProvider_->enableNetworkEventReporting(); enableNetworkEventReporting_ = flagValue; @@ -542,7 +560,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNewBackgroundAndBorderDrawables() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(28, "enableNewBackgroundAndBorderDrawables"); + markFlagAsAccessed(29, "enableNewBackgroundAndBorderDrawables"); flagValue = currentProvider_->enableNewBackgroundAndBorderDrawables(); enableNewBackgroundAndBorderDrawables_ = flagValue; @@ -560,7 +578,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(29, "enablePreparedTextLayout"); + markFlagAsAccessed(30, "enablePreparedTextLayout"); flagValue = currentProvider_->enablePreparedTextLayout(); enablePreparedTextLayout_ = flagValue; @@ -578,7 +596,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(30, "enablePropsUpdateReconciliationAndroid"); + markFlagAsAccessed(31, "enablePropsUpdateReconciliationAndroid"); flagValue = currentProvider_->enablePropsUpdateReconciliationAndroid(); enablePropsUpdateReconciliationAndroid_ = flagValue; @@ -596,7 +614,7 @@ bool ReactNativeFeatureFlagsAccessor::enableResourceTimingAPI() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(31, "enableResourceTimingAPI"); + markFlagAsAccessed(32, "enableResourceTimingAPI"); flagValue = currentProvider_->enableResourceTimingAPI(); enableResourceTimingAPI_ = flagValue; @@ -614,7 +632,7 @@ bool ReactNativeFeatureFlagsAccessor::enableSynchronousStateUpdates() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(32, "enableSynchronousStateUpdates"); + markFlagAsAccessed(33, "enableSynchronousStateUpdates"); flagValue = currentProvider_->enableSynchronousStateUpdates(); enableSynchronousStateUpdates_ = flagValue; @@ -632,7 +650,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(33, "enableViewCulling"); + markFlagAsAccessed(34, "enableViewCulling"); flagValue = currentProvider_->enableViewCulling(); enableViewCulling_ = flagValue; @@ -650,7 +668,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(34, "enableViewRecycling"); + markFlagAsAccessed(35, "enableViewRecycling"); flagValue = currentProvider_->enableViewRecycling(); enableViewRecycling_ = flagValue; @@ -668,7 +686,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(35, "enableViewRecyclingForText"); + markFlagAsAccessed(36, "enableViewRecyclingForText"); flagValue = currentProvider_->enableViewRecyclingForText(); enableViewRecyclingForText_ = flagValue; @@ -686,7 +704,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(36, "enableViewRecyclingForView"); + markFlagAsAccessed(37, "enableViewRecyclingForView"); flagValue = currentProvider_->enableViewRecyclingForView(); enableViewRecyclingForView_ = flagValue; @@ -704,7 +722,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(37, "enableVirtualViewDebugFeatures"); + markFlagAsAccessed(38, "enableVirtualViewDebugFeatures"); flagValue = currentProvider_->enableVirtualViewDebugFeatures(); enableVirtualViewDebugFeatures_ = flagValue; @@ -722,7 +740,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(38, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); + markFlagAsAccessed(39, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); flagValue = currentProvider_->fixMappingOfEventPrioritiesBetweenFabricAndReact(); fixMappingOfEventPrioritiesBetweenFabricAndReact_ = flagValue; @@ -740,7 +758,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(39, "fuseboxEnabledRelease"); + markFlagAsAccessed(40, "fuseboxEnabledRelease"); flagValue = currentProvider_->fuseboxEnabledRelease(); fuseboxEnabledRelease_ = flagValue; @@ -758,7 +776,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(40, "fuseboxNetworkInspectionEnabled"); + markFlagAsAccessed(41, "fuseboxNetworkInspectionEnabled"); flagValue = currentProvider_->fuseboxNetworkInspectionEnabled(); fuseboxNetworkInspectionEnabled_ = flagValue; @@ -776,7 +794,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(41, "traceTurboModulePromiseRejectionsOnAndroid"); + markFlagAsAccessed(42, "traceTurboModulePromiseRejectionsOnAndroid"); flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid(); traceTurboModulePromiseRejectionsOnAndroid_ = flagValue; @@ -794,7 +812,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(42, "updateRuntimeShadowNodeReferencesOnCommit"); + markFlagAsAccessed(43, "updateRuntimeShadowNodeReferencesOnCommit"); flagValue = currentProvider_->updateRuntimeShadowNodeReferencesOnCommit(); updateRuntimeShadowNodeReferencesOnCommit_ = flagValue; @@ -812,7 +830,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(43, "useAlwaysAvailableJSErrorHandling"); + markFlagAsAccessed(44, "useAlwaysAvailableJSErrorHandling"); flagValue = currentProvider_->useAlwaysAvailableJSErrorHandling(); useAlwaysAvailableJSErrorHandling_ = flagValue; @@ -830,7 +848,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(44, "useFabricInterop"); + markFlagAsAccessed(45, "useFabricInterop"); flagValue = currentProvider_->useFabricInterop(); useFabricInterop_ = flagValue; @@ -848,7 +866,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(45, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(46, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -866,7 +884,7 @@ bool ReactNativeFeatureFlagsAccessor::useOptimizedEventBatchingOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(46, "useOptimizedEventBatchingOnAndroid"); + markFlagAsAccessed(47, "useOptimizedEventBatchingOnAndroid"); flagValue = currentProvider_->useOptimizedEventBatchingOnAndroid(); useOptimizedEventBatchingOnAndroid_ = flagValue; @@ -884,7 +902,7 @@ bool ReactNativeFeatureFlagsAccessor::useRawPropsJsiValue() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(47, "useRawPropsJsiValue"); + markFlagAsAccessed(48, "useRawPropsJsiValue"); flagValue = currentProvider_->useRawPropsJsiValue(); useRawPropsJsiValue_ = flagValue; @@ -902,7 +920,7 @@ bool ReactNativeFeatureFlagsAccessor::useShadowNodeStateOnClone() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(48, "useShadowNodeStateOnClone"); + markFlagAsAccessed(49, "useShadowNodeStateOnClone"); flagValue = currentProvider_->useShadowNodeStateOnClone(); useShadowNodeStateOnClone_ = flagValue; @@ -920,7 +938,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(49, "useTurboModuleInterop"); + markFlagAsAccessed(50, "useTurboModuleInterop"); flagValue = currentProvider_->useTurboModuleInterop(); useTurboModuleInterop_ = flagValue; @@ -938,7 +956,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(50, "useTurboModules"); + markFlagAsAccessed(51, "useTurboModules"); flagValue = currentProvider_->useTurboModules(); useTurboModules_ = flagValue; @@ -956,7 +974,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(51, "virtualViewPrerenderRatio"); + markFlagAsAccessed(52, "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 f778f2fbea8fc2..60cadd1ad77beb 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<<65d21b40786d625e15440e7aeb70e0ee>> + * @generated SignedSource<> */ /** @@ -35,6 +35,7 @@ class ReactNativeFeatureFlagsAccessor { bool commonTestFlag(); bool animatedShouldSignalBatch(); bool cxxNativeAnimatedEnabled(); + bool cxxNativeAnimatedRemoveJsSync(); bool disableMainQueueSyncDispatchIOS(); bool disableMountItemReorderingAndroid(); bool disableTextLayoutManagerCacheAndroid(); @@ -95,11 +96,12 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 52> accessedFeatureFlags_; + std::array, 53> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> animatedShouldSignalBatch_; std::atomic> cxxNativeAnimatedEnabled_; + std::atomic> cxxNativeAnimatedRemoveJsSync_; std::atomic> disableMainQueueSyncDispatchIOS_; std::atomic> disableMountItemReorderingAndroid_; std::atomic> disableTextLayoutManagerCacheAndroid_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index fac78898df38a5..7365564673f323 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<> */ /** @@ -39,6 +39,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } + bool cxxNativeAnimatedRemoveJsSync() override { + return false; + } + bool disableMainQueueSyncDispatchIOS() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDynamicProvider.h index da9ec0c47c207d..2b4b322a8577e2 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<<5e0fefd464f6f7f693eaad1b72441d1a>> + * @generated SignedSource<<0e532705f336a7e8fb21ae8056a17083>> */ /** @@ -72,6 +72,15 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef return ReactNativeFeatureFlagsDefaults::cxxNativeAnimatedEnabled(); } + bool cxxNativeAnimatedRemoveJsSync() override { + auto value = values_["cxxNativeAnimatedRemoveJsSync"]; + if (!value.isNull()) { + return value.getBool(); + } + + return ReactNativeFeatureFlagsDefaults::cxxNativeAnimatedRemoveJsSync(); + } + bool disableMainQueueSyncDispatchIOS() override { auto value = values_["disableMainQueueSyncDispatchIOS"]; if (!value.isNull()) { diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index a77964ae7198de..0795ed9ad52cf5 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<<2418719950b4918f5cc2324ef3ed7daa>> + * @generated SignedSource<<678646247ccb523a194255a7fabf45ba>> */ /** @@ -28,6 +28,7 @@ class ReactNativeFeatureFlagsProvider { virtual bool commonTestFlag() = 0; virtual bool animatedShouldSignalBatch() = 0; virtual bool cxxNativeAnimatedEnabled() = 0; + virtual bool cxxNativeAnimatedRemoveJsSync() = 0; virtual bool disableMainQueueSyncDispatchIOS() = 0; virtual bool disableMountItemReorderingAndroid() = 0; virtual bool disableTextLayoutManagerCacheAndroid() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index 73238972427fc1..70772afc96ef5c 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<<56704140bc822ee33a8686ad3e132b41>> + * @generated SignedSource<> */ /** @@ -59,6 +59,11 @@ bool NativeReactNativeFeatureFlags::cxxNativeAnimatedEnabled( return ReactNativeFeatureFlags::cxxNativeAnimatedEnabled(); } +bool NativeReactNativeFeatureFlags::cxxNativeAnimatedRemoveJsSync( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::cxxNativeAnimatedRemoveJsSync(); +} + bool NativeReactNativeFeatureFlags::disableMainQueueSyncDispatchIOS( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::disableMainQueueSyncDispatchIOS(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index 7d83504c041592..ccc7bd91aae7a0 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<<898d5acbbe56a09ea10e9423accd69fd>> + * @generated SignedSource<> */ /** @@ -42,6 +42,8 @@ class NativeReactNativeFeatureFlags bool cxxNativeAnimatedEnabled(jsi::Runtime& runtime); + bool cxxNativeAnimatedRemoveJsSync(jsi::Runtime& runtime); + bool disableMainQueueSyncDispatchIOS(jsi::Runtime& runtime); bool disableMountItemReorderingAndroid(jsi::Runtime& runtime); diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index ab046e7a06c47d..a22b019ba301aa 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -81,6 +81,16 @@ const definitions: FeatureFlagDefinitions = { }, ossReleaseStage: 'none', }, + cxxNativeAnimatedRemoveJsSync: { + defaultValue: false, + metadata: { + dateAdded: '2025-06-16', + description: 'Removes JS sync at end of native animation', + expectedReleaseValue: true, + purpose: 'experimentation', + }, + ossReleaseStage: 'none', + }, disableMainQueueSyncDispatchIOS: { defaultValue: false, metadata: { diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index 503e15278eb9ea..f260aab2dd86f5 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<> * @flow strict * @noformat */ @@ -53,6 +53,7 @@ export type ReactNativeFeatureFlags = $ReadOnly<{ commonTestFlagWithoutNativeImplementation: Getter, animatedShouldSignalBatch: Getter, cxxNativeAnimatedEnabled: Getter, + cxxNativeAnimatedRemoveJsSync: Getter, disableMainQueueSyncDispatchIOS: Getter, disableMountItemReorderingAndroid: Getter, disableTextLayoutManagerCacheAndroid: Getter, @@ -195,6 +196,10 @@ export const animatedShouldSignalBatch: Getter = createNativeFlagGetter * Use a C++ implementation of Native Animated instead of the platform implementation. */ export const cxxNativeAnimatedEnabled: Getter = createNativeFlagGetter('cxxNativeAnimatedEnabled', false); +/** + * Removes JS sync at end of native animation + */ +export const cxxNativeAnimatedRemoveJsSync: Getter = createNativeFlagGetter('cxxNativeAnimatedRemoveJsSync', false); /** * Disable sync dispatch on the main queue on iOS */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index 8b43844f509ae9..2e025a5c7983e4 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<> * @flow strict * @noformat */ @@ -28,6 +28,7 @@ export interface Spec extends TurboModule { +commonTestFlagWithoutNativeImplementation?: () => boolean; +animatedShouldSignalBatch?: () => boolean; +cxxNativeAnimatedEnabled?: () => boolean; + +cxxNativeAnimatedRemoveJsSync?: () => boolean; +disableMainQueueSyncDispatchIOS?: () => boolean; +disableMountItemReorderingAndroid?: () => boolean; +disableTextLayoutManagerCacheAndroid?: () => boolean; From 9b333d73a336145aa111bcd9f8dec97d79052472 Mon Sep 17 00:00:00 2001 From: Zeya Peng Date: Tue, 17 Jun 2025 06:28:04 -0700 Subject: [PATCH 2/2] Gate logic to remove js sync at end of native animation loop (#52068) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/52068 ## Changelog: [Internal] [Changed] - Gate logic to remove js sync at end of native animation loop because https://github.com/facebook/react-native/pull/51264 is causing regression in some cases, and was recently reverted again in https://github.com/facebook/react-native/pull/51933 . Using an extra feature flag to gate this potential optimization Reviewed By: lenaic Differential Revision: D76759441 --- .../Animated/__tests__/Animated-itest.js | 38 ++++++++++++------- .../Animated/animations/Animation.js | 12 +++++- .../animated/NativeAnimatedNodesManager.cpp | 5 ++- .../animated/createAnimatedPropsHook.js | 8 +++- 4 files changed, 46 insertions(+), 17 deletions(-) diff --git a/packages/react-native/Libraries/Animated/__tests__/Animated-itest.js b/packages/react-native/Libraries/Animated/__tests__/Animated-itest.js index 1b85110b909f38..bad2f94ecb5052 100644 --- a/packages/react-native/Libraries/Animated/__tests__/Animated-itest.js +++ b/packages/react-native/Libraries/Animated/__tests__/Animated-itest.js @@ -4,6 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * + * @fantom_flags cxxNativeAnimatedRemoveJsSync:* * @flow strict-local * @format */ @@ -16,6 +17,7 @@ import ensureInstance from '../../../src/private/__tests__/utilities/ensureInsta import * as Fantom from '@react-native/fantom'; import {createRef} from 'react'; import {Animated, View, useAnimatedValue} from 'react-native'; +import * as ReactNativeFeatureFlags from 'react-native/src/private/featureflags/ReactNativeFeatureFlags'; import ReactNativeElement from 'react-native/src/private/webapis/dom/nodes/ReactNativeElement'; test('moving box by 100 points', () => { @@ -73,11 +75,15 @@ test('moving box by 100 points', () => { Fantom.unstable_produceFramesForDuration(500); // Animation is completed now. C++ Animated will commit the final position to the shadow tree. - expect(viewElement.getBoundingClientRect().x).toBe(100); + if (ReactNativeFeatureFlags.cxxNativeAnimatedRemoveJsSync()) { + expect(viewElement.getBoundingClientRect().x).toBe(100); + // TODO(T223344928): this shouldn't be neccessary + Fantom.runWorkLoop(); + } else { + expect(viewElement.getBoundingClientRect().x).toBe(0); + Fantom.runWorkLoop(); // Animated still schedules a React state update for synchronisation to shadow tree + } - // TODO: this shouldn't be needed but C++ Animated still schedules a React state update - // for synchronisation, even though it doesn't need to. - Fantom.runWorkLoop(); expect(viewElement.getBoundingClientRect().x).toBe(100); }); @@ -189,7 +195,7 @@ test('animated opacity', () => { 0, ); - // TODO: this shouldn't be neccessary but C++ Animated still schedules a React state update. + // TODO(T223344928): this shouldn't be neccessary with cxxNativeAnimatedRemoveJsSync:true Fantom.runWorkLoop(); expect(root.getRenderedOutput({props: ['opacity']}).toJSX()).toEqual( @@ -263,12 +269,18 @@ test('moving box by 50 points with offset 10', () => { .translateX, ).toBeCloseTo(60, 0.001); - expect(root.getRenderedOutput({props: ['transform']}).toJSX()).toEqual( - , - ); - - // TODO: this shouldn't be neccessary but C++ Animated still schedules a React state update. - Fantom.runWorkLoop(); + if (ReactNativeFeatureFlags.cxxNativeAnimatedRemoveJsSync()) { + expect(root.getRenderedOutput({props: ['transform']}).toJSX()).toEqual( + , + ); + // TODO(T223344928): this shouldn't be neccessary + Fantom.runWorkLoop(); + } else { + expect(root.getRenderedOutput({props: ['transform']}).toJSX()).toEqual( + , + ); + Fantom.runWorkLoop(); // Animated still schedules a React state update for synchronisation to shadow tree + } expect(root.getRenderedOutput({props: ['transform']}).toJSX()).toEqual( , // // must include offset. @@ -361,7 +373,7 @@ describe('Value.flattenOffset', () => { expect(transform.translateY).toBeCloseTo(40, 0.001); - // TODO: this shouldn't be neccessary. + // TODO(T223344928): this shouldn't be neccessary with cxxNativeAnimatedRemoveJsSync:true Fantom.runWorkLoop(); }); }); @@ -460,7 +472,7 @@ describe('Value.extractOffset', () => { // Previously we set offset to 35. The final value is 35. expect(transform.translateY).toBeCloseTo(35, 0.001); - // TODO: this shouldn't be neccessary. + // TODO(T223344928): this shouldn't be neccessary with cxxNativeAnimatedRemoveJsSync:true Fantom.runWorkLoop(); }); }); diff --git a/packages/react-native/Libraries/Animated/animations/Animation.js b/packages/react-native/Libraries/Animated/animations/Animation.js index 6587e9189fd872..b466dfbf6afc59 100644 --- a/packages/react-native/Libraries/Animated/animations/Animation.js +++ b/packages/react-native/Libraries/Animated/animations/Animation.js @@ -13,6 +13,7 @@ import type AnimatedNode from '../nodes/AnimatedNode'; import type AnimatedValue from '../nodes/AnimatedValue'; import NativeAnimatedHelper from '../../../src/private/animated/NativeAnimatedHelper'; +import * as ReactNativeFeatureFlags from '../../../src/private/featureflags/ReactNativeFeatureFlags'; import AnimatedProps from '../nodes/AnimatedProps'; export type EndResult = { @@ -149,8 +150,15 @@ export default class Animation { if (value != null) { animatedValue.__onAnimatedValueUpdateReceived(value, offset); - if (this.__isLooping === true) { - return; + if ( + !( + ReactNativeFeatureFlags.cxxNativeAnimatedEnabled() && + ReactNativeFeatureFlags.cxxNativeAnimatedRemoveJsSync() + ) + ) { + if (this.__isLooping === true) { + return; + } } // Once the JS side node is synced with the updated values, trigger an diff --git a/packages/react-native/ReactCxxPlatform/react/renderer/animated/NativeAnimatedNodesManager.cpp b/packages/react-native/ReactCxxPlatform/react/renderer/animated/NativeAnimatedNodesManager.cpp index 1a457fc07e743b..2ee9959b15b901 100644 --- a/packages/react-native/ReactCxxPlatform/react/renderer/animated/NativeAnimatedNodesManager.cpp +++ b/packages/react-native/ReactCxxPlatform/react/renderer/animated/NativeAnimatedNodesManager.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -658,7 +659,9 @@ bool NativeAnimatedNodesManager::onAnimationFrame(double timestamp) { if (driver->getIsComplete()) { hasFinishedAnimations = true; - finishedAnimationValueNodes.insert(driver->getAnimatedValueTag()); + if (ReactNativeFeatureFlags::cxxNativeAnimatedRemoveJsSync()) { + finishedAnimationValueNodes.insert(driver->getAnimatedValueTag()); + } } } diff --git a/packages/react-native/src/private/animated/createAnimatedPropsHook.js b/packages/react-native/src/private/animated/createAnimatedPropsHook.js index 444ec9eb8e9a65..90772e80c33c07 100644 --- a/packages/react-native/src/private/animated/createAnimatedPropsHook.js +++ b/packages/react-native/src/private/animated/createAnimatedPropsHook.js @@ -132,7 +132,13 @@ export default function createAnimatedPropsHook( if (node.__isNative) { // Check 2: this is an animation driven by native. // In native driven animations, this callback is only called once the animation completes. - if (isFabricNode) { + if ( + isFabricNode && + !( + ReactNativeFeatureFlags.cxxNativeAnimatedEnabled() && + ReactNativeFeatureFlags.cxxNativeAnimatedRemoveJsSync() + ) + ) { // Call `scheduleUpdate` to synchronise Fiber and Shadow tree. // Must not be called in Paper. scheduleUpdate();