Skip to content

Commit a346096

Browse files
cortinicojavache
andauthored
[0.81] Backport useNativeEqualsInNativeReadableArrayAndroid and useNativeTransformHelperAndroid in the experimental channel (#53567)
* Use native implementation of equals in ReadableNativeArray (#52611) Summary: Pull Request resolved: #52611 We compare the current transform (represented as a ReadableArray) with the incoming one to know whether to invalidate. This can be expensive as it requires to materialize the entire transform data structure over JNI. Instead, we can delegate this comparison to native code, which can compare the underlying folly::dynamic directly. Changelog: [Internal] Reviewed By: NickGerleman Differential Revision: D78340288 fbshipit-source-id: f44a054e234694c316fb080fe2dbc2017780123a * Use native helpers to accelerate transform processing (#52603) Summary: Pull Request resolved: #52603 Processing transforms is expensive in Java, as it requires bridging the entire ReadableNativeArray/Map. Instead, we can use the existing parser logic `resolveTransform` logic to perform this operation in C++. Ideally, we actually re-use the existing parsed transform from Props, that could be something we revisit after Props 2.0. As a follow-up, we should consider also moving the matrix decomposition logic from MatrixMathHelper here, and make that the only information we send back to Java. Changelog: [Internal] Reviewed By: NickGerleman Differential Revision: D78298588 fbshipit-source-id: a698ac8587ccfb2be04665747082398ccdde9294 * Add TransformHelper.cpp to `reactnativejni_common` (#52640) Summary: Pull Request resolved: #52640 Not having `TransformHelper.cpp` included in CMake is causing the C++ code to fail compiling. This diff fixes it. Changelog: [Internal] [Changed] - Reviewed By: cipolleschi, javache Differential Revision: D78414015 fbshipit-source-id: 4900427a86eb38bfec10e5e385296d89c73e9051 * [LOCAL] Unbreak compilation due to CMake dependencies --------- Co-authored-by: Pieter De Baets <pieterdb@meta.com>
1 parent ed92bd6 commit a346096

33 files changed

+412
-33
lines changed

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/bridge/ReadableNativeArray.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
package com.facebook.react.bridge
99

1010
import com.facebook.proguard.annotations.DoNotStrip
11+
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
1112
import java.util.ArrayList
1213
import java.util.Arrays
1314
import kotlin.jvm.JvmStatic
@@ -65,9 +66,16 @@ public open class ReadableNativeArray protected constructor() : NativeArray(), R
6566
if (other !is ReadableNativeArray) {
6667
return false
6768
}
68-
return localArray.contentDeepEquals(other.localArray)
69+
70+
return if (ReactNativeFeatureFlags.useNativeEqualsInNativeReadableArrayAndroid()) {
71+
nativeEquals(other)
72+
} else {
73+
localArray.contentDeepEquals(other.localArray)
74+
}
6975
}
7076

77+
private external fun nativeEquals(other: ReadableNativeArray): Boolean
78+
7179
override fun toArrayList(): ArrayList<Any?> {
7280
val arrayList = ArrayList<Any?>()
7381
repeat(size()) { i ->

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<3e4d74a17c15742d35db9e4247f3e1c1>>
7+
* @generated SignedSource<<c52f3977ea07f976e36177f13c1ec684>>
88
*/
99

1010
/**
@@ -342,6 +342,18 @@ public object ReactNativeFeatureFlags {
342342
@JvmStatic
343343
public fun useFabricInterop(): Boolean = accessor.useFabricInterop()
344344

345+
/**
346+
* Use a native implementation of equals in NativeReadableArray.
347+
*/
348+
@JvmStatic
349+
public fun useNativeEqualsInNativeReadableArrayAndroid(): Boolean = accessor.useNativeEqualsInNativeReadableArrayAndroid()
350+
351+
/**
352+
* Use a native implementation of TransformHelper
353+
*/
354+
@JvmStatic
355+
public fun useNativeTransformHelperAndroid(): Boolean = accessor.useNativeTransformHelperAndroid()
356+
345357
/**
346358
* When enabled, the native view configs are used in bridgeless mode.
347359
*/

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<e7c1c6d184681d98320aac2a23c06288>>
7+
* @generated SignedSource<<8e0125e82b359e6a175ffc49a4df5537>>
88
*/
99

1010
/**
@@ -72,6 +72,8 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
7272
private var updateRuntimeShadowNodeReferencesOnCommitCache: Boolean? = null
7373
private var useAlwaysAvailableJSErrorHandlingCache: Boolean? = null
7474
private var useFabricInteropCache: Boolean? = null
75+
private var useNativeEqualsInNativeReadableArrayAndroidCache: Boolean? = null
76+
private var useNativeTransformHelperAndroidCache: Boolean? = null
7577
private var useNativeViewConfigsInBridgelessModeCache: Boolean? = null
7678
private var useOptimizedEventBatchingOnAndroidCache: Boolean? = null
7779
private var useRawPropsJsiValueCache: Boolean? = null
@@ -548,6 +550,24 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
548550
return cached
549551
}
550552

553+
override fun useNativeEqualsInNativeReadableArrayAndroid(): Boolean {
554+
var cached = useNativeEqualsInNativeReadableArrayAndroidCache
555+
if (cached == null) {
556+
cached = ReactNativeFeatureFlagsCxxInterop.useNativeEqualsInNativeReadableArrayAndroid()
557+
useNativeEqualsInNativeReadableArrayAndroidCache = cached
558+
}
559+
return cached
560+
}
561+
562+
override fun useNativeTransformHelperAndroid(): Boolean {
563+
var cached = useNativeTransformHelperAndroidCache
564+
if (cached == null) {
565+
cached = ReactNativeFeatureFlagsCxxInterop.useNativeTransformHelperAndroid()
566+
useNativeTransformHelperAndroidCache = cached
567+
}
568+
return cached
569+
}
570+
551571
override fun useNativeViewConfigsInBridgelessMode(): Boolean {
552572
var cached = useNativeViewConfigsInBridgelessModeCache
553573
if (cached == null) {

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<ba62d616188ed439c85c66cfd055810d>>
7+
* @generated SignedSource<<a5d9d11cc2a6529641243dc47a61f201>>
88
*/
99

1010
/**
@@ -132,6 +132,10 @@ public object ReactNativeFeatureFlagsCxxInterop {
132132

133133
@DoNotStrip @JvmStatic public external fun useFabricInterop(): Boolean
134134

135+
@DoNotStrip @JvmStatic public external fun useNativeEqualsInNativeReadableArrayAndroid(): Boolean
136+
137+
@DoNotStrip @JvmStatic public external fun useNativeTransformHelperAndroid(): Boolean
138+
135139
@DoNotStrip @JvmStatic public external fun useNativeViewConfigsInBridgelessMode(): Boolean
136140

137141
@DoNotStrip @JvmStatic public external fun useOptimizedEventBatchingOnAndroid(): Boolean

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<12c2727291b635ef7c3163d153669c2c>>
7+
* @generated SignedSource<<10d708ce4449eede46d750a1ed48d02e>>
88
*/
99

1010
/**
@@ -127,6 +127,10 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
127127

128128
override fun useFabricInterop(): Boolean = true
129129

130+
override fun useNativeEqualsInNativeReadableArrayAndroid(): Boolean = false
131+
132+
override fun useNativeTransformHelperAndroid(): Boolean = false
133+
130134
override fun useNativeViewConfigsInBridgelessMode(): Boolean = false
131135

132136
override fun useOptimizedEventBatchingOnAndroid(): Boolean = false

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<3ea9946ef21c8ac8bb9bb63712636e89>>
7+
* @generated SignedSource<<b04948c792c5db63decf1df80d3a867e>>
88
*/
99

1010
/**
@@ -76,6 +76,8 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
7676
private var updateRuntimeShadowNodeReferencesOnCommitCache: Boolean? = null
7777
private var useAlwaysAvailableJSErrorHandlingCache: Boolean? = null
7878
private var useFabricInteropCache: Boolean? = null
79+
private var useNativeEqualsInNativeReadableArrayAndroidCache: Boolean? = null
80+
private var useNativeTransformHelperAndroidCache: Boolean? = null
7981
private var useNativeViewConfigsInBridgelessModeCache: Boolean? = null
8082
private var useOptimizedEventBatchingOnAndroidCache: Boolean? = null
8183
private var useRawPropsJsiValueCache: Boolean? = null
@@ -604,6 +606,26 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
604606
return cached
605607
}
606608

609+
override fun useNativeEqualsInNativeReadableArrayAndroid(): Boolean {
610+
var cached = useNativeEqualsInNativeReadableArrayAndroidCache
611+
if (cached == null) {
612+
cached = currentProvider.useNativeEqualsInNativeReadableArrayAndroid()
613+
accessedFeatureFlags.add("useNativeEqualsInNativeReadableArrayAndroid")
614+
useNativeEqualsInNativeReadableArrayAndroidCache = cached
615+
}
616+
return cached
617+
}
618+
619+
override fun useNativeTransformHelperAndroid(): Boolean {
620+
var cached = useNativeTransformHelperAndroidCache
621+
if (cached == null) {
622+
cached = currentProvider.useNativeTransformHelperAndroid()
623+
accessedFeatureFlags.add("useNativeTransformHelperAndroid")
624+
useNativeTransformHelperAndroidCache = cached
625+
}
626+
return cached
627+
}
628+
607629
override fun useNativeViewConfigsInBridgelessMode(): Boolean {
608630
var cached = useNativeViewConfigsInBridgelessModeCache
609631
if (cached == null) {

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<58da46268043f086730132430735b720>>
7+
* @generated SignedSource<<0bafb0a2fb79c4220d21f1736894af14>>
88
*/
99

1010
/**
@@ -24,4 +24,8 @@ public open class ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android :
2424
// but that is more expensive than just duplicating the defaults here.
2525

2626
override fun preventShadowTreeCommitExhaustion(): Boolean = true
27+
28+
override fun useNativeEqualsInNativeReadableArrayAndroid(): Boolean = true
29+
30+
override fun useNativeTransformHelperAndroid(): Boolean = true
2731
}

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<1e81de36735c6c9286b228c75c9a0228>>
7+
* @generated SignedSource<<21704207ce520def05b05f89dfba1048>>
88
*/
99

1010
/**
@@ -127,6 +127,10 @@ public interface ReactNativeFeatureFlagsProvider {
127127

128128
@DoNotStrip public fun useFabricInterop(): Boolean
129129

130+
@DoNotStrip public fun useNativeEqualsInNativeReadableArrayAndroid(): Boolean
131+
132+
@DoNotStrip public fun useNativeTransformHelperAndroid(): Boolean
133+
130134
@DoNotStrip public fun useNativeViewConfigsInBridgelessMode(): Boolean
131135

132136
@DoNotStrip public fun useOptimizedEventBatchingOnAndroid(): Boolean

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/TransformHelper.kt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88
package com.facebook.react.uimanager
99

1010
import com.facebook.common.logging.FLog
11+
import com.facebook.react.bridge.NativeArray
1112
import com.facebook.react.bridge.ReadableArray
1213
import com.facebook.react.bridge.ReadableMap
1314
import com.facebook.react.bridge.ReadableType
1415
import com.facebook.react.common.ReactConstants
16+
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
1517

1618
public object TransformHelper {
1719

@@ -69,6 +71,14 @@ public object TransformHelper {
6971
transformOrigin: ReadableArray?,
7072
allowPercentageResolution: Boolean
7173
) {
74+
if (allowPercentageResolution &&
75+
ReactNativeFeatureFlags.useNativeTransformHelperAndroid() &&
76+
transforms is NativeArray &&
77+
transformOrigin is NativeArray?) {
78+
nativeProcessTransform(transforms, result, viewWidth, viewHeight, transformOrigin)
79+
return
80+
}
81+
7282
val helperMatrix = helperMatrix.get()!!
7383
MatrixMathHelper.resetIdentityMatrix(result)
7484
val offsets =
@@ -220,4 +230,13 @@ public object TransformHelper {
220230

221231
return doubleArrayOf(newTranslateX, newTranslateY, newTranslateZ)
222232
}
233+
234+
@JvmStatic
235+
private external fun nativeProcessTransform(
236+
transforms: NativeArray,
237+
result: DoubleArray,
238+
viewWidth: Float,
239+
viewHeight: Float,
240+
transformOrigin: NativeArray?
241+
)
223242
}

packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<cf7b6ff66c614ca2acc6667a80c5590d>>
7+
* @generated SignedSource<<bbad4ee8cacd33099874d0c3078ea716>>
88
*/
99

1010
/**
@@ -351,6 +351,18 @@ class ReactNativeFeatureFlagsJavaProvider
351351
return method(javaProvider_);
352352
}
353353

354+
bool useNativeEqualsInNativeReadableArrayAndroid() override {
355+
static const auto method =
356+
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("useNativeEqualsInNativeReadableArrayAndroid");
357+
return method(javaProvider_);
358+
}
359+
360+
bool useNativeTransformHelperAndroid() override {
361+
static const auto method =
362+
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("useNativeTransformHelperAndroid");
363+
return method(javaProvider_);
364+
}
365+
354366
bool useNativeViewConfigsInBridgelessMode() override {
355367
static const auto method =
356368
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("useNativeViewConfigsInBridgelessMode");
@@ -657,6 +669,16 @@ bool JReactNativeFeatureFlagsCxxInterop::useFabricInterop(
657669
return ReactNativeFeatureFlags::useFabricInterop();
658670
}
659671

672+
bool JReactNativeFeatureFlagsCxxInterop::useNativeEqualsInNativeReadableArrayAndroid(
673+
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
674+
return ReactNativeFeatureFlags::useNativeEqualsInNativeReadableArrayAndroid();
675+
}
676+
677+
bool JReactNativeFeatureFlagsCxxInterop::useNativeTransformHelperAndroid(
678+
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
679+
return ReactNativeFeatureFlags::useNativeTransformHelperAndroid();
680+
}
681+
660682
bool JReactNativeFeatureFlagsCxxInterop::useNativeViewConfigsInBridgelessMode(
661683
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
662684
return ReactNativeFeatureFlags::useNativeViewConfigsInBridgelessMode();
@@ -879,6 +901,12 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
879901
makeNativeMethod(
880902
"useFabricInterop",
881903
JReactNativeFeatureFlagsCxxInterop::useFabricInterop),
904+
makeNativeMethod(
905+
"useNativeEqualsInNativeReadableArrayAndroid",
906+
JReactNativeFeatureFlagsCxxInterop::useNativeEqualsInNativeReadableArrayAndroid),
907+
makeNativeMethod(
908+
"useNativeTransformHelperAndroid",
909+
JReactNativeFeatureFlagsCxxInterop::useNativeTransformHelperAndroid),
882910
makeNativeMethod(
883911
"useNativeViewConfigsInBridgelessMode",
884912
JReactNativeFeatureFlagsCxxInterop::useNativeViewConfigsInBridgelessMode),

0 commit comments

Comments
 (0)