Addresses thread safety, GitHub issue #769.
See also: discussions in PR #852 and #786. In addition to improving thread safety, it removes 8 bytes of heap per node.
This commit is contained in:
@@ -22,12 +22,8 @@ struct YGLayout {
|
|||||||
bool doesLegacyStretchFlagAffectsLayout : 1;
|
bool doesLegacyStretchFlagAffectsLayout : 1;
|
||||||
bool hadOverflow : 1;
|
bool hadOverflow : 1;
|
||||||
|
|
||||||
uint32_t computedFlexBasisGeneration = 0;
|
|
||||||
YGFloatOptional computedFlexBasis = {};
|
YGFloatOptional computedFlexBasis = {};
|
||||||
|
|
||||||
// Instead of recomputing the entire layout every single time, we cache some
|
|
||||||
// information to break early when nothing changed
|
|
||||||
uint32_t generationCount = 0;
|
|
||||||
YGDirection lastOwnerDirection = (YGDirection) -1;
|
YGDirection lastOwnerDirection = (YGDirection) -1;
|
||||||
|
|
||||||
uint32_t nextCachedMeasurementsIndex = 0;
|
uint32_t nextCachedMeasurementsIndex = 0;
|
||||||
|
@@ -189,11 +189,6 @@ void YGNode::setLayoutPosition(float position, int index) {
|
|||||||
layout_.position[index] = position;
|
layout_.position[index] = position;
|
||||||
}
|
}
|
||||||
|
|
||||||
void YGNode::setLayoutComputedFlexBasisGeneration(
|
|
||||||
uint32_t computedFlexBasisGeneration) {
|
|
||||||
layout_.computedFlexBasisGeneration = computedFlexBasisGeneration;
|
|
||||||
}
|
|
||||||
|
|
||||||
void YGNode::setLayoutMeasuredDimension(float measuredDimension, int index) {
|
void YGNode::setLayoutMeasuredDimension(float measuredDimension, int index) {
|
||||||
layout_.measuredDimensions[index] = measuredDimension;
|
layout_.measuredDimensions[index] = measuredDimension;
|
||||||
}
|
}
|
||||||
|
@@ -239,8 +239,6 @@ public:
|
|||||||
void setDirty(bool isDirty);
|
void setDirty(bool isDirty);
|
||||||
void setLayoutLastOwnerDirection(YGDirection direction);
|
void setLayoutLastOwnerDirection(YGDirection direction);
|
||||||
void setLayoutComputedFlexBasis(const YGFloatOptional computedFlexBasis);
|
void setLayoutComputedFlexBasis(const YGFloatOptional computedFlexBasis);
|
||||||
void setLayoutComputedFlexBasisGeneration(
|
|
||||||
uint32_t computedFlexBasisGeneration);
|
|
||||||
void setLayoutMeasuredDimension(float measuredDimension, int index);
|
void setLayoutMeasuredDimension(float measuredDimension, int index);
|
||||||
void setLayoutHadOverflow(bool hadOverflow);
|
void setLayoutHadOverflow(bool hadOverflow);
|
||||||
void setLayoutDimension(float dimension, int index);
|
void setLayoutDimension(float dimension, int index);
|
||||||
|
179
yoga/Yoga.cpp
179
yoga/Yoga.cpp
@@ -8,6 +8,8 @@
|
|||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <map>
|
||||||
|
#include <atomic>
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
#include "YGNode.h"
|
#include "YGNode.h"
|
||||||
#include "YGNodePrint.h"
|
#include "YGNodePrint.h"
|
||||||
@@ -25,6 +27,44 @@ __forceinline const float fmaxf(const float a, const float b) {
|
|||||||
|
|
||||||
using namespace facebook::yoga;
|
using namespace facebook::yoga;
|
||||||
|
|
||||||
|
// NodeActions tracks actions on a node.
|
||||||
|
typedef std::map<const YGNodeRef, uint8_t> NodeActions;
|
||||||
|
|
||||||
|
// Standard node actions.
|
||||||
|
typedef YG_ENUM_BEGIN(NodeAction){
|
||||||
|
NodeActionNone,
|
||||||
|
NodeActionDidVisit = 1 << 0,
|
||||||
|
NodeActionDidComputeFlexBasis = 1 << 1,
|
||||||
|
} YG_ENUM_END(NodeAction);
|
||||||
|
|
||||||
|
// NodeActionsMark marks an action against a node.
|
||||||
|
static void NodeActionsMark(NodeActions& nam, const YGNodeRef n, uint8_t mask) {
|
||||||
|
auto iter = nam.find(n);
|
||||||
|
if (iter != nam.end()) {
|
||||||
|
iter->second |= mask; // Update
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nam.insert(std::pair<const YGNodeRef, uint8_t>(n, mask)); // Create
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NodeActionsGet retrieves a mark against a node, or returns 0.
|
||||||
|
static uint8_t NodeActionsGet(NodeActions& nam, const YGNodeRef n) {
|
||||||
|
auto iter = nam.find(n);
|
||||||
|
return iter == nam.end() ? 0 : iter->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convenience macros for marking/getting actions against nodes.
|
||||||
|
#define NodeActionsDidVisit(nam, n) \
|
||||||
|
((NodeActionsGet(nam, n) & NodeActionDidVisit) != 0)
|
||||||
|
#define NodeActionsDidComputeFlexBasis(nam, n) \
|
||||||
|
((NodeActionsGet(nam, n) & NodeActionDidComputeFlexBasis) != 0)
|
||||||
|
|
||||||
|
#define NodeActionsMarkDidVisit(nam, n) \
|
||||||
|
NodeActionsMark(nam, n, NodeActionDidVisit)
|
||||||
|
#define NodeActionsMarkDidComputeFlexBasis(nam, n) \
|
||||||
|
NodeActionsMark(nam, n, NodeActionDidComputeFlexBasis)
|
||||||
|
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
static int YGAndroidLog(
|
static int YGAndroidLog(
|
||||||
const YGConfigRef config,
|
const YGConfigRef config,
|
||||||
@@ -206,8 +246,8 @@ void YGNodeMarkDirtyAndPropogateToDescendants(const YGNodeRef node) {
|
|||||||
return node->markDirtyAndPropogateDownwards();
|
return node->markDirtyAndPropogateDownwards();
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t gNodeInstanceCount = 0;
|
std::atomic<int32_t> gNodeInstanceCount(0);
|
||||||
int32_t gConfigInstanceCount = 0;
|
std::atomic<int32_t> gConfigInstanceCount(0);
|
||||||
|
|
||||||
WIN_EXPORT YGNodeRef YGNodeNewWithConfig(const YGConfigRef config) {
|
WIN_EXPORT YGNodeRef YGNodeNewWithConfig(const YGConfigRef config) {
|
||||||
const YGNodeRef node = new YGNode();
|
const YGNodeRef node = new YGNode();
|
||||||
@@ -1021,10 +1061,9 @@ bool YGNodeLayoutGetDidLegacyStretchFlagAffectLayout(const YGNodeRef node) {
|
|||||||
return node->getLayout().doesLegacyStretchFlagAffectsLayout;
|
return node->getLayout().doesLegacyStretchFlagAffectsLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t gCurrentGenerationCount = 0;
|
|
||||||
|
|
||||||
bool YGLayoutNodeInternal(
|
bool YGLayoutNodeInternal(
|
||||||
const YGNodeRef node,
|
const YGNodeRef node,
|
||||||
|
int depth,
|
||||||
const float availableWidth,
|
const float availableWidth,
|
||||||
const float availableHeight,
|
const float availableHeight,
|
||||||
const YGDirection ownerDirection,
|
const YGDirection ownerDirection,
|
||||||
@@ -1034,7 +1073,8 @@ bool YGLayoutNodeInternal(
|
|||||||
const float ownerHeight,
|
const float ownerHeight,
|
||||||
const bool performLayout,
|
const bool performLayout,
|
||||||
const char* reason,
|
const char* reason,
|
||||||
const YGConfigRef config);
|
const YGConfigRef config,
|
||||||
|
NodeActions& nodeActions);
|
||||||
|
|
||||||
static void YGNodePrintInternal(
|
static void YGNodePrintInternal(
|
||||||
const YGNodeRef node,
|
const YGNodeRef node,
|
||||||
@@ -1265,6 +1305,7 @@ static void YGConstrainMaxSizeForMode(
|
|||||||
|
|
||||||
static void YGNodeComputeFlexBasisForChild(
|
static void YGNodeComputeFlexBasisForChild(
|
||||||
const YGNodeRef node,
|
const YGNodeRef node,
|
||||||
|
int depth,
|
||||||
const YGNodeRef child,
|
const YGNodeRef child,
|
||||||
const float width,
|
const float width,
|
||||||
const YGMeasureMode widthMode,
|
const YGMeasureMode widthMode,
|
||||||
@@ -1273,7 +1314,8 @@ static void YGNodeComputeFlexBasisForChild(
|
|||||||
const float ownerHeight,
|
const float ownerHeight,
|
||||||
const YGMeasureMode heightMode,
|
const YGMeasureMode heightMode,
|
||||||
const YGDirection direction,
|
const YGDirection direction,
|
||||||
const YGConfigRef config) {
|
const YGConfigRef config,
|
||||||
|
NodeActions& nodeActions) {
|
||||||
const YGFlexDirection mainAxis =
|
const YGFlexDirection mainAxis =
|
||||||
YGResolveFlexDirection(node->getStyle().flexDirection, direction);
|
YGResolveFlexDirection(node->getStyle().flexDirection, direction);
|
||||||
const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis);
|
const bool isMainAxisRow = YGFlexDirectionIsRow(mainAxis);
|
||||||
@@ -1296,8 +1338,7 @@ static void YGNodeComputeFlexBasisForChild(
|
|||||||
if (child->getLayout().computedFlexBasis.isUndefined() ||
|
if (child->getLayout().computedFlexBasis.isUndefined() ||
|
||||||
(YGConfigIsExperimentalFeatureEnabled(
|
(YGConfigIsExperimentalFeatureEnabled(
|
||||||
child->getConfig(), YGExperimentalFeatureWebFlexBasis) &&
|
child->getConfig(), YGExperimentalFeatureWebFlexBasis) &&
|
||||||
child->getLayout().computedFlexBasisGeneration !=
|
!NodeActionsDidComputeFlexBasis(nodeActions, child))) {
|
||||||
gCurrentGenerationCount)) {
|
|
||||||
const YGFloatOptional paddingAndBorder = YGFloatOptional(
|
const YGFloatOptional paddingAndBorder = YGFloatOptional(
|
||||||
YGNodePaddingAndBorderForAxis(child, mainAxis, ownerWidth));
|
YGNodePaddingAndBorderForAxis(child, mainAxis, ownerWidth));
|
||||||
child->setLayoutComputedFlexBasis(
|
child->setLayoutComputedFlexBasis(
|
||||||
@@ -1437,6 +1478,7 @@ static void YGNodeComputeFlexBasisForChild(
|
|||||||
// Measure the child
|
// Measure the child
|
||||||
YGLayoutNodeInternal(
|
YGLayoutNodeInternal(
|
||||||
child,
|
child,
|
||||||
|
depth,
|
||||||
childWidth,
|
childWidth,
|
||||||
childHeight,
|
childHeight,
|
||||||
direction,
|
direction,
|
||||||
@@ -1446,23 +1488,26 @@ static void YGNodeComputeFlexBasisForChild(
|
|||||||
ownerHeight,
|
ownerHeight,
|
||||||
false,
|
false,
|
||||||
"measure",
|
"measure",
|
||||||
config);
|
config,
|
||||||
|
nodeActions);
|
||||||
|
|
||||||
child->setLayoutComputedFlexBasis(YGFloatOptional(YGFloatMax(
|
child->setLayoutComputedFlexBasis(YGFloatOptional(YGFloatMax(
|
||||||
child->getLayout().measuredDimensions[dim[mainAxis]],
|
child->getLayout().measuredDimensions[dim[mainAxis]],
|
||||||
YGNodePaddingAndBorderForAxis(child, mainAxis, ownerWidth))));
|
YGNodePaddingAndBorderForAxis(child, mainAxis, ownerWidth))));
|
||||||
}
|
}
|
||||||
child->setLayoutComputedFlexBasisGeneration(gCurrentGenerationCount);
|
NodeActionsMarkDidComputeFlexBasis(nodeActions, child);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void YGNodeAbsoluteLayoutChild(
|
static void YGNodeAbsoluteLayoutChild(
|
||||||
const YGNodeRef node,
|
const YGNodeRef node,
|
||||||
|
int depth,
|
||||||
const YGNodeRef child,
|
const YGNodeRef child,
|
||||||
const float width,
|
const float width,
|
||||||
const YGMeasureMode widthMode,
|
const YGMeasureMode widthMode,
|
||||||
const float height,
|
const float height,
|
||||||
const YGDirection direction,
|
const YGDirection direction,
|
||||||
const YGConfigRef config) {
|
const YGConfigRef config,
|
||||||
|
NodeActions& nodeActions) {
|
||||||
const YGFlexDirection mainAxis =
|
const YGFlexDirection mainAxis =
|
||||||
YGResolveFlexDirection(node->getStyle().flexDirection, direction);
|
YGResolveFlexDirection(node->getStyle().flexDirection, direction);
|
||||||
const YGFlexDirection crossAxis = YGFlexDirectionCross(mainAxis, direction);
|
const YGFlexDirection crossAxis = YGFlexDirectionCross(mainAxis, direction);
|
||||||
@@ -1557,6 +1602,7 @@ static void YGNodeAbsoluteLayoutChild(
|
|||||||
|
|
||||||
YGLayoutNodeInternal(
|
YGLayoutNodeInternal(
|
||||||
child,
|
child,
|
||||||
|
depth,
|
||||||
childWidth,
|
childWidth,
|
||||||
childHeight,
|
childHeight,
|
||||||
direction,
|
direction,
|
||||||
@@ -1566,7 +1612,8 @@ static void YGNodeAbsoluteLayoutChild(
|
|||||||
childHeight,
|
childHeight,
|
||||||
false,
|
false,
|
||||||
"abs-measure",
|
"abs-measure",
|
||||||
config);
|
config,
|
||||||
|
nodeActions);
|
||||||
childWidth = child->getLayout().measuredDimensions[YGDimensionWidth] +
|
childWidth = child->getLayout().measuredDimensions[YGDimensionWidth] +
|
||||||
child->getMarginForAxis(YGFlexDirectionRow, width).unwrap();
|
child->getMarginForAxis(YGFlexDirectionRow, width).unwrap();
|
||||||
childHeight = child->getLayout().measuredDimensions[YGDimensionHeight] +
|
childHeight = child->getLayout().measuredDimensions[YGDimensionHeight] +
|
||||||
@@ -1575,6 +1622,7 @@ static void YGNodeAbsoluteLayoutChild(
|
|||||||
|
|
||||||
YGLayoutNodeInternal(
|
YGLayoutNodeInternal(
|
||||||
child,
|
child,
|
||||||
|
depth,
|
||||||
childWidth,
|
childWidth,
|
||||||
childHeight,
|
childHeight,
|
||||||
direction,
|
direction,
|
||||||
@@ -1584,7 +1632,8 @@ static void YGNodeAbsoluteLayoutChild(
|
|||||||
childHeight,
|
childHeight,
|
||||||
true,
|
true,
|
||||||
"abs-layout",
|
"abs-layout",
|
||||||
config);
|
config,
|
||||||
|
nodeActions);
|
||||||
|
|
||||||
if (child->isTrailingPosDefined(mainAxis) &&
|
if (child->isTrailingPosDefined(mainAxis) &&
|
||||||
!child->isLeadingPositionDefined(mainAxis)) {
|
!child->isLeadingPositionDefined(mainAxis)) {
|
||||||
@@ -1873,6 +1922,7 @@ static float YGNodeCalculateAvailableInnerDim(
|
|||||||
|
|
||||||
static float YGNodeComputeFlexBasisForChildren(
|
static float YGNodeComputeFlexBasisForChildren(
|
||||||
const YGNodeRef node,
|
const YGNodeRef node,
|
||||||
|
int depth,
|
||||||
const float availableInnerWidth,
|
const float availableInnerWidth,
|
||||||
const float availableInnerHeight,
|
const float availableInnerHeight,
|
||||||
YGMeasureMode widthMeasureMode,
|
YGMeasureMode widthMeasureMode,
|
||||||
@@ -1880,7 +1930,8 @@ static float YGNodeComputeFlexBasisForChildren(
|
|||||||
YGDirection direction,
|
YGDirection direction,
|
||||||
YGFlexDirection mainAxis,
|
YGFlexDirection mainAxis,
|
||||||
const YGConfigRef config,
|
const YGConfigRef config,
|
||||||
bool performLayout) {
|
bool performLayout,
|
||||||
|
NodeActions& nodeActions) {
|
||||||
float totalOuterFlexBasis = 0.0f;
|
float totalOuterFlexBasis = 0.0f;
|
||||||
YGNodeRef singleFlexChild = nullptr;
|
YGNodeRef singleFlexChild = nullptr;
|
||||||
YGVector children = node->getChildren();
|
YGVector children = node->getChildren();
|
||||||
@@ -1931,11 +1982,12 @@ static float YGNodeComputeFlexBasisForChildren(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (child == singleFlexChild) {
|
if (child == singleFlexChild) {
|
||||||
child->setLayoutComputedFlexBasisGeneration(gCurrentGenerationCount);
|
NodeActionsMarkDidComputeFlexBasis(nodeActions, child);
|
||||||
child->setLayoutComputedFlexBasis(YGFloatOptional(0));
|
child->setLayoutComputedFlexBasis(YGFloatOptional(0));
|
||||||
} else {
|
} else {
|
||||||
YGNodeComputeFlexBasisForChild(
|
YGNodeComputeFlexBasisForChild(
|
||||||
node,
|
node,
|
||||||
|
depth,
|
||||||
child,
|
child,
|
||||||
availableInnerWidth,
|
availableInnerWidth,
|
||||||
widthMeasureMode,
|
widthMeasureMode,
|
||||||
@@ -1944,7 +1996,8 @@ static float YGNodeComputeFlexBasisForChildren(
|
|||||||
availableInnerHeight,
|
availableInnerHeight,
|
||||||
heightMeasureMode,
|
heightMeasureMode,
|
||||||
direction,
|
direction,
|
||||||
config);
|
config,
|
||||||
|
nodeActions);
|
||||||
}
|
}
|
||||||
|
|
||||||
totalOuterFlexBasis +=
|
totalOuterFlexBasis +=
|
||||||
@@ -2046,6 +2099,7 @@ static YGCollectFlexItemsRowValues YGCalculateCollectFlexItemsRowValues(
|
|||||||
static float YGDistributeFreeSpaceSecondPass(
|
static float YGDistributeFreeSpaceSecondPass(
|
||||||
YGCollectFlexItemsRowValues& collectedFlexItemsValues,
|
YGCollectFlexItemsRowValues& collectedFlexItemsValues,
|
||||||
const YGNodeRef node,
|
const YGNodeRef node,
|
||||||
|
int depth,
|
||||||
const YGFlexDirection mainAxis,
|
const YGFlexDirection mainAxis,
|
||||||
const YGFlexDirection crossAxis,
|
const YGFlexDirection crossAxis,
|
||||||
const float mainAxisownerSize,
|
const float mainAxisownerSize,
|
||||||
@@ -2056,7 +2110,8 @@ static float YGDistributeFreeSpaceSecondPass(
|
|||||||
const bool flexBasisOverflows,
|
const bool flexBasisOverflows,
|
||||||
const YGMeasureMode measureModeCrossDim,
|
const YGMeasureMode measureModeCrossDim,
|
||||||
const bool performLayout,
|
const bool performLayout,
|
||||||
const YGConfigRef config) {
|
const YGConfigRef config,
|
||||||
|
NodeActions& nodeActions) {
|
||||||
float childFlexBasis = 0;
|
float childFlexBasis = 0;
|
||||||
float flexShrinkScaledFactor = 0;
|
float flexShrinkScaledFactor = 0;
|
||||||
float flexGrowFactor = 0;
|
float flexGrowFactor = 0;
|
||||||
@@ -2211,6 +2266,7 @@ static float YGDistributeFreeSpaceSecondPass(
|
|||||||
// main size.
|
// main size.
|
||||||
YGLayoutNodeInternal(
|
YGLayoutNodeInternal(
|
||||||
currentRelativeChild,
|
currentRelativeChild,
|
||||||
|
depth,
|
||||||
childWidth,
|
childWidth,
|
||||||
childHeight,
|
childHeight,
|
||||||
node->getLayout().direction,
|
node->getLayout().direction,
|
||||||
@@ -2220,7 +2276,8 @@ static float YGDistributeFreeSpaceSecondPass(
|
|||||||
availableInnerHeight,
|
availableInnerHeight,
|
||||||
performLayout && !requiresStretchLayout,
|
performLayout && !requiresStretchLayout,
|
||||||
"flex",
|
"flex",
|
||||||
config);
|
config,
|
||||||
|
nodeActions);
|
||||||
node->setLayoutHadOverflow(
|
node->setLayoutHadOverflow(
|
||||||
node->getLayout().hadOverflow |
|
node->getLayout().hadOverflow |
|
||||||
currentRelativeChild->getLayout().hadOverflow);
|
currentRelativeChild->getLayout().hadOverflow);
|
||||||
@@ -2338,6 +2395,7 @@ static void YGDistributeFreeSpaceFirstPass(
|
|||||||
//
|
//
|
||||||
static void YGResolveFlexibleLength(
|
static void YGResolveFlexibleLength(
|
||||||
const YGNodeRef node,
|
const YGNodeRef node,
|
||||||
|
int depth,
|
||||||
YGCollectFlexItemsRowValues& collectedFlexItemsValues,
|
YGCollectFlexItemsRowValues& collectedFlexItemsValues,
|
||||||
const YGFlexDirection mainAxis,
|
const YGFlexDirection mainAxis,
|
||||||
const YGFlexDirection crossAxis,
|
const YGFlexDirection crossAxis,
|
||||||
@@ -2349,7 +2407,8 @@ static void YGResolveFlexibleLength(
|
|||||||
const bool flexBasisOverflows,
|
const bool flexBasisOverflows,
|
||||||
const YGMeasureMode measureModeCrossDim,
|
const YGMeasureMode measureModeCrossDim,
|
||||||
const bool performLayout,
|
const bool performLayout,
|
||||||
const YGConfigRef config) {
|
const YGConfigRef config,
|
||||||
|
NodeActions& nodeActions) {
|
||||||
const float originalFreeSpace = collectedFlexItemsValues.remainingFreeSpace;
|
const float originalFreeSpace = collectedFlexItemsValues.remainingFreeSpace;
|
||||||
// First pass: detect the flex items whose min/max constraints trigger
|
// First pass: detect the flex items whose min/max constraints trigger
|
||||||
YGDistributeFreeSpaceFirstPass(
|
YGDistributeFreeSpaceFirstPass(
|
||||||
@@ -2363,6 +2422,7 @@ static void YGResolveFlexibleLength(
|
|||||||
const float distributedFreeSpace = YGDistributeFreeSpaceSecondPass(
|
const float distributedFreeSpace = YGDistributeFreeSpaceSecondPass(
|
||||||
collectedFlexItemsValues,
|
collectedFlexItemsValues,
|
||||||
node,
|
node,
|
||||||
|
depth,
|
||||||
mainAxis,
|
mainAxis,
|
||||||
crossAxis,
|
crossAxis,
|
||||||
mainAxisownerSize,
|
mainAxisownerSize,
|
||||||
@@ -2373,7 +2433,8 @@ static void YGResolveFlexibleLength(
|
|||||||
flexBasisOverflows,
|
flexBasisOverflows,
|
||||||
measureModeCrossDim,
|
measureModeCrossDim,
|
||||||
performLayout,
|
performLayout,
|
||||||
config);
|
config,
|
||||||
|
nodeActions);
|
||||||
|
|
||||||
collectedFlexItemsValues.remainingFreeSpace =
|
collectedFlexItemsValues.remainingFreeSpace =
|
||||||
originalFreeSpace - distributedFreeSpace;
|
originalFreeSpace - distributedFreeSpace;
|
||||||
@@ -2661,6 +2722,7 @@ static void YGJustifyMainAxis(
|
|||||||
//
|
//
|
||||||
static void YGNodelayoutImpl(
|
static void YGNodelayoutImpl(
|
||||||
const YGNodeRef node,
|
const YGNodeRef node,
|
||||||
|
int depth,
|
||||||
const float availableWidth,
|
const float availableWidth,
|
||||||
const float availableHeight,
|
const float availableHeight,
|
||||||
const YGDirection ownerDirection,
|
const YGDirection ownerDirection,
|
||||||
@@ -2669,7 +2731,8 @@ static void YGNodelayoutImpl(
|
|||||||
const float ownerWidth,
|
const float ownerWidth,
|
||||||
const float ownerHeight,
|
const float ownerHeight,
|
||||||
const bool performLayout,
|
const bool performLayout,
|
||||||
const YGConfigRef config) {
|
const YGConfigRef config,
|
||||||
|
NodeActions& nodeActions) {
|
||||||
YGAssertWithNode(
|
YGAssertWithNode(
|
||||||
node,
|
node,
|
||||||
YGFloatIsUndefined(availableWidth)
|
YGFloatIsUndefined(availableWidth)
|
||||||
@@ -2843,6 +2906,7 @@ static void YGNodelayoutImpl(
|
|||||||
|
|
||||||
float totalOuterFlexBasis = YGNodeComputeFlexBasisForChildren(
|
float totalOuterFlexBasis = YGNodeComputeFlexBasisForChildren(
|
||||||
node,
|
node,
|
||||||
|
depth,
|
||||||
availableInnerWidth,
|
availableInnerWidth,
|
||||||
availableInnerHeight,
|
availableInnerHeight,
|
||||||
widthMeasureMode,
|
widthMeasureMode,
|
||||||
@@ -2850,7 +2914,8 @@ static void YGNodelayoutImpl(
|
|||||||
direction,
|
direction,
|
||||||
mainAxis,
|
mainAxis,
|
||||||
config,
|
config,
|
||||||
performLayout);
|
performLayout,
|
||||||
|
nodeActions);
|
||||||
|
|
||||||
const bool flexBasisOverflows = measureModeMainDim == YGMeasureModeUndefined
|
const bool flexBasisOverflows = measureModeMainDim == YGMeasureModeUndefined
|
||||||
? false
|
? false
|
||||||
@@ -2945,6 +3010,7 @@ static void YGNodelayoutImpl(
|
|||||||
if (!canSkipFlex) {
|
if (!canSkipFlex) {
|
||||||
YGResolveFlexibleLength(
|
YGResolveFlexibleLength(
|
||||||
node,
|
node,
|
||||||
|
depth,
|
||||||
collectedFlexItemsValues,
|
collectedFlexItemsValues,
|
||||||
mainAxis,
|
mainAxis,
|
||||||
crossAxis,
|
crossAxis,
|
||||||
@@ -2956,7 +3022,8 @@ static void YGNodelayoutImpl(
|
|||||||
flexBasisOverflows,
|
flexBasisOverflows,
|
||||||
measureModeCrossDim,
|
measureModeCrossDim,
|
||||||
performLayout,
|
performLayout,
|
||||||
config);
|
config,
|
||||||
|
nodeActions);
|
||||||
}
|
}
|
||||||
|
|
||||||
node->setLayoutHadOverflow(
|
node->setLayoutHadOverflow(
|
||||||
@@ -3112,6 +3179,7 @@ static void YGNodelayoutImpl(
|
|||||||
|
|
||||||
YGLayoutNodeInternal(
|
YGLayoutNodeInternal(
|
||||||
child,
|
child,
|
||||||
|
depth,
|
||||||
childWidth,
|
childWidth,
|
||||||
childHeight,
|
childHeight,
|
||||||
direction,
|
direction,
|
||||||
@@ -3121,7 +3189,8 @@ static void YGNodelayoutImpl(
|
|||||||
availableInnerHeight,
|
availableInnerHeight,
|
||||||
true,
|
true,
|
||||||
"stretch",
|
"stretch",
|
||||||
config);
|
config,
|
||||||
|
nodeActions);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const float remainingCrossDim = containerCrossAxis -
|
const float remainingCrossDim = containerCrossAxis -
|
||||||
@@ -3318,6 +3387,7 @@ static void YGNodelayoutImpl(
|
|||||||
.measuredDimensions[YGDimensionHeight]))) {
|
.measuredDimensions[YGDimensionHeight]))) {
|
||||||
YGLayoutNodeInternal(
|
YGLayoutNodeInternal(
|
||||||
child,
|
child,
|
||||||
|
depth,
|
||||||
childWidth,
|
childWidth,
|
||||||
childHeight,
|
childHeight,
|
||||||
direction,
|
direction,
|
||||||
@@ -3327,7 +3397,8 @@ static void YGNodelayoutImpl(
|
|||||||
availableInnerHeight,
|
availableInnerHeight,
|
||||||
true,
|
true,
|
||||||
"multiline-stretch",
|
"multiline-stretch",
|
||||||
config);
|
config,
|
||||||
|
nodeActions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -3459,12 +3530,14 @@ static void YGNodelayoutImpl(
|
|||||||
}
|
}
|
||||||
YGNodeAbsoluteLayoutChild(
|
YGNodeAbsoluteLayoutChild(
|
||||||
node,
|
node,
|
||||||
|
depth,
|
||||||
child,
|
child,
|
||||||
availableInnerWidth,
|
availableInnerWidth,
|
||||||
isMainAxisRow ? measureModeMainDim : measureModeCrossDim,
|
isMainAxisRow ? measureModeMainDim : measureModeCrossDim,
|
||||||
availableInnerHeight,
|
availableInnerHeight,
|
||||||
direction,
|
direction,
|
||||||
config);
|
config,
|
||||||
|
nodeActions);
|
||||||
}
|
}
|
||||||
|
|
||||||
// STEP 11: SETTING TRAILING POSITIONS FOR CHILDREN
|
// STEP 11: SETTING TRAILING POSITIONS FOR CHILDREN
|
||||||
@@ -3492,9 +3565,8 @@ static void YGNodelayoutImpl(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t gDepth = 0;
|
const bool gPrintChanges = false;
|
||||||
bool gPrintChanges = false;
|
const bool gPrintSkips = false;
|
||||||
bool gPrintSkips = false;
|
|
||||||
|
|
||||||
static const char* spacer =
|
static const char* spacer =
|
||||||
" ";
|
" ";
|
||||||
@@ -3687,6 +3759,7 @@ bool YGNodeCanUseCachedMeasurement(
|
|||||||
//
|
//
|
||||||
bool YGLayoutNodeInternal(
|
bool YGLayoutNodeInternal(
|
||||||
const YGNodeRef node,
|
const YGNodeRef node,
|
||||||
|
int depth,
|
||||||
const float availableWidth,
|
const float availableWidth,
|
||||||
const float availableHeight,
|
const float availableHeight,
|
||||||
const YGDirection ownerDirection,
|
const YGDirection ownerDirection,
|
||||||
@@ -3696,13 +3769,16 @@ bool YGLayoutNodeInternal(
|
|||||||
const float ownerHeight,
|
const float ownerHeight,
|
||||||
const bool performLayout,
|
const bool performLayout,
|
||||||
const char* reason,
|
const char* reason,
|
||||||
const YGConfigRef config) {
|
const YGConfigRef config,
|
||||||
|
NodeActions& nodeActions) {
|
||||||
YGLayout* layout = &node->getLayout();
|
YGLayout* layout = &node->getLayout();
|
||||||
|
|
||||||
gDepth++;
|
if (gPrintChanges) {
|
||||||
|
depth++;
|
||||||
|
}
|
||||||
|
|
||||||
const bool needToVisitNode =
|
const bool needToVisitNode =
|
||||||
(node->isDirty() && layout->generationCount != gCurrentGenerationCount) ||
|
(node->isDirty() && !NodeActionsDidVisit(nodeActions, node)) ||
|
||||||
layout->lastOwnerDirection != ownerDirection;
|
layout->lastOwnerDirection != ownerDirection;
|
||||||
|
|
||||||
if (needToVisitNode) {
|
if (needToVisitNode) {
|
||||||
@@ -3800,8 +3876,8 @@ bool YGLayoutNodeInternal(
|
|||||||
node,
|
node,
|
||||||
YGLogLevelVerbose,
|
YGLogLevelVerbose,
|
||||||
"%s%d.{[skipped] ",
|
"%s%d.{[skipped] ",
|
||||||
YGSpacer(gDepth),
|
YGSpacer(depth),
|
||||||
gDepth);
|
depth);
|
||||||
if (node->getPrintFunc() != nullptr) {
|
if (node->getPrintFunc() != nullptr) {
|
||||||
node->getPrintFunc()(node);
|
node->getPrintFunc()(node);
|
||||||
}
|
}
|
||||||
@@ -3823,8 +3899,8 @@ bool YGLayoutNodeInternal(
|
|||||||
node,
|
node,
|
||||||
YGLogLevelVerbose,
|
YGLogLevelVerbose,
|
||||||
"%s%d.{%s",
|
"%s%d.{%s",
|
||||||
YGSpacer(gDepth),
|
YGSpacer(depth),
|
||||||
gDepth,
|
depth,
|
||||||
needToVisitNode ? "*" : "");
|
needToVisitNode ? "*" : "");
|
||||||
if (node->getPrintFunc() != nullptr) {
|
if (node->getPrintFunc() != nullptr) {
|
||||||
node->getPrintFunc()(node);
|
node->getPrintFunc()(node);
|
||||||
@@ -3842,6 +3918,7 @@ bool YGLayoutNodeInternal(
|
|||||||
|
|
||||||
YGNodelayoutImpl(
|
YGNodelayoutImpl(
|
||||||
node,
|
node,
|
||||||
|
depth,
|
||||||
availableWidth,
|
availableWidth,
|
||||||
availableHeight,
|
availableHeight,
|
||||||
ownerDirection,
|
ownerDirection,
|
||||||
@@ -3850,15 +3927,16 @@ bool YGLayoutNodeInternal(
|
|||||||
ownerWidth,
|
ownerWidth,
|
||||||
ownerHeight,
|
ownerHeight,
|
||||||
performLayout,
|
performLayout,
|
||||||
config);
|
config,
|
||||||
|
nodeActions);
|
||||||
|
|
||||||
if (gPrintChanges) {
|
if (gPrintChanges) {
|
||||||
YGLog(
|
YGLog(
|
||||||
node,
|
node,
|
||||||
YGLogLevelVerbose,
|
YGLogLevelVerbose,
|
||||||
"%s%d.}%s",
|
"%s%d.}%s",
|
||||||
YGSpacer(gDepth),
|
YGSpacer(depth),
|
||||||
gDepth,
|
depth,
|
||||||
needToVisitNode ? "*" : "");
|
needToVisitNode ? "*" : "");
|
||||||
if (node->getPrintFunc() != nullptr) {
|
if (node->getPrintFunc() != nullptr) {
|
||||||
node->getPrintFunc()(node);
|
node->getPrintFunc()(node);
|
||||||
@@ -3918,8 +3996,10 @@ bool YGLayoutNodeInternal(
|
|||||||
node->setDirty(false);
|
node->setDirty(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
gDepth--;
|
if (gPrintChanges) {
|
||||||
layout->generationCount = gCurrentGenerationCount;
|
depth--;
|
||||||
|
}
|
||||||
|
NodeActionsMarkDidVisit(nodeActions, node);
|
||||||
return (needToVisitNode || cachedResults == nullptr);
|
return (needToVisitNode || cachedResults == nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4018,10 +4098,7 @@ void YGNodeCalculateLayout(
|
|||||||
const float ownerWidth,
|
const float ownerWidth,
|
||||||
const float ownerHeight,
|
const float ownerHeight,
|
||||||
const YGDirection ownerDirection) {
|
const YGDirection ownerDirection) {
|
||||||
// Increment the generation count. This will force the recursive routine to
|
NodeActions nodeActions;
|
||||||
// visit all dirty nodes at least once. Subsequent visits will be skipped if
|
|
||||||
// the input parameters don't change.
|
|
||||||
gCurrentGenerationCount++;
|
|
||||||
node->resolveDimension();
|
node->resolveDimension();
|
||||||
float width = YGUndefined;
|
float width = YGUndefined;
|
||||||
YGMeasureMode widthMeasureMode = YGMeasureModeUndefined;
|
YGMeasureMode widthMeasureMode = YGMeasureModeUndefined;
|
||||||
@@ -4069,6 +4146,7 @@ void YGNodeCalculateLayout(
|
|||||||
}
|
}
|
||||||
if (YGLayoutNodeInternal(
|
if (YGLayoutNodeInternal(
|
||||||
node,
|
node,
|
||||||
|
0, // tree root depth
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
ownerDirection,
|
ownerDirection,
|
||||||
@@ -4078,7 +4156,8 @@ void YGNodeCalculateLayout(
|
|||||||
ownerHeight,
|
ownerHeight,
|
||||||
true,
|
true,
|
||||||
"initial",
|
"initial",
|
||||||
node->getConfig())) {
|
node->getConfig(),
|
||||||
|
nodeActions)) {
|
||||||
node->setPosition(
|
node->setPosition(
|
||||||
node->getLayout().direction, ownerWidth, ownerHeight, ownerWidth);
|
node->getLayout().direction, ownerWidth, ownerHeight, ownerWidth);
|
||||||
YGRoundToPixelGrid(node, node->getConfig()->pointScaleFactor, 0.0f, 0.0f);
|
YGRoundToPixelGrid(node, node->getConfig()->pointScaleFactor, 0.0f, 0.0f);
|
||||||
@@ -4103,13 +4182,14 @@ void YGNodeCalculateLayout(
|
|||||||
node->didUseLegacyFlag()) {
|
node->didUseLegacyFlag()) {
|
||||||
const YGNodeRef originalNode = YGNodeDeepClone(node);
|
const YGNodeRef originalNode = YGNodeDeepClone(node);
|
||||||
originalNode->resolveDimension();
|
originalNode->resolveDimension();
|
||||||
// Recursively mark nodes as dirty
|
// Start over: recursively mark nodes as dirty and clear node actions.
|
||||||
originalNode->markDirtyAndPropogateDownwards();
|
originalNode->markDirtyAndPropogateDownwards();
|
||||||
gCurrentGenerationCount++;
|
nodeActions.clear();
|
||||||
// Rerun the layout, and calculate the diff
|
// Rerun the layout, and calculate the diff
|
||||||
originalNode->setAndPropogateUseLegacyFlag(false);
|
originalNode->setAndPropogateUseLegacyFlag(false);
|
||||||
if (YGLayoutNodeInternal(
|
if (YGLayoutNodeInternal(
|
||||||
originalNode,
|
originalNode,
|
||||||
|
0, // tree root depth
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
ownerDirection,
|
ownerDirection,
|
||||||
@@ -4119,7 +4199,8 @@ void YGNodeCalculateLayout(
|
|||||||
ownerHeight,
|
ownerHeight,
|
||||||
true,
|
true,
|
||||||
"initial",
|
"initial",
|
||||||
originalNode->getConfig())) {
|
originalNode->getConfig(),
|
||||||
|
nodeActions)) {
|
||||||
originalNode->setPosition(
|
originalNode->setPosition(
|
||||||
originalNode->getLayout().direction,
|
originalNode->getLayout().direction,
|
||||||
ownerWidth,
|
ownerWidth,
|
||||||
|
Reference in New Issue
Block a user