mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Use native helpers to accelerate transform processing (#52603)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/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
This commit is contained in:
committed by
Nicola Corti
parent
1b5c183bf3
commit
8bac865b5a
+7
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<57a128d47d69507e15f768970753c89e>>
|
||||
* @generated SignedSource<<c52f3977ea07f976e36177f13c1ec684>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -348,6 +348,12 @@ public object ReactNativeFeatureFlags {
|
||||
@JvmStatic
|
||||
public fun useNativeEqualsInNativeReadableArrayAndroid(): Boolean = accessor.useNativeEqualsInNativeReadableArrayAndroid()
|
||||
|
||||
/**
|
||||
* Use a native implementation of TransformHelper
|
||||
*/
|
||||
@JvmStatic
|
||||
public fun useNativeTransformHelperAndroid(): Boolean = accessor.useNativeTransformHelperAndroid()
|
||||
|
||||
/**
|
||||
* When enabled, the native view configs are used in bridgeless mode.
|
||||
*/
|
||||
|
||||
+11
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<aeca459215a07627be807ef85d97e6e6>>
|
||||
* @generated SignedSource<<8e0125e82b359e6a175ffc49a4df5537>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -73,6 +73,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
|
||||
private var useAlwaysAvailableJSErrorHandlingCache: Boolean? = null
|
||||
private var useFabricInteropCache: Boolean? = null
|
||||
private var useNativeEqualsInNativeReadableArrayAndroidCache: Boolean? = null
|
||||
private var useNativeTransformHelperAndroidCache: Boolean? = null
|
||||
private var useNativeViewConfigsInBridgelessModeCache: Boolean? = null
|
||||
private var useOptimizedEventBatchingOnAndroidCache: Boolean? = null
|
||||
private var useRawPropsJsiValueCache: Boolean? = null
|
||||
@@ -558,6 +559,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun useNativeTransformHelperAndroid(): Boolean {
|
||||
var cached = useNativeTransformHelperAndroidCache
|
||||
if (cached == null) {
|
||||
cached = ReactNativeFeatureFlagsCxxInterop.useNativeTransformHelperAndroid()
|
||||
useNativeTransformHelperAndroidCache = cached
|
||||
}
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun useNativeViewConfigsInBridgelessMode(): Boolean {
|
||||
var cached = useNativeViewConfigsInBridgelessModeCache
|
||||
if (cached == null) {
|
||||
|
||||
+3
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<1729eb15adfaaf4daec98240ddc78ca0>>
|
||||
* @generated SignedSource<<a5d9d11cc2a6529641243dc47a61f201>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -134,6 +134,8 @@ public object ReactNativeFeatureFlagsCxxInterop {
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun useNativeEqualsInNativeReadableArrayAndroid(): Boolean
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun useNativeTransformHelperAndroid(): Boolean
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun useNativeViewConfigsInBridgelessMode(): Boolean
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun useOptimizedEventBatchingOnAndroid(): Boolean
|
||||
|
||||
+3
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<ef873d8fc11ffabd9f9d82d4e95ee8d8>>
|
||||
* @generated SignedSource<<10d708ce4449eede46d750a1ed48d02e>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -129,6 +129,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
|
||||
|
||||
override fun useNativeEqualsInNativeReadableArrayAndroid(): Boolean = false
|
||||
|
||||
override fun useNativeTransformHelperAndroid(): Boolean = false
|
||||
|
||||
override fun useNativeViewConfigsInBridgelessMode(): Boolean = false
|
||||
|
||||
override fun useOptimizedEventBatchingOnAndroid(): Boolean = false
|
||||
|
||||
+12
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<5f923f20a4d5da0935058ab99fd264b3>>
|
||||
* @generated SignedSource<<b04948c792c5db63decf1df80d3a867e>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -77,6 +77,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
|
||||
private var useAlwaysAvailableJSErrorHandlingCache: Boolean? = null
|
||||
private var useFabricInteropCache: Boolean? = null
|
||||
private var useNativeEqualsInNativeReadableArrayAndroidCache: Boolean? = null
|
||||
private var useNativeTransformHelperAndroidCache: Boolean? = null
|
||||
private var useNativeViewConfigsInBridgelessModeCache: Boolean? = null
|
||||
private var useOptimizedEventBatchingOnAndroidCache: Boolean? = null
|
||||
private var useRawPropsJsiValueCache: Boolean? = null
|
||||
@@ -615,6 +616,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun useNativeTransformHelperAndroid(): Boolean {
|
||||
var cached = useNativeTransformHelperAndroidCache
|
||||
if (cached == null) {
|
||||
cached = currentProvider.useNativeTransformHelperAndroid()
|
||||
accessedFeatureFlags.add("useNativeTransformHelperAndroid")
|
||||
useNativeTransformHelperAndroidCache = cached
|
||||
}
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun useNativeViewConfigsInBridgelessMode(): Boolean {
|
||||
var cached = useNativeViewConfigsInBridgelessModeCache
|
||||
if (cached == null) {
|
||||
|
||||
+3
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<e3ee9fa62380e175a564d2cd94539335>>
|
||||
* @generated SignedSource<<0bafb0a2fb79c4220d21f1736894af14>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -26,4 +26,6 @@ public open class ReactNativeFeatureFlagsOverrides_RNOSS_Experimental_Android :
|
||||
override fun preventShadowTreeCommitExhaustion(): Boolean = true
|
||||
|
||||
override fun useNativeEqualsInNativeReadableArrayAndroid(): Boolean = true
|
||||
|
||||
override fun useNativeTransformHelperAndroid(): Boolean = true
|
||||
}
|
||||
|
||||
+3
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<95a5bbbe7e05ff51434ff060ef94b74f>>
|
||||
* @generated SignedSource<<21704207ce520def05b05f89dfba1048>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -129,6 +129,8 @@ public interface ReactNativeFeatureFlagsProvider {
|
||||
|
||||
@DoNotStrip public fun useNativeEqualsInNativeReadableArrayAndroid(): Boolean
|
||||
|
||||
@DoNotStrip public fun useNativeTransformHelperAndroid(): Boolean
|
||||
|
||||
@DoNotStrip public fun useNativeViewConfigsInBridgelessMode(): Boolean
|
||||
|
||||
@DoNotStrip public fun useOptimizedEventBatchingOnAndroid(): Boolean
|
||||
|
||||
+19
@@ -8,10 +8,12 @@
|
||||
package com.facebook.react.uimanager
|
||||
|
||||
import com.facebook.common.logging.FLog
|
||||
import com.facebook.react.bridge.NativeArray
|
||||
import com.facebook.react.bridge.ReadableArray
|
||||
import com.facebook.react.bridge.ReadableMap
|
||||
import com.facebook.react.bridge.ReadableType
|
||||
import com.facebook.react.common.ReactConstants
|
||||
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
|
||||
|
||||
public object TransformHelper {
|
||||
|
||||
@@ -69,6 +71,14 @@ public object TransformHelper {
|
||||
transformOrigin: ReadableArray?,
|
||||
allowPercentageResolution: Boolean
|
||||
) {
|
||||
if (allowPercentageResolution &&
|
||||
ReactNativeFeatureFlags.useNativeTransformHelperAndroid() &&
|
||||
transforms is NativeArray &&
|
||||
transformOrigin is NativeArray?) {
|
||||
nativeProcessTransform(transforms, result, viewWidth, viewHeight, transformOrigin)
|
||||
return
|
||||
}
|
||||
|
||||
val helperMatrix = helperMatrix.get()!!
|
||||
MatrixMathHelper.resetIdentityMatrix(result)
|
||||
val offsets =
|
||||
@@ -220,4 +230,13 @@ public object TransformHelper {
|
||||
|
||||
return doubleArrayOf(newTranslateX, newTranslateY, newTranslateZ)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
private external fun nativeProcessTransform(
|
||||
transforms: NativeArray,
|
||||
result: DoubleArray,
|
||||
viewWidth: Float,
|
||||
viewHeight: Float,
|
||||
transformOrigin: NativeArray?
|
||||
)
|
||||
}
|
||||
|
||||
+15
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<0c0ccd76192aba5c7bf22b1655f53b62>>
|
||||
* @generated SignedSource<<bbad4ee8cacd33099874d0c3078ea716>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -357,6 +357,12 @@ class ReactNativeFeatureFlagsJavaProvider
|
||||
return method(javaProvider_);
|
||||
}
|
||||
|
||||
bool useNativeTransformHelperAndroid() override {
|
||||
static const auto method =
|
||||
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("useNativeTransformHelperAndroid");
|
||||
return method(javaProvider_);
|
||||
}
|
||||
|
||||
bool useNativeViewConfigsInBridgelessMode() override {
|
||||
static const auto method =
|
||||
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("useNativeViewConfigsInBridgelessMode");
|
||||
@@ -668,6 +674,11 @@ bool JReactNativeFeatureFlagsCxxInterop::useNativeEqualsInNativeReadableArrayAnd
|
||||
return ReactNativeFeatureFlags::useNativeEqualsInNativeReadableArrayAndroid();
|
||||
}
|
||||
|
||||
bool JReactNativeFeatureFlagsCxxInterop::useNativeTransformHelperAndroid(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
|
||||
return ReactNativeFeatureFlags::useNativeTransformHelperAndroid();
|
||||
}
|
||||
|
||||
bool JReactNativeFeatureFlagsCxxInterop::useNativeViewConfigsInBridgelessMode(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
|
||||
return ReactNativeFeatureFlags::useNativeViewConfigsInBridgelessMode();
|
||||
@@ -893,6 +904,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
|
||||
makeNativeMethod(
|
||||
"useNativeEqualsInNativeReadableArrayAndroid",
|
||||
JReactNativeFeatureFlagsCxxInterop::useNativeEqualsInNativeReadableArrayAndroid),
|
||||
makeNativeMethod(
|
||||
"useNativeTransformHelperAndroid",
|
||||
JReactNativeFeatureFlagsCxxInterop::useNativeTransformHelperAndroid),
|
||||
makeNativeMethod(
|
||||
"useNativeViewConfigsInBridgelessMode",
|
||||
JReactNativeFeatureFlagsCxxInterop::useNativeViewConfigsInBridgelessMode),
|
||||
|
||||
+4
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<2330cbab72534dd16218a09c5d5c8bf5>>
|
||||
* @generated SignedSource<<57f2dcf4b71512c6b15e8021258d6036>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -189,6 +189,9 @@ class JReactNativeFeatureFlagsCxxInterop
|
||||
static bool useNativeEqualsInNativeReadableArrayAndroid(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
||||
|
||||
static bool useNativeTransformHelperAndroid(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
||||
|
||||
static bool useNativeViewConfigsInBridgelessMode(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
||||
|
||||
|
||||
@@ -21,6 +21,10 @@ class NativeArray : public jni::HybridClass<NativeArray> {
|
||||
|
||||
jni::local_ref<jstring> toString();
|
||||
|
||||
const folly::dynamic& getArray() const {
|
||||
return array_;
|
||||
}
|
||||
|
||||
RN_EXPORT folly::dynamic consume();
|
||||
|
||||
// Whether this array has been added to another array or map and no longer
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "JReactMarker.h"
|
||||
#include "NativeArray.h"
|
||||
#include "NativeMap.h"
|
||||
#include "TransformHelper.h"
|
||||
#include "WritableNativeArray.h"
|
||||
#include "WritableNativeMap.h"
|
||||
|
||||
@@ -27,6 +28,7 @@ extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||
ReadableNativeMap::registerNatives();
|
||||
WritableNativeArray::registerNatives();
|
||||
WritableNativeMap::registerNatives();
|
||||
TransformHelper::registerNatives();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include "TransformHelper.h"
|
||||
|
||||
#include <react/renderer/components/view/BaseViewProps.h>
|
||||
#include <react/renderer/components/view/conversions.h>
|
||||
|
||||
#include "NativeArray.h"
|
||||
|
||||
using namespace facebook::jni;
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
namespace {
|
||||
void processTransform(
|
||||
jni::alias_ref<jclass> /*unused*/,
|
||||
NativeArray* jTransforms,
|
||||
jni::alias_ref<jni::JArrayDouble> jResult,
|
||||
float viewWidth,
|
||||
float viewHeight,
|
||||
NativeArray* jTransformOrigin) {
|
||||
// Assuming parsing transforms doesn't require a real PropsParserContext
|
||||
static ContextContainer contextContainer;
|
||||
static PropsParserContext context(0, contextContainer);
|
||||
|
||||
RawValue transformValue(jTransforms->getArray());
|
||||
Transform transform;
|
||||
fromRawValue(context, transformValue, transform);
|
||||
|
||||
TransformOrigin transformOrigin;
|
||||
if (jTransformOrigin != nullptr) {
|
||||
RawValue transformOriginValue(jTransformOrigin->getArray());
|
||||
fromRawValue(context, transformOriginValue, transformOrigin);
|
||||
}
|
||||
|
||||
auto result = BaseViewProps::resolveTransform(
|
||||
Size(viewWidth, viewHeight), transform, transformOrigin);
|
||||
|
||||
// Convert from matrix of floats to double matrix
|
||||
constexpr size_t MatrixSize = std::tuple_size_v<decltype(result.matrix)>;
|
||||
std::array<double, MatrixSize> doubleTransform{};
|
||||
std::copy(
|
||||
result.matrix.begin(), result.matrix.end(), doubleTransform.begin());
|
||||
jResult->setRegion(0, MatrixSize, doubleTransform.data());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void TransformHelper::registerNatives() {
|
||||
javaClassLocal()->registerNatives({
|
||||
makeNativeMethod("nativeProcessTransform", processTransform),
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace facebook::react
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <fbjni/fbjni.h>
|
||||
|
||||
namespace facebook::react {
|
||||
|
||||
class TransformHelper : public jni::JavaClass<TransformHelper> {
|
||||
public:
|
||||
static auto constexpr* kJavaDescriptor =
|
||||
"Lcom/facebook/react/uimanager/TransformHelper;";
|
||||
|
||||
static void registerNatives();
|
||||
};
|
||||
|
||||
} // namespace facebook::react
|
||||
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<b4ea7fdf458f3933176d5769a0774949>>
|
||||
* @generated SignedSource<<2cabd888b74b84201ff027457efc6007>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -238,6 +238,10 @@ bool ReactNativeFeatureFlags::useNativeEqualsInNativeReadableArrayAndroid() {
|
||||
return getAccessor().useNativeEqualsInNativeReadableArrayAndroid();
|
||||
}
|
||||
|
||||
bool ReactNativeFeatureFlags::useNativeTransformHelperAndroid() {
|
||||
return getAccessor().useNativeTransformHelperAndroid();
|
||||
}
|
||||
|
||||
bool ReactNativeFeatureFlags::useNativeViewConfigsInBridgelessMode() {
|
||||
return getAccessor().useNativeViewConfigsInBridgelessMode();
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<0eff4b5f07581cdf3f200924a9a3bb42>>
|
||||
* @generated SignedSource<<e26a0c35f1499abf24e46275bbcbe06d>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -304,6 +304,11 @@ class ReactNativeFeatureFlags {
|
||||
*/
|
||||
RN_EXPORT static bool useNativeEqualsInNativeReadableArrayAndroid();
|
||||
|
||||
/**
|
||||
* Use a native implementation of TransformHelper
|
||||
*/
|
||||
RN_EXPORT static bool useNativeTransformHelperAndroid();
|
||||
|
||||
/**
|
||||
* When enabled, the native view configs are used in bridgeless mode.
|
||||
*/
|
||||
|
||||
+26
-8
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<2240305552c24ef91dcd4b2c87267e28>>
|
||||
* @generated SignedSource<<7ae9a203a94e3a22197bc9eda69b741c>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -983,6 +983,24 @@ bool ReactNativeFeatureFlagsAccessor::useNativeEqualsInNativeReadableArrayAndroi
|
||||
return flagValue.value();
|
||||
}
|
||||
|
||||
bool ReactNativeFeatureFlagsAccessor::useNativeTransformHelperAndroid() {
|
||||
auto flagValue = useNativeTransformHelperAndroid_.load();
|
||||
|
||||
if (!flagValue.has_value()) {
|
||||
// This block is not exclusive but it is not necessary.
|
||||
// If multiple threads try to initialize the feature flag, we would only
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(53, "useNativeTransformHelperAndroid");
|
||||
|
||||
flagValue = currentProvider_->useNativeTransformHelperAndroid();
|
||||
useNativeTransformHelperAndroid_ = flagValue;
|
||||
}
|
||||
|
||||
return flagValue.value();
|
||||
}
|
||||
|
||||
bool ReactNativeFeatureFlagsAccessor::useNativeViewConfigsInBridgelessMode() {
|
||||
auto flagValue = useNativeViewConfigsInBridgelessMode_.load();
|
||||
|
||||
@@ -992,7 +1010,7 @@ bool ReactNativeFeatureFlagsAccessor::useNativeViewConfigsInBridgelessMode() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(53, "useNativeViewConfigsInBridgelessMode");
|
||||
markFlagAsAccessed(54, "useNativeViewConfigsInBridgelessMode");
|
||||
|
||||
flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode();
|
||||
useNativeViewConfigsInBridgelessMode_ = flagValue;
|
||||
@@ -1010,7 +1028,7 @@ bool ReactNativeFeatureFlagsAccessor::useOptimizedEventBatchingOnAndroid() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(54, "useOptimizedEventBatchingOnAndroid");
|
||||
markFlagAsAccessed(55, "useOptimizedEventBatchingOnAndroid");
|
||||
|
||||
flagValue = currentProvider_->useOptimizedEventBatchingOnAndroid();
|
||||
useOptimizedEventBatchingOnAndroid_ = flagValue;
|
||||
@@ -1028,7 +1046,7 @@ bool ReactNativeFeatureFlagsAccessor::useRawPropsJsiValue() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(55, "useRawPropsJsiValue");
|
||||
markFlagAsAccessed(56, "useRawPropsJsiValue");
|
||||
|
||||
flagValue = currentProvider_->useRawPropsJsiValue();
|
||||
useRawPropsJsiValue_ = flagValue;
|
||||
@@ -1046,7 +1064,7 @@ bool ReactNativeFeatureFlagsAccessor::useShadowNodeStateOnClone() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(56, "useShadowNodeStateOnClone");
|
||||
markFlagAsAccessed(57, "useShadowNodeStateOnClone");
|
||||
|
||||
flagValue = currentProvider_->useShadowNodeStateOnClone();
|
||||
useShadowNodeStateOnClone_ = flagValue;
|
||||
@@ -1064,7 +1082,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModuleInterop() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(57, "useTurboModuleInterop");
|
||||
markFlagAsAccessed(58, "useTurboModuleInterop");
|
||||
|
||||
flagValue = currentProvider_->useTurboModuleInterop();
|
||||
useTurboModuleInterop_ = flagValue;
|
||||
@@ -1082,7 +1100,7 @@ bool ReactNativeFeatureFlagsAccessor::useTurboModules() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(58, "useTurboModules");
|
||||
markFlagAsAccessed(59, "useTurboModules");
|
||||
|
||||
flagValue = currentProvider_->useTurboModules();
|
||||
useTurboModules_ = flagValue;
|
||||
@@ -1100,7 +1118,7 @@ double ReactNativeFeatureFlagsAccessor::virtualViewPrerenderRatio() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(59, "virtualViewPrerenderRatio");
|
||||
markFlagAsAccessed(60, "virtualViewPrerenderRatio");
|
||||
|
||||
flagValue = currentProvider_->virtualViewPrerenderRatio();
|
||||
virtualViewPrerenderRatio_ = flagValue;
|
||||
|
||||
+4
-2
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<257e707937b438617004798572dfac2a>>
|
||||
* @generated SignedSource<<74560113d0b23c05d7822eeba1c0dee4>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -85,6 +85,7 @@ class ReactNativeFeatureFlagsAccessor {
|
||||
bool useAlwaysAvailableJSErrorHandling();
|
||||
bool useFabricInterop();
|
||||
bool useNativeEqualsInNativeReadableArrayAndroid();
|
||||
bool useNativeTransformHelperAndroid();
|
||||
bool useNativeViewConfigsInBridgelessMode();
|
||||
bool useOptimizedEventBatchingOnAndroid();
|
||||
bool useRawPropsJsiValue();
|
||||
@@ -103,7 +104,7 @@ class ReactNativeFeatureFlagsAccessor {
|
||||
std::unique_ptr<ReactNativeFeatureFlagsProvider> currentProvider_;
|
||||
bool wasOverridden_;
|
||||
|
||||
std::array<std::atomic<const char*>, 60> accessedFeatureFlags_;
|
||||
std::array<std::atomic<const char*>, 61> accessedFeatureFlags_;
|
||||
|
||||
std::atomic<std::optional<bool>> commonTestFlag_;
|
||||
std::atomic<std::optional<bool>> animatedShouldSignalBatch_;
|
||||
@@ -158,6 +159,7 @@ class ReactNativeFeatureFlagsAccessor {
|
||||
std::atomic<std::optional<bool>> useAlwaysAvailableJSErrorHandling_;
|
||||
std::atomic<std::optional<bool>> useFabricInterop_;
|
||||
std::atomic<std::optional<bool>> useNativeEqualsInNativeReadableArrayAndroid_;
|
||||
std::atomic<std::optional<bool>> useNativeTransformHelperAndroid_;
|
||||
std::atomic<std::optional<bool>> useNativeViewConfigsInBridgelessMode_;
|
||||
std::atomic<std::optional<bool>> useOptimizedEventBatchingOnAndroid_;
|
||||
std::atomic<std::optional<bool>> useRawPropsJsiValue_;
|
||||
|
||||
+5
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<0fb260ec04c9d43bebfac5a5d7726bd0>>
|
||||
* @generated SignedSource<<1a54000b8eb51cb91304902c7f722d45>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -239,6 +239,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool useNativeTransformHelperAndroid() override {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool useNativeViewConfigsInBridgelessMode() override {
|
||||
return false;
|
||||
}
|
||||
|
||||
+10
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<d4e73cc21058df3b15d0550fb211b64c>>
|
||||
* @generated SignedSource<<244db790cc754f31402981967cd902b5>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -522,6 +522,15 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef
|
||||
return ReactNativeFeatureFlagsDefaults::useNativeEqualsInNativeReadableArrayAndroid();
|
||||
}
|
||||
|
||||
bool useNativeTransformHelperAndroid() override {
|
||||
auto value = values_["useNativeTransformHelperAndroid"];
|
||||
if (!value.isNull()) {
|
||||
return value.getBool();
|
||||
}
|
||||
|
||||
return ReactNativeFeatureFlagsDefaults::useNativeTransformHelperAndroid();
|
||||
}
|
||||
|
||||
bool useNativeViewConfigsInBridgelessMode() override {
|
||||
auto value = values_["useNativeViewConfigsInBridgelessMode"];
|
||||
if (!value.isNull()) {
|
||||
|
||||
+5
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<ccc72ace017fc6a3a09a56d7eb0a3fd8>>
|
||||
* @generated SignedSource<<a045579d42e45fa80831856734a063aa>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -34,6 +34,10 @@ class ReactNativeFeatureFlagsOverridesOSSExperimental : public ReactNativeFeatur
|
||||
bool useNativeEqualsInNativeReadableArrayAndroid() override {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool useNativeTransformHelperAndroid() override {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace facebook::react
|
||||
|
||||
+2
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<4b2d5467c78636794139aa5b67fa5c0c>>
|
||||
* @generated SignedSource<<2387ed12fe46fb5b606ad13a17511f03>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -78,6 +78,7 @@ class ReactNativeFeatureFlagsProvider {
|
||||
virtual bool useAlwaysAvailableJSErrorHandling() = 0;
|
||||
virtual bool useFabricInterop() = 0;
|
||||
virtual bool useNativeEqualsInNativeReadableArrayAndroid() = 0;
|
||||
virtual bool useNativeTransformHelperAndroid() = 0;
|
||||
virtual bool useNativeViewConfigsInBridgelessMode() = 0;
|
||||
virtual bool useOptimizedEventBatchingOnAndroid() = 0;
|
||||
virtual bool useRawPropsJsiValue() = 0;
|
||||
|
||||
+6
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<d3fa8a8cd5a5bb65ec2dae61b4e9c486>>
|
||||
* @generated SignedSource<<45e1b08fd2438b27af82591b5cfa5744>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -309,6 +309,11 @@ bool NativeReactNativeFeatureFlags::useNativeEqualsInNativeReadableArrayAndroid(
|
||||
return ReactNativeFeatureFlags::useNativeEqualsInNativeReadableArrayAndroid();
|
||||
}
|
||||
|
||||
bool NativeReactNativeFeatureFlags::useNativeTransformHelperAndroid(
|
||||
jsi::Runtime& /*runtime*/) {
|
||||
return ReactNativeFeatureFlags::useNativeTransformHelperAndroid();
|
||||
}
|
||||
|
||||
bool NativeReactNativeFeatureFlags::useNativeViewConfigsInBridgelessMode(
|
||||
jsi::Runtime& /*runtime*/) {
|
||||
return ReactNativeFeatureFlags::useNativeViewConfigsInBridgelessMode();
|
||||
|
||||
+3
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<439c0e9cf31e443b5678665a9cc8e789>>
|
||||
* @generated SignedSource<<d1862a9ce3cfeda5d140941fcd3b25bc>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -142,6 +142,8 @@ class NativeReactNativeFeatureFlags
|
||||
|
||||
bool useNativeEqualsInNativeReadableArrayAndroid(jsi::Runtime& runtime);
|
||||
|
||||
bool useNativeTransformHelperAndroid(jsi::Runtime& runtime);
|
||||
|
||||
bool useNativeViewConfigsInBridgelessMode(jsi::Runtime& runtime);
|
||||
|
||||
bool useOptimizedEventBatchingOnAndroid(jsi::Runtime& runtime);
|
||||
|
||||
@@ -550,6 +550,13 @@ BorderMetrics BaseViewProps::resolveBorderMetrics(
|
||||
Transform BaseViewProps::resolveTransform(
|
||||
const LayoutMetrics& layoutMetrics) const {
|
||||
const auto& frameSize = layoutMetrics.frame.size;
|
||||
return resolveTransform(frameSize, transform, transformOrigin);
|
||||
}
|
||||
|
||||
Transform BaseViewProps::resolveTransform(
|
||||
const Size& frameSize,
|
||||
const Transform& transform,
|
||||
const TransformOrigin& transformOrigin) {
|
||||
auto transformMatrix = Transform{};
|
||||
if (frameSize.width == 0 && frameSize.height == 0) {
|
||||
return transformMatrix;
|
||||
@@ -562,8 +569,7 @@ Transform BaseViewProps::resolveTransform(
|
||||
} else {
|
||||
for (const auto& operation : transform.operations) {
|
||||
transformMatrix = transformMatrix *
|
||||
Transform::FromTransformOperation(
|
||||
operation, layoutMetrics.frame.size, transform);
|
||||
Transform::FromTransformOperation(operation, frameSize, transform);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -115,6 +115,11 @@ class BaseViewProps : public YogaStylableProps, public AccessibilityProps {
|
||||
Transform resolveTransform(const LayoutMetrics& layoutMetrics) const;
|
||||
bool getClipsContentToBounds() const;
|
||||
|
||||
static Transform resolveTransform(
|
||||
const Size& frameSize,
|
||||
const Transform& transform,
|
||||
const TransformOrigin& transformOrigin);
|
||||
|
||||
#if RN_DEBUG_STRING_CONVERTIBLE
|
||||
SharedDebugStringConvertibleList getDebugProps() const override;
|
||||
#endif
|
||||
|
||||
@@ -606,6 +606,16 @@ const definitions: FeatureFlagDefinitions = {
|
||||
},
|
||||
ossReleaseStage: 'experimental',
|
||||
},
|
||||
useNativeTransformHelperAndroid: {
|
||||
defaultValue: false,
|
||||
metadata: {
|
||||
dateAdded: '2025-07-15',
|
||||
description: 'Use a native implementation of TransformHelper',
|
||||
expectedReleaseValue: true,
|
||||
purpose: 'experimentation',
|
||||
},
|
||||
ossReleaseStage: 'experimental',
|
||||
},
|
||||
useNativeViewConfigsInBridgelessMode: {
|
||||
defaultValue: false,
|
||||
metadata: {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<f34427cdba45c84df525d3352a7136d4>>
|
||||
* @generated SignedSource<<f17b8e4e33228e19b346837e7a33a2dd>>
|
||||
* @flow strict
|
||||
* @noformat
|
||||
*/
|
||||
@@ -104,6 +104,7 @@ export type ReactNativeFeatureFlags = $ReadOnly<{
|
||||
useAlwaysAvailableJSErrorHandling: Getter<boolean>,
|
||||
useFabricInterop: Getter<boolean>,
|
||||
useNativeEqualsInNativeReadableArrayAndroid: Getter<boolean>,
|
||||
useNativeTransformHelperAndroid: Getter<boolean>,
|
||||
useNativeViewConfigsInBridgelessMode: Getter<boolean>,
|
||||
useOptimizedEventBatchingOnAndroid: Getter<boolean>,
|
||||
useRawPropsJsiValue: Getter<boolean>,
|
||||
@@ -409,6 +410,10 @@ export const useFabricInterop: Getter<boolean> = createNativeFlagGetter('useFabr
|
||||
* Use a native implementation of equals in NativeReadableArray.
|
||||
*/
|
||||
export const useNativeEqualsInNativeReadableArrayAndroid: Getter<boolean> = createNativeFlagGetter('useNativeEqualsInNativeReadableArrayAndroid', false);
|
||||
/**
|
||||
* Use a native implementation of TransformHelper
|
||||
*/
|
||||
export const useNativeTransformHelperAndroid: Getter<boolean> = createNativeFlagGetter('useNativeTransformHelperAndroid', false);
|
||||
/**
|
||||
* When enabled, the native view configs are used in bridgeless mode.
|
||||
*/
|
||||
|
||||
+2
-1
@@ -4,7 +4,7 @@
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated SignedSource<<1c47c6a2547badec31526142e4fc1798>>
|
||||
* @generated SignedSource<<8b4f1275a16d5b83f5594da1eb89c6c1>>
|
||||
* @flow strict
|
||||
* @noformat
|
||||
*/
|
||||
@@ -78,6 +78,7 @@ export interface Spec extends TurboModule {
|
||||
+useAlwaysAvailableJSErrorHandling?: () => boolean;
|
||||
+useFabricInterop?: () => boolean;
|
||||
+useNativeEqualsInNativeReadableArrayAndroid?: () => boolean;
|
||||
+useNativeTransformHelperAndroid?: () => boolean;
|
||||
+useNativeViewConfigsInBridgelessMode?: () => boolean;
|
||||
+useOptimizedEventBatchingOnAndroid?: () => boolean;
|
||||
+useRawPropsJsiValue?: () => boolean;
|
||||
|
||||
Reference in New Issue
Block a user