Skip to content

Commit

Permalink
Enable synchronous state update dispatching behind a flag (facebook#4…
Browse files Browse the repository at this point in the history
…3580)

Summary:
Pull Request resolved: facebook#43580

Changelog: [internal]

This introduces a new feature flag to commit state updates synchronously from the UI thread (generally) instead of dispatching them to the JS thread to be processed there. We can do this now because we introduced a UI consistency mechanism in D55024832 to JS would see a consistent revision during the execution of a specific task.

Reviewed By: sammy-SC

Differential Revision: D55083029
  • Loading branch information
rubennorte authored and facebook-github-bot committed Mar 25, 2024
1 parent ffa1d3c commit b106050
Show file tree
Hide file tree
Showing 23 changed files with 142 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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<<20c445fde7a1c2607b58b7797346431f>>
* @generated SignedSource<<e3cfdd93315067ed37e7cf93aa60af74>>
*/

/**
Expand Down Expand Up @@ -76,6 +76,12 @@ public object ReactNativeFeatureFlags {
@JvmStatic
public fun enableSpannableBuildingUnification(): Boolean = accessor.enableSpannableBuildingUnification()

/**
* Dispatches state updates synchronously in Fabric (e.g.: updates the scroll position in the shadow tree synchronously from the main thread).
*/
@JvmStatic
public fun enableSynchronousStateUpdates(): Boolean = accessor.enableSynchronousStateUpdates()

/**
* Ensures that JavaScript always has a consistent view of the state of the UI (e.g.: commits done in other threads are not immediately propagated to JS during its execution).
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<6e973dcdcdfae14c77a6130207333551>>
* @generated SignedSource<<9184044883f829855c2de9db42566287>>
*/

/**
Expand All @@ -28,6 +28,7 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso
private var enableMicrotasksCache: Boolean? = null
private var enableMountHooksAndroidCache: Boolean? = null
private var enableSpannableBuildingUnificationCache: Boolean? = null
private var enableSynchronousStateUpdatesCache: Boolean? = null
private var enableUIConsistencyCache: Boolean? = null
private var inspectorEnableCxxInspectorPackagerConnectionCache: Boolean? = null
private var inspectorEnableModernCDPRegistryCache: Boolean? = null
Expand Down Expand Up @@ -105,6 +106,15 @@ public class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAccesso
return cached
}

override fun enableSynchronousStateUpdates(): Boolean {
var cached = enableSynchronousStateUpdatesCache
if (cached == null) {
cached = ReactNativeFeatureFlagsCxxInterop.enableSynchronousStateUpdates()
enableSynchronousStateUpdatesCache = cached
}
return cached
}

override fun enableUIConsistency(): Boolean {
var cached = enableUIConsistencyCache
if (cached == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<0d34567fc05555ae401e7f5180dc8771>>
* @generated SignedSource<<4154c0f81f2e5ad7ff03e252c4aa965c>>
*/

/**
Expand Down Expand Up @@ -44,6 +44,8 @@ public object ReactNativeFeatureFlagsCxxInterop {

@DoNotStrip @JvmStatic public external fun enableSpannableBuildingUnification(): Boolean

@DoNotStrip @JvmStatic public external fun enableSynchronousStateUpdates(): Boolean

@DoNotStrip @JvmStatic public external fun enableUIConsistency(): Boolean

@DoNotStrip @JvmStatic public external fun inspectorEnableCxxInspectorPackagerConnection(): Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<cfb3e4f5d83a939f4b034bc62762837e>>
* @generated SignedSource<<c903b5aa8d70665c1104baa6670f8cb1>>
*/

/**
Expand Down Expand Up @@ -39,6 +39,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi

override fun enableSpannableBuildingUnification(): Boolean = false

override fun enableSynchronousStateUpdates(): Boolean = false

override fun enableUIConsistency(): Boolean = false

override fun inspectorEnableCxxInspectorPackagerConnection(): Boolean = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<8908de9b9d0186f1916d8b55d5854cb2>>
* @generated SignedSource<<c087df804587a9a02a0547684d0e9c92>>
*/

/**
Expand Down Expand Up @@ -32,6 +32,7 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces
private var enableMicrotasksCache: Boolean? = null
private var enableMountHooksAndroidCache: Boolean? = null
private var enableSpannableBuildingUnificationCache: Boolean? = null
private var enableSynchronousStateUpdatesCache: Boolean? = null
private var enableUIConsistencyCache: Boolean? = null
private var inspectorEnableCxxInspectorPackagerConnectionCache: Boolean? = null
private var inspectorEnableModernCDPRegistryCache: Boolean? = null
Expand Down Expand Up @@ -117,6 +118,16 @@ public class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcces
return cached
}

override fun enableSynchronousStateUpdates(): Boolean {
var cached = enableSynchronousStateUpdatesCache
if (cached == null) {
cached = currentProvider.enableSynchronousStateUpdates()
accessedFeatureFlags.add("enableSynchronousStateUpdates")
enableSynchronousStateUpdatesCache = cached
}
return cached
}

override fun enableUIConsistency(): Boolean {
var cached = enableUIConsistencyCache
if (cached == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<7555a704535615fcea44c1261095419a>>
* @generated SignedSource<<c39073091ea96d16a352d00def1b5532>>
*/

