Skip to content

Commit b46427a

Browse files
zeyapmeta-codesync[bot]
authored andcommitted
Thread down rootTag/surfaceId to AnimatedInterpolation node (#54621)
Summary: Pull Request resolved: #54621 ## Changelog: [General] [Added] - Thread down rootTag/surfaceId to AnimatedInterpolation node Thread down rootTag (aka surfaceId) from AnimatedProps to AnimatedInterpolation in c++ animated for the PlatformColor resolver Directly read rootTag value from RootTagContext in `useAnimatedProps` hook, this might be the fastest way to look up rootTag for AnimatedProps - an alternative is to find ShadowNode in ShadowTreeRegistry with react tag and read surfaceId on it, which is very expensive. Reviewed By: javache Differential Revision: D86999015 fbshipit-source-id: b84fbfe7e8be6a423c3d25e4e3939d59ac338a45
1 parent f327871 commit b46427a

File tree

7 files changed

+68
-7
lines changed

7 files changed

+68
-7
lines changed

packages/react-native/Libraries/Animated/nodes/AnimatedProps.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
* @format
99
*/
1010

11+
import type {RootTag} from '../../Types/RootTagTypes';
1112
import type {PlatformConfig} from '../AnimatedPlatformConfig';
1213
import type {AnimatedNodeConfig} from './AnimatedNode';
1314
import type {AnimatedStyleAllowlist} from './AnimatedStyle';
@@ -97,11 +98,13 @@ export default class AnimatedProps extends AnimatedNode {
9798
_nodes: $ReadOnlyArray<AnimatedNode>;
9899
_props: {[string]: mixed};
99100
_target: ?TargetView = null;
101+
_rootTag: ?RootTag = undefined;
100102

101103
constructor(
102104
inputProps: {[string]: mixed},
103105
callback: () => void,
104106
allowlist?: ?AnimatedPropsAllowlist,
107+
rootTag?: RootTag,
105108
config?: ?AnimatedNodeConfig,
106109
) {
107110
super(config);
@@ -110,6 +113,7 @@ export default class AnimatedProps extends AnimatedNode {
110113
this._nodes = nodes;
111114
this._props = props;
112115
this._callback = callback;
116+
this._rootTag = rootTag;
113117
}
114118

115119
__getValue(): Object {
@@ -318,6 +322,7 @@ export default class AnimatedProps extends AnimatedNode {
318322
return {
319323
type: 'props',
320324
props: propsConfig,
325+
rootTag: this._rootTag ?? undefined,
321326
debugID: this.__getDebugID(),
322327
};
323328
}

packages/react-native/ReactCommon/react/renderer/animated/nodes/InterpolationAnimatedNode.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111

1212
#include "InterpolationAnimatedNode.h"
1313

14+
#include <glog/logging.h>
1415
#include <react/renderer/animated/NativeAnimatedNodesManager.h>
1516
#include <react/renderer/animated/drivers/AnimationDriverUtils.h>
1617
#include <react/renderer/animated/internal/primitives.h>
18+
#include <react/renderer/animated/nodes/PropsAnimatedNode.h>
1719
#include <react/renderer/graphics/HostPlatformColor.h>
1820

1921
namespace facebook::react {
@@ -150,6 +152,10 @@ double InterpolationAnimatedNode::interpolateColor(double value) {
150152
}
151153

152154
double InterpolationAnimatedNode::interpolatePlatformColor(double value) {
155+
if (connectedRootTag_ == animated::undefinedAnimatedNodeIdentifier) {
156+
connectedRootTag_ = resolveConnectedRootTag();
157+
}
158+
153159
// Compute range index
154160
size_t index = 1;
155161
for (; index < inputRanges_.size() - 1; ++index) {
@@ -211,4 +217,27 @@ double InterpolationAnimatedNode::interpolatePlatformColor(double value) {
211217
static_cast<uint8_t>(outputValueA)));
212218
}
213219

220+
SurfaceId InterpolationAnimatedNode::resolveConnectedRootTag() const {
221+
// find nearest connected props node
222+
std::deque<Tag> nodesQueue{tag()};
223+
while (!nodesQueue.empty()) {
224+
auto nodeTag = nodesQueue.front();
225+
nodesQueue.pop_front();
226+
if (auto node = manager_->getAnimatedNode<AnimatedNode>(nodeTag)) {
227+
if (node->type() == AnimatedNodeType::Props) {
228+
if (auto propsNode = static_cast<PropsAnimatedNode*>(node)) {
229+
return propsNode->connectedRootTag();
230+
}
231+
break;
232+
}
233+
auto children = node->getChildren();
234+
nodesQueue.insert(nodesQueue.end(), children.begin(), children.end());
235+
}
236+
}
237+
238+
LOG(ERROR)
239+
<< "InterpolationAnimatedNode: Unable to resolve connected root tag";
240+
return animated::undefinedAnimatedNodeIdentifier;
241+
}
242+
214243
} // namespace facebook::react

packages/react-native/ReactCommon/react/renderer/animated/nodes/InterpolationAnimatedNode.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ class InterpolationAnimatedNode final : public ValueAnimatedNode {
3131
double interpolateColor(double value);
3232
double interpolatePlatformColor(double value);
3333

34+
SurfaceId resolveConnectedRootTag() const;
35+
3436
std::vector<double> inputRanges_;
3537
std::vector<double> defaultOutputRanges_;
3638
std::vector<Color> colorOutputRanges_;

packages/react-native/ReactCommon/react/renderer/animated/nodes/PropsAnimatedNode.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,11 @@ PropsAnimatedNode::PropsAnimatedNode(
4949
const folly::dynamic& config,
5050
NativeAnimatedNodesManager& manager)
5151
: AnimatedNode(tag, config, manager, AnimatedNodeType::Props),
52-
props_(folly::dynamic::object()) {}
52+
props_(folly::dynamic::object()) {
53+
if (auto it = getConfig().find("rootTag"); it != getConfig().items().end()) {
54+
connectedRootTag_ = static_cast<Tag>(it->second.asInt());
55+
}
56+
}
5357

5458
void PropsAnimatedNode::connectToView(Tag viewTag) {
5559
react_native_assert(

packages/react-native/ReactCommon/react/renderer/animated/nodes/PropsAnimatedNode.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ class PropsAnimatedNode final : public AnimatedNode {
2929
return connectedViewTag_;
3030
}
3131

32+
SurfaceId connectedRootTag() const
33+
{
34+
return connectedRootTag_;
35+
}
36+
3237
folly::dynamic props()
3338
{
3439
std::lock_guard<std::mutex> lock(propsMutex_);
@@ -45,5 +50,8 @@ class PropsAnimatedNode final : public AnimatedNode {
4550
bool layoutStyleUpdated_{false};
4651

4752
Tag connectedViewTag_{animated::undefinedAnimatedNodeIdentifier};
53+
54+
// Needed for PlatformColor resolver
55+
SurfaceId connectedRootTag_{animated::undefinedAnimatedNodeIdentifier};
4856
};
4957
} // namespace facebook::react

packages/react-native/src/private/animated/__tests__/AnimatedNative-test.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ describe('Native Animated', () => {
445445
);
446446
expect(NativeAnimatedModule.createAnimatedNode).toBeCalledWith(
447447
expect.any(Number),
448-
{type: 'props', props: {style: expect.any(Number)}},
448+
{type: 'props', props: {style: expect.any(Number)}, rootTag: 0},
449449
);
450450
});
451451

@@ -1195,7 +1195,7 @@ describe('Native Animated', () => {
11951195
);
11961196
expect(NativeAnimatedModule.createAnimatedNode).toBeCalledWith(
11971197
expect.any(Number),
1198-
{type: 'props', props: {style: expect.any(Number)}},
1198+
{type: 'props', props: {style: expect.any(Number)}, rootTag: 0},
11991199
);
12001200
});
12011201
});
@@ -1565,7 +1565,7 @@ describe('Native Animated', () => {
15651565
type: 'style',
15661566
},
15671567
],
1568-
[5, {debugID: undefined, props: {style: 2}, type: 'props'}],
1568+
[5, {debugID: undefined, props: {style: 2}, type: 'props', rootTag: 0}],
15691569
]);
15701570

15711571
createAnimatedNodeCalledTimes += 5;
@@ -1613,7 +1613,7 @@ describe('Native Animated', () => {
16131613
type: 'style',
16141614
},
16151615
],
1616-
[9, {debugID: undefined, props: {style: 7}, type: 'props'}],
1616+
[9, {debugID: undefined, props: {style: 7}, type: 'props', rootTag: 0}],
16171617
]);
16181618

