Skip to content
Closed
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
83 changes: 78 additions & 5 deletions packages/react-native/React/Fabric/RCTSurfacePresenter.mm
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#import <mutex>
#import <shared_mutex>
#import <unordered_set>

#import <React/RCTAssert.h>
#import <React/RCTBridge+Private.h>
Expand Down Expand Up @@ -42,8 +43,28 @@
using namespace facebook::react;

@interface RCTSurfacePresenter () <RCTSchedulerDelegate, RCTMountingManagerDelegate>
- (void)_drainPendingReactRevisionMerges;
@end

namespace {
class ReactRevisionMergeRunLoopObserverDelegate final : public RunLoopObserver::Delegate {
public:
explicit ReactRevisionMergeRunLoopObserverDelegate(RCTSurfacePresenter *surfacePresenter)
: surfacePresenter_(surfacePresenter)
{
}

void activityDidChange(const RunLoopObserver::Delegate * /*delegate*/, RunLoopObserver::Activity /*activity*/)
const noexcept override
{
[surfacePresenter_ _drainPendingReactRevisionMerges];
}

private:
__weak RCTSurfacePresenter *surfacePresenter_;
};
} // namespace

@implementation RCTSurfacePresenter {
RCTMountingManager *_mountingManager; // Thread-safe.
RCTSurfaceRegistry *_surfaceRegistry; // Thread-safe.
Expand All @@ -57,6 +78,12 @@ @implementation RCTSurfacePresenter {

std::shared_mutex _observerListMutex;
std::vector<__weak id<RCTSurfacePresenterObserver>> _observers; // Protected by `_observerListMutex`.

std::mutex _pendingReactRevisionMergesMutex;
// Pending React revision merges, drained on the main run loop just before it sleeps.
std::unordered_set<SurfaceId> _pendingReactRevisionMerges; // Protected by `_pendingReactRevisionMergesMutex`.
std::shared_ptr<ReactRevisionMergeRunLoopObserverDelegate> _mergeRunLoopObserverDelegate;
std::unique_ptr<const MainRunLoopObserver> _mergeRunLoopObserver;
}

- (instancetype)initWithContextContainer:(std::shared_ptr<const ContextContainer>)contextContainer
Expand All @@ -74,6 +101,14 @@ - (instancetype)initWithContextContainer:(std::shared_ptr<const ContextContainer
_mountingManager.contextContainer = contextContainer;
_mountingManager.delegate = self;

if (ReactNativeFeatureFlags::enableFabricCommitBranching()) {
_mergeRunLoopObserverDelegate = std::make_shared<ReactRevisionMergeRunLoopObserverDelegate>(self);
_mergeRunLoopObserver = std::make_unique<const MainRunLoopObserver>(
RunLoopObserver::Activity::BeforeWaiting, _mergeRunLoopObserverDelegate);
_mergeRunLoopObserver->setDelegate(_mergeRunLoopObserverDelegate.get());
_mergeRunLoopObserver->enable();
}

_scheduler = [self _createScheduler];

[[NSNotificationCenter defaultCenter] addObserver:self
Expand Down Expand Up @@ -309,11 +344,49 @@ - (void)schedulerShouldRenderTransactions:(std::shared_ptr<const MountingCoordin

- (void)schedulerShouldMergeReactRevision:(SurfaceId)surfaceId
{
auto scheduler = [self scheduler];
RCTExecuteOnMainQueue(^{
scheduler.uiManager->getShadowTreeRegistry().visit(
surfaceId, [](const ShadowTree &shadowTree) { shadowTree.mergeReactRevision(); });
});
if (RCTIsMainQueue()) {
[self _mergeReactRevisionForSurfaceId:surfaceId];
return;
}

std::lock_guard<std::mutex> lock(_pendingReactRevisionMergesMutex);
_pendingReactRevisionMerges.insert(surfaceId);
}

- (void)_mergeReactRevisionForSurfaceId:(SurfaceId)surfaceId
{
RCTAssertMainQueue();
RCTScheduler *scheduler = [self scheduler];
if (!scheduler) {
return;
}

auto uiManager = scheduler.uiManager;
if (!uiManager) {
return;
}

uiManager->getShadowTreeRegistry().visit(
surfaceId, [](const ShadowTree &shadowTree) { shadowTree.mergeReactRevision(); });
}

- (void)_drainPendingReactRevisionMerges
{
RCTAssertMainQueue();

std::unordered_set<SurfaceId> pending;
{
std::lock_guard<std::mutex> lock(_pendingReactRevisionMergesMutex);
if (_pendingReactRevisionMerges.empty()) {
return;
}

pending.swap(_pendingReactRevisionMerges);
}

for (auto surfaceId : pending) {
[self _mergeReactRevisionForSurfaceId:surfaceId];
}
}

- (void)schedulerDidDispatchCommand:(const ShadowView &)shadowView
Expand Down
Loading