diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm index a9748d0df4fbea..52618dd5dc9b09 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.mm @@ -12,6 +12,7 @@ #import #import +#import #import #import #import @@ -502,7 +503,7 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView }); } } else { - if (!_isUserTriggeredScrolling || CoreFeatures::enableGranularScrollViewStateUpdatesIOS) { + if (!_isUserTriggeredScrolling || ReactNativeFeatureFlags::enableGranularScrollViewStateUpdatesIOS()) { [self _updateStateWithContentOffset]; } diff --git a/packages/react-native/React/Fabric/RCTSurfacePresenter.mm b/packages/react-native/React/Fabric/RCTSurfacePresenter.mm index 77b36af40c2d9e..a60fa6ac8b047d 100644 --- a/packages/react-native/React/Fabric/RCTSurfacePresenter.mm +++ b/packages/react-native/React/Fabric/RCTSurfacePresenter.mm @@ -34,7 +34,6 @@ #import #import #import -#import #import #import "PlatformRunLoopObserver.h" @@ -227,12 +226,6 @@ - (BOOL)resume - (RCTScheduler *)_createScheduler { - auto reactNativeConfig = _contextContainer->at>("ReactNativeConfig"); - - if (reactNativeConfig && reactNativeConfig->getBool("react_fabric:enable_granular_scroll_view_state_updates_ios")) { - CoreFeatures::enableGranularScrollViewStateUpdatesIOS = true; - } - auto componentRegistryFactory = [factory = wrapManagedObject(_mountingManager.componentViewRegistry.componentViewFactory)]( const EventDispatcher::Weak &eventDispatcher, const ContextContainer::Shared &contextContainer) { 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 08621021da133c..db23d460433841 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<<5c7964726373a75fab5d6473bf7d6390>> + * @generated SignedSource<> */ /** @@ -106,6 +106,12 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun enableFabricRendererExclusively(): Boolean = accessor.enableFabricRendererExclusively() + /** + * When enabled, RCTScrollViewComponentView will trigger ShadowTree state updates for all changes in scroll position. + */ + @JvmStatic + public fun enableGranularScrollViewStateUpdatesIOS(): Boolean = accessor.enableGranularScrollViewStateUpdatesIOS() + /** * When enabled, the renderer would only fail commits when they propagate state and the last commit that updated state changed before committing. */ 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 69dbcef478af6c..c486d52f56708d 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<> + * @generated SignedSource<<3792bade51d906046c772bda42edaa09>> */ /** @@ -33,6 +33,7 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso private var enableEagerRootViewAttachmentCache: Boolean? = null private var enableFabricLogsCache: Boolean? = null private var enableFabricRendererExclusivelyCache: Boolean? = null + private var enableGranularScrollViewStateUpdatesIOSCache: Boolean? = null private var enableGranularShadowTreeStateReconciliationCache: Boolean? = null private var enableLongTaskAPICache: Boolean? = null private var enableMicrotasksCache: Boolean? = null @@ -180,6 +181,15 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso return cached } + override fun enableGranularScrollViewStateUpdatesIOS(): Boolean { + var cached = enableGranularScrollViewStateUpdatesIOSCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.enableGranularScrollViewStateUpdatesIOS() + enableGranularScrollViewStateUpdatesIOSCache = cached + } + return cached + } + override fun enableGranularShadowTreeStateReconciliation(): Boolean { var cached = enableGranularShadowTreeStateReconciliationCache 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 c2654c4c9f862e..144fa497112997 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<<3837dde4571d8da810192d1a6ed9931f>> + * @generated SignedSource<<77a1724d3b923becb1c19ec99dd0fb14>> */ /** @@ -54,6 +54,8 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun enableFabricRendererExclusively(): Boolean + @DoNotStrip @JvmStatic public external fun enableGranularScrollViewStateUpdatesIOS(): Boolean + @DoNotStrip @JvmStatic public external fun enableGranularShadowTreeStateReconciliation(): Boolean @DoNotStrip @JvmStatic public external fun enableLongTaskAPI(): 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 cf79b68d24f1cd..b843023096dd51 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<> + * @generated SignedSource<> */ /** @@ -49,6 +49,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun enableFabricRendererExclusively(): Boolean = false + override fun enableGranularScrollViewStateUpdatesIOS(): Boolean = false + override fun enableGranularShadowTreeStateReconciliation(): Boolean = false override fun enableLongTaskAPI(): 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 fb212c71e98037..e55b81749d8765 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<> */ /** @@ -37,6 +37,7 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces private var enableEagerRootViewAttachmentCache: Boolean? = null private var enableFabricLogsCache: Boolean? = null private var enableFabricRendererExclusivelyCache: Boolean? = null + private var enableGranularScrollViewStateUpdatesIOSCache: Boolean? = null private var enableGranularShadowTreeStateReconciliationCache: Boolean? = null private var enableLongTaskAPICache: Boolean? = null private var enableMicrotasksCache: Boolean? = null @@ -197,6 +198,16 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun enableGranularScrollViewStateUpdatesIOS(): Boolean { + var cached = enableGranularScrollViewStateUpdatesIOSCache + if (cached == null) { + cached = currentProvider.enableGranularScrollViewStateUpdatesIOS() + accessedFeatureFlags.add("enableGranularScrollViewStateUpdatesIOS") + enableGranularScrollViewStateUpdatesIOSCache = cached + } + return cached + } + override fun enableGranularShadowTreeStateReconciliation(): Boolean { var cached = enableGranularShadowTreeStateReconciliationCache 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 8a62b1d9f68ceb..0148b116ef506c 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<> */ /** @@ -49,6 +49,8 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun enableFabricRendererExclusively(): Boolean + @DoNotStrip public fun enableGranularScrollViewStateUpdatesIOS(): Boolean + @DoNotStrip public fun enableGranularShadowTreeStateReconciliation(): Boolean @DoNotStrip public fun enableLongTaskAPI(): 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 4e7b7aa2739065..ae64e1139bb81c 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<<1fa4fea1bd8055330de591d6ee315b12>> + * @generated SignedSource<> */ /** @@ -117,6 +117,12 @@ class ReactNativeFeatureFlagsProviderHolder return method(javaProvider_); } + bool enableGranularScrollViewStateUpdatesIOS() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableGranularScrollViewStateUpdatesIOS"); + return method(javaProvider_); + } + bool enableGranularShadowTreeStateReconciliation() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableGranularShadowTreeStateReconciliation"); @@ -360,6 +366,11 @@ bool JReactNativeFeatureFlagsCxxInterop::enableFabricRendererExclusively( return ReactNativeFeatureFlags::enableFabricRendererExclusively(); } +bool JReactNativeFeatureFlagsCxxInterop::enableGranularScrollViewStateUpdatesIOS( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::enableGranularScrollViewStateUpdatesIOS(); +} + bool JReactNativeFeatureFlagsCxxInterop::enableGranularShadowTreeStateReconciliation( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::enableGranularShadowTreeStateReconciliation(); @@ -561,6 +572,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "enableFabricRendererExclusively", JReactNativeFeatureFlagsCxxInterop::enableFabricRendererExclusively), + makeNativeMethod( + "enableGranularScrollViewStateUpdatesIOS", + JReactNativeFeatureFlagsCxxInterop::enableGranularScrollViewStateUpdatesIOS), makeNativeMethod( "enableGranularShadowTreeStateReconciliation", JReactNativeFeatureFlagsCxxInterop::enableGranularShadowTreeStateReconciliation), 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 50cc90ea715104..2732fe1f454b5e 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<> + * @generated SignedSource<<1d277bf5b52d0c6b0f692b135122313d>> */ /** @@ -69,6 +69,9 @@ class JReactNativeFeatureFlagsCxxInterop static bool enableFabricRendererExclusively( facebook::jni::alias_ref); + static bool enableGranularScrollViewStateUpdatesIOS( + facebook::jni::alias_ref); + static bool enableGranularShadowTreeStateReconciliation( 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 3ba6ea93196b5c..b9be43038d9a50 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<> + * @generated SignedSource<<2b872353f06665054445ac161319c5ee>> */ /** @@ -73,6 +73,10 @@ bool ReactNativeFeatureFlags::enableFabricRendererExclusively() { return getAccessor().enableFabricRendererExclusively(); } +bool ReactNativeFeatureFlags::enableGranularScrollViewStateUpdatesIOS() { + return getAccessor().enableGranularScrollViewStateUpdatesIOS(); +} + bool ReactNativeFeatureFlags::enableGranularShadowTreeStateReconciliation() { return getAccessor().enableGranularShadowTreeStateReconciliation(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index f2fdfa713368cb..be4ea11eddfb21 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<> + * @generated SignedSource<> */ /** @@ -102,6 +102,11 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool enableFabricRendererExclusively(); + /** + * When enabled, RCTScrollViewComponentView will trigger ShadowTree state updates for all changes in scroll position. + */ + RN_EXPORT static bool enableGranularScrollViewStateUpdatesIOS(); + /** * When enabled, the renderer would only fail commits when they propagate state and the last commit that updated state changed before committing. */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index de05a063cbf3ef..f0f0db7ec7b1f0 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<<259fdc29e31d60640467883cb486dd95>> + * @generated SignedSource<<8f7e35f28d857140fcb6a7d9bc995598>> */ /** @@ -263,6 +263,24 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricRendererExclusively() { return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::enableGranularScrollViewStateUpdatesIOS() { + auto flagValue = enableGranularScrollViewStateUpdatesIOS_.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(13, "enableGranularScrollViewStateUpdatesIOS"); + + flagValue = currentProvider_->enableGranularScrollViewStateUpdatesIOS(); + enableGranularScrollViewStateUpdatesIOS_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::enableGranularShadowTreeStateReconciliation() { auto flagValue = enableGranularShadowTreeStateReconciliation_.load(); @@ -272,7 +290,7 @@ bool ReactNativeFeatureFlagsAccessor::enableGranularShadowTreeStateReconciliatio // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(13, "enableGranularShadowTreeStateReconciliation"); + markFlagAsAccessed(14, "enableGranularShadowTreeStateReconciliation"); flagValue = currentProvider_->enableGranularShadowTreeStateReconciliation(); enableGranularShadowTreeStateReconciliation_ = flagValue; @@ -290,7 +308,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLongTaskAPI() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(14, "enableLongTaskAPI"); + markFlagAsAccessed(15, "enableLongTaskAPI"); flagValue = currentProvider_->enableLongTaskAPI(); enableLongTaskAPI_ = flagValue; @@ -308,7 +326,7 @@ bool ReactNativeFeatureFlagsAccessor::enableMicrotasks() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(15, "enableMicrotasks"); + markFlagAsAccessed(16, "enableMicrotasks"); flagValue = currentProvider_->enableMicrotasks(); enableMicrotasks_ = flagValue; @@ -326,7 +344,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(16, "enablePropsUpdateReconciliationAndroid"); + markFlagAsAccessed(17, "enablePropsUpdateReconciliationAndroid"); flagValue = currentProvider_->enablePropsUpdateReconciliationAndroid(); enablePropsUpdateReconciliationAndroid_ = flagValue; @@ -344,7 +362,7 @@ bool ReactNativeFeatureFlagsAccessor::enableReportEventPaintTime() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(17, "enableReportEventPaintTime"); + markFlagAsAccessed(18, "enableReportEventPaintTime"); flagValue = currentProvider_->enableReportEventPaintTime(); enableReportEventPaintTime_ = flagValue; @@ -362,7 +380,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(18, "enableSynchronousStateUpdates"); + markFlagAsAccessed(19, "enableSynchronousStateUpdates"); flagValue = currentProvider_->enableSynchronousStateUpdates(); enableSynchronousStateUpdates_ = flagValue; @@ -380,7 +398,7 @@ bool ReactNativeFeatureFlagsAccessor::enableUIConsistency() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(19, "enableUIConsistency"); + markFlagAsAccessed(20, "enableUIConsistency"); flagValue = currentProvider_->enableUIConsistency(); enableUIConsistency_ = flagValue; @@ -398,7 +416,7 @@ bool ReactNativeFeatureFlagsAccessor::excludeYogaFromRawProps() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(20, "excludeYogaFromRawProps"); + markFlagAsAccessed(21, "excludeYogaFromRawProps"); flagValue = currentProvider_->excludeYogaFromRawProps(); excludeYogaFromRawProps_ = flagValue; @@ -416,7 +434,7 @@ bool ReactNativeFeatureFlagsAccessor::fetchImagesInViewPreallocation() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(21, "fetchImagesInViewPreallocation"); + markFlagAsAccessed(22, "fetchImagesInViewPreallocation"); flagValue = currentProvider_->fetchImagesInViewPreallocation(); fetchImagesInViewPreallocation_ = flagValue; @@ -434,7 +452,7 @@ bool ReactNativeFeatureFlagsAccessor::fixIncorrectScrollViewStateUpdateOnAndroid // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(22, "fixIncorrectScrollViewStateUpdateOnAndroid"); + markFlagAsAccessed(23, "fixIncorrectScrollViewStateUpdateOnAndroid"); flagValue = currentProvider_->fixIncorrectScrollViewStateUpdateOnAndroid(); fixIncorrectScrollViewStateUpdateOnAndroid_ = flagValue; @@ -452,7 +470,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(23, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); + markFlagAsAccessed(24, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); flagValue = currentProvider_->fixMappingOfEventPrioritiesBetweenFabricAndReact(); fixMappingOfEventPrioritiesBetweenFabricAndReact_ = flagValue; @@ -470,7 +488,7 @@ bool ReactNativeFeatureFlagsAccessor::fixMissedFabricStateUpdatesOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(24, "fixMissedFabricStateUpdatesOnAndroid"); + markFlagAsAccessed(25, "fixMissedFabricStateUpdatesOnAndroid"); flagValue = currentProvider_->fixMissedFabricStateUpdatesOnAndroid(); fixMissedFabricStateUpdatesOnAndroid_ = flagValue; @@ -488,7 +506,7 @@ bool ReactNativeFeatureFlagsAccessor::forceBatchingMountItemsOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(25, "forceBatchingMountItemsOnAndroid"); + markFlagAsAccessed(26, "forceBatchingMountItemsOnAndroid"); flagValue = currentProvider_->forceBatchingMountItemsOnAndroid(); forceBatchingMountItemsOnAndroid_ = flagValue; @@ -506,7 +524,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxEnabledDebug() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(26, "fuseboxEnabledDebug"); + markFlagAsAccessed(27, "fuseboxEnabledDebug"); flagValue = currentProvider_->fuseboxEnabledDebug(); fuseboxEnabledDebug_ = flagValue; @@ -524,7 +542,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(27, "fuseboxEnabledRelease"); + markFlagAsAccessed(28, "fuseboxEnabledRelease"); flagValue = currentProvider_->fuseboxEnabledRelease(); fuseboxEnabledRelease_ = flagValue; @@ -542,7 +560,7 @@ bool ReactNativeFeatureFlagsAccessor::initEagerTurboModulesOnNativeModulesQueueA // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(28, "initEagerTurboModulesOnNativeModulesQueueAndroid"); + markFlagAsAccessed(29, "initEagerTurboModulesOnNativeModulesQueueAndroid"); flagValue = currentProvider_->initEagerTurboModulesOnNativeModulesQueueAndroid(); initEagerTurboModulesOnNativeModulesQueueAndroid_ = flagValue; @@ -560,7 +578,7 @@ bool ReactNativeFeatureFlagsAccessor::lazyAnimationCallbacks() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(29, "lazyAnimationCallbacks"); + markFlagAsAccessed(30, "lazyAnimationCallbacks"); flagValue = currentProvider_->lazyAnimationCallbacks(); lazyAnimationCallbacks_ = flagValue; @@ -578,7 +596,7 @@ bool ReactNativeFeatureFlagsAccessor::loadVectorDrawablesOnImages() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(30, "loadVectorDrawablesOnImages"); + markFlagAsAccessed(31, "loadVectorDrawablesOnImages"); flagValue = currentProvider_->loadVectorDrawablesOnImages(); loadVectorDrawablesOnImages_ = flagValue; @@ -596,7 +614,7 @@ bool ReactNativeFeatureFlagsAccessor::setAndroidLayoutDirection() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(31, "setAndroidLayoutDirection"); + markFlagAsAccessed(32, "setAndroidLayoutDirection"); flagValue = currentProvider_->setAndroidLayoutDirection(); setAndroidLayoutDirection_ = flagValue; @@ -614,7 +632,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(32, "traceTurboModulePromiseRejectionsOnAndroid"); + markFlagAsAccessed(33, "traceTurboModulePromiseRejectionsOnAndroid"); flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid(); traceTurboModulePromiseRejectionsOnAndroid_ = flagValue; @@ -632,7 +650,7 @@ bool ReactNativeFeatureFlagsAccessor::unstable_enableTurboModuleSyncVoidMethods( // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(33, "unstable_enableTurboModuleSyncVoidMethods"); + markFlagAsAccessed(34, "unstable_enableTurboModuleSyncVoidMethods"); flagValue = currentProvider_->unstable_enableTurboModuleSyncVoidMethods(); unstable_enableTurboModuleSyncVoidMethods_ = flagValue; @@ -650,7 +668,7 @@ bool ReactNativeFeatureFlagsAccessor::useImmediateExecutorInAndroidBridgeless() // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(34, "useImmediateExecutorInAndroidBridgeless"); + markFlagAsAccessed(35, "useImmediateExecutorInAndroidBridgeless"); flagValue = currentProvider_->useImmediateExecutorInAndroidBridgeless(); useImmediateExecutorInAndroidBridgeless_ = flagValue; @@ -668,7 +686,7 @@ bool ReactNativeFeatureFlagsAccessor::useModernRuntimeScheduler() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(35, "useModernRuntimeScheduler"); + markFlagAsAccessed(36, "useModernRuntimeScheduler"); flagValue = currentProvider_->useModernRuntimeScheduler(); useModernRuntimeScheduler_ = flagValue; @@ -686,7 +704,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(36, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(37, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -704,7 +722,7 @@ bool ReactNativeFeatureFlagsAccessor::useNewReactImageViewBackgroundDrawing() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(37, "useNewReactImageViewBackgroundDrawing"); + markFlagAsAccessed(38, "useNewReactImageViewBackgroundDrawing"); flagValue = currentProvider_->useNewReactImageViewBackgroundDrawing(); useNewReactImageViewBackgroundDrawing_ = flagValue; @@ -722,7 +740,7 @@ bool ReactNativeFeatureFlagsAccessor::useOptimisedViewPreallocationOnAndroid() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(38, "useOptimisedViewPreallocationOnAndroid"); + markFlagAsAccessed(39, "useOptimisedViewPreallocationOnAndroid"); flagValue = currentProvider_->useOptimisedViewPreallocationOnAndroid(); useOptimisedViewPreallocationOnAndroid_ = flagValue; @@ -740,7 +758,7 @@ bool ReactNativeFeatureFlagsAccessor::useRuntimeShadowNodeReferenceUpdate() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(39, "useRuntimeShadowNodeReferenceUpdate"); + markFlagAsAccessed(40, "useRuntimeShadowNodeReferenceUpdate"); flagValue = currentProvider_->useRuntimeShadowNodeReferenceUpdate(); useRuntimeShadowNodeReferenceUpdate_ = flagValue; @@ -758,7 +776,7 @@ bool ReactNativeFeatureFlagsAccessor::useRuntimeShadowNodeReferenceUpdateOnLayou // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(40, "useRuntimeShadowNodeReferenceUpdateOnLayout"); + markFlagAsAccessed(41, "useRuntimeShadowNodeReferenceUpdateOnLayout"); flagValue = currentProvider_->useRuntimeShadowNodeReferenceUpdateOnLayout(); useRuntimeShadowNodeReferenceUpdateOnLayout_ = flagValue; @@ -776,7 +794,7 @@ bool ReactNativeFeatureFlagsAccessor::useStateAlignmentMechanism() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(41, "useStateAlignmentMechanism"); + markFlagAsAccessed(42, "useStateAlignmentMechanism"); flagValue = currentProvider_->useStateAlignmentMechanism(); useStateAlignmentMechanism_ = flagValue; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index 0982aebf21bc8f..5e4853e0ee1142 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<> + * @generated SignedSource<> */ /** @@ -44,6 +44,7 @@ class ReactNativeFeatureFlagsAccessor { bool enableEagerRootViewAttachment(); bool enableFabricLogs(); bool enableFabricRendererExclusively(); + bool enableGranularScrollViewStateUpdatesIOS(); bool enableGranularShadowTreeStateReconciliation(); bool enableLongTaskAPI(); bool enableMicrotasks(); @@ -83,7 +84,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 42> accessedFeatureFlags_; + std::array, 43> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> allowCollapsableChildren_; @@ -98,6 +99,7 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> enableEagerRootViewAttachment_; std::atomic> enableFabricLogs_; std::atomic> enableFabricRendererExclusively_; + std::atomic> enableGranularScrollViewStateUpdatesIOS_; std::atomic> enableGranularShadowTreeStateReconciliation_; std::atomic> enableLongTaskAPI_; std::atomic> enableMicrotasks_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index 42fa1542254787..f5ca479c9b9fc9 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<> */ /** @@ -79,6 +79,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } + bool enableGranularScrollViewStateUpdatesIOS() override { + return false; + } + bool enableGranularShadowTreeStateReconciliation() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index 560c9a1d882367..4be8c5117770c6 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<<520c8320673734ee4d86e245e5c40bda>> + * @generated SignedSource<> */ /** @@ -38,6 +38,7 @@ class ReactNativeFeatureFlagsProvider { virtual bool enableEagerRootViewAttachment() = 0; virtual bool enableFabricLogs() = 0; virtual bool enableFabricRendererExclusively() = 0; + virtual bool enableGranularScrollViewStateUpdatesIOS() = 0; virtual bool enableGranularShadowTreeStateReconciliation() = 0; virtual bool enableLongTaskAPI() = 0; virtual bool enableMicrotasks() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index 39e60ed3fb9cf6..5ae2849ac40c25 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<<17dd88e6e7b2bf10ebf11e27cef88b08>> + * @generated SignedSource<<51ab906a53326da7b1f08428631f884f>> */ /** @@ -102,6 +102,11 @@ bool NativeReactNativeFeatureFlags::enableFabricRendererExclusively( return ReactNativeFeatureFlags::enableFabricRendererExclusively(); } +bool NativeReactNativeFeatureFlags::enableGranularScrollViewStateUpdatesIOS( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::enableGranularScrollViewStateUpdatesIOS(); +} + bool NativeReactNativeFeatureFlags::enableGranularShadowTreeStateReconciliation( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::enableGranularShadowTreeStateReconciliation(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index 4c08a9528aa44b..a47594ace44fee 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<> + * @generated SignedSource<<099095e81c5e38dc4a8fe71e4566b5e4>> */ /** @@ -61,6 +61,8 @@ class NativeReactNativeFeatureFlags bool enableFabricRendererExclusively(jsi::Runtime& runtime); + bool enableGranularScrollViewStateUpdatesIOS(jsi::Runtime& runtime); + bool enableGranularShadowTreeStateReconciliation(jsi::Runtime& runtime); bool enableLongTaskAPI(jsi::Runtime& runtime); diff --git a/packages/react-native/ReactCommon/react/utils/CoreFeatures.cpp b/packages/react-native/ReactCommon/react/utils/CoreFeatures.cpp index e6c1a0dec084de..d0b3349ffce8d1 100644 --- a/packages/react-native/ReactCommon/react/utils/CoreFeatures.cpp +++ b/packages/react-native/ReactCommon/react/utils/CoreFeatures.cpp @@ -7,8 +7,4 @@ #include "CoreFeatures.h" -namespace facebook::react { - -bool CoreFeatures::enableGranularScrollViewStateUpdatesIOS = false; - -} // namespace facebook::react +namespace facebook::react {} // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/utils/CoreFeatures.h b/packages/react-native/ReactCommon/react/utils/CoreFeatures.h index 54cc42b038c5eb..c4ab1fb5253b76 100644 --- a/packages/react-native/ReactCommon/react/utils/CoreFeatures.h +++ b/packages/react-native/ReactCommon/react/utils/CoreFeatures.h @@ -16,9 +16,6 @@ namespace facebook::react { */ class CoreFeatures { public: - // When enabled, RCTScrollViewComponentView will trigger ShadowTree state - // updates for all changes in scroll position. - static bool enableGranularScrollViewStateUpdatesIOS; }; } // namespace facebook::react diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index b6d9ead2dd0d70..f21cbcd3cfd31d 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -97,6 +97,11 @@ const definitions: FeatureFlagDefinitions = { description: 'When the app is completely migrated to Fabric, set this flag to true to disable parts of Paper infrastructure that are not needed anymore but consume memory and CPU. Specifically, UIViewOperationQueue and EventDispatcherImpl will no longer work as they will not subscribe to ReactChoreographer for updates.', }, + enableGranularScrollViewStateUpdatesIOS: { + defaultValue: false, + description: + 'When enabled, RCTScrollViewComponentView will trigger ShadowTree state updates for all changes in scroll position.', + }, enableGranularShadowTreeStateReconciliation: { defaultValue: false, description: diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index 97d6efbfb75a96..258a41af401a60 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<<75740b5411de1de36b9c026c5dc3bf1d>> * @flow strict-local */ @@ -56,6 +56,7 @@ export type ReactNativeFeatureFlags = { enableEagerRootViewAttachment: Getter, enableFabricLogs: Getter, enableFabricRendererExclusively: Getter, + enableGranularScrollViewStateUpdatesIOS: Getter, enableGranularShadowTreeStateReconciliation: Getter, enableLongTaskAPI: Getter, enableMicrotasks: Getter, @@ -194,6 +195,10 @@ export const enableFabricLogs: Getter = createNativeFlagGetter('enableF * When the app is completely migrated to Fabric, set this flag to true to disable parts of Paper infrastructure that are not needed anymore but consume memory and CPU. Specifically, UIViewOperationQueue and EventDispatcherImpl will no longer work as they will not subscribe to ReactChoreographer for updates. */ export const enableFabricRendererExclusively: Getter = createNativeFlagGetter('enableFabricRendererExclusively', false); +/** + * When enabled, RCTScrollViewComponentView will trigger ShadowTree state updates for all changes in scroll position. + */ +export const enableGranularScrollViewStateUpdatesIOS: Getter = createNativeFlagGetter('enableGranularScrollViewStateUpdatesIOS', false); /** * When enabled, the renderer would only fail commits when they propagate state and the last commit that updated state changed before committing. */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index 46bbdff92dfe80..455a2b45b72530 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-local */ @@ -36,6 +36,7 @@ export interface Spec extends TurboModule { +enableEagerRootViewAttachment?: () => boolean; +enableFabricLogs?: () => boolean; +enableFabricRendererExclusively?: () => boolean; + +enableGranularScrollViewStateUpdatesIOS?: () => boolean; +enableGranularShadowTreeStateReconciliation?: () => boolean; +enableLongTaskAPI?: () => boolean; +enableMicrotasks?: () => boolean;