From a3dcaeef8b27b8d194f6a77d0e038578509450a7 Mon Sep 17 00:00:00 2001 From: Liron Yahdav Date: Mon, 21 Oct 2024 14:28:13 -0700 Subject: [PATCH] Use RuntimeScheduler in EventBeat Summary: This will allows us to batch sync events which leads to better performance. Differential Revision: D64631346 --- .../React/Fabric/AppleEventBeat.cpp | 4 +-- .../React/Fabric/AppleEventBeat.h | 4 ++- .../React/Fabric/RCTSurfacePresenter.mm | 4 +-- .../jni/react/fabric/AndroidEventBeat.cpp | 4 +-- .../main/jni/react/fabric/AndroidEventBeat.h | 2 +- .../react/fabric/FabricUIManagerBinding.cpp | 25 ++++++++--------- .../react/renderer/core/EventBeat.cpp | 28 +++++++++---------- .../react/renderer/core/EventBeat.h | 6 ++-- 8 files changed, 38 insertions(+), 39 deletions(-) diff --git a/packages/react-native/React/Fabric/AppleEventBeat.cpp b/packages/react-native/React/Fabric/AppleEventBeat.cpp index f172cbcd785da5..4a3d533a0cd94a 100644 --- a/packages/react-native/React/Fabric/AppleEventBeat.cpp +++ b/packages/react-native/React/Fabric/AppleEventBeat.cpp @@ -14,8 +14,8 @@ namespace facebook::react { AppleEventBeat::AppleEventBeat( std::shared_ptr ownerBox, std::unique_ptr uiRunLoopObserver, - RuntimeExecutor runtimeExecutor) - : EventBeat(std::move(ownerBox), std::move(runtimeExecutor)), + RuntimeScheduler& runtimeScheduler) + : EventBeat(std::move(ownerBox), runtimeScheduler), uiRunLoopObserver_(std::move(uiRunLoopObserver)) { uiRunLoopObserver_->setDelegate(this); uiRunLoopObserver_->enable(); diff --git a/packages/react-native/React/Fabric/AppleEventBeat.h b/packages/react-native/React/Fabric/AppleEventBeat.h index d842d4f63d6112..f2f9ef4316a3f4 100644 --- a/packages/react-native/React/Fabric/AppleEventBeat.h +++ b/packages/react-native/React/Fabric/AppleEventBeat.h @@ -13,6 +13,8 @@ namespace facebook::react { +class RuntimeScheduler; + /* * Event beat associated with JavaScript runtime. * The beat is called on `RuntimeExecutor`'s thread induced by the UI thread @@ -23,7 +25,7 @@ class AppleEventBeat : public EventBeat, public RunLoopObserver::Delegate { AppleEventBeat( std::shared_ptr ownerBox, std::unique_ptr uiRunLoopObserver, - RuntimeExecutor runtimeExecutor); + RuntimeScheduler& RuntimeScheduler); #pragma mark - RunLoopObserver::Delegate diff --git a/packages/react-native/React/Fabric/RCTSurfacePresenter.mm b/packages/react-native/React/Fabric/RCTSurfacePresenter.mm index 899e5e843823e4..63d4146ad97291 100644 --- a/packages/react-native/React/Fabric/RCTSurfacePresenter.mm +++ b/packages/react-native/React/Fabric/RCTSurfacePresenter.mm @@ -258,10 +258,10 @@ - (RCTScheduler *)_createScheduler toolbox.bridgelessBindingsExecutor = _bridgelessBindingsExecutor; toolbox.eventBeatFactory = - [runtimeExecutor](std::shared_ptr ownerBox) -> std::unique_ptr { + [runtimeScheduler](std::shared_ptr ownerBox) -> std::unique_ptr { auto runLoopObserver = std::make_unique(RunLoopObserver::Activity::BeforeWaiting, ownerBox->owner); - return std::make_unique(std::move(ownerBox), std::move(runLoopObserver), runtimeExecutor); + return std::make_unique(std::move(ownerBox), std::move(runLoopObserver), *runtimeScheduler); }; RCTScheduler *scheduler = [[RCTScheduler alloc] initWithToolbox:toolbox]; diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AndroidEventBeat.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AndroidEventBeat.cpp index cd902c0d3d2a4e..9c63329613d5aa 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AndroidEventBeat.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AndroidEventBeat.cpp @@ -16,9 +16,9 @@ namespace facebook::react { AndroidEventBeat::AndroidEventBeat( std::shared_ptr ownerBox, EventBeatManager* eventBeatManager, - RuntimeExecutor runtimeExecutor, + RuntimeScheduler& runtimeScheduler, jni::global_ref javaUIManager) - : EventBeat(std::move(ownerBox), std::move(runtimeExecutor)), + : EventBeat(std::move(ownerBox), runtimeScheduler), eventBeatManager_(eventBeatManager), javaUIManager_(std::move(javaUIManager)) { eventBeatManager->addObserver(*this); diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AndroidEventBeat.h b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AndroidEventBeat.h index bd4540bf5887a0..b093a7cf841c30 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AndroidEventBeat.h +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/AndroidEventBeat.h @@ -19,7 +19,7 @@ class AndroidEventBeat final : public EventBeat, AndroidEventBeat( std::shared_ptr ownerBox, EventBeatManager* eventBeatManager, - RuntimeExecutor runtimeExecutor, + RuntimeScheduler& runtimeScheduler, jni::global_ref javaUIManager); ~AndroidEventBeat() override; diff --git a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp index d0762aaa1b5182..9687b580bd2402 100644 --- a/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp +++ b/packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.cpp @@ -471,28 +471,25 @@ void FabricUIManagerBinding::installFabricUIManager( auto runtimeExecutor = runtimeExecutorHolder->cthis()->get(); - if (runtimeSchedulerHolder) { - auto runtimeScheduler = runtimeSchedulerHolder->cthis()->get().lock(); - if (runtimeScheduler) { - runtimeExecutor = - [runtimeScheduler]( - std::function&& callback) { - runtimeScheduler->scheduleWork(std::move(callback)); - }; - contextContainer->insert( - "RuntimeScheduler", - std::weak_ptr(runtimeScheduler)); - } + auto runtimeScheduler = runtimeSchedulerHolder->cthis()->get().lock(); + if (runtimeScheduler) { + runtimeExecutor = + [runtimeScheduler]( + std::function&& callback) { + runtimeScheduler->scheduleWork(std::move(callback)); + }; + contextContainer->insert( + "RuntimeScheduler", std::weak_ptr(runtimeScheduler)); } EventBeat::Factory eventBeatFactory = - [eventBeatManager, runtimeExecutor, globalJavaUiManager]( + [eventBeatManager, &runtimeScheduler, globalJavaUiManager]( std::shared_ptr ownerBox) -> std::unique_ptr { return std::make_unique( std::move(ownerBox), eventBeatManager, - runtimeExecutor, + *runtimeScheduler, globalJavaUiManager); }; diff --git a/packages/react-native/ReactCommon/react/renderer/core/EventBeat.cpp b/packages/react-native/ReactCommon/react/renderer/core/EventBeat.cpp index 2afbbfd52145f1..bb75a6c312e800 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/EventBeat.cpp +++ b/packages/react-native/ReactCommon/react/renderer/core/EventBeat.cpp @@ -13,9 +13,8 @@ namespace facebook::react { EventBeat::EventBeat( std::shared_ptr ownerBox, - RuntimeExecutor runtimeExecutor) - : ownerBox_(std::move(ownerBox)), - runtimeExecutor_(std::move(runtimeExecutor)) {} + RuntimeScheduler& runtimeScheduler) + : ownerBox_(std::move(ownerBox)), runtimeScheduler_(runtimeScheduler) {} void EventBeat::request() const { isRequested_ = true; @@ -33,17 +32,18 @@ void EventBeat::induce() const { isRequested_ = false; isBeatCallbackScheduled_ = true; - runtimeExecutor_([this, ownerBox = ownerBox_](jsi::Runtime& runtime) { - auto owner = ownerBox->owner.lock(); - if (!owner) { - return; - } - - isBeatCallbackScheduled_ = false; - if (beatCallback_) { - beatCallback_(runtime); - } - }); + runtimeScheduler_.scheduleWork( + [this, ownerBox = ownerBox_](jsi::Runtime& runtime) { + auto owner = ownerBox->owner.lock(); + if (!owner) { + return; + } + + isBeatCallbackScheduled_ = false; + if (beatCallback_) { + beatCallback_(runtime); + } + }); } } // namespace facebook::react diff --git a/packages/react-native/ReactCommon/react/renderer/core/EventBeat.h b/packages/react-native/ReactCommon/react/renderer/core/EventBeat.h index 6a3692737df9a6..c14ff148fd9a2f 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/EventBeat.h +++ b/packages/react-native/ReactCommon/react/renderer/core/EventBeat.h @@ -7,7 +7,7 @@ #pragma once -#include +#include #include #include #include @@ -56,7 +56,7 @@ class EventBeat { explicit EventBeat( std::shared_ptr ownerBox, - RuntimeExecutor runtimeExecutor); + RuntimeScheduler& runtimeScheduler); virtual ~EventBeat() = default; @@ -88,7 +88,7 @@ class EventBeat { mutable std::atomic isRequested_{false}; private: - RuntimeExecutor runtimeExecutor_; + RuntimeScheduler& runtimeScheduler_; mutable std::atomic isBeatCallbackScheduled_{false}; };