Bug 1287075 - Back out bug 1273250, part 4 for regressing the rendering of the Australis submenus. r=mstange draft
authorBotond Ballo <botond@mozilla.com>
Wed, 03 Aug 2016 13:48:10 -0400
changeset 396391 ff3a2c7d9025e3edc310b4c289a6149eb9d1b8d5
parent 394512 859eb50fc1bc471f34f26e17cd9128690ac7bf87
child 527193 2ea40eee92e9e20f406565b2475b3b9fb43c1e83
push id24990
push userbballo@mozilla.com
push dateWed, 03 Aug 2016 20:08:44 +0000
reviewersmstange
bugs1287075, 1273250
milestone50.0a1
Bug 1287075 - Back out bug 1273250, part 4 for regressing the rendering of the Australis submenus. r=mstange MozReview-Commit-ID: 1m8lVoIX3qT
layout/base/FrameLayerBuilder.cpp
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -417,17 +417,17 @@ public:
   PaintedLayerData() :
     mAnimatedGeometryRoot(nullptr),
     mScrollClip(nullptr),
     mReferenceFrame(nullptr),
     mLayer(nullptr),
     mSolidColor(NS_RGBA(0, 0, 0, 0)),
     mIsSolidColorInVisibleRegion(false),
     mFontSmoothingBackgroundColor(NS_RGBA(0,0,0,0)),
-    mClipMovesWithLayer(true),
+    mSingleItemFixedToViewport(false),
     mIsCaret(false),
     mNeedComponentAlpha(false),
     mForceTransparentSurface(false),
     mHideAllLayersBelow(false),
     mOpaqueForAnimatedGeometryRootParent(false),
     mDisableFlattening(false),
     mBackfaceHidden(false),
     mImage(nullptr),
@@ -577,20 +577,20 @@ public:
    */
   bool mIsSolidColorInVisibleRegion;
   /**
    * The target background color for smoothing fonts that are drawn on top of
    * transparent parts of the layer.
    */
   nscolor mFontSmoothingBackgroundColor;
   /**
-   * True unless the layer contains exactly one item whose clip scrolls
-   * relative to the layer rather than moving with the layer.
+   * True if the layer contains exactly one item that returned true for
+   * ShouldFixToViewport.
    */
-  bool mClipMovesWithLayer;
+  bool mSingleItemFixedToViewport;
   /**
    * True if the layer contains exactly one item for the caret.
    */
   bool mIsCaret;
   /**
    * True if there is any text visible in the layer that's over
    * transparent pixels in the layer.
    */
@@ -3101,17 +3101,17 @@ void ContainerState::FinishPaintedLayerD
     FLB_LOG_PAINTED_LAYER_DECISION(data, "  Selected painted layer=%p\n", layer.get());
   }
 
   // If the layer is a fixed background layer, the clip on the fixed background
   // display item was not applied to the opaque region in
   // ContainerState::ComputeOpaqueRect(), but was saved in data->mItemClip.
   // Apply it to the opaque region now. Note that it's important to do this
   // before the opaque region is propagated to the NewLayerEntry below.
