Bug 1349418 - Require ASRs to match before allow occlusions between layers. r=mstange
authorMatt Woodrow <mwoodrow@mozilla.com>
Fri, 21 Apr 2017 14:03:40 +1200
changeset 355966 d083575592841cddd154b85598934c501db9886d
parent 355965 9316ff6512163e7d08e981de7ba4dc390ca6a926
child 355967 9fa3d6e54b5b59b88e6f63496d05601e454fa7a0
push id31752
push usercbook@mozilla.com
push dateTue, 02 May 2017 09:05:11 +0000
treeherdermozilla-central@48c0fd9c9ec5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1349418
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1349418 - Require ASRs to match before allow occlusions between layers. r=mstange
layout/painting/FrameLayerBuilder.cpp
--- a/layout/painting/FrameLayerBuilder.cpp
+++ b/layout/painting/FrameLayerBuilder.cpp
@@ -1320,16 +1320,17 @@ protected:
   /**
    * Computes the snapped opaque area of aItem. Sets aList's opaque flag
    * if it covers the entire list bounds. Sets *aHideAllLayersBelow to true
    * this item covers the entire viewport so that all layers below are
    * permanently invisible.
    */
   nsIntRegion ComputeOpaqueRect(nsDisplayItem* aItem,
                                 AnimatedGeometryRoot* aAnimatedGeometryRoot,
+                                const ActiveScrolledRoot* aASR,
                                 const DisplayItemClip& aClip,
                                 nsDisplayList* aList,
                                 bool* aHideAllLayersBelow,
                                 bool* aOpaqueForAnimatedGeometryRootParent);
 
   /**
    * Return a PaintedLayerData object that is initialized for a layer that
    * aItem will be assigned to.
@@ -3770,16 +3771,17 @@ ContainerState::GetDisplayPortForAnimate
   nsIFrame* scrollFrame = do_QueryFrame(sf);
   mLastDisplayPortRect += scrollFrame->GetOffsetToCrossDoc(mContainerReferenceFrame);
   return mLastDisplayPortRect;
 }
 
 nsIntRegion
 ContainerState::ComputeOpaqueRect(nsDisplayItem* aItem,
                                   AnimatedGeometryRoot* aAnimatedGeometryRoot,
+                                  const ActiveScrolledRoot* aASR,
                                   const DisplayItemClip& aClip,
                                   nsDisplayList* aList,
                                   bool* aHideAllLayersBelow,
                                   bool* aOpaqueForAnimatedGeometryRootParent)
 {
   bool snapOpaque;
   nsRegion opaque = aItem->GetOpaqueRegion(mBuilder, &snapOpaque);
   if (opaque.IsEmpty()) {
@@ -3788,16 +3790,17 @@ ContainerState::ComputeOpaqueRect(nsDisp
 
   nsIntRegion opaquePixels;
   nsRegion opaqueClipped;
   for (auto iter = opaque.RectIter(); !iter.Done(); iter.Next()) {
     opaqueClipped.Or(opaqueClipped,
                      aClip.ApproximateIntersectInward(iter.Get()));
   }
   if (aAnimatedGeometryRoot == mContainerAnimatedGeometryRoot &&
+      aASR == mContainerASR &&
       opaqueClipped.Contains(mContainerBounds)) {
     *aHideAllLayersBelow = true;
     aList->SetIsOpaque();
   }
   // Add opaque areas to the "exclude glass" region. Only do this when our
   // container layer is going to be the rootmost layer, otherwise transforms
   // etc will mess us up (and opaque contributions from other containers are
   // not needed).
@@ -4372,17 +4375,17 @@ ContainerState::ProcessDisplayItems(nsDi
           // to avoid failure caused by singular transforms.
           newLayerEntry->mUntransformedVisibleRegion = true;
           newLayerEntry->mVisibleRegion =
             item->GetVisibleRectForChildren().ToOutsidePixels(mAppUnitsPerDevPixel);
         } else {
           newLayerEntry->mVisibleRegion = itemVisibleRegion;
         }
         newLayerEntry->mOpaqueRegion = ComputeOpaqueRect(item,
-          animatedGeometryRoot, itemClip, aList,
+          animatedGeometryRoot, itemASR, itemClip, aList,
           &newLayerEntry->mHideAllLayersBelow,
           &newLayerEntry->mOpaqueForAnimatedGeometryRootParent);
       } else {
         bool useChildrenVisible =
           itemType == nsDisplayItem::TYPE_TRANSFORM &&
           (item->Frame()->IsPreserve3DLeaf() ||
            item->Frame()->HasPerspective());
         const nsIntRegion &visible = useChildrenVisible ?
@@ -4428,17 +4431,17 @@ ContainerState::ProcessDisplayItems(nsDi
         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, itemClip, aList,
+            animatedGeometryRoot, itemASR, itemClip, aList,
             &paintedLayerData->mHideAllLayersBelow,
             &paintedLayerData->mOpaqueForAnimatedGeometryRootParent);
         MOZ_ASSERT(nsIntRegion(itemDrawRect).Contains(opaquePixels));
         opaquePixels.AndWith(itemVisibleRect);
         paintedLayerData->Accumulate(this, item, opaquePixels,
             itemVisibleRect, itemClip, layerState);
 
         if (!paintedLayerData->mLayer) {
@@ -4911,26 +4914,29 @@ ContainerState::CollectOldLayers()
                    "Could not recycle mask layer, unsupported layer type.");
       mRecycledMaskImageLayers.Put(MaskLayerKey(layer, Some(i)), static_cast<ImageLayer*>(maskLayer));
     }
   }
 }
 
 struct OpaqueRegionEntry {
   AnimatedGeometryRoot* mAnimatedGeometryRoot;
+  const ActiveScrolledRoot* mASR;
   nsIntRegion mOpaqueRegion;
 };
 
 static OpaqueRegionEntry*
 FindOpaqueRegionEntry(nsTArray<OpaqueRegionEntry>& aEntries,
-                      AnimatedGeometryRoot* aAnimatedGeometryRoot)
+                      AnimatedGeometryRoot* aAnimatedGeometryRoot,
+                      const ActiveScrolledRoot* aASR)
 {
   for (uint32_t i = 0; i < aEntries.Length(); ++i) {
     OpaqueRegionEntry* d = &aEntries[i];
-    if (d->mAnimatedGeometryRoot == aAnimatedGeometryRoot) {
+    if (d->mAnimatedGeometryRoot == aAnimatedGeometryRoot &&
+        d->mASR == aASR) {
       return d;
     }
   }
   return nullptr;
 }
 
 const ActiveScrolledRoot*
 FindDirectChildASR(const ActiveScrolledRoot* aParent, const ActiveScrolledRoot* aDescendant)
@@ -5150,17 +5156,17 @@ ContainerState::PostprocessRetainedLayer
   int32_t opaqueRegionForContainer = -1;
 
   for (int32_t i = mNewChildLayers.Length() - 1; i >= 0; --i) {
     NewLayerEntry* e = &mNewChildLayers.ElementAt(i);
     if (!e->mLayer) {
       continue;
     }
 
-    OpaqueRegionEntry* data = FindOpaqueRegionEntry(opaqueRegions, e->mAnimatedGeometryRoot);
+    OpaqueRegionEntry* data = FindOpaqueRegionEntry(opaqueRegions, e->mAnimatedGeometryRoot, e->mASR);
 
     SetupScrollingMetadata(e);
 
     if (hideAll) {
       e->mVisibleRegion.SetEmpty();
     } else if (!e->mLayer->IsScrollbarContainer()) {
       Maybe<ParentLayerIntRect> clipRect = GetStationaryClipInContainer(e->mLayer);
       if (clipRect && opaqueRegionForContainer >= 0 &&
@@ -5173,29 +5179,33 @@ ContainerState::PostprocessRetainedLayer
 
     SetOuterVisibleRegionForLayer(e->mLayer,
                                   e->mVisibleRegion,
                                   e->mLayerContentsVisibleRect.width >= 0 ? &e->mLayerContentsVisibleRect : nullptr,
                                   e->mUntransformedVisibleRegion);
 
     if (!e->mOpaqueRegion.IsEmpty()) {
       AnimatedGeometryRoot* animatedGeometryRootToCover = e->mAnimatedGeometryRoot;
+      const ActiveScrolledRoot* asrToCover = e->mASR;
       if (e->mOpaqueForAnimatedGeometryRootParent &&
           e->mAnimatedGeometryRoot->mParentAGR == mContainerAnimatedGeometryRoot) {
         animatedGeometryRootToCover = mContainerAnimatedGeometryRoot;
-        data = FindOpaqueRegionEntry(opaqueRegions, animatedGeometryRootToCover);
+        asrToCover = mContainerASR;
+        data = FindOpaqueRegionEntry(opaqueRegions, animatedGeometryRootToCover, asrToCover);
       }
 
       if (!data) {
-        if (animatedGeometryRootToCover == mContainerAnimatedGeometryRoot) {
+        if (animatedGeometryRootToCover == mContainerAnimatedGeometryRoot &&
+            asrToCover == mContainerASR) {
           NS_ASSERTION(opaqueRegionForContainer == -1, "Already found it?");
           opaqueRegionForContainer = opaqueRegions.Length();
         }
         data = opaqueRegions.AppendElement();
         data->mAnimatedGeometryRoot = animatedGeometryRootToCover;
+        data->mASR = asrToCover;
       }
 
       nsIntRegion clippedOpaque = e->mOpaqueRegion;
       Maybe<ParentLayerIntRect> clipRect = e->mLayer->GetCombinedClipRect();
       if (clipRect) {
         clippedOpaque.AndWith(clipRect->ToUnknownRect());
       }
       if (e->mLayer->GetScrolledClip()) {