Skip to content

Commit d595724

Browse files
committed
Back-port rn81 performance fix
This is based on two commits from the React Native upstream project: 1st: dd12edf35f89aed4872ba40e54fc9caaabfac0bf 2nd: cb20a1cd32c5a9fa79e12223d03b7ade18a890c8 These commits touch a lot of files, but we just need these two: packages/react-native/ReactCommon/react/renderer/mounting/ShadowTree.cpp packages/react-native/ReactCommon/react/renderer/mounting/ShadowTree.h The other files implement the new feature flag, but we can ignore those and just hard-code the change to "on".
1 parent 4f23947 commit d595724

File tree

2 files changed

+138
-0
lines changed

2 files changed

+138
-0
lines changed

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,5 +266,10 @@
266266
},
267267
"engines": {
268268
"node": ">=18"
269+
},
270+
"reanimated": {
271+
"staticFeatureFlags": {
272+
"DISABLE_COMMIT_PAUSING_MECHANISM": true
273+
}
269274
}
270275
}

patches/react-native+0.79.2.patch

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
diff --git a/node_modules/react-native/ReactCommon/react/renderer/mounting/ShadowTree.cpp b/node_modules/react-native/ReactCommon/react/renderer/mounting/ShadowTree.cpp
2+
index 522ec57..e6ad1df 100644
3+
--- a/node_modules/react-native/ReactCommon/react/renderer/mounting/ShadowTree.cpp
4+
+++ b/node_modules/react-native/ReactCommon/react/renderer/mounting/ShadowTree.cpp
5+
@@ -22,6 +22,10 @@
6+
7+
namespace facebook::react {
8+
9+
+namespace {
10+
+const int MAX_COMMIT_ATTEMPTS_BEFORE_LOCKING = 3;
11+
+} // namespace
12+
+
13+
using CommitStatus = ShadowTree::CommitStatus;
14+
using CommitMode = ShadowTree::CommitMode;
15+
16+
@@ -207,7 +211,8 @@ void ShadowTree::setCommitMode(CommitMode commitMode) const {
17+
auto revision = ShadowTreeRevision{};
18+
19+
{
20+
- std::unique_lock lock(commitMutex_);
21+
+ ShadowTree::UniqueLock lock = uniqueCommitLock();
22+
+
23+
if (commitMode_ == commitMode) {
24+
return;
25+
}
26+
@@ -224,7 +229,7 @@ void ShadowTree::setCommitMode(CommitMode commitMode) const {
27+
}
28+
29+
CommitMode ShadowTree::getCommitMode() const {
30+
- std::shared_lock lock(commitMutex_);
31+
+ SharedLock lock = sharedCommitLock();
32+
return commitMode_;
33+
}
34+
35+
@@ -238,17 +243,17 @@ CommitStatus ShadowTree::commit(
36+
const CommitOptions& commitOptions) const {
37+
[[maybe_unused]] int attempts = 0;
38+
39+
- while (true) {
40+
- attempts++;
41+
-
42+
+ while (attempts < MAX_COMMIT_ATTEMPTS_BEFORE_LOCKING) {
43+
auto status = tryCommit(transaction, commitOptions);
44+
if (status != CommitStatus::Failed) {
45+
return status;
46+
}
47+
+ attempts++;
48+
+ }
49+
50+
- // After multiple attempts, we failed to commit the transaction.
51+
- // Something internally went terribly wrong.
52+
- react_native_assert(attempts < 1024);
53+
+ {
54+
+ std::unique_lock lock(commitMutexRecursive_);
55+
+ return tryCommit(transaction, commitOptions);
56+
}
57+
}
58+
59+
@@ -266,7 +271,7 @@ CommitStatus ShadowTree::tryCommit(
60+
61+
{
62+
// Reading `currentRevision_` in shared manner.
63+
- std::shared_lock lock(commitMutex_);
64+
+ SharedLock lock = sharedCommitLock();
65+
commitMode = commitMode_;
66+
oldRevision = currentRevision_;
67+
}
68+
@@ -307,7 +312,7 @@ CommitStatus ShadowTree::tryCommit(
69+
70+
{
71+
// Updating `currentRevision_` in unique manner if it hasn't changed.
72+
- std::unique_lock lock(commitMutex_);
73+
+ UniqueLock lock = uniqueCommitLock();
74+
75+
if (currentRevision_.number != oldRevision.number) {
76+
return CommitStatus::Failed;
77+
@@ -345,7 +350,7 @@ CommitStatus ShadowTree::tryCommit(
78+
}
79+
80+
ShadowTreeRevision ShadowTree::getCurrentRevision() const {
81+
- std::shared_lock lock(commitMutex_);
82+
+ SharedLock lock = sharedCommitLock();
83+
return currentRevision_;
84+
}
85+
86+
@@ -392,4 +397,12 @@ void ShadowTree::notifyDelegatesOfUpdates() const {
87+
delegate_.shadowTreeDidFinishTransaction(mountingCoordinator_, true);
88+
}
89+
90+
+inline ShadowTree::UniqueLock ShadowTree::uniqueCommitLock() const {
91+
+ return std::unique_lock{commitMutexRecursive_};
92+
+}
93+
+
94+
+inline ShadowTree::SharedLock ShadowTree::sharedCommitLock() const {
95+
+ return std::unique_lock{commitMutexRecursive_};
96+
+}
97+
+
98+
} // namespace facebook::react
99+
diff --git a/node_modules/react-native/ReactCommon/react/renderer/mounting/ShadowTree.h b/node_modules/react-native/ReactCommon/react/renderer/mounting/ShadowTree.h
100+
index ae9d005..c3bef0b 100644
101+
--- a/node_modules/react-native/ReactCommon/react/renderer/mounting/ShadowTree.h
102+
+++ b/node_modules/react-native/ReactCommon/react/renderer/mounting/ShadowTree.h
103+
@@ -8,6 +8,8 @@
104+
#pragma once
105+
106+
#include <memory>
107+
+#include <mutex>
108+
+#include <shared_mutex>
109+
110+
#include <react/renderer/components/root/RootComponentDescriptor.h>
111+
#include <react/renderer/components/root/RootShadowNode.h>
112+
@@ -139,10 +141,21 @@ class ShadowTree final {
113+
const SurfaceId surfaceId_;
114+
const ShadowTreeDelegate& delegate_;
115+
mutable std::shared_mutex commitMutex_;
116+
+ mutable std::recursive_mutex commitMutexRecursive_;
117+
mutable CommitMode commitMode_{
118+
CommitMode::Normal}; // Protected by `commitMutex_`.
119+
mutable ShadowTreeRevision currentRevision_; // Protected by `commitMutex_`.
120+
std::shared_ptr<const MountingCoordinator> mountingCoordinator_;
121+
+
122+
+ using UniqueLock = std::variant<
123+
+ std::unique_lock<std::shared_mutex>,
124+
+ std::unique_lock<std::recursive_mutex>>;
125+
+ using SharedLock = std::variant<
126+
+ std::shared_lock<std::shared_mutex>,
127+
+ std::unique_lock<std::recursive_mutex>>;
128+
+
129+
+ inline UniqueLock uniqueCommitLock() const;
130+
+ inline SharedLock sharedCommitLock() const;
131+
};
132+
133+
} // namespace facebook::react

0 commit comments

Comments
 (0)