-  if (!data->mClipMovesWithLayer && data->mItemClip.HasClip()) {
+  if (data->mSingleItemFixedToViewport && data->mItemClip.HasClip()) {
     nsRect clipRect = data->mItemClip.GetClipRect();
     nsRect insideRoundedCorners = data->mItemClip.ApproximateIntersectInward(clipRect);
     nsIntRect insideRoundedCornersScaled = ScaleToInsidePixels(insideRoundedCorners);
     data->mOpaqueRegion.AndWith(insideRoundedCornersScaled);
   }
 
   if (mLayerBuilder->IsBuildingRetainedLayers()) {
     newLayerEntry->mVisibleRegion = data->mVisibleRegion;
@@ -3175,17 +3175,17 @@ void ContainerState::FinishPaintedLayerD
 
     // use a mask layer for rounded rect clipping.
     // data->mCommonClipCount may be -1 if we haven't put any actual
     // drawable items in this layer (i.e. it's only catching events).
     int32_t commonClipCount;
     // If the layer contains a single item fixed to the viewport, we removed
     // its clip in ProcessDisplayItems() and saved it to set on the layer instead.
     // Set the clip on the layer now.
-    if (!data->mClipMovesWithLayer && data->mItemClip.HasClip()) {
+    if (data->mSingleItemFixedToViewport && data->mItemClip.HasClip()) {
       nsIntRect layerClipRect = ScaleToNearestPixels(data->mItemClip.GetClipRect());
       layerClipRect.MoveBy(mParameters.mOffset);
       // The clip from such an item becomes part of the layer's scrolled clip,
       // and the associated mask layer one of the layer's "ancestor mask layers".
       LayerClip scrolledClip;
       scrolledClip.SetClipRect(ViewAs<ParentLayerPixel>(layerClipRect));
       scrolledClip.SetMaskLayerIndex(
           SetupMaskLayerForScrolledClip(data->mLayer, data->mItemClip));
@@ -3517,24 +3517,24 @@ PaintedLayerData::AccumulateEventRegions
   mScaledMaybeHitRegionBounds = aState->ScaleToOutsidePixels(mMaybeHitRegion.GetBounds());
 }
 
 PaintedLayerData
 ContainerState::NewPaintedLayerData(nsDisplayItem* aItem,
                                     AnimatedGeometryRoot* aAnimatedGeometryRoot,
                                     const DisplayItemScrollClip* aScrollClip,
                                     const nsPoint& aTopLeft,
-                                    bool aClipMovesWithLayer)
+                                    bool aShouldFixToViewport)
 {
   PaintedLayerData data;
   data.mAnimatedGeometryRoot = aAnimatedGeometryRoot;
   data.mScrollClip = aScrollClip;
   data.mAnimatedGeometryRootOffset = aTopLeft;
   data.mReferenceFrame = aItem->ReferenceFrame();
-  data.mClipMovesWithLayer = aClipMovesWithLayer;
+  data.mSingleItemFixedToViewport = aShouldFixToViewport;
   data.mBackfaceHidden = aItem->Frame()->In3DContextAndBackfaceIsHidden();
   data.mIsCaret = aItem->GetType() == nsDisplayItem::TYPE_CARET;
 
   data.mNewChildLayersIndex = mNewChildLayers.Length();
   NewLayerEntry* newLayerEntry = mNewChildLayers.AppendElement();
   newLayerEntry->mAnimatedGeometryRoot = aAnimatedGeometryRoot;
   newLayerEntry->mScrollClip = aScrollClip;
   newLayerEntry->mIsCaret = data.mIsCaret;
@@ -3881,23 +3881,27 @@ ContainerState::ProcessDisplayItems(nsDi
           clip.IntersectWith(*scrollClip->mClip);
         }
       }
       item->SetClip(mBuilder, clip);
     }
 
     bool clipMovesWithLayer = (animatedGeometryRoot == animatedGeometryRootForClip);
 
-    // For items whose clip scrolls relative to the layer rather than moving
-    // with the layer, remove their clip at the display item level because
-    // additional areas could be brought into view by async scrolling.
-    // Save the clip so we can set it on the layer instead later.
-    DisplayItemClip scrollingClip = DisplayItemClip::NoClip();
-    if (!clipMovesWithLayer) {
-      scrollingClip = item->GetClip();
+    bool shouldFixToViewport = !clipMovesWithLayer &&
+        !(*animatedGeometryRoot)->GetParent() &&
+        item->ShouldFixToViewport(mBuilder);
+
+    // For items that are fixed to the viewport, remove their clip at the
+    // display item level because additional areas could be brought into
+    // view by async scrolling. Save the clip so we can set it on the layer
+    // instead later.
+    DisplayItemClip fixedToViewportClip = DisplayItemClip::NoClip();
+    if (shouldFixToViewport) {
+      fixedToViewportClip = item->GetClip();
       item->SetClip(mBuilder, DisplayItemClip::NoClip());
     }
 
     bool snap;
     nsRect itemContent = item->GetBounds(mBuilder, &snap);
     if (itemType == nsDisplayItem::TYPE_LAYER_EVENT_REGIONS) {
       nsDisplayLayerEventRegions* eventRegions =
         static_cast<nsDisplayLayerEventRegions*>(item);
@@ -3920,17 +3924,17 @@ ContainerState::ProcessDisplayItems(nsDi
     nsRect bounds = itemContent;
     bool dummy;
     if (itemType == nsDisplayItem::TYPE_LAYER_EVENT_REGIONS) {
       bounds = item->GetBounds(mBuilder, &dummy);
       if (itemClip.HasClip()) {
         bounds.IntersectRect(bounds, itemClip.GetClipRect());
       }
     }
-    bounds = scrollingClip.ApplyNonRoundedIntersection(bounds);
+    bounds = fixedToViewportClip.ApplyNonRoundedIntersection(bounds);
     if (!bounds.IsEmpty()) {
       for (const DisplayItemScrollClip* scrollClip = itemScrollClip;
            scrollClip && scrollClip != mContainerScrollClip;
            scrollClip = scrollClip->mParent) {
         if (scrollClip->mClip) {
           if (scrollClip->mIsAsyncScrollable) {
             bounds = scrollClip->mClip->GetClipRect();
           } else {
@@ -4013,17 +4017,17 @@ ContainerState::ProcessDisplayItems(nsDi
       // geometry root that we give it, but it can't easily figure about
       // overflow:hidden clips on ancestors just by looking at the frame.
       // So we'll do a little hand holding and pass the clip instead of the
       // visible rect for the two important cases.
       nscolor uniformColor = NS_RGBA(0,0,0,0);
       nscolor* uniformColorPtr = (mayDrawOutOfOrder || IsInInactiveLayer()) ? nullptr :
                                                                               &uniformColor;
       nsIntRect clipRectUntyped;
-      const DisplayItemClip& layerClip = clipMovesWithLayer ? itemClip : scrollingClip;
+      const DisplayItemClip& layerClip = shouldFixToViewport ? fixedToViewportClip : itemClip;
       ParentLayerIntRect layerClipRect;
       nsIntRect* clipPtr = nullptr;
       if (layerClip.HasClip()) {
         layerClipRect = ViewAs<ParentLayerPixel>(
           ScaleToNearestPixels(layerClip.GetClipRect()) + mParameters.mOffset);
         clipRectUntyped = layerClipRect.ToUnknownRect();
         clipPtr = &clipRectUntyped;
       }
@@ -4033,17 +4037,17 @@ ContainerState::ProcessDisplayItems(nsDi
         // clip we care about is the overflow:hidden clip on the scrollbar.
         mPaintedLayerDataTree.AddingOwnLayer(animatedGeometryRoot->mParentAGR,
                                              clipPtr,
                                              uniformColorPtr);
       } else if (prerenderedTransform) {
         mPaintedLayerDataTree.AddingOwnLayer(animatedGeometryRoot,
                                              clipPtr,
                                              uniformColorPtr);
-      } else if (!clipMovesWithLayer) {
+      } else if (shouldFixToViewport) {
         mPaintedLayerDataTree.AddingOwnLayer(animatedGeometryRootForClip,
                                              clipPtr,
                                              uniformColorPtr);
       } else {
         // Using itemVisibleRect here isn't perfect. itemVisibleRect can be
         // larger or smaller than the potential bounds of item's contents in
         // animatedGeometryRoot: It's too large if there's a clipped display
         // port somewhere among item's contents (see bug 1147673), and it can
@@ -4117,34 +4121,34 @@ ContainerState::ProcessDisplayItems(nsDi
                    layerClip.GetRoundedRectCount() == 0,
                    "If we have rounded rects, we must have a clip rect");
 
       // It has its own layer. Update that layer's clip and visible rects.
 
       ownLayer->SetClipRect(Nothing());
       ownLayer->SetScrolledClip(Nothing());
       if (layerClip.HasClip()) {
-        // If the clip moves with the layer, it becomes part of the layer
-        // clip. Otherwise, it becomes part of the scrolled clip.
-        if (clipMovesWithLayer) {
+        // For layers fixed to the viewport, the clip becomes part of the
+        // layer's scrolled clip. Otherwise, it becomes part of the layer clip.
+        if (shouldFixToViewport) {
+          LayerClip scrolledClip;
+          scrolledClip.SetClipRect(layerClipRect);
+          if (layerClip.GetRoundedRectCount() > 0) {
+            scrolledClip.SetMaskLayerIndex(
+                SetupMaskLayerForScrolledClip(ownLayer.get(), layerClip));
+          }
+          ownLayer->SetScrolledClip(Some(scrolledClip));
+        } else {
           ownLayer->SetClipRect(Some(layerClipRect));
 
           // rounded rectangle clipping using mask layers
           // (must be done after visible rect is set on layer)
           if (layerClip.GetRoundedRectCount() > 0) {
             SetupMaskLayer(ownLayer, layerClip);
           }
-        } else {
-          LayerClip scrolledClip;
-          scrolledClip.SetClipRect(layerClipRect);
-          if (layerClip.GetRoundedRectCount() > 0) {
-            scrolledClip.SetMaskLayerIndex(
-                SetupMaskLayerForScrolledClip(ownLayer.get(), layerClip));
-          }
-          ownLayer->SetScrolledClip(Some(scrolledClip));
         }
       }
 
       ContainerLayer* oldContainer = ownLayer->GetParent();
       if (oldContainer && oldContainer != mContainerLayer) {
         oldContainer->RemoveChild(ownLayer);
       }
       NS_ASSERTION(FindIndexOfLayerIn(mNewChildLayers, ownLayer) < 0,
@@ -4225,17 +4229,17 @@ ContainerState::ProcessDisplayItems(nsDi
       mLayerBuilder->AddLayerDisplayItem(ownLayer, item, layerState, nullptr);
     } else {
       PaintedLayerData* paintedLayerData =
         mPaintedLayerDataTree.FindPaintedLayerFor(animatedGeometryRoot, agrScrollClip,
                                                   itemVisibleRect,
                                                   item->Frame()->In3DContextAndBackfaceIsHidden(),
                                                   [&]() {
           return NewPaintedLayerData(item, animatedGeometryRoot, agrScrollClip,
-                                     topLeft, clipMovesWithLayer);
+                                     topLeft, shouldFixToViewport);
         });
 
       if (itemType == nsDisplayItem::TYPE_LAYER_EVENT_REGIONS) {
         nsDisplayLayerEventRegions* eventRegions =
             static_cast<nsDisplayLayerEventRegions*>(item);
         paintedLayerData->AccumulateEventRegions(this, eventRegions);
       } else {
         // check to see if the new item has rounded rect clips in common with
@@ -4250,18 +4254,18 @@ ContainerState::ProcessDisplayItems(nsDi
         MOZ_ASSERT(nsIntRegion(itemDrawRect).Contains(opaquePixels));
         opaquePixels.AndWith(itemVisibleRect);
         paintedLayerData->Accumulate(this, item, opaquePixels,
             itemVisibleRect, itemClip, layerState);
 
         // If we removed the clip from the display item above because it's
         // fixed to the viewport, save it on the PaintedLayerData so we can
         // set it on the layer later.
-        if (scrollingClip.HasClip()) {
-          paintedLayerData->mItemClip = scrollingClip;
+        if (fixedToViewportClip.HasClip()) {
+          paintedLayerData->mItemClip = fixedToViewportClip;
         }
 
         if (!paintedLayerData->mLayer) {
           // Try to recycle the old layer of this display item.
           RefPtr<PaintedLayer> layer =
             AttemptToRecyclePaintedLayer(animatedGeometryRoot, item, topLeft);
           if (layer) {
             paintedLayerData->mLayer = layer;