Remove legacy layout diffing
Summary: This removes some unused flags which will cause Yoga to layout every tree twice, then diffing the tree, reporting whether the whole tree is different. This is too expensive to run outside of local experimentation, but we have more nuanced ways to implement the `YGNodeLayoutAffectedByQuirk` I am wanting to add. Changelog: [Internal] Reviewed By: lunaleaps Differential Revision: D42406917 fbshipit-source-id: b415ed02768f6b59de3a6fa90c60c750d56fd4b0
This commit is contained in:
committed by
Facebook GitHub Bot
parent
cac197f5a6
commit
9e1bcd8557
@@ -22,12 +22,8 @@ struct YGLayout {
|
||||
|
||||
private:
|
||||
static constexpr size_t directionOffset = 0;
|
||||
static constexpr size_t didUseLegacyFlagOffset =
|
||||
directionOffset + facebook::yoga::detail::bitWidthFn<YGDirection>();
|
||||
static constexpr size_t doesLegacyStretchFlagAffectsLayoutOffset =
|
||||
didUseLegacyFlagOffset + 1;
|
||||
static constexpr size_t hadOverflowOffset =
|
||||
doesLegacyStretchFlagAffectsLayoutOffset + 1;
|
||||
directionOffset + facebook::yoga::detail::bitWidthFn<YGDirection>();
|
||||
uint8_t flags = 0;
|
||||
|
||||
public:
|
||||
@@ -56,25 +52,6 @@ public:
|
||||
flags, directionOffset, direction);
|
||||
}
|
||||
|
||||
bool didUseLegacyFlag() const {
|
||||
return facebook::yoga::detail::getBooleanData(
|
||||
flags, didUseLegacyFlagOffset);
|
||||
}
|
||||
|
||||
void setDidUseLegacyFlag(bool val) {
|
||||
facebook::yoga::detail::setBooleanData(flags, didUseLegacyFlagOffset, val);
|
||||
}
|
||||
|
||||
bool doesLegacyStretchFlagAffectsLayout() const {
|
||||
return facebook::yoga::detail::getBooleanData(
|
||||
flags, doesLegacyStretchFlagAffectsLayoutOffset);
|
||||
}
|
||||
|
||||
void setDoesLegacyStretchFlagAffectsLayout(bool val) {
|
||||
facebook::yoga::detail::setBooleanData(
|
||||
flags, doesLegacyStretchFlagAffectsLayoutOffset, val);
|
||||
}
|
||||
|
||||
bool hadOverflow() const {
|
||||
return facebook::yoga::detail::getBooleanData(flags, hadOverflowOffset);
|
||||
}
|
||||
|
@@ -560,53 +560,6 @@ YGFloatOptional YGNode::getTrailingPaddingAndBorder(
|
||||
YGFloatOptional(getTrailingBorder(axis));
|
||||
}
|
||||
|
||||
bool YGNode::didUseLegacyFlag() {
|
||||
bool didUseLegacyFlag = layout_.didUseLegacyFlag();
|
||||
if (didUseLegacyFlag) {
|
||||
return true;
|
||||
}
|
||||
for (const auto& child : children_) {
|
||||
if (child->layout_.didUseLegacyFlag()) {
|
||||
didUseLegacyFlag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return didUseLegacyFlag;
|
||||
}
|
||||
|
||||
void YGNode::setLayoutDoesLegacyFlagAffectsLayout(
|
||||
bool doesLegacyFlagAffectsLayout) {
|
||||
layout_.setDoesLegacyStretchFlagAffectsLayout(doesLegacyFlagAffectsLayout);
|
||||
}
|
||||
|
||||
void YGNode::setLayoutDidUseLegacyFlag(bool didUseLegacyFlag) {
|
||||
layout_.setDidUseLegacyFlag(didUseLegacyFlag);
|
||||
}
|
||||
|
||||
bool YGNode::isLayoutTreeEqualToNode(const YGNode& node) const {
|
||||
if (children_.size() != node.children_.size()) {
|
||||
return false;
|
||||
}
|
||||
if (layout_ != node.layout_) {
|
||||
return false;
|
||||
}
|
||||
if (children_.size() == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isLayoutTreeEqual = true;
|
||||
YGNodeRef otherNodeChildren = nullptr;
|
||||
for (std::vector<YGNodeRef>::size_type i = 0; i < children_.size(); ++i) {
|
||||
otherNodeChildren = node.children_[i];
|
||||
isLayoutTreeEqual =
|
||||
children_[i]->isLayoutTreeEqualToNode(*otherNodeChildren);
|
||||
if (!isLayoutTreeEqual) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return isLayoutTreeEqual;
|
||||
}
|
||||
|
||||
void YGNode::reset() {
|
||||
YGAssertWithNode(
|
||||
this,
|
||||
|
@@ -327,8 +327,6 @@ public:
|
||||
const float mainSize,
|
||||
const float crossSize,
|
||||
const float ownerWidth);
|
||||
void setLayoutDoesLegacyFlagAffectsLayout(bool doesLegacyFlagAffectsLayout);
|
||||
void setLayoutDidUseLegacyFlag(bool didUseLegacyFlag);
|
||||
void markDirtyAndPropogateDownwards();
|
||||
|
||||
// Other methods
|
||||
@@ -351,8 +349,6 @@ public:
|
||||
float resolveFlexGrow() const;
|
||||
float resolveFlexShrink() const;
|
||||
bool isNodeFlexible();
|
||||
bool didUseLegacyFlag();
|
||||
bool isLayoutTreeEqualToNode(const YGNode& node) const;
|
||||
void reset();
|
||||
};
|
||||
|
||||
|
123
yoga/Yoga.cpp
123
yoga/Yoga.cpp
@@ -180,10 +180,6 @@ YOGA_EXPORT bool YGNodeIsDirty(YGNodeRef node) {
|
||||
return node->isDirty();
|
||||
}
|
||||
|
||||
YOGA_EXPORT bool YGNodeLayoutGetDidUseLegacyFlag(const YGNodeRef node) {
|
||||
return node->didUseLegacyFlag();
|
||||
}
|
||||
|
||||
YOGA_EXPORT void YGNodeMarkDirtyAndPropogateToDescendants(
|
||||
const YGNodeRef node) {
|
||||
return node->markDirtyAndPropogateDownwards();
|
||||
@@ -220,32 +216,6 @@ YOGA_EXPORT YGNodeRef YGNodeClone(YGNodeRef oldNode) {
|
||||
return node;
|
||||
}
|
||||
|
||||
static YGConfigRef YGConfigClone(const YGConfig& oldConfig) {
|
||||
const YGConfigRef config = new YGConfig(oldConfig);
|
||||
YGAssert(config != nullptr, "Could not allocate memory for config");
|
||||
gConfigInstanceCount++;
|
||||
return config;
|
||||
}
|
||||
|
||||
static YGNodeRef YGNodeDeepClone(YGNodeRef oldNode) {
|
||||
auto config = YGConfigClone(*oldNode->getConfig());
|
||||
auto node = new YGNode{*oldNode, config};
|
||||
node->setOwner(nullptr);
|
||||
Event::publish<Event::NodeAllocation>(node, {node->getConfig()});
|
||||
|
||||
YGVector vec = YGVector();
|
||||
vec.reserve(oldNode->getChildren().size());
|
||||
YGNodeRef childNode = nullptr;
|
||||
for (auto* item : oldNode->getChildren()) {
|
||||
childNode = YGNodeDeepClone(item);
|
||||
childNode->setOwner(node);
|
||||
vec.push_back(childNode);
|
||||
}
|
||||
node->setChildren(vec);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
YOGA_EXPORT void YGNodeFree(const YGNodeRef node) {
|
||||
if (YGNodeRef owner = node->getOwner()) {
|
||||
owner->removeChild(node);
|
||||
@@ -263,17 +233,6 @@ YOGA_EXPORT void YGNodeFree(const YGNodeRef node) {
|
||||
delete node;
|
||||
}
|
||||
|
||||
static void YGConfigFreeRecursive(const YGNodeRef root) {
|
||||
if (root->getConfig() != nullptr) {
|
||||
gConfigInstanceCount--;
|
||||
delete root->getConfig();
|
||||
}
|
||||
// Delete configs recursively for childrens
|
||||
for (auto* child : root->getChildren()) {
|
||||
YGConfigFreeRecursive(child);
|
||||
}
|
||||
}
|
||||
|
||||
YOGA_EXPORT void YGNodeFreeRecursiveWithCleanupFunc(
|
||||
const YGNodeRef root,
|
||||
YGNodeCleanupFunc cleanup) {
|
||||
@@ -993,11 +952,6 @@ YG_NODE_LAYOUT_RESOLVED_PROPERTY_IMPL(float, Margin, margin);
|
||||
YG_NODE_LAYOUT_RESOLVED_PROPERTY_IMPL(float, Border, border);
|
||||
YG_NODE_LAYOUT_RESOLVED_PROPERTY_IMPL(float, Padding, padding);
|
||||
|
||||
YOGA_EXPORT bool YGNodeLayoutGetDidLegacyStretchFlagAffectLayout(
|
||||
const YGNodeRef node) {
|
||||
return node->getLayout().doesLegacyStretchFlagAffectsLayout();
|
||||
}
|
||||
|
||||
std::atomic<uint32_t> gCurrentGenerationCount(0);
|
||||
|
||||
bool YGLayoutNodeInternal(
|
||||
@@ -3051,9 +3005,6 @@ static void YGNodelayoutImpl(
|
||||
collectedFlexItemsValues.sizeConsumedOnCurrentLine;
|
||||
}
|
||||
|
||||
if (node->getConfig()->useLegacyStretchBehaviour) {
|
||||
node->setLayoutDidUseLegacyFlag(true);
|
||||
}
|
||||
sizeBasedOnContent = !node->getConfig()->useLegacyStretchBehaviour;
|
||||
}
|
||||
}
|
||||
@@ -4205,13 +4156,6 @@ static void YGRoundToPixelGrid(
|
||||
}
|
||||
}
|
||||
|
||||
static void unsetUseLegacyFlagRecursively(YGNodeRef node) {
|
||||
node->getConfig()->useLegacyStretchBehaviour = false;
|
||||
for (auto child : node->getChildren()) {
|
||||
unsetUseLegacyFlagRecursively(child);
|
||||
}
|
||||
}
|
||||
|
||||
YOGA_EXPORT void YGNodeCalculateLayoutWithContext(
|
||||
const YGNodeRef node,
|
||||
const float ownerWidth,
|
||||
@@ -4297,67 +4241,6 @@ YOGA_EXPORT void YGNodeCalculateLayoutWithContext(
|
||||
}
|
||||
|
||||
Event::publish<Event::LayoutPassEnd>(node, {layoutContext, &markerData});
|
||||
|
||||
// We want to get rid off `useLegacyStretchBehaviour` from YGConfig. But we
|
||||
// aren't sure whether client's of yoga have gotten rid off this flag or not.
|
||||
// So logging this in YGLayout would help to find out the call sites depending
|
||||
// on this flag. This check would be removed once we are sure no one is
|
||||
// dependent on this flag anymore. The flag
|
||||
// `shouldDiffLayoutWithoutLegacyStretchBehaviour` in YGConfig will help to
|
||||
// run experiments.
|
||||
if (node->getConfig()->shouldDiffLayoutWithoutLegacyStretchBehaviour &&
|
||||
node->didUseLegacyFlag()) {
|
||||
const YGNodeRef nodeWithoutLegacyFlag = YGNodeDeepClone(node);
|
||||
nodeWithoutLegacyFlag->resolveDimension();
|
||||
// Recursively mark nodes as dirty
|
||||
nodeWithoutLegacyFlag->markDirtyAndPropogateDownwards();
|
||||
gCurrentGenerationCount.fetch_add(1, std::memory_order_relaxed);
|
||||
// Rerun the layout, and calculate the diff
|
||||
unsetUseLegacyFlagRecursively(nodeWithoutLegacyFlag);
|
||||
LayoutData layoutMarkerData = {};
|
||||
if (YGLayoutNodeInternal(
|
||||
nodeWithoutLegacyFlag,
|
||||
width,
|
||||
height,
|
||||
ownerDirection,
|
||||
widthMeasureMode,
|
||||
heightMeasureMode,
|
||||
ownerWidth,
|
||||
ownerHeight,
|
||||
true,
|
||||
LayoutPassReason::kInitial,
|
||||
nodeWithoutLegacyFlag->getConfig(),
|
||||
layoutMarkerData,
|
||||
layoutContext,
|
||||
0, // tree root
|
||||
gCurrentGenerationCount.load(std::memory_order_relaxed))) {
|
||||
nodeWithoutLegacyFlag->setPosition(
|
||||
nodeWithoutLegacyFlag->getLayout().direction(),
|
||||
ownerWidth,
|
||||
ownerHeight,
|
||||
ownerWidth);
|
||||
YGRoundToPixelGrid(
|
||||
nodeWithoutLegacyFlag,
|
||||
nodeWithoutLegacyFlag->getConfig()->pointScaleFactor,
|
||||
0.0f,
|
||||
0.0f);
|
||||
|
||||
// Set whether the two layouts are different or not.
|
||||
auto neededLegacyStretchBehaviour =
|
||||
!nodeWithoutLegacyFlag->isLayoutTreeEqualToNode(*node);
|
||||
node->setLayoutDoesLegacyFlagAffectsLayout(neededLegacyStretchBehaviour);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (nodeWithoutLegacyFlag->getConfig()->printTree) {
|
||||
YGNodePrint(
|
||||
nodeWithoutLegacyFlag,
|
||||
(YGPrintOptions) (YGPrintOptionsLayout | YGPrintOptionsChildren | YGPrintOptionsStyle));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
YGConfigFreeRecursive(nodeWithoutLegacyFlag);
|
||||
YGNodeFreeRecursive(nodeWithoutLegacyFlag);
|
||||
}
|
||||
}
|
||||
|
||||
YOGA_EXPORT void YGNodeCalculateLayout(
|
||||
@@ -4381,12 +4264,6 @@ YOGA_EXPORT void YGConfigSetLogger(const YGConfigRef config, YGLogger logger) {
|
||||
}
|
||||
}
|
||||
|
||||
YOGA_EXPORT void YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour(
|
||||
const YGConfigRef config,
|
||||
const bool shouldDiffLayout) {
|
||||
config->shouldDiffLayoutWithoutLegacyStretchBehaviour = shouldDiffLayout;
|
||||
}
|
||||
|
||||
void YGAssert(const bool condition, const char* message) {
|
||||
if (!condition) {
|
||||
Log::log(YGNodeRef{nullptr}, YGLogLevelFatal, nullptr, "%s\n", message);
|
||||
|
@@ -147,7 +147,6 @@ WIN_EXPORT void YGNodeSetHasNewLayout(YGNodeRef node, bool hasNewLayout);
|
||||
YGNodeType YGNodeGetNodeType(YGNodeRef node);
|
||||
void YGNodeSetNodeType(YGNodeRef node, YGNodeType nodeType);
|
||||
WIN_EXPORT bool YGNodeIsDirty(YGNodeRef node);
|
||||
bool YGNodeLayoutGetDidUseLegacyFlag(YGNodeRef node);
|
||||
|
||||
WIN_EXPORT void YGNodeStyleSetDirection(YGNodeRef node, YGDirection direction);
|
||||
WIN_EXPORT YGDirection YGNodeStyleGetDirection(YGNodeConstRef node);
|
||||
@@ -290,7 +289,6 @@ WIN_EXPORT float YGNodeLayoutGetWidth(YGNodeRef node);
|
||||
WIN_EXPORT float YGNodeLayoutGetHeight(YGNodeRef node);
|
||||
WIN_EXPORT YGDirection YGNodeLayoutGetDirection(YGNodeRef node);
|
||||
WIN_EXPORT bool YGNodeLayoutGetHadOverflow(YGNodeRef node);
|
||||
bool YGNodeLayoutGetDidLegacyStretchFlagAffectLayout(YGNodeRef node);
|
||||
|
||||
// Get the computed values for these nodes after performing layout. If they were
|
||||
// set using point values then the returned value will be the same as
|
||||
@@ -315,9 +313,6 @@ WIN_EXPORT void YGAssertWithConfig(
|
||||
WIN_EXPORT void YGConfigSetPointScaleFactor(
|
||||
YGConfigRef config,
|
||||
float pixelsInPoint);
|
||||
void YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour(
|
||||
YGConfigRef config,
|
||||
bool shouldDiffLayout);
|
||||
|
||||
// Yoga previously had an error where containers would take the maximum space
|
||||
// possible instead of the minimum like they are supposed to. In practice this
|
||||
|
Reference in New Issue
Block a user