Skip to content

Commit a18adea

Browse files
Bartlomiej Bloniarzmeta-codesync[bot]
authored andcommitted
Move AnimationBackend initialization from Animated (#55103)
Summary: Pull Request resolved: #55103 This diff decouples AnimationBackend from Animated. Now the backend is intialized in the Scheduler, from where it's passed to UIManager. Animation frontends (such as Animated) can then obtain a reference to the backend, and use it to schedule animation frame updates. # Changelog [General] [Changed] - Moved AnimationBackend initiailzation to `Scheduler` [General] [Added] - `AnimationChoreographer` interface with an implementation for fantom tests Reviewed By: zeyap Differential Revision: D89663251
1 parent 59858b6 commit a18adea

26 files changed

+273
-97
lines changed

packages/react-native/ReactAndroid/src/main/jni/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ add_react_common_subdir(react/debug)
8282
add_react_common_subdir(react/featureflags)
8383
add_react_common_subdir(react/performance/cdpmetrics)
8484
add_react_common_subdir(react/performance/timeline)
85+
add_react_common_subdir(react/renderer/animationbackend)
8586
add_react_common_subdir(react/renderer/animations)
8687
add_react_common_subdir(react/renderer/attributedstring)
8788
add_react_common_subdir(react/renderer/componentregistry)
@@ -200,6 +201,7 @@ add_library(reactnative
200201
$<TARGET_OBJECTS:react_newarchdefaults>
201202
$<TARGET_OBJECTS:react_performance_cdpmetrics>
202203
$<TARGET_OBJECTS:react_performance_timeline>
204+
$<TARGET_OBJECTS:react_renderer_animationbackend>
203205
$<TARGET_OBJECTS:react_renderer_animations>
204206
$<TARGET_OBJECTS:react_renderer_attributedstring>
205207
$<TARGET_OBJECTS:react_renderer_componentregistry>
@@ -293,6 +295,7 @@ target_include_directories(reactnative
293295
$<TARGET_PROPERTY:react_newarchdefaults,INTERFACE_INCLUDE_DIRECTORIES>
294296
$<TARGET_PROPERTY:react_performance_cdpmetrics,INTERFACE_INCLUDE_DIRECTORIES>
295297
$<TARGET_PROPERTY:react_performance_timeline,INTERFACE_INCLUDE_DIRECTORIES>
298+
$<TARGET_PROPERTY:react_renderer_animationbackend,INTERFACE_INCLUDE_DIRECTORIES>
296299
$<TARGET_PROPERTY:react_renderer_animations,INTERFACE_INCLUDE_DIRECTORIES>
297300
$<TARGET_PROPERTY:react_renderer_attributedstring,INTERFACE_INCLUDE_DIRECTORIES>
298301
$<TARGET_PROPERTY:react_renderer_componentregistry,INTERFACE_INCLUDE_DIRECTORIES>

packages/react-native/ReactCommon/React-Fabric.podspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ Pod::Spec.new do |s|
157157
ss.source_files = podspec_sources("react/renderer/scheduler/**/*.{m,mm,cpp,h}", "react/renderer/scheduler/**/*.h")
158158
ss.header_dir = "react/renderer/scheduler"
159159

160+
ss.dependency "React-Fabric/animationbackend"
160161
ss.dependency "React-performancecdpmetrics"
161162
ss.dependency "React-performancetimeline"
162163
ss.dependency "React-Fabric/observers/events"

packages/react-native/ReactCommon/react/renderer/animated/NativeAnimatedNodesManager.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -559,10 +559,8 @@ void NativeAnimatedNodesManager::startRenderCallbackIfNeeded(bool isAsync) {
559559
if (ReactNativeFeatureFlags::useSharedAnimatedBackend()) {
560560
#ifdef RN_USE_ANIMATION_BACKEND
561561
if (auto animationBackend = animationBackend_.lock()) {
562-
std::static_pointer_cast<AnimationBackend>(animationBackend)
563-
->start(
564-
[this](float /*f*/) { return pullAnimationMutations(); },
565-
isAsync);
562+
animationBackend->start(
563+
[this](float /*f*/) { return pullAnimationMutations(); }, isAsync);
566564
}
567565
#endif
568566

packages/react-native/ReactCommon/react/renderer/animated/NativeAnimatedNodesManagerProvider.cpp

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -88,24 +88,17 @@ NativeAnimatedNodesManagerProvider::getOrCreate(
8888

8989
if (ReactNativeFeatureFlags::useSharedAnimatedBackend()) {
9090
#ifdef RN_USE_ANIMATION_BACKEND
91-
// TODO: this should be initialized outside of animated, but for now it
92-
// was convenient to do it here
93-
animationBackend_ = std::make_shared<AnimationBackend>(
94-
std::move(startOnRenderCallback_),
95-
std::move(stopOnRenderCallback_),
96-
std::move(directManipulationCallback),
97-
std::move(fabricCommitCallback),
98-
uiManager,
99-
jsInvoker);
91+
auto animationBackend = uiManager->unstable_getAnimationBackend().lock();
92+
react_native_assert(
93+
animationBackend != nullptr && "animationBackend is nullptr");
94+
animationBackend->registerJSInvoker(jsInvoker);
10095

10196
nativeAnimatedNodesManager_ =
102-
std::make_shared<NativeAnimatedNodesManager>(animationBackend_);
97+
std::make_shared<NativeAnimatedNodesManager>(animationBackend);
10398

10499
nativeAnimatedDelegate_ =
105100
std::make_shared<UIManagerNativeAnimatedDelegateBackendImpl>(
106-
animationBackend_);
107-
108-
uiManager->unstable_setAnimationBackend(animationBackend_);
101+
animationBackend);
109102
#endif
110103
} else {
111104
nativeAnimatedNodesManager_ =

packages/react-native/ReactCommon/react/renderer/animated/NativeAnimatedNodesManagerProvider.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#pragma once
99

1010
#include <react/renderer/animated/MergedValueDispatcher.h>
11+
#include <react/renderer/uimanager/UIManagerAnimationBackend.h>
1112
#include <react/renderer/uimanager/UIManagerNativeAnimatedDelegate.h>
1213
#include "NativeAnimatedNodesManager.h"
1314

@@ -32,7 +33,6 @@ class NativeAnimatedNodesManagerProvider {
3233
std::shared_ptr<EventEmitterListener> getEventEmitterListener();
3334

3435
private:
35-
std::shared_ptr<UIManagerAnimationBackend> animationBackend_;
3636
std::shared_ptr<NativeAnimatedNodesManager> nativeAnimatedNodesManager_;
3737

3838
std::shared_ptr<EventEmitterListenerContainer> eventEmitterListenerContainer_;

packages/react-native/ReactCommon/react/renderer/animationbackend/AnimationBackend.cpp

Lines changed: 28 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,6 @@
1515

1616
namespace facebook::react {
1717

18-
static const auto layoutProps = std::set<PropName>{
19-
WIDTH, HEIGHT, FLEX, MARGIN, PADDING,
20-
POSITION, BORDER_WIDTH, ALIGN_CONTENT, ALIGN_ITEMS, ALIGN_SELF,
21-
ASPECT_RATIO, BOX_SIZING, DISPLAY, FLEX_BASIS, FLEX_DIRECTION,
22-
ROW_GAP, COLUMN_GAP, FLEX_GROW, FLEX_SHRINK, FLEX_WRAP,
23-
JUSTIFY_CONTENT, MAX_HEIGHT, MAX_WIDTH, MIN_HEIGHT, MIN_WIDTH,
24-
STYLE_OVERFLOW, POSITION_TYPE, DIRECTION, Z_INDEX,
25-
};
26-
2718
UIManagerNativeAnimatedDelegateBackendImpl::
2819
UIManagerNativeAnimatedDelegateBackendImpl(
2920
std::weak_ptr<UIManagerAnimationBackend> animationBackend)
@@ -61,20 +52,15 @@ static inline Props::Shared cloneProps(
6152
}
6253

6354
AnimationBackend::AnimationBackend(
64-
StartOnRenderCallback&& startOnRenderCallback,
65-
StopOnRenderCallback&& stopOnRenderCallback,
6655
DirectManipulationCallback&& directManipulationCallback,
67-
FabricCommitCallback&& fabricCommitCallback,
68-
UIManager* uiManager,
69-
std::shared_ptr<CallInvoker> jsInvoker)
70-
: startOnRenderCallback_(std::move(startOnRenderCallback)),
71-
stopOnRenderCallback_(std::move(stopOnRenderCallback)),
72-
directManipulationCallback_(std::move(directManipulationCallback)),
73-
fabricCommitCallback_(std::move(fabricCommitCallback)),
56+
std::shared_ptr<UIManager> uiManager)
57+
: directManipulationCallback_(std::move(directManipulationCallback)),
7458
animatedPropsRegistry_(std::make_shared<AnimatedPropsRegistry>()),
75-
uiManager_(uiManager),
76-
jsInvoker_(std::move(jsInvoker)),
77-
commitHook_(uiManager, animatedPropsRegistry_) {}
59+
uiManager_(uiManager.get()),
60+
commitHook_(*uiManager, animatedPropsRegistry_) {
61+
react_native_assert(directManipulationCallback_ != nullptr);
62+
react_native_assert(uiManager_ != nullptr);
63+
}
7864

7965
void AnimationBackend::onAnimationFrame(double timestamp) {
8066
std::unordered_map<SurfaceId, SurfaceUpdates> surfaceUpdates;
@@ -108,23 +94,20 @@ void AnimationBackend::onAnimationFrame(double timestamp) {
10894
requestAsyncFlushForSurfaces(asyncFlushSurfaces);
10995
}
11096

111-
void AnimationBackend::start(const Callback& callback, bool isAsync) {
97+
void AnimationBackend::start(const Callback& callback, bool /*isAsync*/) {
11298
callbacks.push_back(callback);
113-
// TODO: startOnRenderCallback_ should provide the timestamp from the
114-
// platform
115-
if (startOnRenderCallback_) {
116-
startOnRenderCallback_(
117-
[this]() {
118-
onAnimationFrame(
119-
std::chrono::steady_clock::now().time_since_epoch().count() /
120-
1000);
121-
},
122-
isAsync);
99+
if (!isRenderCallbackStarted_) {
100+
auto delegate = uiManager_->getDelegate();
101+
delegate->uiManagerShouldResumeAnimationBackend();
102+
isRenderCallbackStarted_ = true;
123103
}
124104
}
125-
void AnimationBackend::stop(bool isAsync) {
126-
if (stopOnRenderCallback_) {
127-
stopOnRenderCallback_(isAsync);
105+
106+
void AnimationBackend::stop(bool /*isAsync*/) {
107+
if (isRenderCallbackStarted_) {
108+
auto delegate = uiManager_->getDelegate();
109+
delegate->uiManagerShouldPauseAnimationBackend();
110+
isRenderCallbackStarted_ = false;
128111
}
129112
callbacks.clear();
130113
}
@@ -178,6 +161,9 @@ void AnimationBackend::synchronouslyUpdateProps(
178161

179162
void AnimationBackend::requestAsyncFlushForSurfaces(
180163
const std::set<SurfaceId>& surfaces) {
164+
react_native_assert(
165+
jsInvoker_ != nullptr ||
166+
surfaces.empty() && "jsInvoker_ was not provided");
181167
for (const auto& surfaceId : surfaces) {
182168
// perform an empty commit on the js thread, to force the commit hook to
183169
// push updated shadow nodes to react through RSNRU
@@ -199,4 +185,11 @@ void AnimationBackend::clearRegistry(SurfaceId surfaceId) {
199185
animatedPropsRegistry_->clear(surfaceId);
200186
}
201187

188+
void AnimationBackend::registerJSInvoker(
189+
std::shared_ptr<CallInvoker> jsInvoker) {
190+
if (!jsInvoker_) {
191+
jsInvoker_ = jsInvoker;
192+
}
193+
}
194+
202195
} // namespace facebook::react

packages/react-native/ReactCommon/react/renderer/animationbackend/AnimationBackend.h

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -50,36 +50,28 @@ struct AnimationMutations {
5050
class AnimationBackend : public UIManagerAnimationBackend {
5151
public:
5252
using Callback = std::function<AnimationMutations(float)>;
53-
using StartOnRenderCallback = std::function<void(std::function<void()> &&, bool /* isAsync */)>;
54-
using StopOnRenderCallback = std::function<void(bool /* isAsync */)>;
53+
using ResumeCallback = std::function<void()>;
54+
using PauseCallback = std::function<void()>;
5555
using DirectManipulationCallback = std::function<void(Tag, const folly::dynamic &)>;
56-
using FabricCommitCallback = std::function<void(std::unordered_map<Tag, folly::dynamic> &)>;
5756

5857
std::vector<Callback> callbacks;
59-
const StartOnRenderCallback startOnRenderCallback_;
60-
const StopOnRenderCallback stopOnRenderCallback_;
6158
const DirectManipulationCallback directManipulationCallback_;
62-
const FabricCommitCallback fabricCommitCallback_;
6359
std::shared_ptr<AnimatedPropsRegistry> animatedPropsRegistry_;
6460
UIManager *uiManager_;
6561
std::shared_ptr<CallInvoker> jsInvoker_;
6662
AnimationBackendCommitHook commitHook_;
63+
bool isRenderCallbackStarted_{false};
6764

68-
AnimationBackend(
69-
StartOnRenderCallback &&startOnRenderCallback,
70-
StopOnRenderCallback &&stopOnRenderCallback,
71-
DirectManipulationCallback &&directManipulationCallback,
72-
FabricCommitCallback &&fabricCommitCallback,
73-
UIManager *uiManager,
74-
std::shared_ptr<CallInvoker> jsInvoker);
65+
AnimationBackend(DirectManipulationCallback &&directManipulationCallback, std::shared_ptr<UIManager> uiManager);
7566
void commitUpdates(SurfaceId surfaceId, SurfaceUpdates &surfaceUpdates);
7667
void synchronouslyUpdateProps(const std::unordered_map<Tag, AnimatedProps> &updates);
7768
void requestAsyncFlushForSurfaces(const std::set<SurfaceId> &surfaces);
7869
void clearRegistry(SurfaceId surfaceId) override;
70+
void registerJSInvoker(std::shared_ptr<CallInvoker> jsInvoker) override;
7971

8072
void onAnimationFrame(double timestamp) override;
8173
void trigger() override;
82-
void start(const Callback &callback, bool isAsync);
74+
void start(const Callback &callback, bool isAsync) override;
8375
void stop(bool isAsync) override;
8476
};
8577
} // namespace facebook::react

packages/react-native/ReactCommon/react/renderer/animationbackend/AnimationBackendCommitHook.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@
77

88
#include <react/renderer/animationbackend/AnimationBackendCommitHook.h>
99

10+
#include <utility>
11+
1012
namespace facebook::react {
1113

1214
AnimationBackendCommitHook::AnimationBackendCommitHook(
13-
UIManager* uiManager,
15+
UIManager& uiManager,
1416
std::shared_ptr<AnimatedPropsRegistry> animatedPropsRegistry)
1517
: animatedPropsRegistry_(std::move(animatedPropsRegistry)) {
16-
uiManager->registerCommitHook(*this);
18+
uiManager.registerCommitHook(*this);
1719
}
1820

1921
RootShadowNode::Unshared AnimationBackendCommitHook::shadowTreeWillCommit(

packages/react-native/ReactCommon/react/renderer/animationbackend/AnimationBackendCommitHook.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class AnimationBackendCommitHook : public UIManagerCommitHook {
1919
std::shared_ptr<AnimatedPropsRegistry> animatedPropsRegistry_;
2020

2121
public:
22-
AnimationBackendCommitHook(UIManager *uiManager, std::shared_ptr<AnimatedPropsRegistry> animatedPropsRegistry);
22+
AnimationBackendCommitHook(UIManager &uiManager, std::shared_ptr<AnimatedPropsRegistry> animatedPropsRegistry);
2323
RootShadowNode::Unshared shadowTreeWillCommit(
2424
const ShadowTree &shadowTree,
2525
const RootShadowNode::Shared &oldRootShadowNode,

packages/react-native/ReactCommon/react/renderer/animationbackend/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ target_link_libraries(react_renderer_animationbackend
2020
react_renderer_graphics
2121
react_renderer_mounting
2222
react_renderer_uimanager
23-
react_renderer_scheduler
2423
glog
2524
folly_runtime
2625
)

0 commit comments

Comments
 (0)