Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/react-native/React/Fabric/RCTScheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ NS_ASSUME_NONNULL_BEGIN

- (void)schedulerShouldMergeReactRevision:(facebook::react::SurfaceId)surfaceId;

- (BOOL)schedulerShouldPromoteReactRevision:(facebook::react::SurfaceId)surfaceId;

- (void)schedulerDidDispatchCommand:(const facebook::react::ShadowView &)shadowView
commandName:(const std::string &)commandName
args:(const folly::dynamic &)args;
Expand Down
6 changes: 6 additions & 0 deletions packages/react-native/React/Fabric/RCTScheduler.mm
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ void schedulerShouldMergeReactRevision(SurfaceId surfaceId) override
[scheduler.delegate schedulerShouldMergeReactRevision:surfaceId];
}

bool schedulerShouldPromoteReactRevision(SurfaceId surfaceId) override
{
RCTScheduler *scheduler = (__bridge RCTScheduler *)scheduler_;
return [scheduler.delegate schedulerShouldPromoteReactRevision:surfaceId];
}

void schedulerDidRequestPreliminaryViewAllocation(const ShadowNode &shadowNode) override
{
// Does nothing.
Expand Down
14 changes: 14 additions & 0 deletions packages/react-native/React/Fabric/RCTSurfacePresenter.mm
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,20 @@ - (void)schedulerShouldMergeReactRevision:(SurfaceId)surfaceId
});
}

- (BOOL)schedulerShouldPromoteReactRevision:(SurfaceId)surfaceId
{
if (!RCTIsMainQueue()) {
return NO;
}

auto scheduler = [self scheduler];
scheduler.uiManager->getShadowTreeRegistry().visit(surfaceId, [](const ShadowTree &shadowTree) {
shadowTree.promoteReactRevision();
shadowTree.mergeReactRevision();
});
return YES;
}

- (void)schedulerDidDispatchCommand:(const ShadowView &)shadowView
commandName:(const std::string &)commandName
args:(const folly::dynamic &)args
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<<17abc72a4045c5695818f254be1783b5>>
* @generated SignedSource<<404892ee783081aa311bb8faa55b231f>>
*/

/**
Expand Down Expand Up @@ -67,7 +67,7 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi

override fun enableExclusivePropsUpdateAndroid(): Boolean = false

override fun enableFabricCommitBranching(): Boolean = false
override fun enableFabricCommitBranching(): Boolean = true

override fun enableFabricLogs(): Boolean = false

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,9 @@ class FabricMountingManager final {

void scheduleReactRevisionMerge(SurfaceId surfaceId);

private:
bool isOnMainThread();

private:
jni::global_ref<JFabricUIManager::javaobject> javaUIManager_;

std::recursive_mutex commitMutex_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,23 @@ void FabricUIManagerBinding::schedulerShouldMergeReactRevision(
}
}

bool FabricUIManagerBinding::schedulerShouldPromoteReactRevision(
SurfaceId surfaceId) {
std::shared_lock lock(installMutex_);
auto mountingManager =
getMountingManager("schedulerShouldPromoteReactRevision");
if (!mountingManager || !mountingManager->isOnMainThread()) {
return false;
}

scheduler_->getUIManager()->getShadowTreeRegistry().visit(
surfaceId, [](const ShadowTree& shadowTree) {
shadowTree.promoteReactRevision();
shadowTree.mergeReactRevision();
});
return true;
}

void FabricUIManagerBinding::mergeReactRevision(SurfaceId surfaceId) {
std::shared_lock lock(installMutex_);
scheduler_->getUIManager()->getShadowTreeRegistry().visit(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ class FabricUIManagerBinding : public jni::HybridClass<FabricUIManagerBinding>,

void schedulerShouldMergeReactRevision(SurfaceId surfaceId) override;

bool schedulerShouldPromoteReactRevision(SurfaceId surfaceId) override;

void mergeReactRevision(SurfaceId surfaceId);

void schedulerDidRequestPreliminaryViewAllocation(const ShadowNode &shadowNode) override;
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<<33fd238aafa83c5a42803d3f11d55944>>
* @generated SignedSource<<c5368d536f9c9b5ee0f6a08d53b51929>>
*/

