make yoga threadsafe #852

Closed
tcdat96 wants to merge 2 commits from yoga_threadsafe into master
194 changed files with 3689 additions and 10549 deletions
Showing only changes of commit cdc7512444 - Show all commits

View File

@@ -22,12 +22,12 @@ struct YGLayout {
bool doesLegacyStretchFlagAffectsLayout : 1; bool doesLegacyStretchFlagAffectsLayout : 1;
bool hadOverflow : 1; bool hadOverflow : 1;
uint32_t computedFlexBasisGeneration = 0; uint8_t computedFlexBasisGeneration = 0;
YGFloatOptional computedFlexBasis = {}; YGFloatOptional computedFlexBasis = {};
davidaurelio commented 2019-01-28 11:43:15 -08:00 (Migrated from github.com)
Review

What was the motivation for this change? Due to alignment requirements, this won’t even save memory without reordering data members.

What was the motivation for this change? Due to alignment requirements, this won’t even save memory without reordering data members.
jpap commented 2019-01-29 18:11:49 -08:00 (Migrated from github.com)
Review

The motivation is to save heap: there are many bits left over from alignment of the bitfields above it, so you could combine computedFlexBasisGeneration with it. I suspect you can get away with just one bit, so long as the generation counter is the same width (or is truncated with a logical AND mask when the generation is incremented).

The motivation is to save heap: there are many bits left over from alignment of the bitfields above it, so you could combine `computedFlexBasisGeneration` with it. I suspect you can get away with just one bit, so long as the generation counter is the same width (or is truncated with a logical AND mask when the generation is incremented).
// Instead of recomputing the entire layout every single time, we cache some // Instead of recomputing the entire layout every single time, we cache some
// information to break early when nothing changed // information to break early when nothing changed
uint32_t generationCount = 0; uint8_t generationCount = 0;
YGDirection lastOwnerDirection = (YGDirection) -1; YGDirection lastOwnerDirection = (YGDirection) -1;
uint32_t nextCachedMeasurementsIndex = 0; uint32_t nextCachedMeasurementsIndex = 0;

View File

@@ -257,7 +257,7 @@ void YGNode::setLayoutPosition(float position, int index) {
} }
void YGNode::setLayoutComputedFlexBasisGeneration( void YGNode::setLayoutComputedFlexBasisGeneration(
uint32_t computedFlexBasisGeneration) { uint8_t computedFlexBasisGeneration) {
layout_.computedFlexBasisGeneration = computedFlexBasisGeneration; layout_.computedFlexBasisGeneration = computedFlexBasisGeneration;
} }

View File

@@ -316,7 +316,7 @@ public:
void setLayoutLastOwnerDirection(YGDirection direction); void setLayoutLastOwnerDirection(YGDirection direction);
void setLayoutComputedFlexBasis(const YGFloatOptional computedFlexBasis); void setLayoutComputedFlexBasis(const YGFloatOptional computedFlexBasis);
void setLayoutComputedFlexBasisGeneration( void setLayoutComputedFlexBasisGeneration(
uint32_t computedFlexBasisGeneration); uint8_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);

View File

