Bug 713523. Part 2: Add SimplifyOutward for mVisibleAboveRegion and mDrawAboveRegion to avoid performance sinkholes when many layers are above a single ThebesLayer. r=tn
authorRobert O'Callahan <robert@ocallahan.org>
Thu, 12 Jan 2012 00:26:33 +1300
changeset 85489 27cc07ec8b88109297434a041853a0c95be3e225
parent 85488 2ddeb63ac2d99ec9120c4e2c7893279ea7cbb1f4
child 85490 7c9a9e02b08cd8f754052d84b3f9fb1db860bedc
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstn
bugs713523
milestone12.0a1
Bug 713523. Part 2: Add SimplifyOutward for mVisibleAboveRegion and mDrawAboveRegion to avoid performance sinkholes when many layers are above a single ThebesLayer. r=tn
layout/base/FrameLayerBuilder.cpp
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -227,22 +227,24 @@ protected:
      * list reference frame).
      */
     nsIntRegion  mVisibleRegion;
     /**
      * The region of visible content above the layer and below the
      * next ThebesLayerData currently in the stack, if any. Note that not
      * all ThebesLayers for the container are in the ThebesLayerData stack.
      * Same coordinate system as mVisibleRegion.
+     * This is a conservative approximation: it contains the true region.
      */
     nsIntRegion  mVisibleAboveRegion;
     /**
      * The region containing the bounds of all display items in the layer,
      * regardless of visbility.
      * Same coordinate system as mVisibleRegion.
+     * This is a conservative approximation: it contains the true region.
      */
     nsIntRegion  mDrawRegion;
     /**
      * The region containing the bounds of all display items (regardless
      * of visibility) in the layer and below the next ThebesLayerData
      * currently in the stack, if any.
      * Note that not all ThebesLayers for the container are in the
      * ThebesLayerData stack.
@@ -1100,20 +1102,22 @@ ContainerState::PopThebesLayerData()
     // Since we're going to pop off the last ThebesLayerData, the
     // mVisibleAboveRegion of the second-to-last item will need to include
     // the regions of the last item.
     ThebesLayerData* nextData = mThebesLayerDataStack[lastIndex - 1];
     nextData->mVisibleAboveRegion.Or(nextData->mVisibleAboveRegion,
                                      data->mVisibleAboveRegion);
     nextData->mVisibleAboveRegion.Or(nextData->mVisibleAboveRegion,
                                      data->mVisibleRegion);
+    nextData->mVisibleAboveRegion.SimplifyOutward(4);
     nextData->mDrawAboveRegion.Or(nextData->mDrawAboveRegion,
                                      data->mDrawAboveRegion);
     nextData->mDrawAboveRegion.Or(nextData->mDrawAboveRegion,
                                      data->mDrawRegion);
+    nextData->mDrawAboveRegion.SimplifyOutward(4);
   }
 
   mThebesLayerDataStack.RemoveElementAt(lastIndex);
 }
 
 static bool
 SuppressComponentAlpha(nsDisplayListBuilder* aBuilder,
                        nsDisplayItem* aItem,
@@ -1435,21 +1439,23 @@ ContainerState::ProcessDisplayItems(cons
       if (aClip.mHaveClipRect) {
         ownLayer->IntersectClipRect(
             aClip.mClipRect.ScaleToNearestPixels(
                 mParameters.mXScale, mParameters.mYScale, appUnitsPerDevPixel));
       }
       ThebesLayerData* data = GetTopThebesLayerData();
       if (data) {
         data->mVisibleAboveRegion.Or(data->mVisibleAboveRegion, itemVisibleRect);
+        data->mVisibleAboveRegion.SimplifyOutward(4);
         // Add the entire bounds rect to the mDrawAboveRegion.
         // The visible region may be excluding opaque content above the
         // item, and we need to ensure that that content is not placed
         // in a ThebesLayer below the item!
         data->mDrawAboveRegion.Or(data->mDrawAboveRegion, itemDrawRect);
+        data->mDrawAboveRegion.SimplifyOutward(4);
       }
       RestrictVisibleRegionForLayer(ownLayer, itemVisibleRect);
       ContainerLayer* oldContainer = ownLayer->GetParent();
       if (oldContainer && oldContainer != mContainerLayer) {
         oldContainer->RemoveChild(ownLayer);
       }
       NS_ASSERTION(!mNewChildLayers.Contains(ownLayer),
                    "Layer already in list???");