Bug 1200158 - Avoid expensive region computations in FindPaintedLayerFor(). r=mstange draft
authorBotond Ballo <botond@mozilla.com>
Mon, 31 Aug 2015 19:53:34 -0400
changeset 289350 6c2d9bded9ed02d9078fceb0de46d2d8ab358338
parent 289349 942cc40b8d933b95d2540c8858342a8e7be2180e
child 508887 0c3a25d1fe9fc3856503090d071b8baf22dff2e2
push id4971
push userbballo@mozilla.com
push dateTue, 01 Sep 2015 00:29:28 +0000
reviewersmstange
bugs1200158
milestone43.0a1
Bug 1200158 - Avoid expensive region computations in FindPaintedLayerFor(). r=mstange
layout/base/FrameLayerBuilder.cpp
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -416,17 +416,17 @@ public:
                   const DisplayItemClip& aClip,
                   LayerState aLayerState);
   const nsIFrame* GetAnimatedGeometryRoot() { return mAnimatedGeometryRoot; }
 
   /**
    * Add the given hit regions to the hit regions to the hit retions for this
    * PaintedLayer.
    */
-  void AccumulateEventRegions(nsDisplayLayerEventRegions* aEventRegions);
+  void AccumulateEventRegions(ContainerState* aState, nsDisplayLayerEventRegions* aEventRegions);
 
   /**
    * If this represents only a nsDisplayImage, and the image type supports being
    * optimized to an ImageLayer, returns true.
    */
   bool CanOptimizeToImageLayer(nsDisplayListBuilder* aBuilder);
 
   /**
@@ -481,16 +481,24 @@ public:
   /**
    * The region for this PaintedLayer that is sensitive to events and
    * allows vertical panning but not zooming. This is an approximation
    * and any deviation from the true region will be part of the
    * mDispatchToContentHitRegion.
    */
   nsRegion mVerticalPanRegion;
   /**
+   * Scaled versions of mHitRegion and mMaybeHitRegion.
+   * We store these because FindPaintedLayerFor() needs to consume them
+   * in this form, and it's a hot code path so we don't wnat to scale
+   * them inside that function.
+   */
+  nsIntRegion mScaledHitRegion;
+  nsIntRegion mScaledMaybeHitRegion;
+  /**
    * The "active scrolled root" for all content in the layer. Must
    * be non-null; all content in a PaintedLayer must have the same
    * active scrolled root.
    */
   const nsIFrame* mAnimatedGeometryRoot;
   /**
    * The offset between mAnimatedGeometryRoot and the reference frame.
    */
@@ -2583,18 +2591,18 @@ PaintedLayerDataNode::FindPaintedLayerFo
         lowestUsableLayer = &data;
         nsIntRegion visibleRegion = data.mVisibleRegion;
         // When checking whether the visible region intersects the given
         // visible rect, also include the event-regions in the visible region,
         // unless we're in an inactive layer, in which case the event-regions
         // will be hoisted out into their own layer.
         ContainerState& contState = mTree.ContState();
         if (!contState.IsInInactiveLayer()) {
-          visibleRegion.OrWith(contState.ScaleRegionToOutsidePixels(data.mHitRegion));
-          visibleRegion.OrWith(contState.ScaleRegionToOutsidePixels(data.mMaybeHitRegion));
+          visibleRegion.OrWith(data.mScaledHitRegion);
+          visibleRegion.OrWith(data.mScaledMaybeHitRegion);
         }
         if (visibleRegion.Intersects(aVisibleRect)) {
           break;
         }
       }
       if (lowestUsableLayer) {
         return lowestUsableLayer;
       }
@@ -3424,26 +3432,35 @@ PaintedLayerData::Accumulate(ContainerSt
   if (aState->mParameters.mInActiveTransformedSubtree &&
        (mNeedComponentAlpha ||
          !aItem->GetComponentAlphaBounds(aState->mBuilder).IsEmpty())) {
     mDisableFlattening = true;
   }
 }
 
 void
-PaintedLayerData::AccumulateEventRegions(nsDisplayLayerEventRegions* aEventRegions)
+PaintedLayerData::AccumulateEventRegions(ContainerState* aState, nsDisplayLayerEventRegions* aEventRegions)
 {
   FLB_LOG_PAINTED_LAYER_DECISION(this, "Accumulating event regions %p against pld=%p\n", aEventRegions, this);
 
   mHitRegion.Or(mHitRegion, aEventRegions->HitRegion());
   mMaybeHitRegion.Or(mMaybeHitRegion, aEventRegions->MaybeHitRegion());
   mDispatchToContentHitRegion.Or(mDispatchToContentHitRegion, aEventRegions->DispatchToContentHitRegion());
   mNoActionRegion.Or(mNoActionRegion, aEventRegions->NoActionRegion());
   mHorizontalPanRegion.Or(mHorizontalPanRegion, aEventRegions->HorizontalPanRegion());
   mVerticalPanRegion.Or(mVerticalPanRegion, aEventRegions->VerticalPanRegion());
+
+  // Calculate scaled versions of mHitRegion and mMaybeHitRegion for quick
+  // access in FindPaintedLayerFor().
+  mScaledHitRegion = aState->ScaleRegionToOutsidePixels(mHitRegion);
+  mScaledMaybeHitRegion = aState->ScaleRegionToOutsidePixels(mMaybeHitRegion);
+
+  // Simplify mScaledMaybeHitRegion because it can be a complex region
+  // and it's used in hot code paths such as FindPaintedLayerFor().
+  mScaledMaybeHitRegion.SimplifyOutward(8);
 }
 
 PaintedLayerData
 ContainerState::NewPaintedLayerData(nsDisplayItem* aItem,
                                     const nsIntRect& aVisibleRect,
                                     const nsIFrame* aAnimatedGeometryRoot,
                                     const nsPoint& aTopLeft,
                                     bool aShouldFixToViewport)
@@ -4010,17 +4027,17 @@ ContainerState::ProcessDisplayItems(nsDi
                                                   forceOwnLayer, [&]() {
           return NewPaintedLayerData(item, itemVisibleRect, animatedGeometryRoot,
                                      topLeft, shouldFixToViewport);
         });
 
       if (itemType == nsDisplayItem::TYPE_LAYER_EVENT_REGIONS) {
         nsDisplayLayerEventRegions* eventRegions =
             static_cast<nsDisplayLayerEventRegions*>(item);
-        paintedLayerData->AccumulateEventRegions(eventRegions);
+        paintedLayerData->AccumulateEventRegions(this, eventRegions);
       } else {
         // check to see if the new item has rounded rect clips in common with
         // other items in the layer
         if (mManager->IsWidgetLayerManager()) {
           paintedLayerData->UpdateCommonClipCount(itemClip);
         }
         nsIntRegion opaquePixels = ComputeOpaqueRect(item,
             animatedGeometryRoot, paintedLayerData->mFixedPosFrameForLayerData,