16191619
createAnimatedNodeCalledTimes += 4;
@@ -1672,7 +1672,10 @@ describe('Native Animated', () => {
16721672
type: 'style',
16731673
},
16741674
],
1675-
[13, {debugID: undefined, props: {style: 12}, type: 'props'}],
1675+
[
1676+
13,
1677+
{debugID: undefined, props: {style: 12}, type: 'props', rootTag: 0},
1678+
],
16761679
]);
16771680

16781681
createAnimatedNodeCalledTimes += 4;

packages/react-native/src/private/animated/createAnimatedPropsHook.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@ import AnimatedNode from '../../../Libraries/Animated/nodes/AnimatedNode';
1515
import AnimatedProps from '../../../Libraries/Animated/nodes/AnimatedProps';
1616
import AnimatedValue from '../../../Libraries/Animated/nodes/AnimatedValue';
1717
import {isPublicInstance as isFabricPublicInstance} from '../../../Libraries/ReactNative/ReactFabricPublicInstance/ReactFabricPublicInstanceUtils';
18+
import {RootTagContext} from '../../../Libraries/ReactNative/RootTag';
1819
import useRefEffect from '../../../Libraries/Utilities/useRefEffect';
1920
import * as ReactNativeFeatureFlags from '../featureflags/ReactNativeFeatureFlags';
2021
import {createAnimatedPropsMemoHook} from './createAnimatedPropsMemoHook';
2122
import NativeAnimatedHelper from './NativeAnimatedHelper';
2223
import {
2324
useCallback,
25+
useContext,
2426
useEffect,
2527
useInsertionEffect,
2628
useReducer,
@@ -60,8 +62,16 @@ export default function createAnimatedPropsHook(
6062
const onUpdateRef = useRef<UpdateCallback | null>(null);
6163
const timerRef = useRef<TimeoutID | null>(null);
6264

65+
const rootTag = useContext(RootTagContext);
66+
6367
const node = useAnimatedPropsMemo(
64-
() => new AnimatedProps(props, () => onUpdateRef.current?.(), allowlist),
68+
() =>
69+
new AnimatedProps(
70+
props,
71+
() => onUpdateRef.current?.(),
72+
allowlist,
73+
rootTag,
74+
),
6575
props,
6676
);
6777

0 commit comments

Comments
 (0)