From 0383669a4b19289678ed75b28e38a74fabb01a64 Mon Sep 17 00:00:00 2001 From: John Ward Date: Wed, 1 May 2024 16:41:53 -0700 Subject: [PATCH] Only schedule Choreographer callbacks if there's an active animation Summary: Changelog: [Internal] A very similar diff was attempted with D50647971 and reverted in D51617862. The main difference here is all behavior is gated behind the feature flag. Before, we were enqueuing the extra frame callback on start_animating_node even if ondemand choreographer was disabled. Reviewed By: javache Differential Revision: D56085369 fbshipit-source-id: fa6335303fe98199b18fa2b4819110afb8efcc0d --- .../react/animated/NativeAnimatedModule.java | 30 +++++++++++-------- .../featureflags/ReactNativeFeatureFlags.kt | 8 ++++- .../ReactNativeFeatureFlagsCxxAccessor.kt | 12 +++++++- .../ReactNativeFeatureFlagsCxxInterop.kt | 4 ++- .../ReactNativeFeatureFlagsDefaults.kt | 4 ++- .../ReactNativeFeatureFlagsLocalAccessor.kt | 13 +++++++- .../ReactNativeFeatureFlagsProvider.kt | 4 ++- .../JReactNativeFeatureFlagsCxxInterop.cpp | 16 +++++++++- .../JReactNativeFeatureFlagsCxxInterop.h | 5 +++- .../featureflags/ReactNativeFeatureFlags.cpp | 6 +++- .../featureflags/ReactNativeFeatureFlags.h | 7 ++++- .../ReactNativeFeatureFlagsAccessor.cpp | 28 +++++++++++++---- .../ReactNativeFeatureFlagsAccessor.h | 6 ++-- .../ReactNativeFeatureFlagsDefaults.h | 6 +++- .../ReactNativeFeatureFlagsProvider.h | 3 +- .../NativeReactNativeFeatureFlags.cpp | 7 ++++- .../NativeReactNativeFeatureFlags.h | 4 ++- .../ReactNativeFeatureFlags.config.js | 5 ++++ .../featureflags/ReactNativeFeatureFlags.js | 7 ++++- .../specs/NativeReactNativeFeatureFlags.js | 3 +- 20 files changed, 143 insertions(+), 35 deletions(-) diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java index e8c66da438d322..bbe82a56ed9cf6 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java @@ -25,6 +25,7 @@ import com.facebook.react.bridge.UIManagerListener; import com.facebook.react.bridge.WritableMap; import com.facebook.react.common.annotations.VisibleForTesting; +import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags; import com.facebook.react.module.annotations.ReactModule; import com.facebook.react.modules.core.ReactChoreographer; import com.facebook.react.uimanager.GuardedFrameCallback; @@ -225,6 +226,7 @@ void executeBatch(long maxBatchNumber, NativeAnimatedNodesManager nodesManager) private boolean mInitializedForFabric = false; private boolean mInitializedForNonFabric = false; + private boolean mEnqueuedAnimationOnFrame = false; private @UIManagerType int mUIManagerType = UIManagerType.DEFAULT; private int mNumFabricAnimations = 0; private int mNumNonFabricAnimations = 0; @@ -238,23 +240,20 @@ public NativeAnimatedModule(ReactApplicationContext reactContext) { @Override protected void doFrameGuarded(final long frameTimeNanos) { try { + mEnqueuedAnimationOnFrame = false; NativeAnimatedNodesManager nodesManager = getNodesManager(); if (nodesManager != null && nodesManager.hasActiveAnimations()) { nodesManager.runUpdates(frameTimeNanos); } // This is very unlikely to ever be hit. - if (nodesManager == null && mReactChoreographer == null) { + if (nodesManager == null || mReactChoreographer == null) { return; } - // TODO: Would be great to avoid adding this callback in case there are no active - // animations and no outstanding tasks on the operations queue. Apparently frame - // callbacks can only be posted from the UI thread and therefore we cannot schedule - // them directly from other threads. - Assertions.assertNotNull(mReactChoreographer) - .postFrameCallback( - ReactChoreographer.CallbackType.NATIVE_ANIMATED_MODULE, - mAnimatedFrameCallback); + if (!ReactNativeFeatureFlags.lazyAnimationCallbacks() + || nodesManager.hasActiveAnimations()) { + enqueueFrameCallback(); + } } catch (Exception ex) { throw new RuntimeException(ex); } @@ -406,12 +405,16 @@ private void clearFrameCallback() { Assertions.assertNotNull(mReactChoreographer) .removeFrameCallback( ReactChoreographer.CallbackType.NATIVE_ANIMATED_MODULE, mAnimatedFrameCallback); + mEnqueuedAnimationOnFrame = false; } private void enqueueFrameCallback() { - Assertions.assertNotNull(mReactChoreographer) - .postFrameCallback( - ReactChoreographer.CallbackType.NATIVE_ANIMATED_MODULE, mAnimatedFrameCallback); + if (!mEnqueuedAnimationOnFrame) { + Assertions.assertNotNull(mReactChoreographer) + .postFrameCallback( + ReactChoreographer.CallbackType.NATIVE_ANIMATED_MODULE, mAnimatedFrameCallback); + mEnqueuedAnimationOnFrame = true; + } } @VisibleForTesting @@ -1117,6 +1120,9 @@ public void onValueUpdate(double value) { opsAndArgs.getInt(i++), opsAndArgs.getInt(i++)); break; case OP_CODE_START_ANIMATING_NODE: + if (ReactNativeFeatureFlags.lazyAnimationCallbacks()) { + enqueueFrameCallback(); + } animatedNodesManager.startAnimatingNode( opsAndArgs.getInt(i++), opsAndArgs.getInt(i++), opsAndArgs.getMap(i++), null); break; 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 5eaf2d12ff6c0e..7d790ef2d53be8 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<<2ce486e0fad0c305ea953c877e146104>> + * @generated SignedSource<<3585602cd983452045d3165edbafc0ca>> */ /** @@ -118,6 +118,12 @@ public object ReactNativeFeatureFlags { @JvmStatic public fun inspectorEnableModernCDPRegistry(): Boolean = accessor.inspectorEnableModernCDPRegistry() + /** + * Only enqueue Choreographer calls if there is an ongoing animation, instead of enqueueing every frame. + */ + @JvmStatic + public fun lazyAnimationCallbacks(): Boolean = accessor.lazyAnimationCallbacks() + /** * When enabled, ParagraphShadowNode will no longer call measure twice. */ 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 d6417f03776603..7f6a519fe23bca 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<<36558176ca3a38b086a50ac90cf08c67>> */ /** @@ -35,6 +35,7 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso private var forceBatchingMountItemsOnAndroidCache: Boolean? = null private var inspectorEnableCxxInspectorPackagerConnectionCache: Boolean? = null private var inspectorEnableModernCDPRegistryCache: Boolean? = null + private var lazyAnimationCallbacksCache: Boolean? = null private var preventDoubleTextMeasureCache: Boolean? = null private var useModernRuntimeSchedulerCache: Boolean? = null private var useNativeViewConfigsInBridgelessModeCache: Boolean? = null @@ -175,6 +176,15 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso return cached } + override fun lazyAnimationCallbacks(): Boolean { + var cached = lazyAnimationCallbacksCache + if (cached == null) { + cached = ReactNativeFeatureFlagsCxxInterop.lazyAnimationCallbacks() + lazyAnimationCallbacksCache = cached + } + return cached + } + override fun preventDoubleTextMeasure(): Boolean { var cached = preventDoubleTextMeasureCache 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 2cdf0c0d741cdc..5ae3d2322891a9 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<<766945dd8430333fdf4c66129a97d039>> + * @generated SignedSource<<34806c87ad1769ee08a5322994b0bb1b>> */ /** @@ -58,6 +58,8 @@ public object ReactNativeFeatureFlagsCxxInterop { @DoNotStrip @JvmStatic public external fun inspectorEnableModernCDPRegistry(): Boolean + @DoNotStrip @JvmStatic public external fun lazyAnimationCallbacks(): Boolean + @DoNotStrip @JvmStatic public external fun preventDoubleTextMeasure(): Boolean @DoNotStrip @JvmStatic public external fun useModernRuntimeScheduler(): 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 477f9e4bb180fc..9d3791bbbb576f 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<<0c39f3c8abdce75d6a197b6227bb181e>> + * @generated SignedSource<> */ /** @@ -53,6 +53,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi override fun inspectorEnableModernCDPRegistry(): Boolean = false + override fun lazyAnimationCallbacks(): Boolean = false + override fun preventDoubleTextMeasure(): Boolean = false override fun useModernRuntimeScheduler(): 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 9856e4b3b821c4..00f2aa9e36ca77 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<<2453d73e433ecc5c13e0d08f6323539b>> + * @generated SignedSource<<40609d554dca56ea34653f0a77e5b62c>> */ /** @@ -39,6 +39,7 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces private var forceBatchingMountItemsOnAndroidCache: Boolean? = null private var inspectorEnableCxxInspectorPackagerConnectionCache: Boolean? = null private var inspectorEnableModernCDPRegistryCache: Boolean? = null + private var lazyAnimationCallbacksCache: Boolean? = null private var preventDoubleTextMeasureCache: Boolean? = null private var useModernRuntimeSchedulerCache: Boolean? = null private var useNativeViewConfigsInBridgelessModeCache: Boolean? = null @@ -194,6 +195,16 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces return cached } + override fun lazyAnimationCallbacks(): Boolean { + var cached = lazyAnimationCallbacksCache + if (cached == null) { + cached = currentProvider.lazyAnimationCallbacks() + accessedFeatureFlags.add("lazyAnimationCallbacks") + lazyAnimationCallbacksCache = cached + } + return cached + } + override fun preventDoubleTextMeasure(): Boolean { var cached = preventDoubleTextMeasureCache 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 ad4275617ae463..ec85a09323a061 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<<251133cdd333901af532b1442c68996b>> + * @generated SignedSource<<173f9f2cd094134c32a7a78c7241518c>> */ /** @@ -53,6 +53,8 @@ public interface ReactNativeFeatureFlagsProvider { @DoNotStrip public fun inspectorEnableModernCDPRegistry(): Boolean + @DoNotStrip public fun lazyAnimationCallbacks(): Boolean + @DoNotStrip public fun preventDoubleTextMeasure(): Boolean @DoNotStrip public fun useModernRuntimeScheduler(): Boolean diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp index 6ecc5841922391..3224660f56b8a8 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<<1a5515a24a45dac77e9833fecfa7d952>> + * @generated SignedSource<<70cc98f74b676cb12f4e510b88d551aa>> */ /** @@ -129,6 +129,12 @@ class ReactNativeFeatureFlagsProviderHolder return method(javaProvider_); } + bool lazyAnimationCallbacks() override { + static const auto method = + getReactNativeFeatureFlagsProviderJavaClass()->getMethod("lazyAnimationCallbacks"); + return method(javaProvider_); + } + bool preventDoubleTextMeasure() override { static const auto method = getReactNativeFeatureFlagsProviderJavaClass()->getMethod("preventDoubleTextMeasure"); @@ -232,6 +238,11 @@ bool JReactNativeFeatureFlagsCxxInterop::inspectorEnableModernCDPRegistry( return ReactNativeFeatureFlags::inspectorEnableModernCDPRegistry(); } +bool JReactNativeFeatureFlagsCxxInterop::lazyAnimationCallbacks( + facebook::jni::alias_ref /*unused*/) { + return ReactNativeFeatureFlags::lazyAnimationCallbacks(); +} + bool JReactNativeFeatureFlagsCxxInterop::preventDoubleTextMeasure( facebook::jni::alias_ref /*unused*/) { return ReactNativeFeatureFlags::preventDoubleTextMeasure(); @@ -314,6 +325,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() { makeNativeMethod( "inspectorEnableModernCDPRegistry", JReactNativeFeatureFlagsCxxInterop::inspectorEnableModernCDPRegistry), + makeNativeMethod( + "lazyAnimationCallbacks", + JReactNativeFeatureFlagsCxxInterop::lazyAnimationCallbacks), makeNativeMethod( "preventDoubleTextMeasure", JReactNativeFeatureFlagsCxxInterop::preventDoubleTextMeasure), 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 5d298a133e055a..b84d0c24fb6be7 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<<4fa2aa14a3e8646855b6464dc6fb3668>> + * @generated SignedSource<<5065ed4400b76ae62f43ec64ee03ebd2>> */ /** @@ -75,6 +75,9 @@ class JReactNativeFeatureFlagsCxxInterop static bool inspectorEnableModernCDPRegistry( facebook::jni::alias_ref); + static bool lazyAnimationCallbacks( + facebook::jni::alias_ref); + static bool preventDoubleTextMeasure( 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 05a9ff9d4363c1..8838fe683b6d31 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<<6c09901762e8ae0cb33f014a4b982acc>> + * @generated SignedSource<<6c93c729ef1a05b5b7d00bafa1f386ad>> */ /** @@ -81,6 +81,10 @@ bool ReactNativeFeatureFlags::inspectorEnableModernCDPRegistry() { return getAccessor().inspectorEnableModernCDPRegistry(); } +bool ReactNativeFeatureFlags::lazyAnimationCallbacks() { + return getAccessor().lazyAnimationCallbacks(); +} + bool ReactNativeFeatureFlags::preventDoubleTextMeasure() { return getAccessor().preventDoubleTextMeasure(); } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.h index 536fabdc7e069e..9ed1e0e3e253a0 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<<029cba10ed8a02c85ecc54d4752e8e14>> + * @generated SignedSource<> */ /** @@ -112,6 +112,11 @@ class ReactNativeFeatureFlags { */ RN_EXPORT static bool inspectorEnableModernCDPRegistry(); + /** + * Only enqueue Choreographer calls if there is an ongoing animation, instead of enqueueing every frame. + */ + RN_EXPORT static bool lazyAnimationCallbacks(); + /** * When enabled, ParagraphShadowNode will no longer call measure twice. */ diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.cpp index cf20f14483ef66..987bf78b579f0b 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<<0681b9ba9141253f4caf6e2bac00a60f>> + * @generated SignedSource<<2091c7b1d7d19d8967a6bb5ebb2ac76f>> */ /** @@ -299,6 +299,24 @@ bool ReactNativeFeatureFlagsAccessor::inspectorEnableModernCDPRegistry() { return flagValue.value(); } +bool ReactNativeFeatureFlagsAccessor::lazyAnimationCallbacks() { + auto flagValue = lazyAnimationCallbacks_.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(15, "lazyAnimationCallbacks"); + + flagValue = currentProvider_->lazyAnimationCallbacks(); + lazyAnimationCallbacks_ = flagValue; + } + + return flagValue.value(); +} + bool ReactNativeFeatureFlagsAccessor::preventDoubleTextMeasure() { auto flagValue = preventDoubleTextMeasure_.load(); @@ -308,7 +326,7 @@ bool ReactNativeFeatureFlagsAccessor::preventDoubleTextMeasure() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(15, "preventDoubleTextMeasure"); + markFlagAsAccessed(16, "preventDoubleTextMeasure"); flagValue = currentProvider_->preventDoubleTextMeasure(); preventDoubleTextMeasure_ = flagValue; @@ -326,7 +344,7 @@ bool ReactNativeFeatureFlagsAccessor::useModernRuntimeScheduler() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(16, "useModernRuntimeScheduler"); + markFlagAsAccessed(17, "useModernRuntimeScheduler"); flagValue = currentProvider_->useModernRuntimeScheduler(); useModernRuntimeScheduler_ = flagValue; @@ -344,7 +362,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(17, "useNativeViewConfigsInBridgelessMode"); + markFlagAsAccessed(18, "useNativeViewConfigsInBridgelessMode"); flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode(); useNativeViewConfigsInBridgelessMode_ = flagValue; @@ -362,7 +380,7 @@ bool ReactNativeFeatureFlagsAccessor::useStateAlignmentMechanism() { // be accessing the provider multiple times but the end state of this // instance and the returned flag value would be the same. - markFlagAsAccessed(18, "useStateAlignmentMechanism"); + markFlagAsAccessed(19, "useStateAlignmentMechanism"); flagValue = currentProvider_->useStateAlignmentMechanism(); useStateAlignmentMechanism_ = flagValue; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsAccessor.h index 48c25800054c3e..c27fc587fdfcec 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<<7fde6d4edaab918ff5cfd1df7e496333>> */ /** @@ -46,6 +46,7 @@ class ReactNativeFeatureFlagsAccessor { bool forceBatchingMountItemsOnAndroid(); bool inspectorEnableCxxInspectorPackagerConnection(); bool inspectorEnableModernCDPRegistry(); + bool lazyAnimationCallbacks(); bool preventDoubleTextMeasure(); bool useModernRuntimeScheduler(); bool useNativeViewConfigsInBridgelessMode(); @@ -60,7 +61,7 @@ class ReactNativeFeatureFlagsAccessor { std::unique_ptr currentProvider_; bool wasOverridden_; - std::array, 19> accessedFeatureFlags_; + std::array, 20> accessedFeatureFlags_; std::atomic> commonTestFlag_; std::atomic> allowCollapsableChildren_; @@ -77,6 +78,7 @@ class ReactNativeFeatureFlagsAccessor { std::atomic> forceBatchingMountItemsOnAndroid_; std::atomic> inspectorEnableCxxInspectorPackagerConnection_; std::atomic> inspectorEnableModernCDPRegistry_; + std::atomic> lazyAnimationCallbacks_; std::atomic> preventDoubleTextMeasure_; std::atomic> useModernRuntimeScheduler_; std::atomic> useNativeViewConfigsInBridgelessMode_; diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsDefaults.h index e469eb68834dd5..df9551fd4c42ee 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<> */ /** @@ -87,6 +87,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider { return false; } + bool lazyAnimationCallbacks() override { + return false; + } + bool preventDoubleTextMeasure() override { return false; } diff --git a/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h b/packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlagsProvider.h index cb019a099db308..b5cb2ba0b2a6b7 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<<0f88f63dfcb4b3ca71c010bc24efd56c>> */ /** @@ -40,6 +40,7 @@ class ReactNativeFeatureFlagsProvider { virtual bool forceBatchingMountItemsOnAndroid() = 0; virtual bool inspectorEnableCxxInspectorPackagerConnection() = 0; virtual bool inspectorEnableModernCDPRegistry() = 0; + virtual bool lazyAnimationCallbacks() = 0; virtual bool preventDoubleTextMeasure() = 0; virtual bool useModernRuntimeScheduler() = 0; virtual bool useNativeViewConfigsInBridgelessMode() = 0; diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.cpp index 337e04f7115cb8..66bb302b1f671f 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<<7c26b7fcb1adba6d47b0cc77ccf17bbc>> + * @generated SignedSource<<8c9f24f3410f42027e619c911625944b>> */ /** @@ -112,6 +112,11 @@ bool NativeReactNativeFeatureFlags::inspectorEnableModernCDPRegistry( return ReactNativeFeatureFlags::inspectorEnableModernCDPRegistry(); } +bool NativeReactNativeFeatureFlags::lazyAnimationCallbacks( + jsi::Runtime& /*runtime*/) { + return ReactNativeFeatureFlags::lazyAnimationCallbacks(); +} + bool NativeReactNativeFeatureFlags::preventDoubleTextMeasure( jsi::Runtime& /*runtime*/) { return ReactNativeFeatureFlags::preventDoubleTextMeasure(); diff --git a/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h b/packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h index ac8920073f5115..211328ebe0168e 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<<70c5a5fbd9642cc23318fcd08b3e1fb9>> + * @generated SignedSource<> */ /** @@ -65,6 +65,8 @@ class NativeReactNativeFeatureFlags bool inspectorEnableModernCDPRegistry(jsi::Runtime& runtime); + bool lazyAnimationCallbacks(jsi::Runtime& runtime); + bool preventDoubleTextMeasure(jsi::Runtime& runtime); bool useModernRuntimeScheduler(jsi::Runtime& runtime); diff --git a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js index dae6220f840374..5c9260cdc4e013 100644 --- a/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js +++ b/packages/react-native/scripts/featureflags/ReactNativeFeatureFlags.config.js @@ -107,6 +107,11 @@ const definitions: FeatureFlagDefinitions = { description: 'Flag determining if the modern CDP backend should be enabled. This flag is global and should not be changed across React Host lifetimes.', }, + lazyAnimationCallbacks: { + defaultValue: false, + description: + 'Only enqueue Choreographer calls if there is an ongoing animation, instead of enqueueing every frame.', + }, preventDoubleTextMeasure: { defaultValue: false, description: diff --git a/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js index 681ec124f7ee40..088ca2ff376ecc 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<<583232adaacd64df92bef3d111a08df0>> + * @generated SignedSource<> * @flow strict-local */ @@ -55,6 +55,7 @@ export type ReactNativeFeatureFlags = { forceBatchingMountItemsOnAndroid: Getter, inspectorEnableCxxInspectorPackagerConnection: Getter, inspectorEnableModernCDPRegistry: Getter, + lazyAnimationCallbacks: Getter, preventDoubleTextMeasure: Getter, useModernRuntimeScheduler: Getter, useNativeViewConfigsInBridgelessMode: Getter, @@ -161,6 +162,10 @@ export const inspectorEnableCxxInspectorPackagerConnection: Getter = cr * Flag determining if the modern CDP backend should be enabled. This flag is global and should not be changed across React Host lifetimes. */ export const inspectorEnableModernCDPRegistry: Getter = createNativeFlagGetter('inspectorEnableModernCDPRegistry', false); +/** + * Only enqueue Choreographer calls if there is an ongoing animation, instead of enqueueing every frame. + */ +export const lazyAnimationCallbacks: Getter = createNativeFlagGetter('lazyAnimationCallbacks', false); /** * When enabled, ParagraphShadowNode will no longer call measure twice. */ diff --git a/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js b/packages/react-native/src/private/featureflags/specs/NativeReactNativeFeatureFlags.js index e1595f1bc74d46..10209cf3eef15e 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<<22d2fc7d575d13cf21c782f5f5192580>> * @flow strict-local */ @@ -38,6 +38,7 @@ export interface Spec extends TurboModule { +forceBatchingMountItemsOnAndroid?: () => boolean; +inspectorEnableCxxInspectorPackagerConnection?: () => boolean; +inspectorEnableModernCDPRegistry?: () => boolean; + +lazyAnimationCallbacks?: () => boolean; +preventDoubleTextMeasure?: () => boolean; +useModernRuntimeScheduler?: () => boolean; +useNativeViewConfigsInBridgelessMode?: () => boolean;