Bug 1336708: Key the cached reflow in the computed height of the input too. r?dholbert draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Mon, 06 Feb 2017 13:06:57 +0100
changeset 479438 5b75ae1f74ae7c0f44fc51e12b5cbcb7fe53bf62
parent 479141 20a8536b0bfac74389d3a57bd8dd957d98779ce1
child 479439 7cfe14c45cbf17781d59fc520e602f00b664fbf1
push id44258
push userbmo:emilio+bugs@crisal.io
push dateMon, 06 Feb 2017 17:59:18 +0000
reviewersdholbert
bugs1336708
milestone54.0a1
Bug 1336708: Key the cached reflow in the computed height of the input too. r?dholbert For some stretched items, we override the computed height of the input for measuring reflows, which may change the ascent and height result. Just use that as a key for the reflow result cache too. MozReview-Commit-ID: 9NyObfVucnC
layout/generic/nsFlexContainerFrame.cpp
--- a/layout/generic/nsFlexContainerFrame.cpp
+++ b/layout/generic/nsFlexContainerFrame.cpp
@@ -1782,41 +1782,46 @@ nsFlexContainerFrame::
  * Caching it prevents us from doing exponential reflows in cases of deeply
  * nested flex and scroll frames.
  *
  * We store them in the frame property table for simplicity.
  */
 struct nsFlexContainerFrame::CachedMeasuringReflowResult
 {
   LogicalSize mAvailableSize;
+  const nscoord mComputedHeight;
   const nscoord mHeight;
   const nscoord mAscent;
 
   CachedMeasuringReflowResult(const LogicalSize& aAvailableSize,
+                              nscoord aComputedHeight,
                               nscoord aHeight,
                               nscoord aAscent)
     : mAvailableSize(aAvailableSize)
+    , mComputedHeight(aComputedHeight)
     , mHeight(aHeight)
     , mAscent(aAscent)
   {}
 };
 
 NS_DECLARE_FRAME_PROPERTY_DELETABLE(CachedFlexMeasuringReflow,
                                     CachedMeasuringReflowResult);
 
 const CachedMeasuringReflowResult&
 nsFlexContainerFrame::MeasureAscentAndHeightForFlexItem(
   FlexItem& aItem,
   nsPresContext* aPresContext,
   ReflowInput& aChildReflowInput)
 {
   const auto availableSize = aChildReflowInput.AvailableSize();
   const FrameProperties props = aItem.Frame()->Properties();
+  const nscoord computedHeight = aChildReflowInput.ComputedHeight();
   if (const auto* cachedResult = props.Get(CachedFlexMeasuringReflow())) {
-    if (cachedResult->mAvailableSize == availableSize) {
+    if (cachedResult->mAvailableSize == availableSize &&
+        cachedResult->mComputedHeight == computedHeight) {
       return *cachedResult;
     }
   }
 
   ReflowOutput childDesiredSize(aChildReflowInput);
   nsReflowStatus childReflowStatus;
 
   const uint32_t flags = NS_FRAME_NO_MOVE_FRAME;
@@ -1834,16 +1839,17 @@ nsFlexContainerFrame::MeasureAscentAndHe
 
   // Tell the child we're done with its initial reflow.
   // (Necessary for e.g. GetBaseline() to work below w/out asserting)
   FinishReflowChild(aItem.Frame(), aPresContext,
                     childDesiredSize, &aChildReflowInput, 0, 0, flags);
 
   auto result =
     new CachedMeasuringReflowResult(availableSize,
+                                    computedHeight,
                                     childDesiredSize.Height(),
                                     childDesiredSize.BlockStartAscent());
 
   props.Set(CachedFlexMeasuringReflow(), result);
   return *result;
 }
 
 /* virtual */ void