Copy Differ implementation to new file, feature-flag-gate new differ
Summary: Changes in following diffs will be gated by this feature flag. The differ in the new file is copied from the current stable implementation and will not be modified until it's deleted. Changelog: [Internal] Reviewed By: sammy-SC, mdvacca Differential Revision: D27775698 fbshipit-source-id: 03d9518ffd2b1f25712386c56a38bd2b4d839fc2
This commit is contained in:
Родитель
5eba5c11b0
Коммит
39b8233c93
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
#include "Differentiator.h"
|
||||
#include "DifferentiatorFlatteningClassic.h"
|
||||
|
||||
#include <better/map.h>
|
||||
#include <better/small_vector.h>
|
||||
|
@ -1583,7 +1584,13 @@ ShadowViewNodePair::List sliceChildShadowNodeViewPairsLegacy(
|
|||
|
||||
ShadowViewMutation::List calculateShadowViewMutations(
|
||||
ShadowNode const &oldRootShadowNode,
|
||||
ShadowNode const &newRootShadowNode) {
|
||||
ShadowNode const &newRootShadowNode,
|
||||
bool useNewDiffer) {
|
||||
if (!useNewDiffer) {
|
||||
return DifferOld::calculateShadowViewMutations(
|
||||
oldRootShadowNode, newRootShadowNode);
|
||||
}
|
||||
|
||||
SystraceSection s("calculateShadowViewMutations");
|
||||
|
||||
// Root shadow nodes must be belong the same family.
|
||||
|
|
|
@ -23,7 +23,8 @@ enum class ReparentMode { Flatten, Unflatten };
|
|||
*/
|
||||
ShadowViewMutationList calculateShadowViewMutations(
|
||||
ShadowNode const &oldRootShadowNode,
|
||||
ShadowNode const &newRootShadowNode);
|
||||
ShadowNode const &newRootShadowNode,
|
||||
bool useNewDiffer);
|
||||
|
||||
/**
|
||||
* Generates a list of `ShadowViewNodePair`s that represents a layer of a
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// This file exists as an experimental baseline against which
|
||||
// we can compare changes in Differentiator.
|
||||
// Once changes in Differentiator have been verified safe,
|
||||
// this file will be deleted.
|
||||
|
||||
#include <react/renderer/core/ShadowNode.h>
|
||||
#include <react/renderer/debug/flags.h>
|
||||
#include <react/renderer/mounting/ShadowViewMutation.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
namespace DifferOld {
|
||||
|
||||
enum class ReparentMode { Flatten, Unflatten };
|
||||
|
||||
/*
|
||||
* Calculates a list of view mutations which describes how the old
|
||||
* `ShadowTree` can be transformed to the new one.
|
||||
* The list of mutations might be and might not be optimal.
|
||||
*/
|
||||
ShadowViewMutationList calculateShadowViewMutations(
|
||||
ShadowNode const &oldRootShadowNode,
|
||||
ShadowNode const &newRootShadowNode);
|
||||
|
||||
/**
|
||||
* Generates a list of `ShadowViewNodePair`s that represents a layer of a
|
||||
* flattened view hierarchy. The V2 version preserves nodes even if they do
|
||||
* not form views and their children are flattened.
|
||||
*/
|
||||
ShadowViewNodePair::List sliceChildShadowNodeViewPairsV2(
|
||||
ShadowNode const &shadowNode,
|
||||
bool allowFlattened = false);
|
||||
|
||||
/*
|
||||
* Generates a list of `ShadowViewNodePair`s that represents a layer of a
|
||||
* flattened view hierarchy. This is *only* used by unit tests currently.
|
||||
*/
|
||||
ShadowViewNodePair::List sliceChildShadowNodeViewPairsLegacy(
|
||||
ShadowNode const &shadowNode);
|
||||
|
||||
} // namespace DifferOld
|
||||
} // namespace react
|
||||
} // namespace facebook
|
|
@ -90,7 +90,9 @@ better::optional<MountingTransaction> MountingCoordinator::pullTransaction()
|
|||
telemetry.willDiff();
|
||||
|
||||
auto mutations = calculateShadowViewMutations(
|
||||
*baseRevision_.rootShadowNode, *lastRevision_->rootShadowNode);
|
||||
*baseRevision_.rootShadowNode,
|
||||
*lastRevision_->rootShadowNode,
|
||||
enableNewDiffer_);
|
||||
|
||||
telemetry.didDiff();
|
||||
|
||||
|
@ -186,5 +188,9 @@ void MountingCoordinator::setMountingOverrideDelegate(
|
|||
mountingOverrideDelegate_ = delegate;
|
||||
}
|
||||
|
||||
void MountingCoordinator::setEnableNewDiffer(bool enabled) const {
|
||||
enableNewDiffer_ = enabled;
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
|
|
|
@ -71,6 +71,8 @@ class MountingCoordinator final {
|
|||
|
||||
TelemetryController const &getTelemetryController() const;
|
||||
|
||||
void setEnableNewDiffer(bool enabled) const;
|
||||
|
||||
/*
|
||||
* Methods from this section are meant to be used by
|
||||
* `MountingOverrideDelegate` only.
|
||||
|
@ -112,6 +114,8 @@ class MountingCoordinator final {
|
|||
|
||||
TelemetryController telemetryController_;
|
||||
|
||||
mutable bool enableNewDiffer_{false};
|
||||
|
||||
#ifdef RN_SHADOW_TREE_INTROSPECTION
|
||||
mutable StubViewTree stubViewTree_; // Protected by `mutex_`.
|
||||
#endif
|
||||
|
|
|
@ -223,7 +223,8 @@ ShadowTree::ShadowTree(
|
|||
SurfaceId surfaceId,
|
||||
LayoutConstraints const &layoutConstraints,
|
||||
LayoutContext const &layoutContext,
|
||||
ShadowTreeDelegate const &delegate)
|
||||
ShadowTreeDelegate const &delegate,
|
||||
bool enableNewDiffer)
|
||||
: surfaceId_(surfaceId), delegate_(delegate) {
|
||||
const auto noopEventEmitter = std::make_shared<const ViewEventEmitter>(
|
||||
nullptr, -1, std::shared_ptr<const EventDispatcher>());
|
||||
|
@ -252,6 +253,7 @@ ShadowTree::ShadowTree(
|
|||
|
||||
mountingCoordinator_ =
|
||||
std::make_shared<MountingCoordinator const>(currentRevision_);
|
||||
mountingCoordinator_->setEnableNewDiffer(enableNewDiffer);
|
||||
}
|
||||
|
||||
ShadowTree::~ShadowTree() {
|
||||
|
|
|
@ -70,7 +70,8 @@ class ShadowTree final {
|
|||
SurfaceId surfaceId,
|
||||
LayoutConstraints const &layoutConstraints,
|
||||
LayoutContext const &layoutContext,
|
||||
ShadowTreeDelegate const &delegate);
|
||||
ShadowTreeDelegate const &delegate,
|
||||
bool enableNewDiffer);
|
||||
|
||||
~ShadowTree();
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ StubViewTree buildStubViewTreeUsingDifferentiator(
|
|||
ShadowNode::emptySharedShadowNodeSharedList()});
|
||||
|
||||
auto mutations =
|
||||
calculateShadowViewMutations(*emptyRootShadowNode, rootShadowNode);
|
||||
calculateShadowViewMutations(*emptyRootShadowNode, rootShadowNode, true);
|
||||
|
||||
auto stubViewTree = StubViewTree(ShadowView(*emptyRootShadowNode));
|
||||
stubViewTree.mutate(mutations);
|
||||
|
|
|
@ -242,7 +242,8 @@ TEST(MountingTest, testReorderingInstructionGeneration) {
|
|||
}*/
|
||||
|
||||
// Calculating mutations.
|
||||
auto mutations1 = calculateShadowViewMutations(*rootNodeV1, *rootNodeV2);
|
||||
auto mutations1 =
|
||||
calculateShadowViewMutations(*rootNodeV1, *rootNodeV2, true);
|
||||
|
||||
// The order and exact mutation instructions here may change at any time.
|
||||
// This test just ensures that any changes are intentional.
|
||||
|
@ -258,7 +259,8 @@ TEST(MountingTest, testReorderingInstructionGeneration) {
|
|||
EXPECT_TRUE(mutations1[1].index == 0);
|
||||
|
||||
// Calculating mutations.
|
||||
auto mutations2 = calculateShadowViewMutations(*rootNodeV2, *rootNodeV3);
|
||||
auto mutations2 =
|
||||
calculateShadowViewMutations(*rootNodeV2, *rootNodeV3, true);
|
||||
|
||||
// The order and exact mutation instructions here may change at any time.
|
||||
// This test just ensures that any changes are intentional.
|
||||
|
@ -274,7 +276,8 @@ TEST(MountingTest, testReorderingInstructionGeneration) {
|
|||
EXPECT_TRUE(mutations2[1].oldChildShadowView.tag == 100);
|
||||
|
||||
// Calculating mutations.
|
||||
auto mutations3 = calculateShadowViewMutations(*rootNodeV3, *rootNodeV4);
|
||||
auto mutations3 =
|
||||
calculateShadowViewMutations(*rootNodeV3, *rootNodeV4, true);
|
||||
LOG(ERROR) << "Num mutations IN OLD TEST mutations3: " << mutations3.size();
|
||||
|
||||
// The order and exact mutation instructions here may change at any time.
|
||||
|
@ -296,7 +299,8 @@ TEST(MountingTest, testReorderingInstructionGeneration) {
|
|||
EXPECT_TRUE(mutations3[3].index == 2);
|
||||
|
||||
// Calculating mutations.
|
||||
auto mutations4 = calculateShadowViewMutations(*rootNodeV4, *rootNodeV5);
|
||||
auto mutations4 =
|
||||
calculateShadowViewMutations(*rootNodeV4, *rootNodeV5, true);
|
||||
|
||||
// The order and exact mutation instructions here may change at any time.
|
||||
// This test just ensures that any changes are intentional.
|
||||
|
@ -321,7 +325,8 @@ TEST(MountingTest, testReorderingInstructionGeneration) {
|
|||
EXPECT_TRUE(mutations4[5].newChildShadowView.tag == 102);
|
||||
EXPECT_TRUE(mutations4[5].index == 3);
|
||||
|
||||
auto mutations5 = calculateShadowViewMutations(*rootNodeV5, *rootNodeV6);
|
||||
auto mutations5 =
|
||||
calculateShadowViewMutations(*rootNodeV5, *rootNodeV6, true);
|
||||
|
||||
// The order and exact mutation instructions here may change at any time.
|
||||
// This test just ensures that any changes are intentional.
|
||||
|
@ -340,7 +345,8 @@ TEST(MountingTest, testReorderingInstructionGeneration) {
|
|||
EXPECT_TRUE(mutations5[3].newChildShadowView.tag == 105);
|
||||
EXPECT_TRUE(mutations5[3].index == 3);
|
||||
|
||||
auto mutations6 = calculateShadowViewMutations(*rootNodeV6, *rootNodeV7);
|
||||
auto mutations6 =
|
||||
calculateShadowViewMutations(*rootNodeV6, *rootNodeV7, true);
|
||||
|
||||
// The order and exact mutation instructions here may change at any time.
|
||||
// This test just ensures that any changes are intentional.
|
||||
|
@ -594,7 +600,8 @@ TEST(MountingTest, testViewReparentingInstructionGeneration) {
|
|||
rootNodeV5->sealRecursive();
|
||||
|
||||
// Calculating mutations.
|
||||
auto mutations1 = calculateShadowViewMutations(*rootNodeV1, *rootNodeV2);
|
||||
auto mutations1 =
|
||||
calculateShadowViewMutations(*rootNodeV1, *rootNodeV2, true);
|
||||
|
||||
EXPECT_EQ(mutations1.size(), 5);
|
||||
EXPECT_EQ(mutations1[0].type, ShadowViewMutation::Update);
|
||||
|
@ -608,7 +615,8 @@ TEST(MountingTest, testViewReparentingInstructionGeneration) {
|
|||
EXPECT_EQ(mutations1[4].type, ShadowViewMutation::Insert);
|
||||
EXPECT_EQ(mutations1[4].newChildShadowView.tag, 1000);
|
||||
|
||||
auto mutations2 = calculateShadowViewMutations(*rootNodeV2, *rootNodeV3);
|
||||
auto mutations2 =
|
||||
calculateShadowViewMutations(*rootNodeV2, *rootNodeV3, true);
|
||||
|
||||
EXPECT_EQ(mutations2.size(), 5);
|
||||
EXPECT_EQ(mutations2[0].type, ShadowViewMutation::Update);
|
||||
|
@ -624,7 +632,8 @@ TEST(MountingTest, testViewReparentingInstructionGeneration) {
|
|||
EXPECT_EQ(mutations2[4].type, ShadowViewMutation::Insert);
|
||||
EXPECT_EQ(mutations2[4].newChildShadowView.tag, 1000);
|
||||
|
||||
auto mutations3 = calculateShadowViewMutations(*rootNodeV3, *rootNodeV4);
|
||||
auto mutations3 =
|
||||
calculateShadowViewMutations(*rootNodeV3, *rootNodeV4, true);
|
||||
|
||||
// between these two trees, lots of new nodes are created and inserted - this
|
||||
// is all correct, and this is the minimal amount of mutations
|
||||
|
@ -661,7 +670,8 @@ TEST(MountingTest, testViewReparentingInstructionGeneration) {
|
|||
EXPECT_EQ(mutations3[14].type, ShadowViewMutation::Insert);
|
||||
EXPECT_EQ(mutations3[14].newChildShadowView.tag, 1000);
|
||||
|
||||
auto mutations4 = calculateShadowViewMutations(*rootNodeV4, *rootNodeV5);
|
||||
auto mutations4 =
|
||||
calculateShadowViewMutations(*rootNodeV4, *rootNodeV5, true);
|
||||
|
||||
EXPECT_EQ(mutations4.size(), 9);
|
||||
EXPECT_EQ(mutations4[0].type, ShadowViewMutation::Update);
|
||||
|
|
|
@ -75,7 +75,7 @@ static void testShadowNodeTreeLifeCycle(
|
|||
// Building an initial view hierarchy.
|
||||
auto viewTree = buildStubViewTreeWithoutUsingDifferentiator(*emptyRootNode);
|
||||
viewTree.mutate(
|
||||
calculateShadowViewMutations(*emptyRootNode, *currentRootNode));
|
||||
calculateShadowViewMutations(*emptyRootNode, *currentRootNode, true));
|
||||
|
||||
for (int j = 0; j < stages; j++) {
|
||||
auto nextRootNode = currentRootNode;
|
||||
|
@ -102,7 +102,7 @@ static void testShadowNodeTreeLifeCycle(
|
|||
|
||||
// Calculating mutations.
|
||||
auto mutations =
|
||||
calculateShadowViewMutations(*currentRootNode, *nextRootNode);
|
||||
calculateShadowViewMutations(*currentRootNode, *nextRootNode, true);
|
||||
|
||||
// Make sure that in a single frame, a DELETE for a
|
||||
// view is not followed by a CREATE for the same view.
|
||||
|
|
|
@ -171,8 +171,8 @@ class StackingContextTest : public ::testing::Test {
|
|||
callback(buildStubViewTreeUsingDifferentiator(*rootShadowNode_));
|
||||
callback(buildStubViewTreeWithoutUsingDifferentiator(*rootShadowNode_));
|
||||
|
||||
auto mutations =
|
||||
calculateShadowViewMutations(*currentRootShadowNode_, *rootShadowNode_);
|
||||
auto mutations = calculateShadowViewMutations(
|
||||
*currentRootShadowNode_, *rootShadowNode_, true);
|
||||
currentRootShadowNode_ = rootShadowNode_;
|
||||
currentStubViewTree_.mutate(mutations);
|
||||
callback(currentStubViewTree_);
|
||||
|
|
|
@ -98,7 +98,11 @@ TEST(StateReconciliationTest, testStateReconciliation) {
|
|||
auto state1 = shadowNodeAB->getState();
|
||||
auto shadowTreeDelegate = DummyShadowTreeDelegate{};
|
||||
ShadowTree shadowTree{
|
||||
SurfaceId{11}, LayoutConstraints{}, LayoutContext{}, shadowTreeDelegate};
|
||||
SurfaceId{11},
|
||||
LayoutConstraints{},
|
||||
LayoutContext{},
|
||||
shadowTreeDelegate,
|
||||
true};
|
||||
|
||||
shadowTree.commit(
|
||||
[&](RootShadowNode const &oldRootShadowNode) {
|
||||
|
|
|
@ -129,11 +129,15 @@ Scheduler::Scheduler(
|
|||
#ifdef ANDROID
|
||||
removeOutstandingSurfacesOnDestruction_ = reactNativeConfig_->getBool(
|
||||
"react_fabric:remove_outstanding_surfaces_on_destruction_android");
|
||||
enableNewDiffer_ = reactNativeConfig_->getBool(
|
||||
"react_fabric:enable_new_differ_h1_2021_android");
|
||||
Constants::setPropsForwardingEnabled(reactNativeConfig_->getBool(
|
||||
"react_fabric:enable_props_forwarding_android"));
|
||||
#else
|
||||
removeOutstandingSurfacesOnDestruction_ = reactNativeConfig_->getBool(
|
||||
"react_fabric:remove_outstanding_surfaces_on_destruction_ios");
|
||||
enableNewDiffer_ =
|
||||
reactNativeConfig_->getBool("react_fabric:enable_new_differ_h1_2021_ios");
|
||||
#endif
|
||||
|
||||
uiManager->extractUIManagerBindingOnDemand_ = reactNativeConfig_->getBool(
|
||||
|
@ -199,6 +203,7 @@ Scheduler::~Scheduler() {
|
|||
void Scheduler::registerSurface(
|
||||
SurfaceHandler const &surfaceHandler) const noexcept {
|
||||
surfaceHandler.setUIManager(uiManager_.get());
|
||||
surfaceHandler.setEnableNewDiffer(enableNewDiffer_);
|
||||
}
|
||||
|
||||
void Scheduler::unregisterSurface(
|
||||
|
|
|
@ -121,6 +121,7 @@ class Scheduler final : public UIManagerDelegate {
|
|||
* Temporary flags.
|
||||
*/
|
||||
bool removeOutstandingSurfacesOnDestruction_{false};
|
||||
bool enableNewDiffer_{false};
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
|
|
|
@ -71,7 +71,8 @@ void SurfaceHandler::start() const noexcept {
|
|||
parameters.surfaceId,
|
||||
parameters.layoutConstraints,
|
||||
parameters.layoutContext,
|
||||
*link_.uiManager);
|
||||
*link_.uiManager,
|
||||
enableNewDiffer_);
|
||||
|
||||
link_.shadowTree = shadowTree.get();
|
||||
|
||||
|
@ -138,6 +139,11 @@ DisplayMode SurfaceHandler::getDisplayMode() const noexcept {
|
|||
return parameters_.displayMode;
|
||||
}
|
||||
|
||||
#pragma mark - Feature Flags
|
||||
void SurfaceHandler::setEnableNewDiffer(bool enabled) const noexcept {
|
||||
enableNewDiffer_ = enabled;
|
||||
}
|
||||
|
||||
#pragma mark - Accessors
|
||||
|
||||
SurfaceId SurfaceHandler::getSurfaceId() const noexcept {
|
||||
|
|
|
@ -138,6 +138,9 @@ class SurfaceHandler final {
|
|||
LayoutConstraints getLayoutConstraints() const noexcept;
|
||||
LayoutContext getLayoutContext() const noexcept;
|
||||
|
||||
#pragma mark - Feature Flags
|
||||
void setEnableNewDiffer(bool enabled) const noexcept;
|
||||
|
||||
private:
|
||||
friend class Scheduler;
|
||||
|
||||
|
@ -195,6 +198,11 @@ class SurfaceHandler final {
|
|||
*/
|
||||
mutable better::shared_mutex parametersMutex_;
|
||||
mutable Parameters parameters_;
|
||||
|
||||
/**
|
||||
* Feature flags.
|
||||
*/
|
||||
mutable bool enableNewDiffer_{false};
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
|
|
Загрузка…
Ссылка в новой задаче