/**
Expand Down Expand Up @@ -116,7 +116,7 @@ class ReactNativeFeatureFlagsDefaults : public ReactNativeFeatureFlagsProvider {
}

bool enableFabricCommitBranching() override {
return false;
return true;
}

bool enableFabricLogs() override {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,15 @@ void Scheduler::uiManagerShouldRemoveEventListener(

void Scheduler::uiManagerDidFinishReactCommit(const ShadowTree& shadowTree) {
auto surfaceId = shadowTree.getSurfaceId();

// If the commit is happening on the main thread, it should be merged
// immediately instead of being scheduled. This allows for synchronous
// events to be handled correctly.
if (delegate_ != nullptr &&
delegate_->schedulerShouldPromoteReactRevision(surfaceId)) {
return;
}

runtimeScheduler_->scheduleRenderingUpdate(
surfaceId, [surfaceId, uiManager = uiManager_]() {
uiManager->getShadowTreeRegistry().visit(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ class SchedulerDelegate {
*/
virtual void schedulerShouldMergeReactRevision(SurfaceId surfaceId) = 0;

/*
* Called when a React commit finishes and the JS revision needs to be
* promoted. If the platform is currently on the main thread, it should
* promote and merge the revision immediately, returning true.
* If not on the main thread, it should return false and the caller will
* schedule the promotion at the end of the event loop.
*/
virtual bool schedulerShouldPromoteReactRevision(SurfaceId surfaceId) = 0;

/*
* Called right after a new ShadowNode was created.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ void SchedulerDelegateImpl::schedulerShouldMergeReactRevision(
[](const ShadowTree& shadowTree) { shadowTree.mergeReactRevision(); });
}

bool SchedulerDelegateImpl::schedulerShouldPromoteReactRevision(
SurfaceId /*surfaceId*/) {
return false;
}

