diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java index ee4882d37f5963..4a1ba2aa7ceaad 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java @@ -142,12 +142,6 @@ public class ReactFeatureFlags { /** When enabled, rawProps in Props will not include Yoga specific props. */ public static boolean excludeYogaFromRawProps = false; - /** - * When enabled, it uses the modern fork of RuntimeScheduler that allows scheduling tasks with - * priorities from any thread. - */ - public static boolean useModernRuntimeScheduler = false; - /** * Enables storing js caller stack when creating promise in native module. This is useful in case * of Promise rejection and tracing the cause. 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 57acec871d8e3f..3ec13f323d5034 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<<941c7eb38bebe95c3b038de7bf3ae912>> + * @generated SignedSource<> */ /** @@ -27,6 +27,21 @@ object ReactNativeFeatureFlags { */ fun commonTestFlag() = accessor.commonTestFlag() + /** + * When enabled, it uses the modern fork of RuntimeScheduler that allows scheduling tasks with priorities from any thread. + */ + fun useModernRuntimeScheduler() = accessor.useModernRuntimeScheduler() + + /** + * Enables the use of microtasks in Hermes (scheduling) and RuntimeScheduler (execution). + */ + fun enableMicrotasks() = accessor.enableMicrotasks() + + /** + * 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. + */ + fun batchRenderingUpdatesInEventLoop() = accessor.batchRenderingUpdatesInEventLoop() + /** * Overrides the feature flags with the ones provided by the given provider. */ diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsAccessor.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsAccessor.kt index 07644ec6fac0a4..5202e029a1dc5f 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsAccessor.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsAccessor.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<> */ /** @@ -21,6 +21,9 @@ package com.facebook.react.internal.featureflags class ReactNativeFeatureFlagsAccessor { var commonTestFlagCache: Boolean? = null + var useModernRuntimeSchedulerCache: Boolean? = null + var enableMicrotasksCache: Boolean? = null + var batchRenderingUpdatesInEventLoopCache: Boolean? = null fun commonTestFlag(): Boolean { var cached = commonTestFlagCache @@ -30,4 +33,31 @@ class ReactNativeFeatureFlagsAccessor { } return cached } + + fun useModernRuntimeScheduler(): Boolean { + var cached = useModernRuntimeSchedulerCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.useModernRuntimeScheduler() + useModernRuntimeSchedulerCache = cached + } + return cached + } + + fun enableMicrotasks(): Boolean { + var cached = enableMicrotasksCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.enableMicrotasks() + enableMicrotasksCache = cached + } + return cached + } + + fun batchRenderingUpdatesInEventLoop(): Boolean { + var cached = batchRenderingUpdatesInEventLoopCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.batchRenderingUpdatesInEventLoop() + batchRenderingUpdatesInEventLoopCache = cached + } + return cached + } } 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 2d89df3fd95ec5..b7d27b6b66d77a 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<<08ea12cf0c10faa724fd7e16c713337b>> + * @generated SignedSource<<03e87d8f77dda52d055d719c937037e5>> */ /** @@ -29,6 +29,9 @@ object ReactNativeFeatureFlagsCxxInterop { } @DoNotStrip @JvmStatic external fun commonTestFlag(): Boolean + @DoNotStrip @JvmStatic external fun useModernRuntimeScheduler(): Boolean + @DoNotStrip @JvmStatic external fun enableMicrotasks(): Boolean + @DoNotStrip @JvmStatic external fun batchRenderingUpdatesInEventLoop(): Boolean @DoNotStrip @JvmStatic external fun override(provider: Object) 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 672547d08f5c9f..c586bc933eddaa 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<<35de3b0df307b57616b1da2c31d0e918>> + * @generated SignedSource<<3aeb4bb38c6c3e2d6ea8e868d6cd104f>> */ /** @@ -24,4 +24,7 @@ open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvider { // but that is more expensive than just duplicating the defaults here. override fun commonTestFlag(): Boolean = false + override fun useModernRuntimeScheduler(): Boolean = false + override fun enableMicrotasks(): Boolean = false + override fun batchRenderingUpdatesInEventLoop(): Boolean = false } 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 35dba61bc1c1da..45c3fd4b8ca391 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<<9f38db38c05560c89d27ce8c70000332>> + * @generated SignedSource<<6547cf335e54203e8ebfca6d737203e2>> */ /** @@ -21,4 +21,7 @@ package com.facebook.react.internal.featureflags interface ReactNativeFeatureFlagsProvider { fun commonTestFlag(): Boolean + fun useModernRuntimeScheduler(): Boolean + fun enableMicrotasks(): Boolean + fun batchRenderingUpdatesInEventLoop(): Boolean } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.java index da24155a6758f3..f9191d23d5b81d 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactInstance.java @@ -170,9 +170,6 @@ public void onHostDestroy() { // Notify JS if profiling is enabled boolean isProfiling = Systrace.isTracing(Systrace.TRACE_TAG_REACT_APPS | Systrace.TRACE_TAG_REACT_JS_VM_CALLS); - // TODO(T166383606): Remove this parameter when we remove the legacy runtime scheduler or we - // have access to ReactNativeConfig before we initialize it. - boolean useModernRuntimeScheduler = ReactFeatureFlags.useModernRuntimeScheduler; mHybridData = initHybrid( jsRuntimeFactory, @@ -182,8 +179,7 @@ public void onHostDestroy() { jsTimerExecutor, reactExceptionManager, bindingsInstaller, - isProfiling, - useModernRuntimeScheduler); + isProfiling); // Set up TurboModules Systrace.beginSection( @@ -457,8 +453,7 @@ private native HybridData initHybrid( JSTimerExecutor jsTimerExecutor, ReactJsExceptionHandler jReactExceptionsManager, @Nullable BindingsInstaller jBindingsInstaller, - boolean isProfiling, - boolean useModernRuntimeScheduler); + boolean isProfiling); @DoNotStrip private static native JSTimerExecutor createJSTimerExecutor(); 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 d23dc2b27e227a..9f1f9f04590255 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<<0c0fd104af5903288313b9e33fcc3da4>> + * @generated SignedSource<> */ /** @@ -28,6 +28,21 @@ bool JReactNativeFeatureFlagsCxxInterop::commonTestFlag( return ReactNativeFeatureFlags::commonTestFlag(); } +bool JReactNativeFeatureFlagsCxxInterop::useModernRuntimeScheduler( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::useModernRuntimeScheduler(); +} + +bool JReactNativeFeatureFlagsCxxInterop::enableMicrotasks( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::enableMicrotasks(); +} + +bool JReactNativeFeatureFlagsCxxInterop::batchRenderingUpdatesInEventLoop( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::batchRenderingUpdatesInEventLoop(); +} + void JReactNativeFeatureFlagsCxxInterop::override( facebook::jni::alias_ref /*unused*/, jni::alias_ref provider) { @@ -48,6 +63,15 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "commonTestFlag", JReactNativeFeatureFlagsCxxInterop::commonTestFlag), + makeNativeMethod( + "useModernRuntimeScheduler", + JReactNativeFeatureFlagsCxxInterop::useModernRuntimeScheduler), + makeNativeMethod( + "enableMicrotasks", + JReactNativeFeatureFlagsCxxInterop::enableMicrotasks), + makeNativeMethod( + "batchRenderingUpdatesInEventLoop", + JReactNativeFeatureFlagsCxxInterop::batchRenderingUpdatesInEventLoop), }); } 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 d64abbfd341f7d..27e7371fbc183a 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<<92dbf3bd6e30ad982edb39de8a0ca392>> + * @generated SignedSource<<6e949d7527942b6337b80caad83bce56>> */ /** @@ -33,6 +33,15 @@ class JReactNativeFeatureFlagsCxxInterop static bool commonTestFlag( facebook::jni::alias_ref); + static bool useModernRuntimeScheduler( + facebook::jni::alias_ref); + + static bool enableMicrotasks( + facebook::jni::alias_ref); + + static bool batchRenderingUpdatesInEventLoop( + facebook::jni::alias_ref); + static void override( facebook::jni::alias_ref, jni::alias_ref provider); diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/ReactNativeFeatureFlagsProviderHolder.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/ReactNativeFeatureFlagsProviderHolder.cpp index 73a1f238861fce..f7fa7967cae585 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/ReactNativeFeatureFlagsProviderHolder.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/ReactNativeFeatureFlagsProviderHolder.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<<5ed61cfc9fb54e538493d042e789dd50>> + * @generated SignedSource<> */ /** @@ -29,4 +29,28 @@ bool ReactNativeFeatureFlagsProviderHolder::commonTestFlag() { return method(javaProvider_); } +bool ReactNativeFeatureFlagsProviderHolder::useModernRuntimeScheduler() { + static const auto method = + facebook::jni::findClassStatic( + "com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider") + ->getMethod("useModernRuntimeScheduler"); + return method(javaProvider_); +} + +bool ReactNativeFeatureFlagsProviderHolder::enableMicrotasks() { + static const auto method = + facebook::jni::findClassStatic( + "com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider") + ->getMethod("enableMicrotasks"); + return method(javaProvider_); +} + +bool ReactNativeFeatureFlagsProviderHolder::batchRenderingUpdatesInEventLoop() { + static const auto method = + facebook::jni::findClassStatic( + "com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider") + ->getMethod("batchRenderingUpdatesInEventLoop"); + return method(javaProvider_); +} + } // namespace facebook::react diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/ReactNativeFeatureFlagsProviderHolder.h b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/ReactNativeFeatureFlagsProviderHolder.h index 99b67cbbcda678..8ccde6953e9ece 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/ReactNativeFeatureFlagsProviderHolder.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/ReactNativeFeatureFlagsProviderHolder.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<<3a53c648a733faf65e0524c629348a05>> + * @generated SignedSource<> */ /** @@ -36,6 +36,9 @@ class ReactNativeFeatureFlagsProviderHolder : javaProvider_(make_global(javaProvider)){}; bool commonTestFlag() override; + bool useModernRuntimeScheduler() override; + bool enableMicrotasks() override; + bool batchRenderingUpdatesInEventLoop() override; private: jni::global_ref javaProvider_; diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactInstance.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactInstance.cpp index 09a46dc4e58c90..0adccf64d7f1c1 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactInstance.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactInstance.cpp @@ -36,8 +36,7 @@ JReactInstance::JReactInstance( jni::alias_ref jsTimerExecutor, jni::alias_ref jReactExceptionManager, jni::alias_ref jBindingsInstaller, - bool isProfiling, - bool useModernRuntimeScheduler) noexcept { + bool isProfiling) noexcept { // TODO(janzer): Lazily create runtime auto sharedJSMessageQueueThread = std::make_shared(jsMessageQueueThread); @@ -65,8 +64,7 @@ JReactInstance::JReactInstance( jsRuntimeFactory->cthis()->createJSRuntime(sharedJSMessageQueueThread), sharedJSMessageQueueThread, timerManager, - std::move(jsErrorHandlingFunc), - useModernRuntimeScheduler); + std::move(jsErrorHandlingFunc)); auto bufferedRuntimeExecutor = instance_->getBufferedRuntimeExecutor(); timerManager->setRuntimeExecutor(bufferedRuntimeExecutor); @@ -117,8 +115,7 @@ jni::local_ref JReactInstance::initHybrid( jni::alias_ref jsTimerExecutor, jni::alias_ref jReactExceptionManager, jni::alias_ref jBindingsInstaller, - bool isProfiling, - bool useModernRuntimeScheduler) { + bool isProfiling) { return makeCxxInstance( jsRuntimeFactory, jsMessageQueueThread, @@ -127,8 +124,7 @@ jni::local_ref JReactInstance::initHybrid( jsTimerExecutor, jReactExceptionManager, jBindingsInstaller, - isProfiling, - useModernRuntimeScheduler); + isProfiling); } void JReactInstance::loadJSBundleFromAssets( diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactInstance.h b/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactInstance.h index 41ea4891bd50bf..b07ed7377fdfeb 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactInstance.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactInstance.h @@ -45,8 +45,7 @@ class JReactInstance : public jni::HybridClass { jni::alias_ref jsTimerExecutor, jni::alias_ref jReactExceptionManager, jni::alias_ref jBindingsInstaller, - bool isProfiling, - bool useModernRuntimeScheduler); + bool isProfiling); /* * Instantiates and returns an instance of `JSTimerExecutor`. @@ -91,8 +90,7 @@ class JReactInstance : public jni::HybridClass { jni::alias_ref jsTimerExecutor, jni::alias_ref jReactExceptionManager, jni::alias_ref jBindingsInstaller, - bool isProfiling, - bool useModernRuntimeScheduler) noexcept; + bool isProfiling) noexcept; jni::alias_ref getJSCallInvokerHolder(); jni::alias_ref diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp index 001e3d83d3d63b..0d670a78b758cf 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<<9e0a265d128f9160e999a62597098057>> + * @generated SignedSource<> */ /** @@ -25,6 +25,18 @@ bool ReactNativeFeatureFlags::commonTestFlag() { return getAccessor().commonTestFlag(); } +bool ReactNativeFeatureFlags::useModernRuntimeScheduler() { + return getAccessor().useModernRuntimeScheduler(); +} + +bool ReactNativeFeatureFlags::enableMicrotasks() { + return getAccessor().enableMicrotasks(); +} + +bool ReactNativeFeatureFlags::batchRenderingUpdatesInEventLoop() { + return getAccessor().batchRenderingUpdatesInEventLoop(); +} + void ReactNativeFeatureFlags::override( std::unique_ptr provider) { getAccessor().override(std::move(provider)); diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index 34fd4295a1add9..8607f58ec79e2a 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<0ca6f8f9d45a8c98197f8b6643076acf>> */ /** @@ -32,6 +32,21 @@ class ReactNativeFeatureFlags { */ static bool commonTestFlag(); + /** + * When enabled, it uses the modern fork of RuntimeScheduler that allows scheduling tasks with priorities from any thread. + */ + static bool useModernRuntimeScheduler(); + + /** + * Enables the use of microtasks in Hermes (scheduling) and RuntimeScheduler (execution). + */ + static bool enableMicrotasks(); + + /** + * 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. + */ + static bool batchRenderingUpdatesInEventLoop(); + /** * Overrides the feature flags with the ones provided by the given provider. */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index 315cbdac8225f8..2b5f0f39140f89 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<> */ /** @@ -36,6 +36,33 @@ bool ReactNativeFeatureFlagsAccessor::commonTestFlag() { return commonTestFlag_.value(); } +bool ReactNativeFeatureFlagsAccessor::useModernRuntimeScheduler() { + if (!useModernRuntimeScheduler_.has_value()) { + accessedFeatureFlags_.emplace("useModernRuntimeScheduler"); + useModernRuntimeScheduler_.emplace(provider_->useModernRuntimeScheduler()); + } + + return useModernRuntimeScheduler_.value(); +} + +bool ReactNativeFeatureFlagsAccessor::enableMicrotasks() { + if (!enableMicrotasks_.has_value()) { + accessedFeatureFlags_.emplace("enableMicrotasks"); + enableMicrotasks_.emplace(provider_->enableMicrotasks()); + } + + return enableMicrotasks_.value(); +} + +bool ReactNativeFeatureFlagsAccessor::batchRenderingUpdatesInEventLoop() { + if (!batchRenderingUpdatesInEventLoop_.has_value()) { + accessedFeatureFlags_.emplace("batchRenderingUpdatesInEventLoop"); + batchRenderingUpdatesInEventLoop_.emplace(provider_->batchRenderingUpdatesInEventLoop()); + } + + return batchRenderingUpdatesInEventLoop_.value(); +} + void ReactNativeFeatureFlagsAccessor::override( std::unique_ptr provider) { if (!accessedFeatureFlags_.empty()) { diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index e3aa8ec0789576..d0ea1b1fcaeb67 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -32,6 +32,9 @@ class ReactNativeFeatureFlagsAccessor { ReactNativeFeatureFlagsAccessor(); bool commonTestFlag(); + bool useModernRuntimeScheduler(); + bool enableMicrotasks(); + bool batchRenderingUpdatesInEventLoop(); void override(std::unique_ptr provider); @@ -40,6 +43,9 @@ class ReactNativeFeatureFlagsAccessor { std::set accessedFeatureFlags_; std::optional commonTestFlag_; + std::optional useModernRuntimeScheduler_; + std::optional enableMicrotasks_; + std::optional batchRenderingUpdatesInEventLoop_; }; } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index cd7ce1800d9e69..6f4b6efabea6e8 100644 --- a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h +++ b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<<4290b8b2b93d468f3c8543ea7aeedb96>> */ /** @@ -30,6 +30,18 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { bool commonTestFlag() override { return false; } + + bool useModernRuntimeScheduler() override { + return false; + } + + bool enableMicrotasks() override { + return false; + } + + bool batchRenderingUpdatesInEventLoop() override { + return false; + } }; } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index 4a8f47c305045a..0bd1d786907b78 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<<407e39a4c5d0512b267095d1a500065c>> */ /** @@ -26,6 +26,9 @@ class ReactNativeFeatureFlagsProvider { virtual ~ReactNativeFeatureFlagsProvider() = default; virtual bool commonTestFlag() = 0; + virtual bool useModernRuntimeScheduler() = 0; + virtual bool enableMicrotasks() = 0; + virtual bool batchRenderingUpdatesInEventLoop() = 0; }; } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/CMakeLists.txt b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/CMakeLists.txt index b8ad2984c8e563..7c7ec30f4ebf7a 100644 --- a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/CMakeLists.txt +++ b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/CMakeLists.txt @@ -26,4 +26,5 @@ target_link_libraries(react_render_runtimescheduler react_render_core react_render_debug react_utils + react_featureflags runtimeexecutor) diff --git a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/React-runtimescheduler.podspec b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/React-runtimescheduler.podspec index 3d44f25c8b2e06..642d71980a948b 100644 --- a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/React-runtimescheduler.podspec +++ b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/React-runtimescheduler.podspec @@ -56,6 +56,7 @@ Pod::Spec.new do |s| s.dependency "React-cxxreact" s.dependency "React-rendererdebug" s.dependency "React-utils" + s.dependency "React-featureflags" s.dependency "glog" s.dependency "RCT-Folly", folly_version s.dependency "React-jsi" diff --git a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.cpp b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.cpp index df44f0523a6639..79be477d2c240a 100644 --- a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.cpp +++ b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.cpp @@ -10,6 +10,7 @@ #include "RuntimeScheduler_Modern.h" #include "SchedulerPriorityUtils.h" +#include #include #include #include "ErrorUtils.h" @@ -19,9 +20,8 @@ namespace facebook::react { namespace { std::unique_ptr getRuntimeSchedulerImplementation( RuntimeExecutor runtimeExecutor, - bool useModernRuntimeScheduler, std::function now) { - if (useModernRuntimeScheduler) { + if (ReactNativeFeatureFlags::useModernRuntimeScheduler()) { return std::make_unique( std::move(runtimeExecutor), std::move(now)); } else { @@ -33,11 +33,9 @@ std::unique_ptr getRuntimeSchedulerImplementation( RuntimeScheduler::RuntimeScheduler( RuntimeExecutor runtimeExecutor, - bool useModernRuntimeScheduler, std::function now) : runtimeSchedulerImpl_(getRuntimeSchedulerImplementation( std::move(runtimeExecutor), - useModernRuntimeScheduler, std::move(now))) {} void RuntimeScheduler::scheduleWork(RawCallback&& callback) noexcept { diff --git a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.h b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.h index 40482a9872a838..26c2c336202df2 100644 --- a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.h +++ b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.h @@ -44,7 +44,6 @@ class RuntimeScheduler final : RuntimeSchedulerBase { public: explicit RuntimeScheduler( RuntimeExecutor runtimeExecutor, - bool useModernRuntimeScheduler = false, std::function now = RuntimeSchedulerClock::now); 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 033d5a2219e451..4a30a2ff5c4034 100644 --- a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler_Modern.cpp +++ b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler_Modern.cpp @@ -9,8 +9,8 @@ #include "SchedulerPriorityUtils.h" #include +#include #include -#include #include #include "ErrorUtils.h" @@ -173,7 +173,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 (CoreFeatures::enableMicrotasks) { + if (ReactNativeFeatureFlags::enableMicrotasks()) { return; } @@ -185,7 +185,7 @@ void RuntimeScheduler_Modern::scheduleRenderingUpdate( RuntimeSchedulerRenderingUpdate&& renderingUpdate) { SystraceSection s("RuntimeScheduler::scheduleRenderingUpdate"); - if (CoreFeatures::blockPaintForUseLayoutEffect) { + if (ReactNativeFeatureFlags::batchRenderingUpdatesInEventLoop()) { pendingRenderingUpdates_.push(renderingUpdate); } else { if (renderingUpdate != nullptr) { @@ -296,12 +296,12 @@ void RuntimeScheduler_Modern::executeTask( executeMacrotask(runtime, task, didUserCallbackTimeout); - if (CoreFeatures::enableMicrotasks) { + if (ReactNativeFeatureFlags::enableMicrotasks()) { // "Perform a microtask checkpoint" step. executeMicrotasks(runtime); } - if (CoreFeatures::blockPaintForUseLayoutEffect) { + if (ReactNativeFeatureFlags::batchRenderingUpdatesInEventLoop()) { // "Update the rendering" step. updateRendering(); } 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 8897a223d05b87..d42cc974a68b80 100644 --- a/packages/react-native/ReactCommon/react/renderer/runtimescheduler/tests/RuntimeSchedulerTest.cpp +++ b/packages/react-native/ReactCommon/react/renderer/runtimescheduler/tests/RuntimeSchedulerTest.cpp @@ -8,8 +8,9 @@ #include #include #include +#include +#include #include -#include #include #include @@ -21,19 +22,41 @@ namespace facebook::react { using namespace std::chrono_literals; +static bool forcedBatchRenderingUpdatesInEventLoop = false; + +class RuntimeSchedulerTestFeatureFlags + : public ReactNativeFeatureFlagsDefaults { + public: + RuntimeSchedulerTestFeatureFlags(bool useModernRuntimeScheduler) + : useModernRuntimeScheduler_(useModernRuntimeScheduler) {} + + bool useModernRuntimeScheduler() override { + return useModernRuntimeScheduler_; + } + + bool enableMicrotasks() override { + return useModernRuntimeScheduler_; + } + + bool batchRenderingUpdatesInEventLoop() override { + return forcedBatchRenderingUpdatesInEventLoop; + } + + private: + bool useModernRuntimeScheduler_; +}; + class RuntimeSchedulerTest : public testing::TestWithParam { protected: void SetUp() override { hostFunctionCallCount_ = 0; - auto useModernRuntimeScheduler = GetParam(); - - CoreFeatures::enableMicrotasks = useModernRuntimeScheduler; + ReactNativeFeatureFlags::override( + std::make_unique(GetParam())); // Configuration that enables microtasks ::hermes::vm::RuntimeConfig::Builder runtimeConfigBuilder = - ::hermes::vm::RuntimeConfig::Builder().withMicrotaskQueue( - useModernRuntimeScheduler); + ::hermes::vm::RuntimeConfig::Builder().withMicrotaskQueue(GetParam()); runtime_ = facebook::hermes::makeHermesRuntime(runtimeConfigBuilder.build()); @@ -54,8 +77,8 @@ class RuntimeSchedulerTest : public testing::TestWithParam { return stubClock_->getNow(); }; - runtimeScheduler_ = std::make_unique( - runtimeExecutor, useModernRuntimeScheduler, stubNow); + runtimeScheduler_ = + std::make_unique(runtimeExecutor, stubNow); } jsi::Function createHostFunctionFromLambda( @@ -125,7 +148,7 @@ TEST_P(RuntimeSchedulerTest, scheduleSingleTask) { } TEST_P(RuntimeSchedulerTest, scheduleNonBatchedRenderingUpdate) { - CoreFeatures::blockPaintForUseLayoutEffect = false; + forcedBatchRenderingUpdatesInEventLoop = false; bool didRunRenderingUpdate = false; @@ -143,7 +166,7 @@ TEST_P( return; } - CoreFeatures::blockPaintForUseLayoutEffect = true; + forcedBatchRenderingUpdatesInEventLoop = true; uint nextOperationPosition = 1; diff --git a/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp b/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp index 55e286d9434df8..d7023bc128afab 100644 --- a/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp +++ b/packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.cpp @@ -139,17 +139,6 @@ Scheduler::Scheduler( reduceDeleteCreateMutationLayoutAnimation_ = true; #endif -#ifdef ANDROID - CoreFeatures::enableMicrotasks = - reactNativeConfig_->getBool("react_fabric:enable_microtasks_android"); -#else - CoreFeatures::enableMicrotasks = - reactNativeConfig_->getBool("react_fabric:enable_microtasks_ios"); -#endif - - CoreFeatures::blockPaintForUseLayoutEffect = reactNativeConfig_->getBool( - "react_fabric:block_paint_for_use_layout_effect"); - CoreFeatures::cacheLastTextMeasurement = reactNativeConfig_->getBool("react_fabric:enable_text_measure_cache"); diff --git a/packages/react-native/ReactCommon/react/runtime/CMakeLists.txt b/packages/react-native/ReactCommon/react/runtime/CMakeLists.txt index 3a6bb1a64f1f0b..0c3bad5ab858cb 100644 --- a/packages/react-native/ReactCommon/react/runtime/CMakeLists.txt +++ b/packages/react-native/ReactCommon/react/runtime/CMakeLists.txt @@ -35,4 +35,5 @@ target_link_libraries( jsi jsireact react_utils + react_featureflags ) diff --git a/packages/react-native/ReactCommon/react/runtime/React-RuntimeCore.podspec b/packages/react-native/ReactCommon/react/runtime/React-RuntimeCore.podspec index 8ac8cc92605aa1..c94f83cafd65a4 100644 --- a/packages/react-native/ReactCommon/react/runtime/React-RuntimeCore.podspec +++ b/packages/react-native/ReactCommon/react/runtime/React-RuntimeCore.podspec @@ -55,6 +55,7 @@ Pod::Spec.new do |s| s.dependency "React-jserrorhandler" s.dependency "React-runtimescheduler" s.dependency "React-utils" + s.dependency "React-featureflags" if ENV["USE_HERMES"] == nil || ENV["USE_HERMES"] == "1" s.dependency "hermes-engine" diff --git a/packages/react-native/ReactCommon/react/runtime/React-RuntimeHermes.podspec b/packages/react-native/ReactCommon/react/runtime/React-RuntimeHermes.podspec index 6fb5d40b348b37..15ba2bde3eafa8 100644 --- a/packages/react-native/ReactCommon/react/runtime/React-RuntimeHermes.podspec +++ b/packages/react-native/ReactCommon/react/runtime/React-RuntimeHermes.podspec @@ -50,6 +50,7 @@ Pod::Spec.new do |s| s.dependency "React-utils" s.dependency "React-jsi" s.dependency "React-RuntimeCore" + s.dependency "React-featureflags" if ENV["USE_HERMES"] == nil || ENV["USE_HERMES"] == "1" s.dependency "hermes-engine" diff --git a/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp b/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp index 76b8029d258e46..75960335f68daf 100644 --- a/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp +++ b/packages/react-native/ReactCommon/react/runtime/ReactInstance.cpp @@ -15,8 +15,8 @@ #include #include #include +#include #include -#include #include #include @@ -29,8 +29,7 @@ ReactInstance::ReactInstance( std::unique_ptr runtime, std::shared_ptr jsMessageQueueThread, std::shared_ptr timerManager, - JsErrorHandler::JsErrorHandlingFunc jsErrorHandlingFunc, - bool useModernRuntimeScheduler) + JsErrorHandler::JsErrorHandlingFunc jsErrorHandlingFunc) : runtime_(std::move(runtime)), jsMessageQueueThread_(jsMessageQueueThread), timerManager_(std::move(timerManager)), @@ -70,7 +69,7 @@ ReactInstance::ReactInstance( // If we have first-class support for microtasks, // they would've been called as part of the previous callback. - if (!CoreFeatures::enableMicrotasks) { + if (!ReactNativeFeatureFlags::enableMicrotasks()) { if (auto strongTimerManager = weakTimerManager.lock()) { strongTimerManager->callReactNativeMicrotasks(jsiRuntime); } @@ -83,8 +82,8 @@ ReactInstance::ReactInstance( } }; - runtimeScheduler_ = std::make_shared( - std::move(runtimeExecutor), useModernRuntimeScheduler); + runtimeScheduler_ = + std::make_shared(std::move(runtimeExecutor)); auto pipedRuntimeExecutor = [runtimeScheduler = runtimeScheduler_.get()]( diff --git a/packages/react-native/ReactCommon/react/runtime/ReactInstance.h b/packages/react-native/ReactCommon/react/runtime/ReactInstance.h index caad761b7f07f5..b33bef28db0a23 100644 --- a/packages/react-native/ReactCommon/react/runtime/ReactInstance.h +++ b/packages/react-native/ReactCommon/react/runtime/ReactInstance.h @@ -33,8 +33,7 @@ class ReactInstance final { std::unique_ptr runtime, std::shared_ptr jsMessageQueueThread, std::shared_ptr timerManager, - JsErrorHandler::JsErrorHandlingFunc JsErrorHandlingFunc, - bool useModernRuntimeScheduler = false); + JsErrorHandler::JsErrorHandlingFunc JsErrorHandlingFunc); RuntimeExecutor getUnbufferedRuntimeExecutor() noexcept; diff --git a/packages/react-native/ReactCommon/react/runtime/hermes/CMakeLists.txt b/packages/react-native/ReactCommon/react/runtime/hermes/CMakeLists.txt index e46f159bd12f96..cbca9d9ba948fb 100644 --- a/packages/react-native/ReactCommon/react/runtime/hermes/CMakeLists.txt +++ b/packages/react-native/ReactCommon/react/runtime/hermes/CMakeLists.txt @@ -23,6 +23,7 @@ target_link_libraries(bridgelesshermes jsi hermes_executor_common bridgeless + react_featureflags ) if(${CMAKE_BUILD_TYPE} MATCHES Debug) diff --git a/packages/react-native/ReactCommon/react/runtime/hermes/HermesInstance.cpp b/packages/react-native/ReactCommon/react/runtime/hermes/HermesInstance.cpp index 6938f93b400814..50ec845f41cf61 100644 --- a/packages/react-native/ReactCommon/react/runtime/hermes/HermesInstance.cpp +++ b/packages/react-native/ReactCommon/react/runtime/hermes/HermesInstance.cpp @@ -9,6 +9,7 @@ #include #include +#include #ifdef HERMES_ENABLE_DEBUGGER #include @@ -107,16 +108,6 @@ std::unique_ptr HermesInstance::createJSRuntime( ? static_cast<::hermes::vm::gcheapsize_t>(heapSizeConfig) : 3072; -#ifdef ANDROID - bool enableMicrotasks = reactNativeConfig - ? reactNativeConfig->getBool("react_fabric:enable_microtasks_android") - : false; -#else - bool enableMicrotasks = reactNativeConfig - ? reactNativeConfig->getBool("react_fabric:enable_microtasks_ios") - : false; -#endif - ::hermes::vm::RuntimeConfig::Builder runtimeConfigBuilder = ::hermes::vm::RuntimeConfig::Builder() .withGCConfig(::hermes::vm::GCConfig::Builder() @@ -131,7 +122,7 @@ std::unique_ptr HermesInstance::createJSRuntime( .build()) .withES6Proxy(false) .withEnableSampleProfiling(true) - .withMicrotaskQueue(enableMicrotasks) + .withMicrotaskQueue(ReactNativeFeatureFlags::enableMicrotasks()) .withVMExperimentFlags(vmExperimentFlags); if (cm) { diff --git a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.h b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.h index 124504a638f997..6b869377a836a5 100644 --- a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.h +++ b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.h @@ -35,18 +35,6 @@ NS_ASSUME_NONNULL_BEGIN @end -/** - * This is a private protocol used to configure internal behavior of the runtime. - * DO NOT USE THIS OUTSIDE OF THE REACT NATIVE CODEBASE. - */ -@protocol RCTHostDelegateInternal - -// TODO(T166383606): Remove this method when we remove the legacy runtime scheduler or we have access to -// ReactNativeConfig before we initialize it. -- (BOOL)useModernRuntimeScheduler:(RCTHost *)host; - -@end - @protocol RCTHostRuntimeDelegate - (void)host:(RCTHost *)host didInitializeRuntime:(facebook::jsi::Runtime &)runtime; diff --git a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.mm b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.mm index 64daf56c38d7be..635def663353e7 100644 --- a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.mm +++ b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.mm @@ -23,7 +23,7 @@ using namespace facebook::react; -@interface RCTHost () +@interface RCTHost () @end @implementation RCTHost { @@ -247,17 +247,6 @@ - (void)instance:(RCTInstance *)instance didInitializeRuntime:(facebook::jsi::Ru [self.runtimeDelegate host:self didInitializeRuntime:runtime]; } -#pragma mark - RCTInstanceDelegateInternal - -- (BOOL)useModernRuntimeScheduler:(RCTHost *)host -{ - if ([_hostDelegate respondsToSelector:@selector(useModernRuntimeScheduler:)]) { - return [(id)_hostDelegate useModernRuntimeScheduler:self]; - } - - return NO; -} - #pragma mark - RCTContextContainerHandling - (void)didCreateContextContainer:(std::shared_ptr)contextContainer diff --git a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.h b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.h index 047dc38af97774..befe718b0535be 100644 --- a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.h +++ b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.h @@ -46,18 +46,6 @@ RCT_EXTERN void RCTInstanceSetRuntimeDiagnosticFlags(NSString *_Nullable flags); @end -/** - * This is a private protocol used to configure internal behavior of the runtime. - * DO NOT USE THIS OUTSIDE OF THE REACT NATIVE CODEBASE. - */ -@protocol RCTInstanceDelegateInternal - -// TODO(T166383606): Remove this method when we remove the legacy runtime scheduler or we have access to -// ReactNativeConfig before we initialize it. -- (BOOL)useModernRuntimeScheduler:(RCTInstance *)instance; - -@end - typedef void (^_Null_unspecified RCTInstanceInitialBundleLoadCompletionBlock)(); /** diff --git a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.mm b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.mm index 6ed73ed4d85814..03d6d9a25ae47f 100644 --- a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.mm +++ b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.mm @@ -216,18 +216,12 @@ - (void)_start __weak __typeof(self) weakSelf = self; auto jsErrorHandlingFunc = [=](MapBuffer errorMap) { [weakSelf _handleJSErrorMap:std::move(errorMap)]; }; - auto useModernRuntimeScheduler = false; - if ([_delegate respondsToSelector:@selector(useModernRuntimeScheduler:)]) { - useModernRuntimeScheduler = [(id)_delegate useModernRuntimeScheduler:self]; - } - // Create the React Instance _reactInstance = std::make_unique( _jsRuntimeFactory->createJSRuntime(_jsThreadManager.jsMessageThread), _jsThreadManager.jsMessageThread, timerManager, - jsErrorHandlingFunc, - useModernRuntimeScheduler); + jsErrorHandlingFunc); _valid = true; RuntimeExecutor bufferedRuntimeExecutor = _reactInstance->getBufferedRuntimeExecutor(); diff --git a/packages/react-native/ReactCommon/react/utils/CoreFeatures.cpp b/packages/react-native/ReactCommon/react/utils/CoreFeatures.cpp index fcdc92e97f9941..19b3535c5473c1 100644 --- a/packages/react-native/ReactCommon/react/utils/CoreFeatures.cpp +++ b/packages/react-native/ReactCommon/react/utils/CoreFeatures.cpp @@ -10,7 +10,6 @@ namespace facebook::react { bool CoreFeatures::enablePropIteratorSetter = false; -bool CoreFeatures::blockPaintForUseLayoutEffect = false; bool CoreFeatures::cacheLastTextMeasurement = false; bool CoreFeatures::cancelImageDownloadsOnRecycle = false; bool CoreFeatures::enableGranularScrollViewStateUpdatesIOS = false; @@ -19,7 +18,6 @@ bool CoreFeatures::enableGranularShadowTreeStateReconciliation = false; bool CoreFeatures::enableDefaultAsyncBatchedPriority = false; bool CoreFeatures::enableClonelessStateProgression = false; bool CoreFeatures::excludeYogaFromRawProps = false; -bool CoreFeatures::enableMicrotasks = false; bool CoreFeatures::enableReportEventPaintTime = false; } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/utils/CoreFeatures.h b/packages/react-native/ReactCommon/react/utils/CoreFeatures.h index 2af28d74a10b9e..7e94452c58d56a 100644 --- a/packages/react-native/ReactCommon/react/utils/CoreFeatures.h +++ b/packages/react-native/ReactCommon/react/utils/CoreFeatures.h @@ -19,11 +19,6 @@ class CoreFeatures { // Specifies whether the iterator-style prop parsing is enabled. static bool enablePropIteratorSetter; - // When enabled, Fabric will block paint to allow for state updates in - // useLayoutEffect hooks to be processed. This changes affects scheduling of - // when a transaction is mounted. - static bool blockPaintForUseLayoutEffect; - // Yoga might measure multiple times the same Text with the same constraints // This flag enables a caching mechanism to avoid subsequents measurements // of the same Text with the same constrainst. @@ -54,10 +49,6 @@ class CoreFeatures { // When enabled, rawProps in Props will not include Yoga specific props. static bool excludeYogaFromRawProps; - // Enables the use of microtasks in Hermes (scheduling) and RuntimeScheduler - // (execution). - static bool enableMicrotasks; - // Report paint time inside the Event Timing API implementation // (PerformanceObserver). static bool enableReportEventPaintTime; diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json index 974c2f6fce5c13..dc94424def4951 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.json @@ -3,6 +3,18 @@ "commonTestFlag": { "description": "Common flag for testing. Do NOT modify.", "defaultValue": false + }, + "useModernRuntimeScheduler": { + "description": "When enabled, it uses the modern fork of RuntimeScheduler that allows scheduling tasks with priorities from any thread.", + "defaultValue": false + }, + "enableMicrotasks": { + "description": "Enables the use of microtasks in Hermes (scheduling) and RuntimeScheduler (execution).", + "defaultValue": false + }, + "batchRenderingUpdatesInEventLoop": { + "description": "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.", + "defaultValue": false } }, "jsOnly": { diff --git a/packages/react-native/src/private/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/src/private/featureflags/NativeReactNativeFeatureFlags.cpp index 5ada029545dbb6..131dba150a9463 100644 --- a/packages/react-native/src/private/featureflags/NativeReactNativeFeatureFlags.cpp +++ b/packages/react-native/src/private/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<> + * @generated SignedSource<> */ /** @@ -40,4 +40,19 @@ bool NativeReactNativeFeatureFlags::commonTestFlag( return ReactNativeFeatureFlags::commonTestFlag(); } +bool NativeReactNativeFeatureFlags::useModernRuntimeScheduler( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::useModernRuntimeScheduler(); +} + +bool NativeReactNativeFeatureFlags::enableMicrotasks( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::enableMicrotasks(); +} + +bool NativeReactNativeFeatureFlags::batchRenderingUpdatesInEventLoop( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::batchRenderingUpdatesInEventLoop(); +} + } // namespace facebook::react diff --git a/packages/react-native/src/private/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/src/private/featureflags/NativeReactNativeFeatureFlags.h index 75b35bbf810b8a..bf9114aea84700 100644 --- a/packages/react-native/src/private/featureflags/NativeReactNativeFeatureFlags.h +++ b/packages/react-native/src/private/featureflags/NativeReactNativeFeatureFlags.h @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<> + * @generated SignedSource<> */ /** @@ -31,6 +31,12 @@ class NativeReactNativeFeatureFlags NativeReactNativeFeatureFlags(std::shared_ptr jsInvoker); bool commonTestFlag(jsi::Runtime& runtime); + + bool useModernRuntimeScheduler(jsi::Runtime& runtime); + + bool enableMicrotasks(jsi::Runtime& runtime); + + bool batchRenderingUpdatesInEventLoop(jsi::Runtime& runtime); }; } // namespace facebook::react diff --git a/packages/react-native/src/private/featureflags/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/NativeReactNativeFeatureFlags.js index ed0ae35f6cb38e..ff54caee54bd9f 100644 --- a/packages/react-native/src/private/featureflags/NativeReactNativeFeatureFlags.js +++ b/packages/react-native/src/private/featureflags/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<<12aae6bfc9c4a95590a87d7db664e201>> + * @generated SignedSource<<68f610d57514d247f87e4c4c1feef76b>> * @flow strict-local */ @@ -24,6 +24,9 @@ import * as TurboModuleRegistry from '../../../Libraries/TurboModule/TurboModule export interface Spec extends TurboModule { +commonTestFlag?: () => boolean; + +useModernRuntimeScheduler?: () => boolean; + +enableMicrotasks?: () => boolean; + +batchRenderingUpdatesInEventLoop?: () => boolean; } const NativeReactNativeFeatureFlags: ?Spec = TurboModuleRegistry.get( diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index 182cda6eef857f..1b608995767f52 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<<061d4aa2a7aef7d44565de7f62561846>> + * @generated SignedSource<> * @flow strict-local */ @@ -34,6 +34,9 @@ export type ReactNativeFeatureFlagsJsOnlyOverrides = Partial, + useModernRuntimeScheduler: Getter, + enableMicrotasks: Getter, + batchRenderingUpdatesInEventLoop: Getter, } /** @@ -45,6 +48,18 @@ export const jsOnlyTestFlag: Getter = createJavaScriptFlagGetter('jsOnl * Common flag for testing. Do NOT modify. */ export const commonTestFlag: Getter = createNativeFlagGetter('commonTestFlag', false); +/** + * When enabled, it uses the modern fork of RuntimeScheduler that allows scheduling tasks with priorities from any thread. + */ +export const useModernRuntimeScheduler: Getter = createNativeFlagGetter('useModernRuntimeScheduler', false); +/** + * Enables the use of microtasks in Hermes (scheduling) and RuntimeScheduler (execution). + */ +export const enableMicrotasks: Getter = createNativeFlagGetter('enableMicrotasks', false); +/** + * 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. + */ +export const batchRenderingUpdatesInEventLoop: Getter = createNativeFlagGetter('batchRenderingUpdatesInEventLoop', false); /** * Overrides the feature flags with the provided methods.