@@ -962,7 +962,7 @@ bool YGNodeLayoutGetDidLegacyStretchFlagAffectLayout(const YGNodeRef node) {
return node->getLayout().doesLegacyStretchFlagAffectsLayout; return node->getLayout().doesLegacyStretchFlagAffectsLayout;
} }
uint32_t gCurrentGenerationCount = 0; uint8_t gCurrentGenerationCount = 0;
bool YGLayoutNodeInternal( bool YGLayoutNodeInternal(
const YGNodeRef node, const YGNodeRef node,
@@ -977,7 +977,9 @@ bool YGLayoutNodeInternal(
const char* reason, const char* reason,
const YGConfigRef config, const YGConfigRef config,
YGMarkerLayoutData& layoutMarkerData, YGMarkerLayoutData& layoutMarkerData,
void* const layoutContext); void* const layoutContext,
const uint32_t depth,
const uint8_t generationCount);
static void YGNodePrintInternal( static void YGNodePrintInternal(
const YGNodeRef node, const YGNodeRef node,
@@ -1220,7 +1222,9 @@ static void YGNodeComputeFlexBasisForChild(
const YGDirection direction, const YGDirection direction,
const YGConfigRef config, const YGConfigRef config,
YGMarkerLayoutData& layoutMarkerData, YGMarkerLayoutData& layoutMarkerData,
void* const layoutContext) { void* const layoutContext,
const uint32_t depth,
const uint8_t generationCount) {
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);
@@ -1243,8 +1247,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 != child->getLayout().computedFlexBasisGeneration != generationCount)) {
gCurrentGenerationCount)) {
const YGFloatOptional paddingAndBorder = YGFloatOptional( const YGFloatOptional paddingAndBorder = YGFloatOptional(
YGNodePaddingAndBorderForAxis(child, mainAxis, ownerWidth)); YGNodePaddingAndBorderForAxis(child, mainAxis, ownerWidth));
child->setLayoutComputedFlexBasis( child->setLayoutComputedFlexBasis(
@@ -1395,13 +1398,16 @@ static void YGNodeComputeFlexBasisForChild(
"measure", "measure",
config, config,
layoutMarkerData, layoutMarkerData,
layoutContext); layoutContext,
depth,
generationCount
);
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); child->setLayoutComputedFlexBasisGeneration(generationCount);
} }
static void YGNodeAbsoluteLayoutChild( static void YGNodeAbsoluteLayoutChild(
@@ -1413,7 +1419,9 @@ static void YGNodeAbsoluteLayoutChild(
const YGDirection direction, const YGDirection direction,
const YGConfigRef config, const YGConfigRef config,
YGMarkerLayoutData& layoutMarkerData, YGMarkerLayoutData& layoutMarkerData,
void* const layoutContext) { void* const layoutContext,
const uint32_t depth,
const uint8_t generationCount) {
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);
@@ -1519,7 +1527,9 @@ static void YGNodeAbsoluteLayoutChild(
"abs-measure", "abs-measure",
config, config,
layoutMarkerData, layoutMarkerData,
layoutContext); layoutContext,
depth,
generationCount);
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] +
@@ -1539,7 +1549,9 @@ static void YGNodeAbsoluteLayoutChild(
"abs-layout", "abs-layout",
config, config,
layoutMarkerData, layoutMarkerData,
layoutContext); layoutContext,
depth,
generationCount);
if (child->isTrailingPosDefined(mainAxis) && if (child->isTrailingPosDefined(mainAxis) &&
!child->isLeadingPositionDefined(mainAxis)) { !child->isLeadingPositionDefined(mainAxis)) {
@@ -1843,7 +1855,9 @@ static float YGNodeComputeFlexBasisForChildren(
const YGConfigRef config, const YGConfigRef config,
bool performLayout, bool performLayout,
YGMarkerLayoutData& layoutMarkerData, YGMarkerLayoutData& layoutMarkerData,
void* const layoutContext) { void* const layoutContext,
const uint32_t depth,
const uint8_t generationCount) {
float totalOuterFlexBasis = 0.0f; float totalOuterFlexBasis = 0.0f;
YGNodeRef singleFlexChild = nullptr; YGNodeRef singleFlexChild = nullptr;
YGVector children = node->getChildren(); YGVector children = node->getChildren();
@@ -1894,7 +1908,7 @@ static float YGNodeComputeFlexBasisForChildren(
continue; continue;
} }
if (child == singleFlexChild) { if (child == singleFlexChild) {
child->setLayoutComputedFlexBasisGeneration(gCurrentGenerationCount); child->setLayoutComputedFlexBasisGeneration(generationCount);
child->setLayoutComputedFlexBasis(YGFloatOptional(0)); child->setLayoutComputedFlexBasis(YGFloatOptional(0));
} else { } else {
YGNodeComputeFlexBasisForChild( YGNodeComputeFlexBasisForChild(
@@ -1909,7 +1923,9 @@ static float YGNodeComputeFlexBasisForChildren(
direction, direction,
config, config,
layoutMarkerData, layoutMarkerData,
layoutContext); layoutContext,
depth,
generationCount);
} }
totalOuterFlexBasis += totalOuterFlexBasis +=
@@ -2023,7 +2039,9 @@ static float YGDistributeFreeSpaceSecondPass(
const bool performLayout, const bool performLayout,
const YGConfigRef config, const YGConfigRef config,
YGMarkerLayoutData& layoutMarkerData, YGMarkerLayoutData& layoutMarkerData,
void* const layoutContext) { void* const layoutContext,
const uint32_t depth,
const uint8_t generationCount) {
float childFlexBasis = 0; float childFlexBasis = 0;
float flexShrinkScaledFactor = 0; float flexShrinkScaledFactor = 0;
float flexGrowFactor = 0; float flexGrowFactor = 0;
@@ -2189,7 +2207,9 @@ static float YGDistributeFreeSpaceSecondPass(
"flex", "flex",
config, config,
layoutMarkerData, layoutMarkerData,
layoutContext); layoutContext,
depth,
generationCount);
node->setLayoutHadOverflow( node->setLayoutHadOverflow(
node->getLayout().hadOverflow | node->getLayout().hadOverflow |
currentRelativeChild->getLayout().hadOverflow); currentRelativeChild->getLayout().hadOverflow);
@@ -2320,7 +2340,9 @@ static void YGResolveFlexibleLength(
const bool performLayout, const bool performLayout,
const YGConfigRef config, const YGConfigRef config,
YGMarkerLayoutData& layoutMarkerData, YGMarkerLayoutData& layoutMarkerData,
void* const layoutContext) { void* const layoutContext,
const uint32_t depth,
const uint8_t generationCount) {
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(
@@ -2346,7 +2368,9 @@ static void YGResolveFlexibleLength(
performLayout, performLayout,
config, config,
layoutMarkerData, layoutMarkerData,
layoutContext); layoutContext,
depth,
generationCount);
collectedFlexItemsValues.remainingFreeSpace = collectedFlexItemsValues.remainingFreeSpace =
originalFreeSpace - distributedFreeSpace; originalFreeSpace - distributedFreeSpace;
@@ -2645,7 +2669,9 @@ static void YGNodelayoutImpl(
const bool performLayout, const bool performLayout,
const YGConfigRef config, const YGConfigRef config,
YGMarkerLayoutData& layoutMarkerData, YGMarkerLayoutData& layoutMarkerData,
void* const layoutContext) { void* const layoutContext,
const uint32_t depth,
const uint8_t generationCount) {
YGAssertWithNode( YGAssertWithNode(
node, node,
YGFloatIsUndefined(availableWidth) YGFloatIsUndefined(availableWidth)
@@ -2831,7 +2857,9 @@ static void YGNodelayoutImpl(
config, config,
performLayout, performLayout,
layoutMarkerData, layoutMarkerData,
layoutContext); layoutContext,
depth,
generationCount);
const bool flexBasisOverflows = measureModeMainDim == YGMeasureModeUndefined const bool flexBasisOverflows = measureModeMainDim == YGMeasureModeUndefined
? false ? false
@@ -2939,7 +2967,9 @@ static void YGNodelayoutImpl(
performLayout, performLayout,
config, config,
layoutMarkerData, layoutMarkerData,
layoutContext); layoutContext,
depth,
generationCount);
} }
node->setLayoutHadOverflow( node->setLayoutHadOverflow(
@@ -3107,7 +3137,9 @@ static void YGNodelayoutImpl(
"stretch", "stretch",
config, config,
layoutMarkerData, layoutMarkerData,
layoutContext); layoutContext,
depth,
generationCount);
} }
} else { } else {
const float remainingCrossDim = containerCrossAxis - const float remainingCrossDim = containerCrossAxis -
@@ -3315,7 +3347,9 @@ static void YGNodelayoutImpl(
"multiline-stretch", "multiline-stretch",
config, config,
layoutMarkerData, layoutMarkerData,
layoutContext); layoutContext,
depth,
generationCount);
} }
} }
break; break;
@@ -3455,7 +3489,9 @@ static void YGNodelayoutImpl(
direction, direction,
config, config,
layoutMarkerData, layoutMarkerData,
layoutContext); layoutContext,
depth,
generationCount);
} }
// STEP 11: SETTING TRAILING POSITIONS FOR CHILDREN // STEP 11: SETTING TRAILING POSITIONS FOR CHILDREN
@@ -3483,7 +3519,6 @@ static void YGNodelayoutImpl(
} }
} }
uint32_t gDepth = 0;
bool gPrintChanges = false; bool gPrintChanges = false;
bool gPrintSkips = false; bool gPrintSkips = false;
@@ -3689,13 +3724,15 @@ bool YGLayoutNodeInternal(
const char* reason, const char* reason,
const YGConfigRef config, const YGConfigRef config,
YGMarkerLayoutData& layoutMarkerData, YGMarkerLayoutData& layoutMarkerData,
void* const layoutContext) { void* const layoutContext,
uint32_t depth,
const uint8_t generationCount) {
YGLayout* layout = &node->getLayout(); YGLayout* layout = &node->getLayout();
gDepth++; depth++;
const bool needToVisitNode = const bool needToVisitNode =
(node->isDirty() && layout->generationCount != gCurrentGenerationCount) || (node->isDirty() && layout->generationCount != generationCount) ||
layout->lastOwnerDirection != ownerDirection; layout->lastOwnerDirection != ownerDirection;
if (needToVisitNode) { if (needToVisitNode) {
@@ -3785,8 +3822,7 @@ bool YGLayoutNodeInternal(
if (!needToVisitNode && cachedResults != nullptr) { if (!needToVisitNode && cachedResults != nullptr) {
layout->measuredDimensions[YGDimensionWidth] = cachedResults->computedWidth; layout->measuredDimensions[YGDimensionWidth] = cachedResults->computedWidth;
layout->measuredDimensions[YGDimensionHeight] = layout->measuredDimensions[YGDimensionHeight] = cachedResults->computedHeight;
cachedResults->computedHeight;
(performLayout ? layoutMarkerData.cachedLayouts (performLayout ? layoutMarkerData.cachedLayouts
: layoutMarkerData.cachedMeasures) += 1; : layoutMarkerData.cachedMeasures) += 1;
@@ -3797,8 +3833,8 @@ bool YGLayoutNodeInternal(
YGLogLevelVerbose, YGLogLevelVerbose,
nullptr, nullptr,
"%s%d.{[skipped] ", "%s%d.{[skipped] ",
YGSpacer(gDepth), YGSpacer(depth),
gDepth); depth);
node->print(layoutContext); node->print(layoutContext);
Log::log( Log::log(
node, node,
@@ -3820,8 +3856,8 @@ bool YGLayoutNodeInternal(
YGLogLevelVerbose, YGLogLevelVerbose,
nullptr, nullptr,
"%s%d.{%s", "%s%d.{%s",
YGSpacer(gDepth), YGSpacer(depth),
gDepth, depth,
needToVisitNode ? "*" : ""); needToVisitNode ? "*" : "");
node->print(layoutContext); node->print(layoutContext);
Log::log( Log::log(
@@ -3848,7 +3884,9 @@ bool YGLayoutNodeInternal(
performLayout, performLayout,
config, config,
layoutMarkerData, layoutMarkerData,
layoutContext); layoutContext,
depth,
generationCount);
if (gPrintChanges) { if (gPrintChanges) {
Log::log( Log::log(
@@ -3856,8 +3894,8 @@ bool YGLayoutNodeInternal(
YGLogLevelVerbose, YGLogLevelVerbose,
nullptr, nullptr,
"%s%d.}%s", "%s%d.}%s",
YGSpacer(gDepth), YGSpacer(depth),
gDepth, depth,
needToVisitNode ? "*" : ""); needToVisitNode ? "*" : "");
node->print(layoutContext); node->print(layoutContext);
Log::log( Log::log(
@@ -3921,8 +3959,7 @@ bool YGLayoutNodeInternal(
node->setDirty(false); node->setDirty(false);
} }
gDepth--; layout->generationCount = generationCount;
layout->generationCount = gCurrentGenerationCount;
return (needToVisitNode || cachedResults == nullptr); return (needToVisitNode || cachedResults == nullptr);
} }
@@ -4086,7 +4123,9 @@ void YGNodeCalculateLayoutWithContext(
"initial", "initial",
node->getConfig(), node->getConfig(),
marker.data, marker.data,
layoutContext)) { layoutContext,
0, // tree root
gCurrentGenerationCount)) {
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);
@@ -4130,7 +4169,9 @@ void YGNodeCalculateLayoutWithContext(
"initial", "initial",
originalNode->getConfig(), originalNode->getConfig(),
layoutMarkerData, layoutMarkerData,
layoutContext)) { layoutContext,
0, // tree root
gCurrentGenerationCount)) {
originalNode->setPosition( originalNode->setPosition(
originalNode->getLayout().direction, originalNode->getLayout().direction,
ownerWidth, ownerWidth,