mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Delete ShadowTreeRevision on background thread (#50997)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/50997 In some apps, we spend a non-trivial amount of time calling ShadowNode destructors on the UI thread. A simple way to avoid stalling the UI thread is to move the `baseRevision_` instance to a data structure that is cleared on a background thread, so it's tree of ShadowNode shared_ptrs are released (and in most cases destroyed) on the background thread. Rather than using std::thread, this change introduces the LowPriorityExecutor abstraction that should be supplied by host platforms. The implementation of this LowPriorityExecutor for each platform is as follows: - iOS: uses dispatch_async to a low priority dispatch queue - Android: uses a pthread with SCHED_OTHER and priority = 19 Moving the ShadowTreeRevision into a lambda capture and punting the lambda to the LowPriorityExecutor moves the destructor calls of the ShadowNodes to the host platform implementation of the LowPriorityExecutor. This change is also guarded by a feature flag so we can keep an eye out for potential memory leaks. ## Changelog [Internal] Reviewed By: NickGerleman Differential Revision: D73688009 fbshipit-source-id: 6a66da248e6fe5c38375bf026499346e8381e75a
This commit is contained in:
committed by
Facebook GitHub Bot
parent
8d08845cda
commit
d9823d80bb
+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<<b86b8bb1d53ca03240c25adb8b423040>>
|
||||
* @generated SignedSource<<31638ef8ac6992a354785b74af8fbe0d>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -90,6 +90,12 @@ public object ReactNativeFeatureFlags {
|
||||
@JvmStatic
|
||||
public fun enableCustomFocusSearchOnClippedElementsAndroid(): Boolean = accessor.enableCustomFocusSearchOnClippedElementsAndroid()
|
||||
|
||||
/**
|
||||
* Enables destructor calls for ShadowTreeRevision in the background to reduce UI thread work.
|
||||
*/
|
||||
@JvmStatic
|
||||
public fun enableDestroyShadowTreeRevisionAsync(): Boolean = accessor.enableDestroyShadowTreeRevisionAsync()
|
||||
|
||||
/**
|
||||
* When enabled a subset of components will avoid double measurement on Android.
|
||||
*/
|
||||
|
||||
+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<<9c1e0e7e87aead96e2554ef5ecf9e7af>>
|
||||
* @generated SignedSource<<6b382661025db56592b44255f5a8694c>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -30,6 +30,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
|
||||
private var enableBridgelessArchitectureCache: Boolean? = null
|
||||
private var enableCppPropsIteratorSetterCache: Boolean? = null
|
||||
private var enableCustomFocusSearchOnClippedElementsAndroidCache: Boolean? = null
|
||||
private var enableDestroyShadowTreeRevisionAsyncCache: Boolean? = null
|
||||
private var enableDoubleMeasurementFixAndroidCache: Boolean? = null
|
||||
private var enableEagerRootViewAttachmentCache: Boolean? = null
|
||||
private var enableFabricLogsCache: Boolean? = null
|
||||
@@ -156,6 +157,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun enableDestroyShadowTreeRevisionAsync(): Boolean {
|
||||
var cached = enableDestroyShadowTreeRevisionAsyncCache
|
||||
if (cached == null) {
|
||||
cached = ReactNativeFeatureFlagsCxxInterop.enableDestroyShadowTreeRevisionAsync()
|
||||
enableDestroyShadowTreeRevisionAsyncCache = cached
|
||||
}
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun enableDoubleMeasurementFixAndroid(): Boolean {
|
||||
var cached = enableDoubleMeasurementFixAndroidCache
|
||||
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<<b95c0d1f576b67fcf9d9df498ea30994>>
|
||||
* @generated SignedSource<<8276fd1166cdd235f11a0b490bb7d924>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -48,6 +48,8 @@ public object ReactNativeFeatureFlagsCxxInterop {
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun enableCustomFocusSearchOnClippedElementsAndroid(): Boolean
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun enableDestroyShadowTreeRevisionAsync(): Boolean
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun enableDoubleMeasurementFixAndroid(): Boolean
|
||||
|
||||
@DoNotStrip @JvmStatic public external fun enableEagerRootViewAttachment(): 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<<c7425e6212e4e9d70e64452e550bf638>>
|
||||
* @generated SignedSource<<ffadd7912aed2d95b0c6199aa8902690>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -43,6 +43,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
|
||||
|
||||
override fun enableCustomFocusSearchOnClippedElementsAndroid(): Boolean = true
|
||||
|
||||
override fun enableDestroyShadowTreeRevisionAsync(): Boolean = false
|
||||
|
||||
override fun enableDoubleMeasurementFixAndroid(): Boolean = false
|
||||
|
||||
override fun enableEagerRootViewAttachment(): 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<<5b145ee103cf6b40e13d33c88cd52777>>
|
||||
* @generated SignedSource<<5dc41059d71d3a345be45a6a233b05a0>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -34,6 +34,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
|
||||
private var enableBridgelessArchitectureCache: Boolean? = null
|
||||
private var enableCppPropsIteratorSetterCache: Boolean? = null
|
||||
private var enableCustomFocusSearchOnClippedElementsAndroidCache: Boolean? = null
|
||||
private var enableDestroyShadowTreeRevisionAsyncCache: Boolean? = null
|
||||
private var enableDoubleMeasurementFixAndroidCache: Boolean? = null
|
||||
private var enableEagerRootViewAttachmentCache: Boolean? = null
|
||||
private var enableFabricLogsCache: Boolean? = null
|
||||
@@ -170,6 +171,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun enableDestroyShadowTreeRevisionAsync(): Boolean {
|
||||
var cached = enableDestroyShadowTreeRevisionAsyncCache
|
||||
if (cached == null) {
|
||||
cached = currentProvider.enableDestroyShadowTreeRevisionAsync()
|
||||
accessedFeatureFlags.add("enableDestroyShadowTreeRevisionAsync")
|
||||
enableDestroyShadowTreeRevisionAsyncCache = cached
|
||||
}
|
||||
return cached
|
||||
}
|
||||
|
||||
override fun enableDoubleMeasurementFixAndroid(): Boolean {
|
||||
var cached = enableDoubleMeasurementFixAndroidCache
|
||||
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<<9cdb965a420d53cf36b6531684cb07ae>>
|
||||
* @generated SignedSource<<35f6d9ae3c445c81fc4bab7509fd3179>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -43,6 +43,8 @@ public interface ReactNativeFeatureFlagsProvider {
|
||||
|
||||
@DoNotStrip public fun enableCustomFocusSearchOnClippedElementsAndroid(): Boolean
|
||||
|
||||
@DoNotStrip public fun enableDestroyShadowTreeRevisionAsync(): Boolean
|
||||
|
||||
@DoNotStrip public fun enableDoubleMeasurementFixAndroid(): Boolean
|
||||
|
||||
@DoNotStrip public fun enableEagerRootViewAttachment(): Boolean
|
||||
|
||||
+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<<c89831646046b10c7b2a40e14deb3d1a>>
|
||||
* @generated SignedSource<<d566c157b7db07e235bada071067f11d>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -99,6 +99,12 @@ class ReactNativeFeatureFlagsJavaProvider
|
||||
return method(javaProvider_);
|
||||
}
|
||||
|
||||
bool enableDestroyShadowTreeRevisionAsync() override {
|
||||
static const auto method =
|
||||
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableDestroyShadowTreeRevisionAsync");
|
||||
return method(javaProvider_);
|
||||
}
|
||||
|
||||
bool enableDoubleMeasurementFixAndroid() override {
|
||||
static const auto method =
|
||||
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableDoubleMeasurementFixAndroid");
|
||||
@@ -363,6 +369,11 @@ bool JReactNativeFeatureFlagsCxxInterop::enableCustomFocusSearchOnClippedElement
|
||||
return ReactNativeFeatureFlags::enableCustomFocusSearchOnClippedElementsAndroid();
|
||||
}
|
||||
|
||||
bool JReactNativeFeatureFlagsCxxInterop::enableDestroyShadowTreeRevisionAsync(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
|
||||
return ReactNativeFeatureFlags::enableDestroyShadowTreeRevisionAsync();
|
||||
}
|
||||
|
||||
bool JReactNativeFeatureFlagsCxxInterop::enableDoubleMeasurementFixAndroid(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
|
||||
return ReactNativeFeatureFlags::enableDoubleMeasurementFixAndroid();
|
||||
@@ -599,6 +610,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
|
||||
makeNativeMethod(
|
||||
"enableCustomFocusSearchOnClippedElementsAndroid",
|
||||
JReactNativeFeatureFlagsCxxInterop::enableCustomFocusSearchOnClippedElementsAndroid),
|
||||
makeNativeMethod(
|
||||
"enableDestroyShadowTreeRevisionAsync",
|
||||
JReactNativeFeatureFlagsCxxInterop::enableDestroyShadowTreeRevisionAsync),
|
||||
makeNativeMethod(
|
||||
"enableDoubleMeasurementFixAndroid",
|
||||
JReactNativeFeatureFlagsCxxInterop::enableDoubleMeasurementFixAndroid),
|
||||
|
||||
+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<<2a5ad62d2cb4f1111391f1b566e10c1d>>
|
||||
* @generated SignedSource<<270b461fa199f8e6365948cded0785ad>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -60,6 +60,9 @@ class JReactNativeFeatureFlagsCxxInterop
|
||||
static bool enableCustomFocusSearchOnClippedElementsAndroid(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
||||
|
||||
static bool enableDestroyShadowTreeRevisionAsync(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
||||
|
||||
static bool enableDoubleMeasurementFixAndroid(
|
||||
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
||||
|
||||
|
||||
@@ -46,12 +46,12 @@ Pod::Spec.new do |s|
|
||||
s.dependency "React-Core"
|
||||
s.dependency "React-debug"
|
||||
s.dependency "React-featureflags"
|
||||
s.dependency "React-utils"
|
||||
s.dependency "React-runtimescheduler"
|
||||
s.dependency "React-cxxreact"
|
||||
|
||||
add_dependency(s, "React-rendererdebug")
|
||||
add_dependency(s, "React-graphics", :additional_framework_paths => ["react/renderer/graphics/platform/ios"])
|
||||
add_dependency(s, "React-utils", :additional_framework_paths => ["react/utils/platform/ios"])
|
||||
|
||||
depend_on_js_engine(s)
|
||||
add_rn_third_party_dependencies(s)
|
||||
|
||||
@@ -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<<0eb63ead191be88440cbb73fd760dec7>>
|
||||
* @generated SignedSource<<74f22c6a0302a9923e99d2455d84e231>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -66,6 +66,10 @@ bool ReactNativeFeatureFlags::enableCustomFocusSearchOnClippedElementsAndroid()
|
||||
return getAccessor().enableCustomFocusSearchOnClippedElementsAndroid();
|
||||
}
|
||||
|
||||
bool ReactNativeFeatureFlags::enableDestroyShadowTreeRevisionAsync() {
|
||||
return getAccessor().enableDestroyShadowTreeRevisionAsync();
|
||||
}
|
||||
|
||||
bool ReactNativeFeatureFlags::enableDoubleMeasurementFixAndroid() {
|
||||
return getAccessor().enableDoubleMeasurementFixAndroid();
|
||||
}
|
||||
|
||||
@@ -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<<80dcd75591a392144c2fd2817cc4408a>>
|
||||
* @generated SignedSource<<b941543bc6f12dbb0e12ac2ae0042186>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -89,6 +89,11 @@ class ReactNativeFeatureFlags {
|
||||
*/
|
||||
RN_EXPORT static bool enableCustomFocusSearchOnClippedElementsAndroid();
|
||||
|
||||
/**
|
||||
* Enables destructor calls for ShadowTreeRevision in the background to reduce UI thread work.
|
||||
*/
|
||||
RN_EXPORT static bool enableDestroyShadowTreeRevisionAsync();
|
||||
|
||||
/**
|
||||
* When enabled a subset of components will avoid double measurement on Android.
|
||||
*/
|
||||
|
||||
+54
-36
@@ -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<<0c39183e7858453bfc18515be46eb17f>>
|
||||
* @generated SignedSource<<4efbb3f094edbcc89c6ac4d586169b9a>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -209,6 +209,24 @@ bool ReactNativeFeatureFlagsAccessor::enableCustomFocusSearchOnClippedElementsAn
|
||||
return flagValue.value();
|
||||
}
|
||||
|
||||
bool ReactNativeFeatureFlagsAccessor::enableDestroyShadowTreeRevisionAsync() {
|
||||
auto flagValue = enableDestroyShadowTreeRevisionAsync_.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(10, "enableDestroyShadowTreeRevisionAsync");
|
||||
|
||||
flagValue = currentProvider_->enableDestroyShadowTreeRevisionAsync();
|
||||
enableDestroyShadowTreeRevisionAsync_ = flagValue;
|
||||
}
|
||||
|
||||
return flagValue.value();
|
||||
}
|
||||
|
||||
bool ReactNativeFeatureFlagsAccessor::enableDoubleMeasurementFixAndroid() {
|
||||
auto flagValue = enableDoubleMeasurementFixAndroid_.load();
|
||||
|
||||
@@ -218,7 +236,7 @@ bool ReactNativeFeatureFlagsAccessor::enableDoubleMeasurementFixAndroid() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(10, "enableDoubleMeasurementFixAndroid");
|
||||
markFlagAsAccessed(11, "enableDoubleMeasurementFixAndroid");
|
||||
|
||||
flagValue = currentProvider_->enableDoubleMeasurementFixAndroid();
|
||||
enableDoubleMeasurementFixAndroid_ = flagValue;
|
||||
@@ -236,7 +254,7 @@ bool ReactNativeFeatureFlagsAccessor::enableEagerRootViewAttachment() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(11, "enableEagerRootViewAttachment");
|
||||
markFlagAsAccessed(12, "enableEagerRootViewAttachment");
|
||||
|
||||
flagValue = currentProvider_->enableEagerRootViewAttachment();
|
||||
enableEagerRootViewAttachment_ = flagValue;
|
||||
@@ -254,7 +272,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricLogs() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(12, "enableFabricLogs");
|
||||
markFlagAsAccessed(13, "enableFabricLogs");
|
||||
|
||||
flagValue = currentProvider_->enableFabricLogs();
|
||||
enableFabricLogs_ = flagValue;
|
||||
@@ -272,7 +290,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFabricRenderer() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(13, "enableFabricRenderer");
|
||||
markFlagAsAccessed(14, "enableFabricRenderer");
|
||||
|
||||
flagValue = currentProvider_->enableFabricRenderer();
|
||||
enableFabricRenderer_ = flagValue;
|
||||
@@ -290,7 +308,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFixForParentTagDuringReparenting() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(14, "enableFixForParentTagDuringReparenting");
|
||||
markFlagAsAccessed(15, "enableFixForParentTagDuringReparenting");
|
||||
|
||||
flagValue = currentProvider_->enableFixForParentTagDuringReparenting();
|
||||
enableFixForParentTagDuringReparenting_ = flagValue;
|
||||
@@ -308,7 +326,7 @@ bool ReactNativeFeatureFlagsAccessor::enableFontScaleChangesUpdatingLayout() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(15, "enableFontScaleChangesUpdatingLayout");
|
||||
markFlagAsAccessed(16, "enableFontScaleChangesUpdatingLayout");
|
||||
|
||||
flagValue = currentProvider_->enableFontScaleChangesUpdatingLayout();
|
||||
enableFontScaleChangesUpdatingLayout_ = flagValue;
|
||||
@@ -326,7 +344,7 @@ bool ReactNativeFeatureFlagsAccessor::enableIOSViewClipToPaddingBox() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(16, "enableIOSViewClipToPaddingBox");
|
||||
markFlagAsAccessed(17, "enableIOSViewClipToPaddingBox");
|
||||
|
||||
flagValue = currentProvider_->enableIOSViewClipToPaddingBox();
|
||||
enableIOSViewClipToPaddingBox_ = flagValue;
|
||||
@@ -344,7 +362,7 @@ bool ReactNativeFeatureFlagsAccessor::enableJSRuntimeGCOnMemoryPressureOnIOS() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(17, "enableJSRuntimeGCOnMemoryPressureOnIOS");
|
||||
markFlagAsAccessed(18, "enableJSRuntimeGCOnMemoryPressureOnIOS");
|
||||
|
||||
flagValue = currentProvider_->enableJSRuntimeGCOnMemoryPressureOnIOS();
|
||||
enableJSRuntimeGCOnMemoryPressureOnIOS_ = flagValue;
|
||||
@@ -362,7 +380,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnAndroid() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(18, "enableLayoutAnimationsOnAndroid");
|
||||
markFlagAsAccessed(19, "enableLayoutAnimationsOnAndroid");
|
||||
|
||||
flagValue = currentProvider_->enableLayoutAnimationsOnAndroid();
|
||||
enableLayoutAnimationsOnAndroid_ = flagValue;
|
||||
@@ -380,7 +398,7 @@ bool ReactNativeFeatureFlagsAccessor::enableLayoutAnimationsOnIOS() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(19, "enableLayoutAnimationsOnIOS");
|
||||
markFlagAsAccessed(20, "enableLayoutAnimationsOnIOS");
|
||||
|
||||
flagValue = currentProvider_->enableLayoutAnimationsOnIOS();
|
||||
enableLayoutAnimationsOnIOS_ = flagValue;
|
||||
@@ -398,7 +416,7 @@ bool ReactNativeFeatureFlagsAccessor::enableMainQueueModulesOnIOS() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(20, "enableMainQueueModulesOnIOS");
|
||||
markFlagAsAccessed(21, "enableMainQueueModulesOnIOS");
|
||||
|
||||
flagValue = currentProvider_->enableMainQueueModulesOnIOS();
|
||||
enableMainQueueModulesOnIOS_ = flagValue;
|
||||
@@ -416,7 +434,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNativeCSSParsing() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(21, "enableNativeCSSParsing");
|
||||
markFlagAsAccessed(22, "enableNativeCSSParsing");
|
||||
|
||||
flagValue = currentProvider_->enableNativeCSSParsing();
|
||||
enableNativeCSSParsing_ = flagValue;
|
||||
@@ -434,7 +452,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNetworkEventReporting() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(22, "enableNetworkEventReporting");
|
||||
markFlagAsAccessed(23, "enableNetworkEventReporting");
|
||||
|
||||
flagValue = currentProvider_->enableNetworkEventReporting();
|
||||
enableNetworkEventReporting_ = flagValue;
|
||||
@@ -452,7 +470,7 @@ bool ReactNativeFeatureFlagsAccessor::enableNewBackgroundAndBorderDrawables() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(23, "enableNewBackgroundAndBorderDrawables");
|
||||
markFlagAsAccessed(24, "enableNewBackgroundAndBorderDrawables");
|
||||
|
||||
flagValue = currentProvider_->enableNewBackgroundAndBorderDrawables();
|
||||
enableNewBackgroundAndBorderDrawables_ = flagValue;
|
||||
@@ -470,7 +488,7 @@ bool ReactNativeFeatureFlagsAccessor::enablePropsUpdateReconciliationAndroid() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(24, "enablePropsUpdateReconciliationAndroid");
|
||||
markFlagAsAccessed(25, "enablePropsUpdateReconciliationAndroid");
|
||||
|
||||
flagValue = currentProvider_->enablePropsUpdateReconciliationAndroid();
|
||||
enablePropsUpdateReconciliationAndroid_ = flagValue;
|
||||
@@ -488,7 +506,7 @@ bool ReactNativeFeatureFlagsAccessor::enableResourceTimingAPI() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(25, "enableResourceTimingAPI");
|
||||
markFlagAsAccessed(26, "enableResourceTimingAPI");
|
||||
|
||||
flagValue = currentProvider_->enableResourceTimingAPI();
|
||||
enableResourceTimingAPI_ = flagValue;
|
||||
@@ -506,7 +524,7 @@ bool ReactNativeFeatureFlagsAccessor::enableSynchronousStateUpdates() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(26, "enableSynchronousStateUpdates");
|
||||
markFlagAsAccessed(27, "enableSynchronousStateUpdates");
|
||||
|
||||
flagValue = currentProvider_->enableSynchronousStateUpdates();
|
||||
enableSynchronousStateUpdates_ = flagValue;
|
||||
@@ -524,7 +542,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewCulling() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(27, "enableViewCulling");
|
||||
markFlagAsAccessed(28, "enableViewCulling");
|
||||
|
||||
flagValue = currentProvider_->enableViewCulling();
|
||||
enableViewCulling_ = flagValue;
|
||||
@@ -542,7 +560,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecycling() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(28, "enableViewRecycling");
|
||||
markFlagAsAccessed(29, "enableViewRecycling");
|
||||
|
||||
flagValue = currentProvider_->enableViewRecycling();
|
||||
enableViewRecycling_ = flagValue;
|
||||
@@ -560,7 +578,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForText() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(29, "enableViewRecyclingForText");
|
||||
markFlagAsAccessed(30, "enableViewRecyclingForText");
|
||||
|
||||
flagValue = currentProvider_->enableViewRecyclingForText();
|
||||
enableViewRecyclingForText_ = flagValue;
|
||||
@@ -578,7 +596,7 @@ bool ReactNativeFeatureFlagsAccessor::enableViewRecyclingForView() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(30, "enableViewRecyclingForView");
|
||||
markFlagAsAccessed(31, "enableViewRecyclingForView");
|
||||
|
||||
flagValue = currentProvider_->enableViewRecyclingForView();
|
||||
enableViewRecyclingForView_ = flagValue;
|
||||
@@ -596,7 +614,7 @@ bool ReactNativeFeatureFlagsAccessor::fixMappingOfEventPrioritiesBetweenFabricAn
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(31, "fixMappingOfEventPrioritiesBetweenFabricAndReact");
|
||||
markFlagAsAccessed(32, "fixMappingOfEventPrioritiesBetweenFabricAndReact");
|
||||
|
||||
flagValue = currentProvider_->fixMappingOfEventPrioritiesBetweenFabricAndReact();
|
||||
fixMappingOfEventPrioritiesBetweenFabricAndReact_ = flagValue;
|
||||
@@ -614,7 +632,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxEnabledRelease() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(32, "fuseboxEnabledRelease");
|
||||
markFlagAsAccessed(33, "fuseboxEnabledRelease");
|
||||
|
||||
flagValue = currentProvider_->fuseboxEnabledRelease();
|
||||
fuseboxEnabledRelease_ = flagValue;
|
||||
@@ -632,7 +650,7 @@ bool ReactNativeFeatureFlagsAccessor::fuseboxNetworkInspectionEnabled() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(33, "fuseboxNetworkInspectionEnabled");
|
||||
markFlagAsAccessed(34, "fuseboxNetworkInspectionEnabled");
|
||||
|
||||
flagValue = currentProvider_->fuseboxNetworkInspectionEnabled();
|
||||
fuseboxNetworkInspectionEnabled_ = flagValue;
|
||||
@@ -650,7 +668,7 @@ bool ReactNativeFeatureFlagsAccessor::incorporateMaxLinesDuringAndroidLayout() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(34, "incorporateMaxLinesDuringAndroidLayout");
|
||||
markFlagAsAccessed(35, "incorporateMaxLinesDuringAndroidLayout");
|
||||
|
||||
flagValue = currentProvider_->incorporateMaxLinesDuringAndroidLayout();
|
||||
incorporateMaxLinesDuringAndroidLayout_ = flagValue;
|
||||
@@ -668,7 +686,7 @@ bool ReactNativeFeatureFlagsAccessor::traceTurboModulePromiseRejectionsOnAndroid
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(35, "traceTurboModulePromiseRejectionsOnAndroid");
|
||||
markFlagAsAccessed(36, "traceTurboModulePromiseRejectionsOnAndroid");
|
||||
|
||||
flagValue = currentProvider_->traceTurboModulePromiseRejectionsOnAndroid();
|
||||
traceTurboModulePromiseRejectionsOnAndroid_ = flagValue;
|
||||
@@ -686,7 +704,7 @@ bool ReactNativeFeatureFlagsAccessor::updateRuntimeShadowNodeReferencesOnCommit(
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(36, "updateRuntimeShadowNodeReferencesOnCommit");
|
||||
markFlagAsAccessed(37, "updateRuntimeShadowNodeReferencesOnCommit");
|
||||
|
||||
flagValue = currentProvider_->updateRuntimeShadowNodeReferencesOnCommit();
|
||||
updateRuntimeShadowNodeReferencesOnCommit_ = flagValue;
|
||||
@@ -704,7 +722,7 @@ bool ReactNativeFeatureFlagsAccessor::useAlwaysAvailableJSErrorHandling() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(37, "useAlwaysAvailableJSErrorHandling");
|
||||
markFlagAsAccessed(38, "useAlwaysAvailableJSErrorHandling");
|
||||
|
||||
flagValue = currentProvider_->useAlwaysAvailableJSErrorHandling();
|
||||
useAlwaysAvailableJSErrorHandling_ = flagValue;
|
||||
@@ -722,7 +740,7 @@ bool ReactNativeFeatureFlagsAccessor::useFabricInterop() {
|
||||
// be accessing the provider multiple times but the end state of this
|
||||
// instance and the returned flag value would be the same.
|
||||
|
||||
markFlagAsAccessed(38, "useFabricInterop");
|
||||
markFlagAsAccessed(39, "useFabricInterop");
|
||||
|
||||
flagValue = currentProvider_->useFabricInterop();
|
||||
useFabricInterop_ = flagValue;
|
||||
@@ -740,7 +758,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(39, "useNativeViewConfigsInBridgelessMode");
|
||||
markFlagAsAccessed(40, "useNativeViewConfigsInBridgelessMode");
|
||||
|
||||
flagValue = currentProvider_->useNativeViewConfigsInBridgelessMode();
|
||||
useNativeViewConfigsInBridgelessMode_ = flagValue;
|
||||
@@ -758,7 +776,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(40, "useOptimizedEventBatchingOnAndroid");
|
||||
markFlagAsAccessed(41, "useOptimizedEventBatchingOnAndroid");
|
||||
|
||||
flagValue = currentProvider_->useOptimizedEventBatchingOnAndroid();
|
||||
useOptimizedEventBatchingOnAndroid_ = flagValue;
|
||||
@@ -776,7 +794,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(41, "useRawPropsJsiValue");
|
||||
markFlagAsAccessed(42, "useRawPropsJsiValue");
|
||||
|
||||
flagValue = currentProvider_->useRawPropsJsiValue();
|
||||
useRawPropsJsiValue_ = flagValue;
|
||||
@@ -794,7 +812,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(42, "useShadowNodeStateOnClone");
|
||||
markFlagAsAccessed(43, "useShadowNodeStateOnClone");
|
||||
|
||||
flagValue = currentProvider_->useShadowNodeStateOnClone();
|
||||
useShadowNodeStateOnClone_ = flagValue;
|
||||
@@ -812,7 +830,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(43, "useTurboModuleInterop");
|
||||
markFlagAsAccessed(44, "useTurboModuleInterop");
|
||||
|
||||
flagValue = currentProvider_->useTurboModuleInterop();
|
||||
useTurboModuleInterop_ = flagValue;
|
||||
@@ -830,7 +848,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(44, "useTurboModules");
|
||||
markFlagAsAccessed(45, "useTurboModules");
|
||||
|
||||
flagValue = currentProvider_->useTurboModules();
|
||||
useTurboModules_ = 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<<336504fac084993c9aff86f274d45342>>
|
||||
* @generated SignedSource<<31b5c2776ad91fd0d3bd2cfc3672575b>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -42,6 +42,7 @@ class ReactNativeFeatureFlagsAccessor {
|
||||
bool enableBridgelessArchitecture();
|
||||
bool enableCppPropsIteratorSetter();
|
||||
bool enableCustomFocusSearchOnClippedElementsAndroid();
|
||||
bool enableDestroyShadowTreeRevisionAsync();
|
||||
bool enableDoubleMeasurementFixAndroid();
|
||||
bool enableEagerRootViewAttachment();
|
||||
bool enableFabricLogs();
|
||||
@@ -88,7 +89,7 @@ class ReactNativeFeatureFlagsAccessor {
|
||||
std::unique_ptr<ReactNativeFeatureFlagsProvider> currentProvider_;
|
||||
bool wasOverridden_;
|
||||
|
||||
std::array<std::atomic<const char*>, 45> accessedFeatureFlags_;
|
||||
std::array<std::atomic<const char*>, 46> accessedFeatureFlags_;
|
||||
|
||||
std::atomic<std::optional<bool>> commonTestFlag_;
|
||||
std::atomic<std::optional<bool>> animatedShouldSignalBatch_;
|
||||
@@ -100,6 +101,7 @@ class ReactNativeFeatureFlagsAccessor {
|
||||
std::atomic<std::optional<bool>> enableBridgelessArchitecture_;
|
||||
std::atomic<std::optional<bool>> enableCppPropsIteratorSetter_;
|
||||
std::atomic<std::optional<bool>> enableCustomFocusSearchOnClippedElementsAndroid_;
|
||||
std::atomic<std::optional<bool>> enableDestroyShadowTreeRevisionAsync_;
|
||||
std::atomic<std::optional<bool>> enableDoubleMeasurementFixAndroid_;
|
||||
std::atomic<std::optional<bool>> enableEagerRootViewAttachment_;
|
||||
std::atomic<std::optional<bool>> enableFabricLogs_;
|
||||
|
||||
+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<<825294594363fb672b6cd64eaa954dd4>>
|
||||
* @generated SignedSource<<9cc33ba9f5ef67d6c98700d772bbc0de>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -67,6 +67,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool enableDestroyShadowTreeRevisionAsync() override {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool enableDoubleMeasurementFixAndroid() 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<<d9dc055d9cda1ac17b7039aa70691a6b>>
|
||||
* @generated SignedSource<<d336ecdd8ce51394df6d7baf6ea6457a>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -135,6 +135,15 @@ class ReactNativeFeatureFlagsDynamicProvider : public ReactNativeFeatureFlagsDef
|
||||
return ReactNativeFeatureFlagsDefaults::enableCustomFocusSearchOnClippedElementsAndroid();
|
||||
}
|
||||
|
||||
bool enableDestroyShadowTreeRevisionAsync() override {
|
||||
auto value = values_["enableDestroyShadowTreeRevisionAsync"];
|
||||
if (!value.isNull()) {
|
||||
return value.getBool();
|
||||
}
|
||||
|
||||
return ReactNativeFeatureFlagsDefaults::enableDestroyShadowTreeRevisionAsync();
|
||||
}
|
||||
|
||||
bool enableDoubleMeasurementFixAndroid() override {
|
||||
auto value = values_["enableDoubleMeasurementFixAndroid"];
|
||||
if (!value.isNull()) {
|
||||
|
||||
+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<<905f26c85dc731205b1a6f44c4e32468>>
|
||||
* @generated SignedSource<<ac9ae2b709bdc6358523ebf91fc2f78e>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -35,6 +35,7 @@ class ReactNativeFeatureFlagsProvider {
|
||||
virtual bool enableBridgelessArchitecture() = 0;
|
||||
virtual bool enableCppPropsIteratorSetter() = 0;
|
||||
virtual bool enableCustomFocusSearchOnClippedElementsAndroid() = 0;
|
||||
virtual bool enableDestroyShadowTreeRevisionAsync() = 0;
|
||||
virtual bool enableDoubleMeasurementFixAndroid() = 0;
|
||||
virtual bool enableEagerRootViewAttachment() = 0;
|
||||
virtual bool enableFabricLogs() = 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<<614814062283858cf70138a2ac3d6304>>
|
||||
* @generated SignedSource<<82e2e7118453787377248101925b56d1>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -94,6 +94,11 @@ bool NativeReactNativeFeatureFlags::enableCustomFocusSearchOnClippedElementsAndr
|
||||
return ReactNativeFeatureFlags::enableCustomFocusSearchOnClippedElementsAndroid();
|
||||
}
|
||||
|
||||
bool NativeReactNativeFeatureFlags::enableDestroyShadowTreeRevisionAsync(
|
||||
jsi::Runtime& /*runtime*/) {
|
||||
return ReactNativeFeatureFlags::enableDestroyShadowTreeRevisionAsync();
|
||||
}
|
||||
|
||||
bool NativeReactNativeFeatureFlags::enableDoubleMeasurementFixAndroid(
|
||||
jsi::Runtime& /*runtime*/) {
|
||||
return ReactNativeFeatureFlags::enableDoubleMeasurementFixAndroid();
|
||||
|
||||
+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<<1c0248c3eda43cc89a61b3e3ff8b4345>>
|
||||
* @generated SignedSource<<d0d056652d60269b736d4fb0bc71ab4f>>
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -57,6 +57,8 @@ class NativeReactNativeFeatureFlags
|
||||
|
||||
bool enableCustomFocusSearchOnClippedElementsAndroid(jsi::Runtime& runtime);
|
||||
|
||||
bool enableDestroyShadowTreeRevisionAsync(jsi::Runtime& runtime);
|
||||
|
||||
bool enableDoubleMeasurementFixAndroid(jsi::Runtime& runtime);
|
||||
|
||||
bool enableEagerRootViewAttachment(jsi::Runtime& runtime);
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
|
||||
#include <cxxreact/TraceSection.h>
|
||||
#include <react/debug/react_native_assert.h>
|
||||
#include <react/featureflags/ReactNativeFeatureFlags.h>
|
||||
#include <react/renderer/mounting/ShadowViewMutation.h>
|
||||
#include <react/utils/LowPriorityExecutor.h>
|
||||
#include <condition_variable>
|
||||
#include "updateMountedFlag.h"
|
||||
|
||||
@@ -186,6 +188,9 @@ std::optional<MountingTransaction> MountingCoordinator::pullTransaction(
|
||||
#endif
|
||||
|
||||
if (lastRevision_.has_value()) {
|
||||
if (ReactNativeFeatureFlags::enableDestroyShadowTreeRevisionAsync()) {
|
||||
LowPriorityExecutor::execute([toDelete = std::move(baseRevision_)]() {});
|
||||
}
|
||||
baseRevision_ = std::move(*lastRevision_);
|
||||
lastRevision_.reset();
|
||||
|
||||
|
||||
@@ -8,10 +8,14 @@ set(CMAKE_VERBOSE_MAKEFILE on)
|
||||
|
||||
include(${REACT_COMMON_DIR}/cmake-utils/react-native-flags.cmake)
|
||||
|
||||
file(GLOB react_utils_SRC CONFIGURE_DEPENDS *.cpp *.mm)
|
||||
file(GLOB react_utils_SRC CONFIGURE_DEPENDS *.cpp platform/android/react/utils/*.cpp)
|
||||
add_library(react_utils OBJECT ${react_utils_SRC})
|
||||
|
||||
target_include_directories(react_utils PUBLIC ${REACT_COMMON_DIR})
|
||||
target_include_directories(react_utils
|
||||
PUBLIC
|
||||
${REACT_COMMON_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/platform/android/
|
||||
)
|
||||
|
||||
target_link_libraries(react_utils
|
||||
glog
|
||||
|
||||
@@ -16,12 +16,12 @@ else
|
||||
source[:tag] = "v#{version}"
|
||||
end
|
||||
|
||||
header_search_paths = [
|
||||
"\"$(PODS_TARGET_SRCROOT)\"",
|
||||
"\"$(PODS_TARGET_SRCROOT)/ReactCommon\"",
|
||||
]
|
||||
|
||||
Pod::Spec.new do |s|
|
||||
source_files = "*.{m,mm,cpp,h}", "platform/ios/**/*.{m,mm,cpp,h}"
|
||||
header_search_paths = [
|
||||
"\"$(PODS_TARGET_SRCROOT)/../../\"",
|
||||
]
|
||||
|
||||
s.name = "React-utils"
|
||||
s.version = version
|
||||
s.summary = "-" # TODO
|
||||
@@ -30,18 +30,21 @@ Pod::Spec.new do |s|
|
||||
s.author = "Meta Platforms, Inc. and its affiliates"
|
||||
s.platforms = min_supported_versions
|
||||
s.source = source
|
||||
s.source_files = "**/*.{cpp,h,mm}"
|
||||
s.source_files = source_files
|
||||
s.header_dir = "react/utils"
|
||||
s.exclude_files = "tests"
|
||||
s.pod_target_xcconfig = { "CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(),
|
||||
"HEADER_SEARCH_PATHS" => header_search_paths.join(' '),
|
||||
"DEFINES_MODULE" => "YES" }
|
||||
|
||||
if ENV['USE_FRAMEWORKS']
|
||||
s.module_name = "React_utils"
|
||||
s.header_mappings_dir = "../.."
|
||||
header_search_paths = header_search_paths + ["\"$(PODS_TARGET_SRCROOT)/platform/ios\""]
|
||||
end
|
||||
|
||||
s.pod_target_xcconfig = { "USE_HEADERMAP" => "NO",
|
||||
"CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(),
|
||||
"HEADER_SEARCH_PATHS" => header_search_paths.join(' '),
|
||||
"DEFINES_MODULE" => "YES" }
|
||||
|
||||
s.dependency "React-jsi", version
|
||||
|
||||
depend_on_js_engine(s)
|
||||
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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 <pthread.h>
|
||||
#include <sched.h>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
|
||||
namespace facebook::react::LowPriorityExecutor {
|
||||
|
||||
struct LowPriorityExecutorThread {
|
||||
LowPriorityExecutorThread() : thread_{std::thread([this] { run(); })} {
|
||||
pthread_t hThread = thread_.native_handle();
|
||||
struct sched_param param {};
|
||||
param.sched_priority = 19; // Higher value means lower priority
|
||||
pthread_setschedparam(hThread, SCHED_OTHER, ¶m);
|
||||
}
|
||||
|
||||
// Deleted constructors
|
||||
LowPriorityExecutorThread(const LowPriorityExecutorThread& other) = delete;
|
||||
LowPriorityExecutorThread(LowPriorityExecutorThread&& other) = delete;
|
||||
LowPriorityExecutorThread& operator=(const LowPriorityExecutorThread& other) =
|
||||
delete;
|
||||
LowPriorityExecutorThread& operator=(LowPriorityExecutorThread&& other) =
|
||||
delete;
|
||||
|
||||
~LowPriorityExecutorThread() {
|
||||
// Stop the thread
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
running_ = false;
|
||||
}
|
||||
|
||||
// Unblock the thread to check the running_ flag and terminate.
|
||||
cv_.notify_one();
|
||||
|
||||
// Wait for thread completion to avoid use-after-free on background thread.
|
||||
thread_.join();
|
||||
}
|
||||
|
||||
void post(std::function<void()>&& workItem) {
|
||||
// Move the object to the queue.
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
queue_.emplace(std::move(workItem));
|
||||
}
|
||||
|
||||
// Notify the background thread.
|
||||
cv_.notify_one();
|
||||
}
|
||||
|
||||
private:
|
||||
void run() {
|
||||
pthread_setname_np(pthread_self(), "LowPriorityExecutorThread");
|
||||
|
||||
while (true) {
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
|
||||
// Wait until an object is in the queue or the thread is stopped.
|
||||
cv_.wait(lock, [this] { return !queue_.empty() || !running_; });
|
||||
|
||||
// Empty the queue.
|
||||
while (!queue_.empty()) {
|
||||
queue_.front()();
|
||||
queue_.pop();
|
||||
}
|
||||
|
||||
// Check if the thread is stopping.
|
||||
if (!running_) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string threadName_;
|
||||
std::thread thread_;
|
||||
std::queue<std::function<void()>> queue_;
|
||||
std::mutex mutex_;
|
||||
std::condition_variable cv_;
|
||||
bool running_{true};
|
||||
};
|
||||
|
||||
void execute(std::function<void()>&& workItem) {
|
||||
static LowPriorityExecutorThread thread{};
|
||||
thread.post(std::move(workItem));
|
||||
}
|
||||
|
||||
} // namespace facebook::react::LowPriorityExecutor
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
namespace facebook::react::LowPriorityExecutor {
|
||||
|
||||
void execute(std::function<void()>&& workItem);
|
||||
|
||||
} // namespace facebook::react::LowPriorityExecutor
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* 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 <functional>
|
||||
|
||||
namespace facebook::react::LowPriorityExecutor {
|
||||
|
||||
inline void execute(std::function<void()>&& workItem) {
|
||||
workItem();
|
||||
}
|
||||
|
||||
} // namespace facebook::react::LowPriorityExecutor
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* 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 <functional>
|
||||
|
||||
namespace facebook::react::LowPriorityExecutor {
|
||||
|
||||
void execute(std::function<void()>&& workItem);
|
||||
|
||||
} // namespace facebook::react::LowPriorityExecutor
|
||||
+22
@@ -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.
|
||||
*/
|
||||
|
||||
#import "LowPriorityExecutor.h"
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
namespace facebook::react::LowPriorityExecutor {
|
||||
|
||||
void execute(std::function<void()> &&workItem)
|
||||
{
|
||||
std::function<void()> localWorkItem = std::move(workItem);
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
|
||||
localWorkItem();
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace facebook::react::LowPriorityExecutor
|
||||
@@ -155,6 +155,17 @@ const definitions: FeatureFlagDefinitions = {
|
||||
},
|
||||
ossReleaseStage: 'none',
|
||||
},
|
||||
enableDestroyShadowTreeRevisionAsync: {
|
||||
defaultValue: false,
|
||||
metadata: {
|
||||
dateAdded: '2025-04-29',
|
||||
description:
|
||||
'Enables destructor calls for ShadowTreeRevision in the background to reduce UI thread work.',
|
||||
expectedReleaseValue: true,
|
||||
purpose: 'experimentation',
|
||||
},
|
||||
ossReleaseStage: 'none',
|
||||
},
|
||||
enableDoubleMeasurementFixAndroid: {
|
||||
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<<fab0bb6a5cd8a2b8366e8184659188c0>>
|
||||
* @generated SignedSource<<fc8743f0fb9cb153412a1e81f585f07d>>
|
||||
* @flow strict
|
||||
*/
|
||||
|
||||
@@ -56,6 +56,7 @@ export type ReactNativeFeatureFlags = $ReadOnly<{
|
||||
enableBridgelessArchitecture: Getter<boolean>,
|
||||
enableCppPropsIteratorSetter: Getter<boolean>,
|
||||
enableCustomFocusSearchOnClippedElementsAndroid: Getter<boolean>,
|
||||
enableDestroyShadowTreeRevisionAsync: Getter<boolean>,
|
||||
enableDoubleMeasurementFixAndroid: Getter<boolean>,
|
||||
enableEagerRootViewAttachment: Getter<boolean>,
|
||||
enableFabricLogs: Getter<boolean>,
|
||||
@@ -197,6 +198,10 @@ export const enableCppPropsIteratorSetter: Getter<boolean> = createNativeFlagGet
|
||||
* This enables the fabric implementation of focus search so that we can focus clipped elements
|
||||
*/
|
||||
export const enableCustomFocusSearchOnClippedElementsAndroid: Getter<boolean> = createNativeFlagGetter('enableCustomFocusSearchOnClippedElementsAndroid', true);
|
||||
/**
|
||||
* Enables destructor calls for ShadowTreeRevision in the background to reduce UI thread work.
|
||||
*/
|
||||
export const enableDestroyShadowTreeRevisionAsync: Getter<boolean> = createNativeFlagGetter('enableDestroyShadowTreeRevisionAsync', false);
|
||||
/**
|
||||
* When enabled a subset of components will avoid double measurement on Android.
|
||||
*/
|
||||
|
||||
+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<<715d2a137ded85479120f5090c05b3b6>>
|
||||
* @generated SignedSource<<995633c3b12e26369518ff579f006f68>>
|
||||
* @flow strict
|
||||
*/
|
||||
|
||||
@@ -34,6 +34,7 @@ export interface Spec extends TurboModule {
|
||||
+enableBridgelessArchitecture?: () => boolean;
|
||||
+enableCppPropsIteratorSetter?: () => boolean;
|
||||
+enableCustomFocusSearchOnClippedElementsAndroid?: () => boolean;
|
||||
+enableDestroyShadowTreeRevisionAsync?: () => boolean;
|
||||
+enableDoubleMeasurementFixAndroid?: () => boolean;
|
||||
+enableEagerRootViewAttachment?: () => boolean;
|
||||
+enableFabricLogs?: () => boolean;
|
||||
|
||||
Reference in New Issue
Block a user