From 2d9fe115789d1e00d2fee3440ec372025c7b2a4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Norte?= Date: Thu, 17 Oct 2024 04:42:37 -0700 Subject: [PATCH] Unify feature flags for event loop (2nd attempt) (#47084) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47084 Changelog: [internal] This unifies all the feature flags that control the new event loop on RN. Before, we'd have granular flags for different aspects of it. With this diff, we enable the event loop by default with bridgeless, and we introduce a new flag to explicitly disable it in that case if necessary. When we're ready to clean up this opt-out, we just need to remove the `&& !ReactNativeFeatureFlags::disableEventLoopOnBridgeless()` conditions. Reviewed By: fkgozali Differential Revision: D64464902 fbshipit-source-id: d1a0ba38dd4c189c2da905b49de23a821223ac3a --- .../Libraries/AppDelegate/RCTAppDelegate.mm | 12 -- .../Libraries/Core/setUpTimers.js | 31 +++-- .../featureflags/ReactNativeFeatureFlags.kt | 26 +--- .../ReactNativeFeatureFlagsCxxAccessor.kt | 42 ++---- .../ReactNativeFeatureFlagsCxxInterop.kt | 10 +- .../ReactNativeFeatureFlagsDefaults.kt | 10 +- .../ReactNativeFeatureFlagsLocalAccessor.kt | 46 ++----- .../ReactNativeFeatureFlagsProvider.kt | 10 +- ...tiveNewArchitectureFeatureFlagsDefaults.kt | 9 -- .../JReactNativeFeatureFlagsCxxInterop.cpp | 58 ++------ .../JReactNativeFeatureFlagsCxxInterop.h | 12 +- .../featureflags/ReactNativeFeatureFlags.cpp | 18 +-- .../featureflags/ReactNativeFeatureFlags.h | 22 +-- .../ReactNativeFeatureFlagsAccessor.cpp | 128 +++++++---------- .../ReactNativeFeatureFlagsAccessor.h | 12 +- .../ReactNativeFeatureFlagsDefaults.h | 14 +- .../ReactNativeFeatureFlagsProvider.h | 6 +- .../NativeReactNativeFeatureFlags.cpp | 19 ++- .../NativeReactNativeFeatureFlags.h | 4 +- .../NativeMutationObserver.cpp | 3 +- .../runtimescheduler/RuntimeScheduler.cpp | 3 +- .../RuntimeScheduler_Modern.cpp | 30 +--- .../tests/RuntimeSchedulerTest.cpp | 47 ++----- .../react/runtime/ReactInstance.cpp | 2 +- .../react/runtime/TimerManager.cpp | 2 +- .../react/runtime/hermes/HermesInstance.cpp | 4 +- .../runtime/tests/cxx/ReactInstanceTest.cpp | 130 ------------------ .../scripts/featureflags/README.md | 20 +-- .../ReactNativeFeatureFlags.config.js | 14 ++ .../featureflags/ReactNativeFeatureFlags.js | 7 +- .../specs/NativeReactNativeFeatureFlags.js | 3 +- 31 files changed, 224 insertions(+), 530 deletions(-) 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;