Consolidate measure cache for layout nodes and leaf nodes

Reviewed By: astreet

Differential Revision: D4957570

fbshipit-source-id: 5c5f39b67bd3f72d92b939ecee2d9a46c80b583f
This commit is contained in:
Emil Sjolander 2017-04-27 13:02:55 -07:00 committed by Facebook Github Bot
parent 39f9e7a6b1
commit 6272ef87bc
1 changed files with 35 additions and 61 deletions

View File

@ -3116,71 +3116,45 @@ bool YGLayoutNodeInternal(const YGNodeRef node,
layout->cachedLayout.computedHeight = -1; layout->cachedLayout.computedHeight = -1;
} }
YGCachedMeasurement *cachedResults = NULL;
// Determine whether the results are already cached. We maintain a separate // Determine whether the results are already cached. We maintain a separate
// cache for layouts and measurements. A layout operation modifies the // cache for layouts and measurements. A layout operation modifies the
// positions // positions and dimensions for nodes in the subtree. The algorithm assumes that each
// and dimensions for nodes in the subtree. The algorithm assumes that each // node gets layed out a maximum of one time per tree layout, but multiple
// node // measurements may be required to resolve all of the flex dimensions.
// gets layed out a maximum of one time per tree layout, but multiple
// measurements
// may be required to resolve all of the flex dimensions.
// We handle nodes with measure functions specially here because they are the
// most
// expensive to measure, so it's worth avoiding redundant measurements if at
// all possible.
if (node->measure) {
const float marginAxisRow = YGNodeMarginForAxis(node, YGFlexDirectionRow, parentWidth);
const float marginAxisColumn = YGNodeMarginForAxis(node, YGFlexDirectionColumn, parentWidth);
// First, try to use the layout cache. YGCachedMeasurement *cachedResults = NULL;
if (YGNodeCanUseCachedMeasurement(widthMeasureMode, const float marginAxisRow = YGNodeMarginForAxis(node, YGFlexDirectionRow, parentWidth);
availableWidth, const float marginAxisColumn = YGNodeMarginForAxis(node, YGFlexDirectionColumn, parentWidth);
heightMeasureMode,
availableHeight, // First, try to use the layout cache.
layout->cachedLayout.widthMeasureMode, if ((node->measure || performLayout) && YGNodeCanUseCachedMeasurement(widthMeasureMode,
layout->cachedLayout.availableWidth, availableWidth,
layout->cachedLayout.heightMeasureMode, heightMeasureMode,
layout->cachedLayout.availableHeight, availableHeight,
layout->cachedLayout.computedWidth, layout->cachedLayout.widthMeasureMode,
layout->cachedLayout.computedHeight, layout->cachedLayout.availableWidth,
marginAxisRow, layout->cachedLayout.heightMeasureMode,
marginAxisColumn)) { layout->cachedLayout.availableHeight,
cachedResults = &layout->cachedLayout; layout->cachedLayout.computedWidth,
} else { layout->cachedLayout.computedHeight,
// Try to use the measurement cache. marginAxisRow,
for (uint32_t i = 0; i < layout->nextCachedMeasurementsIndex; i++) { marginAxisColumn)) {
if (YGNodeCanUseCachedMeasurement(widthMeasureMode, cachedResults = &layout->cachedLayout;
availableWidth, } else if (node->measure || !performLayout) {
heightMeasureMode, // Try to use the measurement cache.
availableHeight,
layout->cachedMeasurements[i].widthMeasureMode,
layout->cachedMeasurements[i].availableWidth,
layout->cachedMeasurements[i].heightMeasureMode,
layout->cachedMeasurements[i].availableHeight,
layout->cachedMeasurements[i].computedWidth,
layout->cachedMeasurements[i].computedHeight,
marginAxisRow,
marginAxisColumn)) {
cachedResults = &layout->cachedMeasurements[i];
break;
}
}
}
} else if (performLayout) {
if (YGFloatsEqual(layout->cachedLayout.availableWidth, availableWidth) &&
YGFloatsEqual(layout->cachedLayout.availableHeight, availableHeight) &&
layout->cachedLayout.widthMeasureMode == widthMeasureMode &&
layout->cachedLayout.heightMeasureMode == heightMeasureMode) {
cachedResults = &layout->cachedLayout;
}
} else {
for (uint32_t i = 0; i < layout->nextCachedMeasurementsIndex; i++) { for (uint32_t i = 0; i < layout->nextCachedMeasurementsIndex; i++) {
if (YGFloatsEqual(layout->cachedMeasurements[i].availableWidth, availableWidth) && if (YGNodeCanUseCachedMeasurement(widthMeasureMode,
YGFloatsEqual(layout->cachedMeasurements[i].availableHeight, availableHeight) && availableWidth,
layout->cachedMeasurements[i].widthMeasureMode == widthMeasureMode && heightMeasureMode,
layout->cachedMeasurements[i].heightMeasureMode == heightMeasureMode) { availableHeight,
layout->cachedMeasurements[i].widthMeasureMode,
layout->cachedMeasurements[i].availableWidth,
layout->cachedMeasurements[i].heightMeasureMode,
layout->cachedMeasurements[i].availableHeight,
layout->cachedMeasurements[i].computedWidth,
layout->cachedMeasurements[i].computedHeight,
marginAxisRow,
marginAxisColumn)) {
cachedResults = &layout->cachedMeasurements[i]; cachedResults = &layout->cachedMeasurements[i];
break; break;
} }