/**
Expand Down Expand Up @@ -39,6 +39,8 @@ public interface ReactNativeFeatureFlagsProvider {

@DoNotStrip public fun enableSpannableBuildingUnification(): Boolean

@DoNotStrip public fun enableSynchronousStateUpdates(): Boolean

@DoNotStrip public fun enableUIConsistency(): Boolean

@DoNotStrip public fun inspectorEnableCxxInspectorPackagerConnection(): Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<e6f57d186226377e4558f633433aa1fc>>
* @generated SignedSource<<db9ab5f48de2fdbee406ddea10125feb>>
*/

/**
Expand Down Expand Up @@ -87,6 +87,12 @@ class ReactNativeFeatureFlagsProviderHolder
return method(javaProvider_);
}

bool enableSynchronousStateUpdates() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableSynchronousStateUpdates");
return method(javaProvider_);
}

bool enableUIConsistency() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableUIConsistency");
Expand Down Expand Up @@ -155,6 +161,11 @@ bool JReactNativeFeatureFlagsCxxInterop::enableSpannableBuildingUnification(
return ReactNativeFeatureFlags::enableSpannableBuildingUnification();
}

bool JReactNativeFeatureFlagsCxxInterop::enableSynchronousStateUpdates(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::enableSynchronousStateUpdates();
}

bool JReactNativeFeatureFlagsCxxInterop::enableUIConsistency(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::enableUIConsistency();
Expand Down Expand Up @@ -216,6 +227,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
makeNativeMethod(
"enableSpannableBuildingUnification",
JReactNativeFeatureFlagsCxxInterop::enableSpannableBuildingUnification),
makeNativeMethod(
"enableSynchronousStateUpdates",
JReactNativeFeatureFlagsCxxInterop::enableSynchronousStateUpdates),
makeNativeMethod(
"enableUIConsistency",
JReactNativeFeatureFlagsCxxInterop::enableUIConsistency),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<a90ff7ce4734046fd9aab1c501ca22b4>>
* @generated SignedSource<<6b33129341a4b68cdbbdbce9f57e4d63>>
*/

/**
Expand Down Expand Up @@ -54,6 +54,9 @@ class JReactNativeFeatureFlagsCxxInterop
static bool enableSpannableBuildingUnification(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);

static bool enableSynchronousStateUpdates(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);

static bool enableUIConsistency(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<a5c58cc8c0294fd073f43fda88b908f8>>
* @generated SignedSource<<56f79a4cb62a993f9c3a8ea01eed2ab6>>
*/

/**
Expand Down Expand Up @@ -53,6 +53,10 @@ bool ReactNativeFeatureFlags::enableSpannableBuildingUnification() {
return getAccessor().enableSpannableBuildingUnification();
}

bool ReactNativeFeatureFlags::enableSynchronousStateUpdates() {
return getAccessor().enableSynchronousStateUpdates();
}

bool ReactNativeFeatureFlags::enableUIConsistency() {
return getAccessor().enableUIConsistency();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<e94d55bad5f8bf6cf933ddc50e3b4886>>
* @generated SignedSource<<bab6aad25607059d465d6c80711a4adf>>
*/

/**
Expand Down Expand Up @@ -77,6 +77,11 @@ class ReactNativeFeatureFlags {
*/
RN_EXPORT static bool enableSpannableBuildingUnification();

/**
* Dispatches state updates synchronously in Fabric (e.g.: updates the scroll position in the shadow tree synchronously from the main thread).
*/
RN_EXPORT static bool enableSynchronousStateUpdates();

/**
* Ensures that JavaScript always has a consistent view of the state of the UI (e.g.: commits done in other threads are not immediately propagated to JS during its execution).
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<2ff39fd4c8330ddca994fc40cdeaaf4c>>
* @generated SignedSource<<5b42b33319369b7936662a2608794ba5>>
*/

