From a8c242088b1090a97d68eedc70398089ecb3d066 Mon Sep 17 00:00:00 2001 From: Bartlomiej Bloniarz Date: Mon, 12 Jan 2026 03:11:16 -0800 Subject: [PATCH] Introduce Scheduler briding logic for native Choreographer implementations (#55102) Summary: This diff adds a scaffolding allowing for the Animation Backend to access platform-specific animation frame scheduling. # Changelog [General] [Added] - `schedulerShouldResumeAnimationFrameCallbacks` and `schedulerShouldPauseAnimationFrameCallbacks` methods to `SchedulerDelegate` Differential Revision: D89663244 --- packages/react-native/React/Fabric/RCTScheduler.mm | 12 ++++++++++++ .../main/jni/react/fabric/FabricUIManagerBinding.cpp | 4 ++++ .../main/jni/react/fabric/FabricUIManagerBinding.h | 4 ++++ .../react/renderer/scheduler/SchedulerDelegate.h | 12 ++++++++++++ .../renderer/scheduler/SchedulerDelegateImpl.cpp | 8 ++++++++ .../react/renderer/scheduler/SchedulerDelegateImpl.h | 4 ++++ 6 files changed, 44 insertions(+) diff --git a/packages/react-native/React/Fabric/RCTScheduler.mm b/packages/react-native/React/Fabric/RCTScheduler.mm index 6cc4e5b6feb730..b60e96da05d673 100644 --- a/packages/react-native/React/Fabric/RCTScheduler.mm +++ b/packages/react-native/React/Fabric/RCTScheduler.mm @@ -78,6 +78,18 @@ void schedulerDidUpdateShadowTree(const std::unordered_map // This delegate method is not currently used on iOS. } + void schedulerShouldResumeAnimationBackend() override + { + // Does nothing. + // This delegate method is not currently used on iOS. + } + + void schedulerShouldPauseAnimationBackend() override + { + // Does nothing. + // This delegate method is not currently used on iOS. + } + private: void *scheduler_; }; diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp index 3b2be76a229812..3451fc67fce66d 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp @@ -764,6 +764,10 @@ void FabricUIManagerBinding::schedulerDidUpdateShadowTree( // no-op } +void FabricUIManagerBinding::schedulerShouldResumeAnimationBackend() {} + +void FabricUIManagerBinding::schedulerShouldPauseAnimationBackend() {} + void FabricUIManagerBinding::onAnimationStarted() { auto mountingManager = getMountingManager("onAnimationStarted"); if (!mountingManager) { diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.h b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.h index 29adfde41cebb6..248de755d30378 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.h @@ -112,6 +112,10 @@ class FabricUIManagerBinding : public jni::HybridClass, void schedulerDidUpdateShadowTree(const std::unordered_map &tagToProps) override; + void schedulerShouldResumeAnimationBackend() override; + + void schedulerShouldPauseAnimationBackend() override; + void setPixelDensity(float pointScaleFactor); void driveCxxAnimations(); diff --git a/packages/react-native/ReactCommon/react/renderer/scheduler/SchedulerDelegate.h b/packages/react-native/ReactCommon/react/renderer/scheduler/SchedulerDelegate.h index afa2d57de6574d..7f4cc667691bd8 100644 --- a/packages/react-native/ReactCommon/react/renderer/scheduler/SchedulerDelegate.h +++ b/packages/react-native/ReactCommon/react/renderer/scheduler/SchedulerDelegate.h @@ -60,6 +60,18 @@ class SchedulerDelegate { virtual void schedulerDidUpdateShadowTree(const std::unordered_map &tagToProps) = 0; + /* + * Called when the animation backend should start receiving frame callbacks. + * This is used to control the platform-specific animation frame scheduling. + */ + virtual void schedulerShouldResumeAnimationBackend() = 0; + + /* + * Called when the animation backend should stop receiving frame callbacks. + * This is used to pause the platform-specific animation frame scheduling. + */ + virtual void schedulerShouldPauseAnimationBackend() = 0; + virtual ~SchedulerDelegate() noexcept = default; }; diff --git a/packages/react-native/ReactCxxPlatform/react/renderer/scheduler/SchedulerDelegateImpl.cpp b/packages/react-native/ReactCxxPlatform/react/renderer/scheduler/SchedulerDelegateImpl.cpp index ad9ca80551be87..c33648cbd29f17 100644 --- a/packages/react-native/ReactCxxPlatform/react/renderer/scheduler/SchedulerDelegateImpl.cpp +++ b/packages/react-native/ReactCxxPlatform/react/renderer/scheduler/SchedulerDelegateImpl.cpp @@ -63,4 +63,12 @@ void SchedulerDelegateImpl::schedulerDidUpdateShadowTree( mountingManager_->onUpdateShadowTree(tagToProps); } +void SchedulerDelegateImpl::schedulerShouldResumeAnimationBackend() { + // no-op for ReactCxxPlatform +} + +void SchedulerDelegateImpl::schedulerShouldPauseAnimationBackend() { + // no-op for ReactCxxPlatform +} + } // namespace facebook::react diff --git a/packages/react-native/ReactCxxPlatform/react/renderer/scheduler/SchedulerDelegateImpl.h b/packages/react-native/ReactCxxPlatform/react/renderer/scheduler/SchedulerDelegateImpl.h index 2167e5fe143121..1232102504594d 100644 --- a/packages/react-native/ReactCxxPlatform/react/renderer/scheduler/SchedulerDelegateImpl.h +++ b/packages/react-native/ReactCxxPlatform/react/renderer/scheduler/SchedulerDelegateImpl.h @@ -47,6 +47,10 @@ class SchedulerDelegateImpl : public SchedulerDelegate { void schedulerDidUpdateShadowTree(const std::unordered_map &tagToProps) override; + void schedulerShouldResumeAnimationBackend() override; + + void schedulerShouldPauseAnimationBackend() override; + std::shared_ptr mountingManager_; };