void SchedulerDelegateImpl::schedulerDidRequestPreliminaryViewAllocation(
const ShadowNode& shadowNode) {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class SchedulerDelegateImpl : public SchedulerDelegate {

void schedulerShouldMergeReactRevision(SurfaceId surfaceId) override;

bool schedulerShouldPromoteReactRevision(SurfaceId surfaceId) override;

void schedulerDidRequestPreliminaryViewAllocation(const ShadowNode &shadowNode) override;

void schedulerDidDispatchCommand(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ const definitions: FeatureFlagDefinitions = {
ossReleaseStage: 'none',
},
enableFabricCommitBranching: {
defaultValue: false,
defaultValue: true,
metadata: {
description:
'Enables Fabric commit branching to fix starvation problems and atomic JS updates.',
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<<1ec2592998e830300fc777070dfdc49d>>
* @generated SignedSource<<4e307a9c3ceae21cc7f1e201c58a51ad>>
* @flow strict
* @noformat
*/
Expand Down Expand Up @@ -287,7 +287,7 @@ export const enableExclusivePropsUpdateAndroid: Getter<boolean> = createNativeFl
/**
* Enables Fabric commit branching to fix starvation problems and atomic JS updates.
*/
export const enableFabricCommitBranching: Getter<boolean> = createNativeFlagGetter('enableFabricCommitBranching', false);
export const enableFabricCommitBranching: Getter<boolean> = createNativeFlagGetter('enableFabricCommitBranching', true);
/**
* This feature flag enables logs for Fabric.
*/
Expand Down
14 changes: 9 additions & 5 deletions scripts/cxx-api/api-snapshots/ReactAndroidDebugCxx.api
Original file line number Diff line number Diff line change
Expand Up @@ -1824,15 +1824,17 @@ class facebook::react::BindingsInstallerHolder : public jni::HybridClass<faceboo
public void installBindings(facebook::jsi::Runtime& runtime, const std::shared_ptr<facebook::react::CallInvoker>& callInvoker);
}

class facebook::react::BlobCollector : public jni::HybridClass<facebook::react::BlobCollector>, public facebook::jsi::HostObject {
class facebook::react::BlobCollector : public facebook::jsi::HostObject {
public BlobCollector(jni::global_ref<jobject> blobModule, std::string blobId);
public size_t getBlobLength();
public static constexpr auto kJavaDescriptor;
public static void nativeInstall(jni::alias_ref<jclass>, jni::alias_ref<jobject> blobModule, jlong jsContextNativePointer);
public static void registerNatives();
public ~BlobCollector();
}

class facebook::react::BlobModuleJSIBindings : public jni::JavaClass<facebook::react::BlobModuleJSIBindings> {
public static constexpr char* kJavaDescriptor;
public static void registerNatives();
}

class facebook::react::BridgelessNativeMethodCallInvoker : public facebook::react::NativeMethodCallInvoker {
public BridgelessNativeMethodCallInvoker(std::shared_ptr<facebook::react::MessageQueueThread> messageQueueThread);
public virtual void invokeAsync(const std::string& methodName, facebook::react::NativeMethodCallFunc&& func) noexcept override;
Expand Down Expand Up @@ -2311,6 +2313,7 @@ class facebook::react::ExecutorDelegate {
class facebook::react::FabricMountingManager {
public FabricMountingManager(const facebook::react::FabricMountingManager&) = delete;
public FabricMountingManager(jni::global_ref<JFabricUIManager::javaobject>& javaUIManager);
public bool isOnMainThread();
public bool isViewAllocated(facebook::react::SurfaceId surfaceId, facebook::react::Tag tag);
public void destroyUnmountedShadowNode(const facebook::react::ShadowNodeFamily& family);
public void dispatchCommand(const facebook::react::ShadowView& shadowView, const std::string& commandName, const folly::dynamic& args);
Expand Down Expand Up @@ -4477,6 +4480,7 @@ class facebook::react::Scheduler : public facebook::react::UIManagerDelegate {
}

class facebook::react::SchedulerDelegate {
public virtual bool schedulerShouldPromoteReactRevision(facebook::react::SurfaceId surfaceId) = 0;
public virtual void schedulerDidDispatchCommand(const facebook::react::ShadowView& shadowView, const std::string& commandName, const folly::dynamic& args) = 0;
public virtual void schedulerDidFinishTransaction(const std::shared_ptr<const facebook::react::MountingCoordinator>& mountingCoordinator) = 0;
public virtual void schedulerDidRequestPreliminaryViewAllocation(const facebook::react::ShadowNode& shadowNode) = 0;
Expand Down Expand Up @@ -7440,7 +7444,7 @@ struct facebook::react::NativePerformanceEntry {
}

struct facebook::react::PerformanceEntrySorter {
public bool operator()(const facebook::react::PerformanceEntry& lhs, const facebook::react::PerformanceEntry& rhs);
public bool operator()(const facebook::react::PerformanceEntry& lhs, const facebook::react::PerformanceEntry& rhs) const;
}

struct facebook::react::PerformanceEventTiming : public facebook::react::AbstractPerformanceEntry {
Expand Down
14 changes: 9 additions & 5 deletions scripts/cxx-api/api-snapshots/ReactAndroidReleaseCxx.api
Original file line number Diff line number Diff line change
Expand Up @@ -1822,15 +1822,17 @@ class facebook::react::BindingsInstallerHolder : public jni::HybridClass<faceboo
public void installBindings(facebook::jsi::Runtime& runtime, const std::shared_ptr<facebook::react::CallInvoker>& callInvoker);
}

class facebook::react::BlobCollector : public jni::HybridClass<facebook::react::BlobCollector>, public facebook::jsi::HostObject {
class facebook::react::BlobCollector : public facebook::jsi::HostObject {
public BlobCollector(jni::global_ref<jobject> blobModule, std::string blobId);
public size_t getBlobLength();
public static constexpr auto kJavaDescriptor;
public static void nativeInstall(jni::alias_ref<jclass>, jni::alias_ref<jobject> blobModule, jlong jsContextNativePointer);
public static void registerNatives();
public ~BlobCollector();
}

class facebook::react::BlobModuleJSIBindings : public jni::JavaClass<facebook::react::BlobModuleJSIBindings> {
public static constexpr char* kJavaDescriptor;
public static void registerNatives();
}

class facebook::react::BridgelessNativeMethodCallInvoker : public facebook::react::NativeMethodCallInvoker {
public BridgelessNativeMethodCallInvoker(std::shared_ptr<facebook::react::MessageQueueThread> messageQueueThread);
public virtual void invokeAsync(const std::string& methodName, facebook::react::NativeMethodCallFunc&& func) noexcept override;
Expand Down Expand Up @@ -2309,6 +2311,7 @@ class facebook::react::ExecutorDelegate {
class facebook::react::FabricMountingManager {
public FabricMountingManager(const facebook::react::FabricMountingManager&) = delete;
public FabricMountingManager(jni::global_ref<JFabricUIManager::javaobject>& javaUIManager);
public bool isOnMainThread();
public bool isViewAllocated(facebook::react::SurfaceId surfaceId, facebook::react::Tag tag);
public void destroyUnmountedShadowNode(const facebook::react::ShadowNodeFamily& family);
public void dispatchCommand(const facebook::react::ShadowView& shadowView, const std::string& commandName, const folly::dynamic& args);
Expand Down Expand Up @@ -4474,6 +4477,7 @@ class facebook::react::Scheduler : public facebook::react::UIManagerDelegate {
}

class facebook::react::SchedulerDelegate {
public virtual bool schedulerShouldPromoteReactRevision(facebook::react::SurfaceId surfaceId) = 0;
public virtual void schedulerDidDispatchCommand(const facebook::react::ShadowView& shadowView, const std::string& commandName, const folly::dynamic& args) = 0;
public virtual void schedulerDidFinishTransaction(const std::shared_ptr<const facebook::react::MountingCoordinator>& mountingCoordinator) = 0;
public virtual void schedulerDidRequestPreliminaryViewAllocation(const facebook::react::ShadowNode& shadowNode) = 0;
Expand Down Expand Up @@ -7431,7 +7435,7 @@ struct facebook::react::NativePerformanceEntry {
}

struct facebook::react::PerformanceEntrySorter {
public bool operator()(const facebook::react::PerformanceEntry& lhs, const facebook::react::PerformanceEntry& rhs);
public bool operator()(const facebook::react::PerformanceEntry& lhs, const facebook::react::PerformanceEntry& rhs) const;
}

struct facebook::react::PerformanceEventTiming : public facebook::react::AbstractPerformanceEntry {
Expand Down
4 changes: 3 additions & 1 deletion scripts/cxx-api/api-snapshots/ReactAppleDebugCxx.api
Original file line number Diff line number Diff line change
Expand Up @@ -3349,6 +3349,7 @@ protocol RCTSafeAreaViewViewProtocol : public NSObject {
}

protocol RCTSchedulerDelegate {
public virtual BOOL schedulerShouldPromoteReactRevision:(facebook::react::SurfaceId surfaceId);
public virtual void schedulerDidDispatchCommand:commandName:args:(const facebook::react::ShadowView& shadowView, const std::string& commandName, const folly::dynamic& args);
public virtual void schedulerDidFinishTransaction:(std::shared_ptr<const facebook::react::MountingCoordinator> mountingCoordinator);
public virtual void schedulerDidSendAccessibilityEvent:eventType:(const facebook::react::ShadowView& shadowView, const std::string& eventType);
Expand Down Expand Up @@ -7064,6 +7065,7 @@ class facebook::react::Scheduler : public facebook::react::UIManagerDelegate {
}

class facebook::react::SchedulerDelegate {
public virtual bool schedulerShouldPromoteReactRevision(facebook::react::SurfaceId surfaceId) = 0;
public virtual void schedulerDidDispatchCommand(const facebook::react::ShadowView& shadowView, const std::string& commandName, const folly::dynamic& args) = 0;
public virtual void schedulerDidFinishTransaction(const std::shared_ptr<const facebook::react::MountingCoordinator>& mountingCoordinator) = 0;
public virtual void schedulerDidRequestPreliminaryViewAllocation(const facebook::react::ShadowNode& shadowNode) = 0;
Expand Down Expand Up @@ -9891,7 +9893,7 @@ struct facebook::react::NativePerformanceEntry {
}

struct facebook::react::PerformanceEntrySorter {
public bool operator()(const facebook::react::PerformanceEntry& lhs, const facebook::react::PerformanceEntry& rhs);
public bool operator()(const facebook::react::PerformanceEntry& lhs, const facebook::react::PerformanceEntry& rhs) const;
}

struct facebook::react::PerformanceEventTiming : public facebook::react::AbstractPerformanceEntry {
Expand Down
4 changes: 3 additions & 1 deletion scripts/cxx-api/api-snapshots/ReactAppleReleaseCxx.api
Original file line number Diff line number Diff line change
Expand Up @@ -3349,6 +3349,7 @@ protocol RCTSafeAreaViewViewProtocol : public NSObject {
}

protocol RCTSchedulerDelegate {
public virtual BOOL schedulerShouldPromoteReactRevision:(facebook::react::SurfaceId surfaceId);
public virtual void schedulerDidDispatchCommand:commandName:args:(const facebook::react::ShadowView& shadowView, const std::string& commandName, const folly::dynamic& args);
public virtual void schedulerDidFinishTransaction:(std::shared_ptr<const facebook::react::MountingCoordinator> mountingCoordinator);
public virtual void schedulerDidSendAccessibilityEvent:eventType:(const facebook::react::ShadowView& shadowView, const std::string& eventType);
Expand Down Expand Up @@ -7061,6 +7062,7 @@ class facebook::react::Scheduler : public facebook::react::UIManagerDelegate {
}

class facebook::react::SchedulerDelegate {
public virtual bool schedulerShouldPromoteReactRevision(facebook::react::SurfaceId surfaceId) = 0;
public virtual void schedulerDidDispatchCommand(const facebook::react::ShadowView& shadowView, const std::string& commandName, const folly::dynamic& args) = 0;
public virtual void schedulerDidFinishTransaction(const std::shared_ptr<const facebook::react::MountingCoordinator>& mountingCoordinator) = 0;
public virtual void schedulerDidRequestPreliminaryViewAllocation(const facebook::react::ShadowNode& shadowNode) = 0;
Expand Down Expand Up @@ -9882,7 +9884,7 @@ struct facebook::react::NativePerformanceEntry {
}

struct facebook::react::PerformanceEntrySorter {
public bool operator()(const facebook::react::PerformanceEntry& lhs, const facebook::react::PerformanceEntry& rhs);
public bool operator()(const facebook::react::PerformanceEntry& lhs, const facebook::react::PerformanceEntry& rhs) const;
}

struct facebook::react::PerformanceEventTiming : public facebook::react::AbstractPerformanceEntry {
Expand Down
3 changes: 2 additions & 1 deletion scripts/cxx-api/api-snapshots/ReactCommonDebugCxx.api
Original file line number Diff line number Diff line change
Expand Up @@ -3045,6 +3045,7 @@ class facebook::react::Scheduler : public facebook::react::UIManagerDelegate {
}

class facebook::react::SchedulerDelegate {
public virtual bool schedulerShouldPromoteReactRevision(facebook::react::SurfaceId surfaceId) = 0;
public virtual void schedulerDidDispatchCommand(const facebook::react::ShadowView& shadowView, const std::string& commandName, const folly::dynamic& args) = 0;
public virtual void schedulerDidFinishTransaction(const std::shared_ptr<const facebook::react::MountingCoordinator>& mountingCoordinator) = 0;
public virtual void schedulerDidRequestPreliminaryViewAllocation(const facebook::react::ShadowNode& shadowNode) = 0;
Expand Down Expand Up @@ -5629,7 +5630,7 @@ struct facebook::react::NativePerformanceEntry {
}

struct facebook::react::PerformanceEntrySorter {
public bool operator()(const facebook::react::PerformanceEntry& lhs, const facebook::react::PerformanceEntry& rhs);
public bool operator()(const facebook::react::PerformanceEntry& lhs, const facebook::react::PerformanceEntry& rhs) const;
}

struct facebook::react::PerformanceEventTiming : public facebook::react::AbstractPerformanceEntry {
Expand Down
3 changes: 2 additions & 1 deletion scripts/cxx-api/api-snapshots/ReactCommonReleaseCxx.api
Original file line number Diff line number Diff line change
Expand Up @@ -3042,6 +3042,7 @@ class facebook::react::Scheduler : public facebook::react::UIManagerDelegate {
}

class facebook::react::SchedulerDelegate {
public virtual bool schedulerShouldPromoteReactRevision(facebook::react::SurfaceId surfaceId) = 0;
public virtual void schedulerDidDispatchCommand(const facebook::react::ShadowView& shadowView, const std::string& commandName, const folly::dynamic& args) = 0;
public virtual void schedulerDidFinishTransaction(const std::shared_ptr<const facebook::react::MountingCoordinator>& mountingCoordinator) = 0;
public virtual void schedulerDidRequestPreliminaryViewAllocation(const facebook::react::ShadowNode& shadowNode) = 0;
Expand Down Expand Up @@ -5620,7 +5621,7 @@ struct facebook::react::NativePerformanceEntry {
}

struct facebook::react::PerformanceEntrySorter {
public bool operator()(const facebook::react::PerformanceEntry& lhs, const facebook::react::PerformanceEntry& rhs);
public bool operator()(const facebook::react::PerformanceEntry& lhs, const facebook::react::PerformanceEntry& rhs) const;
}

struct facebook::react::PerformanceEventTiming : public facebook::react::AbstractPerformanceEntry {
Expand Down
Loading