/**
Expand Down Expand Up @@ -173,6 +173,24 @@ bool ReactNativeFeatureFlagsAccessor::enableSpannableBuildingUnification() {
return flagValue.value();
}

bool ReactNativeFeatureFlagsAccessor::enableSynchronousStateUpdates() {
auto flagValue = enableSynchronousStateUpdates_.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(8, "enableSynchronousStateUpdates");

flagValue = currentProvider_->enableSynchronousStateUpdates();
enableSynchronousStateUpdates_ = flagValue;
}

return flagValue.value();
}

bool ReactNativeFeatureFlagsAccessor::enableUIConsistency() {
auto flagValue = enableUIConsistency_.load();

Expand All @@ -182,7 +200,7 @@ bool ReactNativeFeatureFlagsAccessor::enableUIConsistency() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.

markFlagAsAccessed(8, "enableUIConsistency");
markFlagAsAccessed(9, "enableUIConsistency");

flagValue = currentProvider_->enableUIConsistency();
enableUIConsistency_ = flagValue;
Expand All @@ -200,7 +218,7 @@ bool ReactNativeFeatureFlagsAccessor::inspectorEnableCxxInspectorPackagerConnect
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.

markFlagAsAccessed(9, "inspectorEnableCxxInspectorPackagerConnection");
markFlagAsAccessed(10, "inspectorEnableCxxInspectorPackagerConnection");

flagValue = currentProvider_->inspectorEnableCxxInspectorPackagerConnection();
inspectorEnableCxxInspectorPackagerConnection_ = flagValue;
Expand All @@ -218,7 +236,7 @@ bool ReactNativeFeatureFlagsAccessor::inspectorEnableModernCDPRegistry() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.

markFlagAsAccessed(10, "inspectorEnableModernCDPRegistry");
markFlagAsAccessed(11, "inspectorEnableModernCDPRegistry");

flagValue = currentProvider_->inspectorEnableModernCDPRegistry();
inspectorEnableModernCDPRegistry_ = flagValue;
Expand All @@ -236,7 +254,7 @@ bool ReactNativeFeatureFlagsAccessor::useModernRuntimeScheduler() {
// be accessing the provider multiple times but the end state of this
// instance and the returned flag value would be the same.

markFlagAsAccessed(11, "useModernRuntimeScheduler");
markFlagAsAccessed(12, "useModernRuntimeScheduler");

flagValue = currentProvider_->useModernRuntimeScheduler();
useModernRuntimeScheduler_ = flagValue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<a8e0d8c5bc041f814bffb1701a124646>>
* @generated SignedSource<<a508f23dce88a9c186d6bd84e65b3af7>>
*/

/**
Expand Down Expand Up @@ -39,6 +39,7 @@ class ReactNativeFeatureFlagsAccessor {
bool enableMicrotasks();
bool enableMountHooksAndroid();
bool enableSpannableBuildingUnification();
bool enableSynchronousStateUpdates();
bool enableUIConsistency();
bool inspectorEnableCxxInspectorPackagerConnection();
bool inspectorEnableModernCDPRegistry();
Expand All @@ -53,7 +54,7 @@ class ReactNativeFeatureFlagsAccessor {
std::unique_ptr<ReactNativeFeatureFlagsProvider> currentProvider_;
bool wasOverridden_;

std::array<std::atomic<const char*>, 12> accessedFeatureFlags_;
std::array<std::atomic<const char*>, 13> accessedFeatureFlags_;

std::atomic<std::optional<bool>> commonTestFlag_;
std::atomic<std::optional<bool>> batchRenderingUpdatesInEventLoop_;
Expand All @@ -63,6 +64,7 @@ class ReactNativeFeatureFlagsAccessor {
std::atomic<std::optional<bool>> enableMicrotasks_;
std::atomic<std::optional<bool>> enableMountHooksAndroid_;
std::atomic<std::optional<bool>> enableSpannableBuildingUnification_;
std::atomic<std::optional<bool>> enableSynchronousStateUpdates_;
std::atomic<std::optional<bool>> enableUIConsistency_;
std::atomic<std::optional<bool>> inspectorEnableCxxInspectorPackagerConnection_;
std::atomic<std::optional<bool>> inspectorEnableModernCDPRegistry_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<1450d89abc68821fb348574016874719>>
* @generated SignedSource<<9fd009411ce19224a3102d2713b0b042>>
*/

/**
Expand Down Expand Up @@ -59,6 +59,10 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider {
return false;
}

bool enableSynchronousStateUpdates() override {
return false;
}

bool enableUIConsistency() override {
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<<d369db4d7cd374081941bff6c6f3e08f>>
* @generated SignedSource<<7384eeb8615a45b79cdcceb731d98e9d>>
*/

/**
Expand Down Expand Up @@ -33,6 +33,7 @@ class ReactNativeFeatureFlagsProvider {
virtual bool enableMicrotasks() = 0;
virtual bool enableMountHooksAndroid() = 0;
virtual bool enableSpannableBuildingUnification() = 0;
virtual bool enableSynchronousStateUpdates() = 0;
virtual bool enableUIConsistency() = 0;
virtual bool inspectorEnableCxxInspectorPackagerConnection() = 0;
virtual bool inspectorEnableModernCDPRegistry() = 0;
Expand Down
Loading

0 comments on commit b106050

Please sign in to comment.