diff --git a/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm b/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm index 39a32efe34f..5deab25265a 100644 --- a/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm +++ b/packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm @@ -307,18 +307,6 @@ class RCTAppDelegateBridgelessFeatureFlags : public facebook::react::ReactNativeFeatureFlagsDefaults { public: - bool useModernRuntimeScheduler() override - { - return true; - } - bool enableMicrotasks() override - { - return true; - } - bool batchRenderingUpdatesInEventLoop() override - { - return true; - } bool enableBridgelessArchitecture() override { return true; diff --git a/packages/react-native/Libraries/Core/setUpTimers.js b/packages/react-native/Libraries/Core/setUpTimers.js index 43481c931cd..486ff03646c 100644 --- a/packages/react-native/Libraries/Core/setUpTimers.js +++ b/packages/react-native/Libraries/Core/setUpTimers.js @@ -21,6 +21,25 @@ if (__DEV__) { } } +const isEventLoopEnabled = (() => { + if (NativeReactNativeFeatureFlags == null) { + return false; + } + + if (NativeReactNativeFeatureFlags.disableEventLoopOnBridgeless == null) { + // Flags not unified yet + return ( + ReactNativeFeatureFlags.useModernRuntimeScheduler() && + ReactNativeFeatureFlags.enableMicrotasks() + ); + } else { + return ( + ReactNativeFeatureFlags.enableBridgelessArchitecture() && + !ReactNativeFeatureFlags.disableEventLoopOnBridgeless() + ); + } +})(); + // In bridgeless mode, timers are host functions installed from cpp. if (global.RN$Bridgeless !== true) { /** @@ -48,12 +67,7 @@ if (global.RN$Bridgeless !== true) { defineLazyTimer('cancelAnimationFrame'); defineLazyTimer('requestIdleCallback'); defineLazyTimer('cancelIdleCallback'); -} else if ( - // TODO remove this condition when bridgeless == modern scheduler everywhere. - NativeReactNativeFeatureFlags != null && - // eslint-disable-next-line react-hooks/rules-of-hooks -- false positive due to `use` prefix - ReactNativeFeatureFlags.useModernRuntimeScheduler() -) { +} else if (isEventLoopEnabled) { polyfillGlobal( 'requestIdleCallback', () => @@ -72,10 +86,7 @@ if (global.RN$Bridgeless !== true) { // We need to check if the native module is available before accessing the // feature flag, because otherwise the API would throw an error in the legacy // architecture in OSS, where the native module isn't available. -if ( - NativeReactNativeFeatureFlags != null && - ReactNativeFeatureFlags.enableMicrotasks() -) { +if (isEventLoopEnabled) { // This is the flag that tells React to use `queueMicrotask` to batch state // updates, instead of using the scheduler to schedule a regular task. // We use a global variable because we don't currently have any other 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 3f76b06c119..781de9e2d58 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<<7d0c7d2dac41c4a64c3c8301b3865fdd>> + * @generated SignedSource<<9735aa2b6c596980927a6899b528cad7>> */ /** @@ -40,18 +40,18 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun allowRecursiveCommitsWithSynchronousMountOnAndroid(): Boolean = accessor.allowRecursiveCommitsWithSynchronousMountOnAndroid() - /** - * When enabled, the RuntimeScheduler processing the event loop will batch all rendering updates and dispatch them together at the end of each iteration of the loop. - */ - @JvmStatic - public fun batchRenderingUpdatesInEventLoop(): Boolean = accessor.batchRenderingUpdatesInEventLoop() - /** * Do not wait for a main-thread dispatch to complete init to start executing work on the JS thread on Android */ @JvmStatic public fun completeReactInstanceCreationOnBgThreadOnAndroid(): Boolean = accessor.completeReactInstanceCreationOnBgThreadOnAndroid() + /** + * The bridgeless architecture enables the event loop by default. This feature flag allows us to force disabling it in specific instances. + */ + @JvmStatic + public fun disableEventLoopOnBridgeless(): Boolean = accessor.disableEventLoopOnBridgeless() + /** * Kill-switch to turn off support for aling-items:baseline on Fabric iOS. */ @@ -142,12 +142,6 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun enableLongTaskAPI(): Boolean = accessor.enableLongTaskAPI() - /** - * Enables the use of microtasks in Hermes (scheduling) and RuntimeScheduler (execution). - */ - @JvmStatic - public fun enableMicrotasks(): Boolean = accessor.enableMicrotasks() - /** * Moves execution of pre-mount items to outside the choregrapher in the main thread, so we can estimate idle time more precisely (Android only). */ @@ -268,12 +262,6 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun useImmediateExecutorInAndroidBridgeless(): Boolean = accessor.useImmediateExecutorInAndroidBridgeless() - /** - * When enabled, it uses the modern fork of RuntimeScheduler that allows scheduling tasks with priorities from any thread. - */ - @JvmStatic - public fun useModernRuntimeScheduler(): Boolean = accessor.useModernRuntimeScheduler() - /** * When enabled, the native view configs are used in bridgeless mode. */ 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 62cfcd32f05..4da3bf5cd44 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<> */ /** @@ -22,8 +22,8 @@ package com.facebook.react.internal.featureflags public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccessor { private var commonTestFlagCache: Boolean? = null private var allowRecursiveCommitsWithSynchronousMountOnAndroidCache: Boolean? = null - private var batchRenderingUpdatesInEventLoopCache: Boolean? = null private var completeReactInstanceCreationOnBgThreadOnAndroidCache: Boolean? = null + private var disableEventLoopOnBridgelessCache: Boolean? = null private var enableAlignItemsBaselineOnFabricIOSCache: Boolean? = null private var enableAndroidLineHeightCenteringCache: Boolean? = null private var enableBridgelessArchitectureCache: Boolean? = null @@ -39,7 +39,6 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso private var enableLayoutAnimationsOnAndroidCache: Boolean? = null private var enableLayoutAnimationsOnIOSCache: Boolean? = null private var enableLongTaskAPICache: Boolean? = null - private var enableMicrotasksCache: Boolean? = null private var enablePreciseSchedulingForPremountItemsOnAndroidCache: Boolean? = null private var enablePropsUpdateReconciliationAndroidCache: Boolean? = null private var enableReportEventPaintTimeCache: Boolean? = null @@ -60,7 +59,6 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso private var traceTurboModulePromiseRejectionsOnAndroidCache: Boolean? = null private var useFabricInteropCache: Boolean? = null private var useImmediateExecutorInAndroidBridgelessCache: Boolean? = null - private var useModernRuntimeSchedulerCache: Boolean? = null private var useNativeViewConfigsInBridgelessModeCache: Boolean? = null private var useOptimisedViewPreallocationOnAndroidCache: Boolean? = null private var useOptimizedEventBatchingOnAndroidCache: Boolean? = null @@ -86,15 +84,6 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso return cached } - override fun batchRenderingUpdatesInEventLoop(): Boolean { - var cached = batchRenderingUpdatesInEventLoopCache - if (cached == null) { - cached = ReactNativeFeatureFlagsCxxInterop.batchRenderingUpdatesInEventLoop() - batchRenderingUpdatesInEventLoopCache = cached - } - return cached - } - override fun completeReactInstanceCreationOnBgThreadOnAndroid(): Boolean { var cached = completeReactInstanceCreationOnBgThreadOnAndroidCache if (cached == null) { @@ -104,6 +93,15 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso return cached } + override fun disableEventLoopOnBridgeless(): Boolean { + var cached = disableEventLoopOnBridgelessCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.disableEventLoopOnBridgeless() + disableEventLoopOnBridgelessCache = cached + } + return cached + } + override fun enableAlignItemsBaselineOnFabricIOS(): Boolean { var cached = enableAlignItemsBaselineOnFabricIOSCache if (cached == null) { @@ -239,15 +237,6 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso return cached } - override fun enableMicrotasks(): Boolean { - var cached = enableMicrotasksCache - if (cached == null) { - cached = ReactNativeFeatureFlagsCxxInterop.enableMicrotasks() - enableMicrotasksCache = cached - } - return cached - } - override fun enablePreciseSchedulingForPremountItemsOnAndroid(): Boolean { var cached = enablePreciseSchedulingForPremountItemsOnAndroidCache if (cached == null) { @@ -428,15 +417,6 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso return cached } - override fun useModernRuntimeScheduler(): Boolean { - var cached = useModernRuntimeSchedulerCache - if (cached == null) { - cached = ReactNativeFeatureFlagsCxxInterop.useModernRuntimeScheduler() - useModernRuntimeSchedulerCache = cached - } - return cached - } - override fun useNativeViewConfigsInBridgelessMode(): Boolean { var cached = useNativeViewConfigsInBridgelessModeCache 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 a0922e9bc8d..057e48e3bd8 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<<731105cf7807fd9a3c929c92de91be90>> */ /** @@ -32,10 +32,10 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun allowRecursiveCommitsWithSynchronousMountOnAndroid(): Boolean - @DoNotStrip @JvmStatic public external fun batchRenderingUpdatesInEventLoop(): Boolean - @DoNotStrip @JvmStatic public external fun completeReactInstanceCreationOnBgThreadOnAndroid(): Boolean + @DoNotStrip @JvmStatic public external fun disableEventLoopOnBridgeless(): Boolean + @DoNotStrip @JvmStatic public external fun enableAlignItemsBaselineOnFabricIOS(): Boolean @DoNotStrip @JvmStatic public external fun enableAndroidLineHeightCentering(): Boolean @@ -66,8 +66,6 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun enableLongTaskAPI(): Boolean - @DoNotStrip @JvmStatic public external fun enableMicrotasks(): Boolean - @DoNotStrip @JvmStatic public external fun enablePreciseSchedulingForPremountItemsOnAndroid(): Boolean @DoNotStrip @JvmStatic public external fun enablePropsUpdateReconciliationAndroid(): Boolean @@ -108,8 +106,6 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun useImmediateExecutorInAndroidBridgeless(): Boolean - @DoNotStrip @JvmStatic public external fun useModernRuntimeScheduler(): Boolean - @DoNotStrip @JvmStatic public external fun useNativeViewConfigsInBridgelessMode(): Boolean @DoNotStrip @JvmStatic public external fun useOptimisedViewPreallocationOnAndroid(): 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 153a3d250fe..b4685e85cc7 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<<5613f8d9d9403d005becbbd9348882c6>> + * @generated SignedSource<<246695bd5949b60404bf5fa9d1c6a9da>> */ /** @@ -27,10 +27,10 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun allowRecursiveCommitsWithSynchronousMountOnAndroid(): Boolean = false - override fun batchRenderingUpdatesInEventLoop(): Boolean = false - override fun completeReactInstanceCreationOnBgThreadOnAndroid(): Boolean = false + override fun disableEventLoopOnBridgeless(): Boolean = false + override fun enableAlignItemsBaselineOnFabricIOS(): Boolean = true override fun enableAndroidLineHeightCentering(): Boolean = false @@ -61,8 +61,6 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun enableLongTaskAPI(): Boolean = false - override fun enableMicrotasks(): Boolean = false - override fun enablePreciseSchedulingForPremountItemsOnAndroid(): Boolean = false override fun enablePropsUpdateReconciliationAndroid(): Boolean = false @@ -103,8 +101,6 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun useImmediateExecutorInAndroidBridgeless(): Boolean = false - override fun useModernRuntimeScheduler(): Boolean = false - override fun useNativeViewConfigsInBridgelessMode(): Boolean = false override fun useOptimisedViewPreallocationOnAndroid(): 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 883dd08688d..8a859ee159d 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<<29d21f7f4928086a912088a14cdbd3db>> + * @generated SignedSource<<6b0da530cc8e7a846b5a9527bc5e3648>> */ /** @@ -26,8 +26,8 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces private var commonTestFlagCache: Boolean? = null private var allowRecursiveCommitsWithSynchronousMountOnAndroidCache: Boolean? = null - private var batchRenderingUpdatesInEventLoopCache: Boolean? = null private var completeReactInstanceCreationOnBgThreadOnAndroidCache: Boolean? = null + private var disableEventLoopOnBridgelessCache: Boolean? = null private var enableAlignItemsBaselineOnFabricIOSCache: Boolean? = null private var enableAndroidLineHeightCenteringCache: Boolean? = null private var enableBridgelessArchitectureCache: Boolean? = null @@ -43,7 +43,6 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces private var enableLayoutAnimationsOnAndroidCache: Boolean? = null private var enableLayoutAnimationsOnIOSCache: Boolean? = null private var enableLongTaskAPICache: Boolean? = null - private var enableMicrotasksCache: Boolean? = null private var enablePreciseSchedulingForPremountItemsOnAndroidCache: Boolean? = null private var enablePropsUpdateReconciliationAndroidCache: Boolean? = null private var enableReportEventPaintTimeCache: Boolean? = null @@ -64,7 +63,6 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces private var traceTurboModulePromiseRejectionsOnAndroidCache: Boolean? = null private var useFabricInteropCache: Boolean? = null private var useImmediateExecutorInAndroidBridgelessCache: Boolean? = null - private var useModernRuntimeSchedulerCache: Boolean? = null private var useNativeViewConfigsInBridgelessModeCache: Boolean? = null private var useOptimisedViewPreallocationOnAndroidCache: Boolean? = null private var useOptimizedEventBatchingOnAndroidCache: Boolean? = null @@ -92,16 +90,6 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces return cached } - override fun batchRenderingUpdatesInEventLoop(): Boolean { - var cached = batchRenderingUpdatesInEventLoopCache - if (cached == null) { - cached = currentProvider.batchRenderingUpdatesInEventLoop() - accessedFeatureFlags.add("batchRenderingUpdatesInEventLoop") - batchRenderingUpdatesInEventLoopCache = cached - } - return cached - } - override fun completeReactInstanceCreationOnBgThreadOnAndroid(): Boolean { var cached = completeReactInstanceCreationOnBgThreadOnAndroidCache if (cached == null) { @@ -112,6 +100,16 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun disableEventLoopOnBridgeless(): Boolean { + var cached = disableEventLoopOnBridgelessCache + if (cached == null) { + cached = currentProvider.disableEventLoopOnBridgeless() + accessedFeatureFlags.add("disableEventLoopOnBridgeless") + disableEventLoopOnBridgelessCache = cached + } + return cached + } + override fun enableAlignItemsBaselineOnFabricIOS(): Boolean { var cached = enableAlignItemsBaselineOnFabricIOSCache if (cached == null) { @@ -262,16 +260,6 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces return cached } - override fun enableMicrotasks(): Boolean { - var cached = enableMicrotasksCache - if (cached == null) { - cached = currentProvider.enableMicrotasks() - accessedFeatureFlags.add("enableMicrotasks") - enableMicrotasksCache = cached - } - return cached - } - override fun enablePreciseSchedulingForPremountItemsOnAndroid(): Boolean { var cached = enablePreciseSchedulingForPremountItemsOnAndroidCache if (cached == null) { @@ -472,16 +460,6 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces return cached } - override fun useModernRuntimeScheduler(): Boolean { - var cached = useModernRuntimeSchedulerCache - if (cached == null) { - cached = currentProvider.useModernRuntimeScheduler() - accessedFeatureFlags.add("useModernRuntimeScheduler") - useModernRuntimeSchedulerCache = cached - } - return cached - } - override fun useNativeViewConfigsInBridgelessMode(): Boolean { var cached = useNativeViewConfigsInBridgelessModeCache 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 e7551a3a607..5700afcf488 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<> */ /** @@ -27,10 +27,10 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun allowRecursiveCommitsWithSynchronousMountOnAndroid(): Boolean - @DoNotStrip public fun batchRenderingUpdatesInEventLoop(): Boolean - @DoNotStrip public fun completeReactInstanceCreationOnBgThreadOnAndroid(): Boolean + @DoNotStrip public fun disableEventLoopOnBridgeless(): Boolean + @DoNotStrip public fun enableAlignItemsBaselineOnFabricIOS(): Boolean @DoNotStrip public fun enableAndroidLineHeightCentering(): Boolean @@ -61,8 +61,6 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun enableLongTaskAPI(): Boolean - @DoNotStrip public fun enableMicrotasks(): Boolean - @DoNotStrip public fun enablePreciseSchedulingForPremountItemsOnAndroid(): Boolean @DoNotStrip public fun enablePropsUpdateReconciliationAndroid(): Boolean @@ -103,8 +101,6 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun useImmediateExecutorInAndroidBridgeless(): Boolean - @DoNotStrip public fun useModernRuntimeScheduler(): Boolean - @DoNotStrip public fun useNativeViewConfigsInBridgelessMode(): Boolean @DoNotStrip public fun useOptimisedViewPreallocationOnAndroid(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeNewArchitectureFeatureFlagsDefaults.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeNewArchitectureFeatureFlagsDefaults.kt index e365b5cd1b5..0b137ad2e51 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeNewArchitectureFeatureFlagsDefaults.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeNewArchitectureFeatureFlagsDefaults.kt @@ -23,21 +23,12 @@ package com.facebook.react.internal.featureflags public open class ReactNativeNewArchitectureFeatureFlagsDefaults( private val newArchitectureEnabled: Boolean = true ) : ReactNativeFeatureFlagsDefaults() { - - override fun batchRenderingUpdatesInEventLoop(): Boolean = - newArchitectureEnabled || super.batchRenderingUpdatesInEventLoop() - override fun enableBridgelessArchitecture(): Boolean = newArchitectureEnabled - override fun enableMicrotasks(): Boolean = newArchitectureEnabled || super.enableMicrotasks() - override fun enableFabricRenderer(): Boolean = newArchitectureEnabled override fun useFabricInterop(): Boolean = newArchitectureEnabled - override fun useModernRuntimeScheduler(): Boolean = - newArchitectureEnabled || super.useModernRuntimeScheduler() - override fun useNativeViewConfigsInBridgelessMode(): Boolean = newArchitectureEnabled || super.useNativeViewConfigsInBridgelessMode() 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 948f6c159b1..2c9e5dd4142 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<<3898770919a834c4c4466d0b2797ba8b>> + * @generated SignedSource<> */ /** @@ -51,18 +51,18 @@ class ReactNativeFeatureFlagsProviderHolder return method(javaProvider_); } - bool batchRenderingUpdatesInEventLoop() override { - static const auto method = - getReactNativeFeatureFlagsProviderJavaClass()->getMethod("batchRenderingUpdatesInEventLoop"); - return method(javaProvider_); - } - bool completeReactInstanceCreationOnBgThreadOnAndroid() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("completeReactInstanceCreationOnBgThreadOnAndroid"); return method(javaProvider_); } + bool disableEventLoopOnBridgeless() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("disableEventLoopOnBridgeless"); + return method(javaProvider_); + } + bool enableAlignItemsBaselineOnFabricIOS() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableAlignItemsBaselineOnFabricIOS"); @@ -153,12 +153,6 @@ class ReactNativeFeatureFlagsProviderHolder return method(javaProvider_); } - bool enableMicrotasks() override { - static const auto method = - getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enableMicrotasks"); - return method(javaProvider_); - } - bool enablePreciseSchedulingForPremountItemsOnAndroid() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("enablePreciseSchedulingForPremountItemsOnAndroid"); @@ -279,12 +273,6 @@ class ReactNativeFeatureFlagsProviderHolder return method(javaProvider_); } - bool useModernRuntimeScheduler() override { - static const auto method = - getReactNativeFeatureFlagsProviderJavaClass()->getMethod("useModernRuntimeScheduler"); - return method(javaProvider_); - } - bool useNativeViewConfigsInBridgelessMode() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("useNativeViewConfigsInBridgelessMode"); @@ -335,16 +323,16 @@ bool JReactNativeFeatureFlagsCxxInterop::allowRecursiveCommitsWithSynchronousMou return ReactNativeFeatureFlags::allowRecursiveCommitsWithSynchronousMountOnAndroid(); } -bool JReactNativeFeatureFlagsCxxInterop::batchRenderingUpdatesInEventLoop( - facebook::jni::alias_ref /*unused*/) { - return ReactNativeFeatureFlags::batchRenderingUpdatesInEventLoop(); -} - bool JReactNativeFeatureFlagsCxxInterop::completeReactInstanceCreationOnBgThreadOnAndroid( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::completeReactInstanceCreationOnBgThreadOnAndroid(); } +bool JReactNativeFeatureFlagsCxxInterop::disableEventLoopOnBridgeless( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::disableEventLoopOnBridgeless(); +} + bool JReactNativeFeatureFlagsCxxInterop::enableAlignItemsBaselineOnFabricIOS( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::enableAlignItemsBaselineOnFabricIOS(); @@ -420,11 +408,6 @@ bool JReactNativeFeatureFlagsCxxInterop::enableLongTaskAPI( return ReactNativeFeatureFlags::enableLongTaskAPI(); } -bool JReactNativeFeatureFlagsCxxInterop::enableMicrotasks( - facebook::jni::alias_ref /*unused*/) { - return ReactNativeFeatureFlags::enableMicrotasks(); -} - bool JReactNativeFeatureFlagsCxxInterop::enablePreciseSchedulingForPremountItemsOnAndroid( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::enablePreciseSchedulingForPremountItemsOnAndroid(); @@ -525,11 +508,6 @@ bool JReactNativeFeatureFlagsCxxInterop::useImmediateExecutorInAndroidBridgeless return ReactNativeFeatureFlags::useImmediateExecutorInAndroidBridgeless(); } -bool JReactNativeFeatureFlagsCxxInterop::useModernRuntimeScheduler( - facebook::jni::alias_ref /*unused*/) { - return ReactNativeFeatureFlags::useModernRuntimeScheduler(); -} - bool JReactNativeFeatureFlagsCxxInterop::useNativeViewConfigsInBridgelessMode( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::useNativeViewConfigsInBridgelessMode(); @@ -597,12 +575,12 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "allowRecursiveCommitsWithSynchronousMountOnAndroid", JReactNativeFeatureFlagsCxxInterop::allowRecursiveCommitsWithSynchronousMountOnAndroid), - makeNativeMethod( - "batchRenderingUpdatesInEventLoop", - JReactNativeFeatureFlagsCxxInterop::batchRenderingUpdatesInEventLoop), makeNativeMethod( "completeReactInstanceCreationOnBgThreadOnAndroid", JReactNativeFeatureFlagsCxxInterop::completeReactInstanceCreationOnBgThreadOnAndroid), + makeNativeMethod( + "disableEventLoopOnBridgeless", + JReactNativeFeatureFlagsCxxInterop::disableEventLoopOnBridgeless), makeNativeMethod( "enableAlignItemsBaselineOnFabricIOS", JReactNativeFeatureFlagsCxxInterop::enableAlignItemsBaselineOnFabricIOS), @@ -648,9 +626,6 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "enableLongTaskAPI", JReactNativeFeatureFlagsCxxInterop::enableLongTaskAPI), - makeNativeMethod( - "enableMicrotasks", - JReactNativeFeatureFlagsCxxInterop::enableMicrotasks), makeNativeMethod( "enablePreciseSchedulingForPremountItemsOnAndroid", JReactNativeFeatureFlagsCxxInterop::enablePreciseSchedulingForPremountItemsOnAndroid), @@ -711,9 +686,6 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "useImmediateExecutorInAndroidBridgeless", JReactNativeFeatureFlagsCxxInterop::useImmediateExecutorInAndroidBridgeless), - makeNativeMethod( - "useModernRuntimeScheduler", - JReactNativeFeatureFlagsCxxInterop::useModernRuntimeScheduler), makeNativeMethod( "useNativeViewConfigsInBridgelessMode", JReactNativeFeatureFlagsCxxInterop::useNativeViewConfigsInBridgelessMode), 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 0ff427ce4d7..1350c785e9f 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<> */ /** @@ -36,10 +36,10 @@ class JReactNativeFeatureFlagsCxxInterop static bool allowRecursiveCommitsWithSynchronousMountOnAndroid( facebook::jni::alias_ref); - static bool batchRenderingUpdatesInEventLoop( + static bool completeReactInstanceCreationOnBgThreadOnAndroid( facebook::jni::alias_ref); - static bool completeReactInstanceCreationOnBgThreadOnAndroid( + static bool disableEventLoopOnBridgeless( facebook::jni::alias_ref); static bool enableAlignItemsBaselineOnFabricIOS( @@ -87,9 +87,6 @@ class JReactNativeFeatureFlagsCxxInterop static bool enableLongTaskAPI( facebook::jni::alias_ref); - static bool enableMicrotasks( - facebook::jni::alias_ref); - static bool enablePreciseSchedulingForPremountItemsOnAndroid( facebook::jni::alias_ref); @@ -150,9 +147,6 @@ class JReactNativeFeatureFlagsCxxInterop static bool useImmediateExecutorInAndroidBridgeless( facebook::jni::alias_ref); - static bool useModernRuntimeScheduler( - facebook::jni::alias_ref); - static bool useNativeViewConfigsInBridgelessMode( 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 4ab0189b2a8..c6bd45bf27e 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<<6a62793678276e28e04ebe3d1b8b0d46>> + * @generated SignedSource<<0ce2cf26cad2385dc49eb4bcfa0cceec>> */ /** @@ -34,14 +34,14 @@ bool ReactNativeFeatureFlags::allowRecursiveCommitsWithSynchronousMountOnAndroid return getAccessor().allowRecursiveCommitsWithSynchronousMountOnAndroid(); } -bool ReactNativeFeatureFlags::batchRenderingUpdatesInEventLoop() { - return getAccessor().batchRenderingUpdatesInEventLoop(); -} - bool ReactNativeFeatureFlags::completeReactInstanceCreationOnBgThreadOnAndroid() { return getAccessor().completeReactInstanceCreationOnBgThreadOnAndroid(); } +bool ReactNativeFeatureFlags::disableEventLoopOnBridgeless() { + return getAccessor().disableEventLoopOnBridgeless(); +} + bool ReactNativeFeatureFlags::enableAlignItemsBaselineOnFabricIOS() { return getAccessor().enableAlignItemsBaselineOnFabricIOS(); } @@ -102,10 +102,6 @@ bool ReactNativeFeatureFlags::enableLongTaskAPI() { return getAccessor().enableLongTaskAPI(); } -bool ReactNativeFeatureFlags::enableMicrotasks() { - return getAccessor().enableMicrotasks(); -} - bool ReactNativeFeatureFlags::enablePreciseSchedulingForPremountItemsOnAndroid() { return getAccessor().enablePreciseSchedulingForPremountItemsOnAndroid(); } @@ -186,10 +182,6 @@ bool ReactNativeFeatureFlags::useImmediateExecutorInAndroidBridgeless() { return getAccessor().useImmediateExecutorInAndroidBridgeless(); } -bool ReactNativeFeatureFlags::useModernRuntimeScheduler() { - return getAccessor().useModernRuntimeScheduler(); -} - bool ReactNativeFeatureFlags::useNativeViewConfigsInBridgelessMode() { return getAccessor().useNativeViewConfigsInBridgelessMode(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index 9585a18d4d7..871d38ae09d 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<<5a537adba978cd74ba62e69d4aeb72b0>> + * @generated SignedSource<<42056925ce0f349d1d27090b0750f414>> */ /** @@ -49,16 +49,16 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool allowRecursiveCommitsWithSynchronousMountOnAndroid(); - /** - * When enabled, the RuntimeScheduler processing the event loop will batch all rendering updates and dispatch them together at the end of each iteration of the loop. - */ - RN_EXPORT static bool batchRenderingUpdatesInEventLoop(); - /** * Do not wait for a main-thread dispatch to complete init to start executing work on the JS thread on Android */ RN_EXPORT static bool completeReactInstanceCreationOnBgThreadOnAndroid(); + /** + * The bridgeless architecture enables the event loop by default. This feature flag allows us to force disabling it in specific instances. + */ + RN_EXPORT static bool disableEventLoopOnBridgeless(); + /** * Kill-switch to turn off support for aling-items:baseline on Fabric iOS. */ @@ -134,11 +134,6 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool enableLongTaskAPI(); - /** - * Enables the use of microtasks in Hermes (scheduling) and RuntimeScheduler (execution). - */ - RN_EXPORT static bool enableMicrotasks(); - /** * Moves execution of pre-mount items to outside the choregrapher in the main thread, so we can estimate idle time more precisely (Android only). */ @@ -239,11 +234,6 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool useImmediateExecutorInAndroidBridgeless(); - /** - * When enabled, it uses the modern fork of RuntimeScheduler that allows scheduling tasks with priorities from any thread. - */ - RN_EXPORT static bool useModernRuntimeScheduler(); - /** * When enabled, the native view configs are used in bridgeless mode. */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index 54d3491c50c..1b1c237727e 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<> */ /** @@ -65,24 +65,6 @@ bool ReactNativeFeatureFlagsAccessor::allowRecursiveCommitsWithSynchronousMountO return flagValue.value(); } -bool ReactNativeFeatureFlagsAccessor::batchRenderingUpdatesInEventLoop() { - auto flagValue = batchRenderingUpdatesInEventLoop_.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(2, "batchRenderingUpdatesInEventLoop"); - - flagValue = currentProvider_->batchRenderingUpdatesInEventLoop(); - batchRenderingUpdatesInEventLoop_ = flagValue; - } - - return flagValue.value(); -} - bool ReactNativeFeatureFlagsAccessor::completeReactInstanceCreationOnBgThreadOnAndroid() { auto flagValue = completeReactInstanceCreationOnBgThreadOnAndroid_.load(); @@ -92,7 +74,7 @@ bool ReactNativeFeatureFlagsAccessor::completeReactInstanceCreationOnBgThreadOnA // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(3, "completeReactInstanceCreationOnBgThreadOnAndroid"); + markFlagAsAccessed(2, "completeReactInstanceCreationOnBgThreadOnAndroid"); flagValue = currentProvider_->completeReactInstanceCreationOnBgThreadOnAndroid(); completeReactInstanceCreationOnBgThreadOnAndroid_ = flagValue; @@ -101,6 +83,24 @@ bool ReactNativeFeatureFlagsAccessor::completeReactInstanceCreationOnBgThreadOnA return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::disableEventLoopOnBridgeless() { + auto flagValue = disableEventLoopOnBridgeless_.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, "disableEventLoopOnBridgeless"); + + flagValue = currentProvider_->disableEventLoopOnBridgeless(); + disableEventLoopOnBridgeless_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::enableAlignItemsBaselineOnFabricIOS() { auto flagValue = enableAlignItemsBaselineOnFabricIOS_.load(); @@ -371,24 +371,6 @@ bool ReactNativeFeatureFlagsAccessor::enableLongTaskAPI() { return flagValue.value(); } -bool ReactNativeFeatureFlagsAccessor::enableMicrotasks() { - auto flagValue = enableMicrotasks_.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(19, "enableMicrotasks"); - - flagValue = currentProvider_->enableMicrotasks(); - enableMicrotasks_ = flagValue; - } - - return flagValue.value(); -} - bool ReactNativeFeatureFlagsAccessor::enablePreciseSchedulingForPremountItemsOnAndroid() { auto flagValue = enablePreciseSchedulingForPremountItemsOnAndroid_.load(); @@ -398,7 +380,7 @@ bool ReactNativeFeatureFlagsAccessor::enablePreciseSchedulingForPremountItemsOnA // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(20, "enablePreciseSchedulingForPremountItemsOnAndroid"); + markFlagAsAccessed(19, "enablePreciseSchedulingForPremountItemsOnAndroid"); flagValue = currentProvider_->enablePreciseSchedulingForPremountItemsOnAndroid(); enablePreciseSchedulingForPremountItemsOnAndroid_ = flagValue; @@ -416,7 +398,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(21, "enablePropsUpdateReconciliationAndroid"); + markFlagAsAccessed(20, "enablePropsUpdateReconciliationAndroid"); flagValue = currentProvider_->enablePropsUpdateReconciliationAndroid(); enablePropsUpdateReconciliationAndroid_ = flagValue; @@ -434,7 +416,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(22, "enableReportEventPaintTime"); + markFlagAsAccessed(21, "enableReportEventPaintTime"); flagValue = currentProvider_->enableReportEventPaintTime(); enableReportEventPaintTime_ = flagValue; @@ -452,7 +434,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(23, "enableSynchronousStateUpdates"); + markFlagAsAccessed(22, "enableSynchronousStateUpdates"); flagValue = currentProvider_->enableSynchronousStateUpdates(); enableSynchronousStateUpdates_ = flagValue; @@ -470,7 +452,7 @@ bool ReactNativeFeatureFlagsAccessor::enableTextPreallocationOptimisation() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(24, "enableTextPreallocationOptimisation"); + markFlagAsAccessed(23, "enableTextPreallocationOptimisation"); flagValue = currentProvider_->enableTextPreallocationOptimisation(); enableTextPreallocationOptimisation_ = flagValue; @@ -488,7 +470,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(25, "enableUIConsistency"); + markFlagAsAccessed(24, "enableUIConsistency"); flagValue = currentProvider_->enableUIConsistency(); enableUIConsistency_ = flagValue; @@ -506,7 +488,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(26, "enableViewRecycling"); + markFlagAsAccessed(25, "enableViewRecycling"); flagValue = currentProvider_->enableViewRecycling(); enableViewRecycling_ = flagValue; @@ -524,7 +506,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(27, "excludeYogaFromRawProps"); + markFlagAsAccessed(26, "excludeYogaFromRawProps"); flagValue = currentProvider_->excludeYogaFromRawProps(); excludeYogaFromRawProps_ = flagValue; @@ -542,7 +524,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(28, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); + markFlagAsAccessed(27, "fixMappingOfEventPrioritiesBetweenFabricAndReact"); flagValue = currentProvider_->fixMappingOfEventPrioritiesBetweenFabricAndReact(); fixMappingOfEventPrioritiesBetweenFabricAndReact_ = flagValue; @@ -560,7 +542,7 @@ bool ReactNativeFeatureFlagsAccessor::fixMountingCoordinatorReportedPendingTrans // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(29, "fixMountingCoordinatorReportedPendingTransactionsOnAndroid"); + markFlagAsAccessed(28, "fixMountingCoordinatorReportedPendingTransactionsOnAndroid"); flagValue = currentProvider_->fixMountingCoordinatorReportedPendingTransactionsOnAndroid(); fixMountingCoordinatorReportedPendingTransactionsOnAndroid_ = flagValue; @@ -578,7 +560,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(30, "forceBatchingMountItemsOnAndroid"); + markFlagAsAccessed(29, "forceBatchingMountItemsOnAndroid"); flagValue = currentProvider_->forceBatchingMountItemsOnAndroid(); forceBatchingMountItemsOnAndroid_ = flagValue; @@ -596,7 +578,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(31, "fuseboxEnabledDebug"); + markFlagAsAccessed(30, "fuseboxEnabledDebug"); flagValue = currentProvider_->fuseboxEnabledDebug(); fuseboxEnabledDebug_ = flagValue; @@ -614,7 +596,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(32, "fuseboxEnabledRelease"); + markFlagAsAccessed(31, "fuseboxEnabledRelease"); flagValue = currentProvider_->fuseboxEnabledRelease(); fuseboxEnabledRelease_ = flagValue; @@ -632,7 +614,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(33, "initEagerTurboModulesOnNativeModulesQueueAndroid"); + markFlagAsAccessed(32, "initEagerTurboModulesOnNativeModulesQueueAndroid"); flagValue = currentProvider_->initEagerTurboModulesOnNativeModulesQueueAndroid(); initEagerTurboModulesOnNativeModulesQueueAndroid_ = flagValue; @@ -650,7 +632,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(34, "lazyAnimationCallbacks"); + markFlagAsAccessed(33, "lazyAnimationCallbacks"); flagValue = currentProvider_->lazyAnimationCallbacks(); lazyAnimationCallbacks_ = flagValue; @@ -668,7 +650,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(35, "loadVectorDrawablesOnImages"); + markFlagAsAccessed(34, "loadVectorDrawablesOnImages"); flagValue = currentProvider_->loadVectorDrawablesOnImages(); loadVectorDrawablesOnImages_ = flagValue; @@ -686,7 +668,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(36, "setAndroidLayoutDirection"); + markFlagAsAccessed(35, "setAndroidLayoutDirection"); flagValue = currentProvider_->setAndroidLayoutDirection(); setAndroidLayoutDirection_ = flagValue; @@ -704,7 +686,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(37, "traceTurboModulePromiseRejectionsOnAndroid"); + markFlagAsAccessed(36, "traceTurboModulePromiseRejectionsOnAndroid"); flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid(); traceTurboModulePromiseRejectionsOnAndroid_ = flagValue; @@ -722,7 +704,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(38, "useFabricInterop"); + markFlagAsAccessed(37, "useFabricInterop"); flagValue = currentProvider_->useFabricInterop(); useFabricInterop_ = flagValue; @@ -740,7 +722,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(39, "useImmediateExecutorInAndroidBridgeless"); + markFlagAsAccessed(38, "useImmediateExecutorInAndroidBridgeless"); flagValue = currentProvider_->useImmediateExecutorInAndroidBridgeless(); useImmediateExecutorInAndroidBridgeless_ = flagValue; @@ -749,24 +731,6 @@ bool ReactNativeFeatureFlagsAccessor::useImmediateExecutorInAndroidBridgeless() return flagValue.value(); } -bool ReactNativeFeatureFlagsAccessor::useModernRuntimeScheduler() { - auto flagValue = useModernRuntimeScheduler_.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(40, "useModernRuntimeScheduler"); - - flagValue = currentProvider_->useModernRuntimeScheduler(); - useModernRuntimeScheduler_ = flagValue; - } - - return flagValue.value(); -} - bool ReactNativeFeatureFlagsAccessor::useNativeViewConfigsInBridgelessMode() { auto flagValue = useNativeViewConfigsInBridgelessMode_.load(); @@ -776,7 +740,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(41, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(39, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -794,7 +758,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(42, "useOptimisedViewPreallocationOnAndroid"); + markFlagAsAccessed(40, "useOptimisedViewPreallocationOnAndroid"); flagValue = currentProvider_->useOptimisedViewPreallocationOnAndroid(); useOptimisedViewPreallocationOnAndroid_ = flagValue; @@ -812,7 +776,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(43, "useOptimizedEventBatchingOnAndroid"); + markFlagAsAccessed(41, "useOptimizedEventBatchingOnAndroid"); flagValue = currentProvider_->useOptimizedEventBatchingOnAndroid(); useOptimizedEventBatchingOnAndroid_ = flagValue; @@ -830,7 +794,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(44, "useRuntimeShadowNodeReferenceUpdate"); + markFlagAsAccessed(42, "useRuntimeShadowNodeReferenceUpdate"); flagValue = currentProvider_->useRuntimeShadowNodeReferenceUpdate(); useRuntimeShadowNodeReferenceUpdate_ = flagValue; @@ -848,7 +812,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(45, "useTurboModuleInterop"); + markFlagAsAccessed(43, "useTurboModuleInterop"); flagValue = currentProvider_->useTurboModuleInterop(); useTurboModuleInterop_ = flagValue; @@ -866,7 +830,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(46, "useTurboModules"); + markFlagAsAccessed(44, "useTurboModules"); flagValue = currentProvider_->useTurboModules(); useTurboModules_ = flagValue; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index 20ba372edb1..eecc74498d4 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<<3accca8a4ee3ca498f3de148b5c9865f>> + * @generated SignedSource<> */ /** @@ -34,8 +34,8 @@ class ReactNativeFeatureFlagsAccessor { bool commonTestFlag(); bool allowRecursiveCommitsWithSynchronousMountOnAndroid(); - bool batchRenderingUpdatesInEventLoop(); bool completeReactInstanceCreationOnBgThreadOnAndroid(); + bool disableEventLoopOnBridgeless(); bool enableAlignItemsBaselineOnFabricIOS(); bool enableAndroidLineHeightCentering(); bool enableBridgelessArchitecture(); @@ -51,7 +51,6 @@ class ReactNativeFeatureFlagsAccessor { bool enableLayoutAnimationsOnAndroid(); bool enableLayoutAnimationsOnIOS(); bool enableLongTaskAPI(); - bool enableMicrotasks(); bool enablePreciseSchedulingForPremountItemsOnAndroid(); bool enablePropsUpdateReconciliationAndroid(); bool enableReportEventPaintTime(); @@ -72,7 +71,6 @@ class ReactNativeFeatureFlagsAccessor { bool traceTurboModulePromiseRejectionsOnAndroid(); bool useFabricInterop(); bool useImmediateExecutorInAndroidBridgeless(); - bool useModernRuntimeScheduler(); bool useNativeViewConfigsInBridgelessMode(); bool useOptimisedViewPreallocationOnAndroid(); bool useOptimizedEventBatchingOnAndroid(); @@ -90,12 +88,12 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 47> accessedFeatureFlags_; + std::array, 45> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> allowRecursiveCommitsWithSynchronousMountOnAndroid_; - std::atomic> batchRenderingUpdatesInEventLoop_; std::atomic> completeReactInstanceCreationOnBgThreadOnAndroid_; + std::atomic> disableEventLoopOnBridgeless_; std::atomic> enableAlignItemsBaselineOnFabricIOS_; std::atomic> enableAndroidLineHeightCentering_; std::atomic> enableBridgelessArchitecture_; @@ -111,7 +109,6 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> enableLayoutAnimationsOnAndroid_; std::atomic> enableLayoutAnimationsOnIOS_; std::atomic> enableLongTaskAPI_; - std::atomic> enableMicrotasks_; std::atomic> enablePreciseSchedulingForPremountItemsOnAndroid_; std::atomic> enablePropsUpdateReconciliationAndroid_; std::atomic> enableReportEventPaintTime_; @@ -132,7 +129,6 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> traceTurboModulePromiseRejectionsOnAndroid_; std::atomic> useFabricInterop_; std::atomic> useImmediateExecutorInAndroidBridgeless_; - std::atomic> useModernRuntimeScheduler_; std::atomic> useNativeViewConfigsInBridgelessMode_; std::atomic> useOptimisedViewPreallocationOnAndroid_; std::atomic> useOptimizedEventBatchingOnAndroid_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index 51b6d132ed9..ed528bd1e78 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<<868e09dabcb458d56f73d5c6ef9ed05b>> + * @generated SignedSource<<6cee65011f4651b671cb6ac61e3a7f63>> */ /** @@ -35,11 +35,11 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } - bool batchRenderingUpdatesInEventLoop() override { + bool completeReactInstanceCreationOnBgThreadOnAndroid() override { return false; } - bool completeReactInstanceCreationOnBgThreadOnAndroid() override { + bool disableEventLoopOnBridgeless() override { return false; } @@ -103,10 +103,6 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } - bool enableMicrotasks() override { - return false; - } - bool enablePreciseSchedulingForPremountItemsOnAndroid() override { return false; } @@ -187,10 +183,6 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } - bool useModernRuntimeScheduler() override { - return false; - } - bool useNativeViewConfigsInBridgelessMode() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index 61b65a990c1..082ea4a1139 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<> + * @generated SignedSource<<27f8bf0762a51825e7fb93df268ae3f0>> */ /** @@ -27,8 +27,8 @@ class ReactNativeFeatureFlagsProvider { virtual bool commonTestFlag() = 0; virtual bool allowRecursiveCommitsWithSynchronousMountOnAndroid() = 0; - virtual bool batchRenderingUpdatesInEventLoop() = 0; virtual bool completeReactInstanceCreationOnBgThreadOnAndroid() = 0; + virtual bool disableEventLoopOnBridgeless() = 0; virtual bool enableAlignItemsBaselineOnFabricIOS() = 0; virtual bool enableAndroidLineHeightCentering() = 0; virtual bool enableBridgelessArchitecture() = 0; @@ -44,7 +44,6 @@ class ReactNativeFeatureFlagsProvider { virtual bool enableLayoutAnimationsOnAndroid() = 0; virtual bool enableLayoutAnimationsOnIOS() = 0; virtual bool enableLongTaskAPI() = 0; - virtual bool enableMicrotasks() = 0; virtual bool enablePreciseSchedulingForPremountItemsOnAndroid() = 0; virtual bool enablePropsUpdateReconciliationAndroid() = 0; virtual bool enableReportEventPaintTime() = 0; @@ -65,7 +64,6 @@ class ReactNativeFeatureFlagsProvider { virtual bool traceTurboModulePromiseRejectionsOnAndroid() = 0; virtual bool useFabricInterop() = 0; virtual bool useImmediateExecutorInAndroidBridgeless() = 0; - virtual bool useModernRuntimeScheduler() = 0; virtual bool useNativeViewConfigsInBridgelessMode() = 0; virtual bool useOptimisedViewPreallocationOnAndroid() = 0; virtual bool useOptimizedEventBatchingOnAndroid() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index 700ec221db4..389ab6751f9 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<<61c80a52ec4c2cf0904bb17c8f479f9d>> + * @generated SignedSource<> */ /** @@ -56,7 +56,9 @@ bool NativeReactNativeFeatureFlags::allowRecursiveCommitsWithSynchronousMountOnA bool NativeReactNativeFeatureFlags::batchRenderingUpdatesInEventLoop( jsi::Runtime& /*runtime*/) { - return ReactNativeFeatureFlags::batchRenderingUpdatesInEventLoop(); + // This flag is configured with `skipNativeAPI: true`. + // TODO(T204838867): Implement support for optional methods in C++ TM codegen and remove the method definition altogether. + return false; } bool NativeReactNativeFeatureFlags::completeReactInstanceCreationOnBgThreadOnAndroid( @@ -64,6 +66,11 @@ bool NativeReactNativeFeatureFlags::completeReactInstanceCreationOnBgThreadOnAnd return ReactNativeFeatureFlags::completeReactInstanceCreationOnBgThreadOnAndroid(); } +bool NativeReactNativeFeatureFlags::disableEventLoopOnBridgeless( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::disableEventLoopOnBridgeless(); +} + bool NativeReactNativeFeatureFlags::enableAlignItemsBaselineOnFabricIOS( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::enableAlignItemsBaselineOnFabricIOS(); @@ -141,7 +148,9 @@ bool NativeReactNativeFeatureFlags::enableLongTaskAPI( bool NativeReactNativeFeatureFlags::enableMicrotasks( jsi::Runtime& /*runtime*/) { - return ReactNativeFeatureFlags::enableMicrotasks(); + // This flag is configured with `skipNativeAPI: true`. + // TODO(T204838867): Implement support for optional methods in C++ TM codegen and remove the method definition altogether. + return false; } bool NativeReactNativeFeatureFlags::enablePreciseSchedulingForPremountItemsOnAndroid( @@ -246,7 +255,9 @@ bool NativeReactNativeFeatureFlags::useImmediateExecutorInAndroidBridgeless( bool NativeReactNativeFeatureFlags::useModernRuntimeScheduler( jsi::Runtime& /*runtime*/) { - return ReactNativeFeatureFlags::useModernRuntimeScheduler(); + // This flag is configured with `skipNativeAPI: true`. + // TODO(T204838867): Implement support for optional methods in C++ TM codegen and remove the method definition altogether. + return false; } bool NativeReactNativeFeatureFlags::useNativeViewConfigsInBridgelessMode( diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index 024cc0c0912..2379fcf5c5d 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<<68423ab013e1357ec176da0fbef4f7e8>> + * @generated SignedSource<> */ /** @@ -45,6 +45,8 @@ class NativeReactNativeFeatureFlags bool completeReactInstanceCreationOnBgThreadOnAndroid(jsi::Runtime& runtime); + bool disableEventLoopOnBridgeless(jsi::Runtime& runtime); + bool enableAlignItemsBaselineOnFabricIOS(jsi::Runtime& runtime); bool enableAndroidLineHeightCentering(jsi::Runtime& runtime); diff --git a/packages/react-native/ReactCommon/react/nativemodule/mutationobserver/NativeMutationObserver.cpp b/packages/react-native/ReactCommon/react/nativemodule/mutationobserver/NativeMutationObserver.cpp index cba57fd72c5..d6754ffc7f9 100644 --- a/packages/react-native/ReactCommon/react/nativemodule/mutationobserver/NativeMutationObserver.cpp +++ b/packages/react-native/ReactCommon/react/nativemodule/mutationobserver/NativeMutationObserver.cpp @@ -142,7 +142,8 @@ void NativeMutationObserver::notifyMutationObserversIfNecessary() { if (dispatchNotification) { SystraceSection s("NativeMutationObserver::notifyObservers"); - if (ReactNativeFeatureFlags::enableMicrotasks()) { + if (ReactNativeFeatureFlags::enableBridgelessArchitecture() && + !ReactNativeFeatureFlags::disableEventLoopOnBridgeless()) { runtime_->queueMicrotask(notifyMutationObservers_.value()); } else { jsInvoker_->invokeAsync([&](jsi::Runtime& runtime) { diff --git a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.cpp b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.cpp index aca04466179..e889cee86df 100644 --- a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.cpp +++ b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.cpp @@ -22,7 +22,8 @@ std::unique_ptr getRuntimeSchedulerImplementation( RuntimeExecutor runtimeExecutor, std::function now, RuntimeSchedulerTaskErrorHandler onTaskError) { - if (ReactNativeFeatureFlags::useModernRuntimeScheduler()) { + if (ReactNativeFeatureFlags::enableBridgelessArchitecture() && + !ReactNativeFeatureFlags::disableEventLoopOnBridgeless()) { return std::make_unique( std::move(runtimeExecutor), std::move(now), std::move(onTaskError)); } else { diff --git a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler_Modern.cpp b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler_Modern.cpp index 97933129b0e..0a05dd76b33 100644 --- a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler_Modern.cpp +++ b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler_Modern.cpp @@ -195,13 +195,7 @@ void RuntimeScheduler_Modern::executeNowOnTheSameThread( } void RuntimeScheduler_Modern::callExpiredTasks(jsi::Runtime& runtime) { - // If we have first-class support for microtasks, this a no-op. - if (ReactNativeFeatureFlags::enableMicrotasks()) { - return; - } - - SystraceSection s("RuntimeScheduler::callExpiredTasks"); - runEventLoop(runtime, true); + // No-op in the event loop implementation. } void RuntimeScheduler_Modern::scheduleRenderingUpdate( @@ -209,14 +203,8 @@ void RuntimeScheduler_Modern::scheduleRenderingUpdate( RuntimeSchedulerRenderingUpdate&& renderingUpdate) { SystraceSection s("RuntimeScheduler::scheduleRenderingUpdate"); - if (ReactNativeFeatureFlags::batchRenderingUpdatesInEventLoop()) { - surfaceIdsWithPendingRenderingUpdates_.insert(surfaceId); - pendingRenderingUpdates_.push(renderingUpdate); - } else { - if (renderingUpdate != nullptr) { - renderingUpdate(); - } - } + surfaceIdsWithPendingRenderingUpdates_.insert(surfaceId); + pendingRenderingUpdates_.push(renderingUpdate); } void RuntimeScheduler_Modern::setShadowTreeRevisionConsistencyManager( @@ -337,10 +325,8 @@ void RuntimeScheduler_Modern::runEventLoopTick( auto didUserCallbackTimeout = task.expirationTime <= taskStartTime; executeTask(runtime, task, didUserCallbackTimeout); - if (ReactNativeFeatureFlags::enableMicrotasks()) { - // "Perform a microtask checkpoint" step. - performMicrotaskCheckpoint(runtime); - } + // "Perform a microtask checkpoint" step. + performMicrotaskCheckpoint(runtime); if (ReactNativeFeatureFlags::enableLongTaskAPI()) { auto taskEndTime = now_(); @@ -348,10 +334,8 @@ void RuntimeScheduler_Modern::runEventLoopTick( reportLongTasks(task, taskStartTime, taskEndTime); } - if (ReactNativeFeatureFlags::batchRenderingUpdatesInEventLoop()) { - // "Update the rendering" step. - updateRendering(); - } + // "Update the rendering" step. + updateRendering(); currentTask_ = nullptr; } diff --git a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/tests/RuntimeSchedulerTest.cpp b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/tests/RuntimeSchedulerTest.cpp index 2dc9a8b1276..bc8be4d44e3 100644 --- a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/tests/RuntimeSchedulerTest.cpp +++ b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/tests/RuntimeSchedulerTest.cpp @@ -28,19 +28,11 @@ static bool forcedBatchRenderingUpdatesInEventLoop = false; class RuntimeSchedulerTestFeatureFlags : public ReactNativeFeatureFlagsDefaults { public: - RuntimeSchedulerTestFeatureFlags(bool useModernRuntimeScheduler) - : useModernRuntimeScheduler_(useModernRuntimeScheduler) {} + explicit RuntimeSchedulerTestFeatureFlags(bool enableEventLoop) + : enableEventLoop_(enableEventLoop) {} - bool useModernRuntimeScheduler() override { - return useModernRuntimeScheduler_; - } - - bool enableMicrotasks() override { - return useModernRuntimeScheduler_; - } - - bool batchRenderingUpdatesInEventLoop() override { - return forcedBatchRenderingUpdatesInEventLoop; + bool enableBridgelessArchitecture() override { + return enableEventLoop_; } bool enableLongTaskAPI() override { @@ -48,7 +40,7 @@ class RuntimeSchedulerTestFeatureFlags } private: - bool useModernRuntimeScheduler_; + bool enableEventLoop_; }; class RuntimeSchedulerTest : public testing::TestWithParam { @@ -162,21 +154,10 @@ TEST_P(RuntimeSchedulerTest, scheduleSingleTask) { EXPECT_EQ(stubQueue_->size(), 0); } -TEST_P(RuntimeSchedulerTest, scheduleNonBatchedRenderingUpdate) { - forcedBatchRenderingUpdatesInEventLoop = false; - - bool didRunRenderingUpdate = false; - - runtimeScheduler_->scheduleRenderingUpdate( - 0, [&]() { didRunRenderingUpdate = true; }); - - EXPECT_TRUE(didRunRenderingUpdate); -} - TEST_P( RuntimeSchedulerTest, scheduleSingleTaskWithMicrotasksAndBatchedRenderingUpdate) { - // Only for modern runtime scheduler + // Only for event loop if (!GetParam()) { return; } @@ -616,7 +597,7 @@ TEST_P(RuntimeSchedulerTest, immediateTaskDoesntYieldToPlatformEvent) { } TEST_P(RuntimeSchedulerTest, scheduleTaskWithYielding) { - // Only for modern runtime scheduler + // Only for event loop if (!GetParam()) { return; } @@ -640,7 +621,7 @@ TEST_P(RuntimeSchedulerTest, scheduleTaskWithYielding) { } TEST_P(RuntimeSchedulerTest, normalTaskYieldsToSynchronousAccess) { - // Only for modern runtime scheduler + // Only for event loop if (!GetParam()) { return; } @@ -709,7 +690,7 @@ TEST_P(RuntimeSchedulerTest, normalTaskYieldsToSynchronousAccess) { } TEST_P(RuntimeSchedulerTest, normalTaskYieldsToSynchronousAccessAndResumes) { - // Only for modern runtime scheduler + // Only for event loop if (!GetParam()) { return; } @@ -766,7 +747,7 @@ TEST_P(RuntimeSchedulerTest, normalTaskYieldsToSynchronousAccessAndResumes) { } TEST_P(RuntimeSchedulerTest, immediateTaskYieldsToSynchronousAccess) { - // Only for modern runtime scheduler + // Only for event loop if (!GetParam()) { return; } @@ -1090,7 +1071,7 @@ TEST_P(RuntimeSchedulerTest, legacyTwoThreadsRequestAccessToTheRuntime) { } TEST_P(RuntimeSchedulerTest, modernTwoThreadsRequestAccessToTheRuntime) { - // Only for modern runtime scheduler + // Only for event loop if (!GetParam()) { return; } @@ -1173,7 +1154,7 @@ TEST_P(RuntimeSchedulerTest, modernTwoThreadsRequestAccessToTheRuntime) { } TEST_P(RuntimeSchedulerTest, errorInTaskShouldNotStopMicrotasks) { - // Only for modern runtime scheduler + // Only for event loop if (!GetParam()) { return; } @@ -1219,7 +1200,7 @@ TEST_P(RuntimeSchedulerTest, errorInTaskShouldNotStopMicrotasks) { } TEST_P(RuntimeSchedulerTest, reportsLongTasks) { - // Only for modern runtime scheduler + // Only for event loop if (!GetParam()) { return; } @@ -1271,7 +1252,7 @@ TEST_P(RuntimeSchedulerTest, reportsLongTasks) { } TEST_P(RuntimeSchedulerTest, reportsLongTasksWithYielding) { - // Only for modern runtime scheduler + // Only for event loop if (!GetParam()) { return; } diff --git a/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp b/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp index 97c420ccf5b..a96f875e2fd 100644 --- a/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp +++ b/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp @@ -78,7 +78,7 @@ ReactInstance::ReactInstance( // If we have first-class support for microtasks, // they would've been called as part of the previous callback. - if (!ReactNativeFeatureFlags::enableMicrotasks()) { + if (ReactNativeFeatureFlags::disableEventLoopOnBridgeless()) { if (auto timerManager = weakTimerManager.lock()) { timerManager->callReactNativeMicrotasks(jsiRuntime); } diff --git a/packages/react-native/ReactCommon/react/runtime/TimerManager.cpp b/packages/react-native/ReactCommon/react/runtime/TimerManager.cpp index bc205ce3181..e450159a7f6 100644 --- a/packages/react-native/ReactCommon/react/runtime/TimerManager.cpp +++ b/packages/react-native/ReactCommon/react/runtime/TimerManager.cpp @@ -226,7 +226,7 @@ void TimerManager::attachGlobals(jsi::Runtime& runtime) { // Ensure that we don't define `setImmediate` and `clearImmediate` if // microtasks are enabled (as we polyfill them using `queueMicrotask` then). - if (!ReactNativeFeatureFlags::enableMicrotasks()) { + if (ReactNativeFeatureFlags::disableEventLoopOnBridgeless()) { runtime.global().setProperty( runtime, "setImmediate", diff --git a/packages/react-native/ReactCommon/react/runtime/hermes/HermesInstance.cpp b/packages/react-native/ReactCommon/react/runtime/hermes/HermesInstance.cpp index 8e2e193a53c..9d59d460438 100644 --- a/packages/react-native/ReactCommon/react/runtime/hermes/HermesInstance.cpp +++ b/packages/react-native/ReactCommon/react/runtime/hermes/HermesInstance.cpp @@ -147,7 +147,9 @@ std::unique_ptr HermesInstance::createJSRuntime( ::hermes::vm::RuntimeConfig::Builder() .withGCConfig(gcConfig.build()) .withEnableSampleProfiling(true) - .withMicrotaskQueue(ReactNativeFeatureFlags::enableMicrotasks()) + .withMicrotaskQueue( + ReactNativeFeatureFlags::enableBridgelessArchitecture() && + !ReactNativeFeatureFlags::disableEventLoopOnBridgeless()) .withVMExperimentFlags(vmExperimentFlags); if (crashManager) { diff --git a/packages/react-native/ReactCommon/react/runtime/tests/cxx/ReactInstanceTest.cpp b/packages/react-native/ReactCommon/react/runtime/tests/cxx/ReactInstanceTest.cpp index cfee71e3c3e..7fb0c662c23 100644 --- a/packages/react-native/ReactCommon/react/runtime/tests/cxx/ReactInstanceTest.cpp +++ b/packages/react-native/ReactCommon/react/runtime/tests/cxx/ReactInstanceTest.cpp @@ -237,136 +237,6 @@ TEST_F(ReactInstanceTest, testProfilingFlag) { EXPECT_EQ(val.getBool(), true); } -TEST_F(ReactInstanceTest, testPromiseIntegration) { - initializeRuntimeWithScript(""); - - eval(R"xyz123( -let called = 0; -function getResult() { - return called; -} -Promise.resolve().then(() => { - called++; -}).then(() => { - called++; -}) -)xyz123"); - auto result = runtime_->global() - .getPropertyAsFunction(*runtime_, "getResult") - .call(*runtime_); - EXPECT_EQ(result.getNumber(), 2); -} - -TEST_F(ReactInstanceTest, testSetImmediate) { - initializeRuntimeWithScript(""); - - eval(R"xyz123( -let called = false; -function getResult() { - return called; -} -setImmediate(() => { - called = true; -}); -)xyz123"); - auto result = runtime_->global() - .getPropertyAsFunction(*runtime_, "getResult") - .call(*runtime_); - EXPECT_EQ(result.getBool(), true); -} - -TEST_F(ReactInstanceTest, testNestedSetImmediate) { - initializeRuntimeWithScript(""); - - eval(R"xyz123( -let called = false; -function getResult() { - return called; -} -setImmediate(() => { - setImmediate(() => { - called = true; - }) -}); -)xyz123"); - auto result = runtime_->global() - .getPropertyAsFunction(*runtime_, "getResult") - .call(*runtime_); - EXPECT_EQ(result.getBool(), true); -} - -TEST_F(ReactInstanceTest, testSetImmediateWithInvalidArgs) { - initializeRuntimeWithScript(""); - - EXPECT_EQ( - getErrorMessage("setImmediate();"), - "setImmediate must be called with at least one argument (a function to call)"); - - eval("setImmediate('invalid');"); - expectNoError(); - - eval("setImmediate({});"); - expectNoError(); -} - -TEST_F(ReactInstanceTest, testClearImmediate) { - initializeRuntimeWithScript(""); - - eval(R"xyz123( -let called = false; -function getResult() { - return called; -} -const handle = setImmediate(() => { - called = true; -}); -clearImmediate(handle); -)xyz123"); - - auto func = runtime_->global().getPropertyAsFunction(*runtime_, "getResult"); - auto val = func.call(*runtime_); - EXPECT_EQ(val.getBool(), false); -} - -TEST_F(ReactInstanceTest, testClearImmediateWithInvalidHandle) { - initializeRuntimeWithScript(""); - - auto js = R"xyz123( -let called = false; -const handle = setImmediate(() => { - called = true; -}); -function getResult() { - return called; -} -function clearInvalidHandle() { - clearImmediate(handle); -} -)xyz123"; - eval(js); - - auto clear = - runtime_->global().getPropertyAsFunction(*runtime_, "clearInvalidHandle"); - // Clearing an invalid handle should fail silently. - EXPECT_NO_THROW(clear.call((*runtime_))); -} - -TEST_F(ReactInstanceTest, testClearImmediateWithInvalidArgs) { - initializeRuntimeWithScript(""); - - eval("clearImmediate();"); - expectNoError(); - - eval("clearImmediate('invalid');"); - expectNoError(); - - eval("clearImmediate({});"); - expectNoError(); - - eval("clearImmediate(undefined);"); - expectNoError(); -} - TEST_F(ReactInstanceTest, testSetTimeout) { initializeRuntimeWithScript(""); diff --git a/packages/react-native/scripts/featureflags/README.md b/packages/react-native/scripts/featureflags/README.md index b39adfbda6a..7f774a944c4 100644 --- a/packages/react-native/scripts/featureflags/README.md +++ b/packages/react-native/scripts/featureflags/README.md @@ -18,14 +18,14 @@ Example contents: ```javascript module.exports = { common: { - enableMicrotasks: { - description: 'Enable the use of microtasks in the JS runtime.', + enableNativeBehavior: { + description: 'Enable some behavior both in native and in JS.', defaultValue: false } }, jsOnly: { - enableAccessToHostTreeInFabric: { - description: 'Enables access to the host tree in Fabric using DOM-compatible APIs.', + enableJSBehavior: { + description: 'Enables some behavior in the JS layer.', defaultValue: false } } @@ -57,7 +57,7 @@ from JavaScript. ```c++ #include -if (ReactNativeFeatureFlags::enableMicrotasks()) { +if (ReactNativeFeatureFlags::enableNativeBehavior()) { // do something } ``` @@ -68,7 +68,7 @@ if (ReactNativeFeatureFlags::enableMicrotasks()) { import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags fun someMethod() { - if (ReactNativeFeatureFlags.enableMicrotasks()) { + if (ReactNativeFeatureFlags.enableNativeBehavior()) { // do something } } @@ -79,11 +79,11 @@ fun someMethod() { ```javascript import * as ReactNativeFeatureFlags from 'react-native/src/private/featureflags/ReactNativeFeatureFlags'; -if (ReactNativeFeatureFlags.enableMicrotasks()) { +if (ReactNativeFeatureFlags.enableNativeBehavior()) { // Native flag } -if (ReactNativeFeatureFlags.enableAccessToHostTreeInFabric()) { +if (ReactNativeFeatureFlags.enableJSBehavior()) { // JS-only flag } ``` @@ -109,7 +109,7 @@ class CustomReactNativeFeatureFlags : public ReactNativeFeatureFlagsDefaults { public: CustomReactNativeFeatureFlags(); - bool enableMicrotasks() override { + bool enableNativeBehavior() override { return true; } } @@ -136,7 +136,7 @@ fun overrideFeatureFlags() { import * as ReactNativeFeatureFlags from 'react-native/src/private/featureflags/ReactNativeFeatureFlags'; ReactNativeFeatureFlags.override({ - enableAccessToHostTreeInFabric: () => true, + enableJSBehavior: () => true, }); ``` diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index 765f7f18613..30305c627d6 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -70,6 +70,8 @@ const definitions: FeatureFlagDefinitions = { 'When enabled, the RuntimeScheduler processing the event loop will batch all rendering updates and dispatch them together at the end of each iteration of the loop.', purpose: 'release', }, + // We're preparing to clean up this feature flag. + skipNativeAPI: true, }, completeReactInstanceCreationOnBgThreadOnAndroid: { defaultValue: false, @@ -80,6 +82,14 @@ const definitions: FeatureFlagDefinitions = { purpose: 'experimentation', }, }, + disableEventLoopOnBridgeless: { + defaultValue: false, + metadata: { + description: + 'The bridgeless architecture enables the event loop by default. This feature flag allows us to force disabling it in specific instances.', + purpose: 'release', + }, + }, enableAlignItemsBaselineOnFabricIOS: { defaultValue: true, metadata: { @@ -211,6 +221,8 @@ const definitions: FeatureFlagDefinitions = { 'Enables the use of microtasks in Hermes (scheduling) and RuntimeScheduler (execution).', purpose: 'release', }, + // We're preparing to clean up this feature flag. + skipNativeAPI: true, }, enablePreciseSchedulingForPremountItemsOnAndroid: { defaultValue: false, @@ -393,6 +405,8 @@ const definitions: FeatureFlagDefinitions = { 'When enabled, it uses the modern fork of RuntimeScheduler that allows scheduling tasks with priorities from any thread.', purpose: 'release', }, + // We're preparing to clean up this feature flag. + skipNativeAPI: true, }, useNativeViewConfigsInBridgelessMode: { defaultValue: false, diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index 22521f5378d..c770fc30a73 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<<1c91049b99046065031ca8b826ab20a6>> * @flow strict */ @@ -55,6 +55,7 @@ export type ReactNativeFeatureFlags = { allowRecursiveCommitsWithSynchronousMountOnAndroid: Getter, batchRenderingUpdatesInEventLoop: Getter, completeReactInstanceCreationOnBgThreadOnAndroid: Getter, + disableEventLoopOnBridgeless: Getter, enableAlignItemsBaselineOnFabricIOS: Getter, enableAndroidLineHeightCentering: Getter, enableBridgelessArchitecture: Getter, @@ -205,6 +206,10 @@ export const batchRenderingUpdatesInEventLoop: Getter = createNativeFla * Do not wait for a main-thread dispatch to complete init to start executing work on the JS thread on Android */ export const completeReactInstanceCreationOnBgThreadOnAndroid: Getter = createNativeFlagGetter('completeReactInstanceCreationOnBgThreadOnAndroid', false); +/** + * The bridgeless architecture enables the event loop by default. This feature flag allows us to force disabling it in specific instances. + */ +export const disableEventLoopOnBridgeless: Getter = createNativeFlagGetter('disableEventLoopOnBridgeless', false); /** * Kill-switch to turn off support for aling-items:baseline on Fabric iOS. */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index d908c98b408..7e28062e988 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<<255e1fec50a4c211c3cc814eaf92ee9b>> * @flow strict */ @@ -28,6 +28,7 @@ export interface Spec extends TurboModule { +allowRecursiveCommitsWithSynchronousMountOnAndroid?: () => boolean; +batchRenderingUpdatesInEventLoop?: () => boolean; +completeReactInstanceCreationOnBgThreadOnAndroid?: () => boolean; + +disableEventLoopOnBridgeless?: () => boolean; +enableAlignItemsBaselineOnFabricIOS?: () => boolean; +enableAndroidLineHeightCentering?: () => boolean; +enableBridgelessArchitecture?: () => boolean;