From 00a0343a6db5810311f302fbf09504bc968c695f Mon Sep 17 00:00:00 2001 From: Emil Sjolander Date: Fri, 28 Apr 2017 03:57:13 -0700 Subject: [PATCH] Revert D4957570: [yoga] Consolidate measure cache for layout nodes and leaf nodes Differential Revision: D4957570 fbshipit-source-id: 4d30de37c6911aac2dc1243a54914515aabfb229 --- ReactCommon/yoga/yoga/Yoga.c | 96 +++++++++++++++++++++++------------- 1 file changed, 61 insertions(+), 35 deletions(-) diff --git a/ReactCommon/yoga/yoga/Yoga.c b/ReactCommon/yoga/yoga/Yoga.c index 085e04e4a..2ec842875 100644 --- a/ReactCommon/yoga/yoga/Yoga.c +++ b/ReactCommon/yoga/yoga/Yoga.c @@ -3116,45 +3116,71 @@ bool YGLayoutNodeInternal(const YGNodeRef node, layout->cachedLayout.computedHeight = -1; } + YGCachedMeasurement *cachedResults = NULL; + // Determine whether the results are already cached. We maintain a separate // cache for layouts and measurements. A layout operation modifies the - // positions 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 - // measurements may be required to resolve all of the flex dimensions. + // positions + // 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 + // 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); - YGCachedMeasurement *cachedResults = NULL; - const float marginAxisRow = YGNodeMarginForAxis(node, YGFlexDirectionRow, parentWidth); - const float marginAxisColumn = YGNodeMarginForAxis(node, YGFlexDirectionColumn, parentWidth); - - // First, try to use the layout cache. - if ((node->measure || performLayout) && YGNodeCanUseCachedMeasurement(widthMeasureMode, - availableWidth, - heightMeasureMode, - availableHeight, - layout->cachedLayout.widthMeasureMode, - layout->cachedLayout.availableWidth, - layout->cachedLayout.heightMeasureMode, - layout->cachedLayout.availableHeight, - layout->cachedLayout.computedWidth, - layout->cachedLayout.computedHeight, - marginAxisRow, - marginAxisColumn)) { - cachedResults = &layout->cachedLayout; - } else if (node->measure || !performLayout) { - // Try to use the measurement cache. + // First, try to use the layout cache. + if (YGNodeCanUseCachedMeasurement(widthMeasureMode, + availableWidth, + heightMeasureMode, + availableHeight, + layout->cachedLayout.widthMeasureMode, + layout->cachedLayout.availableWidth, + layout->cachedLayout.heightMeasureMode, + layout->cachedLayout.availableHeight, + layout->cachedLayout.computedWidth, + layout->cachedLayout.computedHeight, + marginAxisRow, + marginAxisColumn)) { + cachedResults = &layout->cachedLayout; + } else { + // Try to use the measurement cache. + for (uint32_t i = 0; i < layout->nextCachedMeasurementsIndex; i++) { + if (YGNodeCanUseCachedMeasurement(widthMeasureMode, + availableWidth, + 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]; + 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++) { - if (YGNodeCanUseCachedMeasurement(widthMeasureMode, - availableWidth, - 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)) { + if (YGFloatsEqual(layout->cachedMeasurements[i].availableWidth, availableWidth) && + YGFloatsEqual(layout->cachedMeasurements[i].availableHeight, availableHeight) && + layout->cachedMeasurements[i].widthMeasureMode == widthMeasureMode && + layout->cachedMeasurements[i].heightMeasureMode == heightMeasureMode) { cachedResults = &layout->cachedMeasurements[i]; break; }