From 16a1fc7b7ae1a00a3cc61db9c24b280ee4f860bf Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Fri, 15 Jan 2021 16:20:15 -0800 Subject: [PATCH] Fabric: Introducing `ShadowTree::CommitMode` Summary: CommitMode allows customizing the side-effects of commit operations. In `Suspended` mode, the results of commit operations will not be passed down to a MountingCoordinator which will result in skipping the mounting phase completely. This is one of the core elements of the Pre-rendering infrastructure. Changelog: [Internal] Fabric-specific internal change. Differential Revision: D24290773 fbshipit-source-id: c10ec20d13f3131fc632352ef22f4465c9dfb3c2 --- .../react/renderer/mounting/ShadowTree.cpp | 37 +++++++++++++++++-- .../react/renderer/mounting/ShadowTree.h | 28 ++++++++++++++ 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/ReactCommon/react/renderer/mounting/ShadowTree.cpp b/ReactCommon/react/renderer/mounting/ShadowTree.cpp index 00aaa003d67..d4bb334261d 100644 --- a/ReactCommon/react/renderer/mounting/ShadowTree.cpp +++ b/ReactCommon/react/renderer/mounting/ShadowTree.cpp @@ -22,6 +22,7 @@ namespace facebook { namespace react { using CommitStatus = ShadowTree::CommitStatus; +using CommitMode = ShadowTree::CommitMode; /* * Generates (possibly) a new tree where all nodes with non-obsolete `State` @@ -257,6 +258,29 @@ Tag ShadowTree::getSurfaceId() const { return surfaceId_; } +void ShadowTree::setCommitMode(CommitMode commitMode) const { + auto revision = ShadowTreeRevision{}; + + { + std::unique_lock lock(commitMutex_); + if (commitMode_ == commitMode) { + return; + } + + commitMode_ = commitMode; + revision = currentRevision_; + } + + if (commitMode == CommitMode::Normal) { + mount(revision); + } +} + +CommitMode ShadowTree::getCommitMode() const { + std::shared_lock lock(commitMutex_); + return commitMode_; +} + MountingCoordinator::Shared ShadowTree::getMountingCoordinator() const { return mountingCoordinator_; } @@ -290,12 +314,14 @@ CommitStatus ShadowTree::tryCommit( auto telemetry = TransactionTelemetry{}; telemetry.willCommit(); + CommitMode commitMode; auto oldRevision = ShadowTreeRevision{}; auto newRevision = ShadowTreeRevision{}; { // Reading `currentRevision_` in shared manner. std::shared_lock lock(commitMutex_); + commitMode = commitMode_; oldRevision = currentRevision_; } @@ -369,9 +395,9 @@ CommitStatus ShadowTree::tryCommit( emitLayoutEvents(affectedLayoutableNodes); - mountingCoordinator_->push(newRevision); - - notifyDelegatesOfUpdates(); + if (commitMode == CommitMode::Normal) { + mount(newRevision); + } return CommitStatus::Succeeded; } @@ -381,6 +407,11 @@ ShadowTreeRevision ShadowTree::getCurrentRevision() const { return currentRevision_; } +void ShadowTree::mount(ShadowTreeRevision const &revision) const { + mountingCoordinator_->push(revision); + delegate_.shadowTreeDidFinishTransaction(*this, mountingCoordinator_); +} + void ShadowTree::commitEmptyTree() const { commit( [](RootShadowNode const &oldRootShadowNode) -> RootShadowNode::Unshared { diff --git a/ReactCommon/react/renderer/mounting/ShadowTree.h b/ReactCommon/react/renderer/mounting/ShadowTree.h index 9f01e01da4a..1075ce6a8c5 100644 --- a/ReactCommon/react/renderer/mounting/ShadowTree.h +++ b/ReactCommon/react/renderer/mounting/ShadowTree.h @@ -31,12 +31,28 @@ using ShadowTreeCommitTransaction = std::function &affectedLayoutableNodes) const; SurfaceId const surfaceId_; ShadowTreeDelegate const &delegate_; mutable better::shared_mutex commitMutex_; + mutable CommitMode commitMode_{ + CommitMode::Normal}; // Protected by `commitMutex_`. mutable ShadowTreeRevision currentRevision_; // Protected by `commitMutex_`. MountingCoordinator::Shared mountingCoordinator_; };