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 hadOverflow : 1;
uint32_t computedFlexBasisGeneration = 0;
uint8_t computedFlexBasisGeneration = 0;
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
// information to break early when nothing changed
uint32_t generationCount = 0;
uint8_t generationCount = 0;
YGDirection lastOwnerDirection = (YGDirection) -1;
uint32_t nextCachedMeasurementsIndex = 0;

View File

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

View File

@@ -316,7 +316,7 @@ public:
void setLayoutLastOwnerDirection(YGDirection direction);
void setLayoutComputedFlexBasis(const YGFloatOptional computedFlexBasis);
void setLayoutComputedFlexBasisGeneration(
uint32_t computedFlexBasisGeneration);
uint8_t computedFlexBasisGeneration);
void setLayoutMeasuredDimension(float measuredDimension, int index);
void setLayoutHadOverflow(bool hadOverflow);
void setLayoutDimension(float dimension, int index);

View File

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