Bug 1181135 - Copy DisplayItemClips in order to avoid dangling pointers. r=tn
authorMarkus Stange <mstange@themasta.com>
Wed, 09 Sep 2015 19:08:03 -0400
changeset 294266 1dace02633b302631f37e9c7af733f2c65d0b05e
parent 294265 f8581952130268f9b58570ea096b74ed0ac76d45
child 294267 ed0e18820d4a231e81b4d9874c5a5c1621dcb2a5
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstn
bugs1181135
milestone43.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 1181135 - Copy DisplayItemClips in order to avoid dangling pointers. r=tn
layout/base/FrameLayerBuilder.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsGfxScrollFrame.h
layout/generic/nsIScrollableFrame.h
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -3665,17 +3665,17 @@ GetScrollClipIntersection(nsDisplayListB
       return DisplayItemClip();
     }
 
     nsIScrollableFrame* scrollFrame = nsLayoutUtils::GetScrollableFrameFor(f);
     if (!scrollFrame) {
       continue;
     }
 
-    const DisplayItemClip* clip = scrollFrame->ComputeScrollClip(aIsCaret);
+    Maybe<DisplayItemClip> clip = scrollFrame->ComputeScrollClip(aIsCaret);
     if (clip) {
       resultClip.IntersectWith(*clip);
     }
   }
   return resultClip;
 }
 
 /*
@@ -4537,17 +4537,17 @@ ContainerState::SetupScrollingMetadata(N
 
     Maybe<FrameMetricsAndClip> info =
       scrollFrame->ComputeFrameMetrics(aEntry->mLayer, mContainerReferenceFrame, mParameters, aEntry->mIsCaret);
     if (!info) {
       continue;
     }
 
     FrameMetrics& metrics = info->metrics;
-    const DisplayItemClip* clip = info->clip;
+    Maybe<DisplayItemClip> clip = info->clip;
 
     if (clip &&
         clip->HasClip() &&
         clip->GetRoundedRectCount() > 0)
     {
       // The clip in between this scrollframe and its ancestor scrollframe
       // requires a mask layer. Since this mask layer should not move with
       // the APZC associated with this FrameMetrics, we attach the mask
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -1801,18 +1801,16 @@ ScrollFrameHelper::ScrollFrameHelper(nsC
   , mScrollGeneration(++sScrollGenerationCounter)
   , mDestination(0, 0)
   , mScrollPosAtLastPaint(0, 0)
   , mRestorePos(-1, -1)
   , mLastPos(-1, -1)
   , mResolution(1.0)
   , mScrollPosForLayerPixelAlignment(-1, -1)
   , mLastUpdateImagesPos(-1, -1)
-  , mAncestorClip(nullptr)
-  , mAncestorClipForCaret(nullptr)
   , mNeverHasVerticalScrollbar(false)
   , mNeverHasHorizontalScrollbar(false)
   , mHasVerticalScrollbar(false)
   , mHasHorizontalScrollbar(false)
   , mFrameIsUpdatingScrollbar(false)
   , mDidHistoryRestore(false)
   , mIsRoot(aIsRoot)
   , mClipAllDescendants(aIsRoot)
@@ -2781,18 +2779,18 @@ ScrollFrameHelper::BuildDisplayList(nsDi
         mScrollPosForLayerPixelAlignment = mScrollPosAtLastPaint;
       }
     } else {
       mScrollPosForLayerPixelAlignment = nsPoint(-1,-1);
     }
   }
 
   // Clear the scroll port clip that was set during the last paint.
-  mAncestorClip = nullptr;
-  mAncestorClipForCaret = nullptr;
+  mAncestorClip = Nothing();
+  mAncestorClipForCaret = Nothing();
 
   // We put non-overlay scrollbars in their own layers when this is the root
   // scroll frame and we are a toplevel content document. In this situation,
   // the scrollbar(s) would normally be assigned their own layer anyway, since
   // they're not scrolled with the rest of the document. But when both
   // scrollbars are visible, the layer's visible rectangle would be the size
   // of the viewport, so most layer implementations would create a layer buffer
   // that's much larger than necessary. Creating independent layers for each
@@ -3023,30 +3021,30 @@ ScrollFrameHelper::BuildDisplayList(nsDi
       }
     }
 
     Maybe<DisplayListClipState::AutoSaveRestore> clipStateNonCaret;
     if (usingDisplayport) {
       // Capture the clip state of the parent scroll frame. This will be saved
       // on FrameMetrics for layers with this frame as their animated geoemetry
       // root.
-      mAncestorClipForCaret = aBuilder->ClipState().GetCurrentCombinedClip(aBuilder);
+      mAncestorClipForCaret = ToMaybe(aBuilder->ClipState().GetCurrentCombinedClip(aBuilder));
 
       // Add the non-caret content box clip here so that it gets picked up by
       // mAncestorClip.
       if (contentBoxClipForNonCaretContent) {
         clipStateNonCaret.emplace(aBuilder);
         clipStatePtr = &*clipStateNonCaret;
         if (mClipAllDescendants) {
           clipStateNonCaret->ClipContentDescendants(*contentBoxClipForNonCaretContent);
         } else {
           clipStateNonCaret->ClipContainingBlockDescendants(*contentBoxClipForNonCaretContent);
         }
       }
-      mAncestorClip = aBuilder->ClipState().GetCurrentCombinedClip(aBuilder);
+      mAncestorClip = ToMaybe(aBuilder->ClipState().GetCurrentCombinedClip(aBuilder));
 
       // If we are using a display port, then ignore any pre-existing clip
       // passed down from our parents. The pre-existing clip would just defeat
       // the purpose of a display port which is to paint regions that are not
       // currently visible so that they can be brought into view asynchronously.
       // Notes:
       //   - The pre-existing clip state will be restored when the
       //     AutoSaveRestore goes out of scope, so there is no permanent change
@@ -3116,22 +3114,22 @@ ScrollFrameHelper::BuildDisplayList(nsDi
     }
   }
   // Now display overlay scrollbars and the resizer, if we have one.
   AppendScrollPartsTo(aBuilder, aDirtyRect, scrolledContent, usingDisplayport,
                       createLayersForScrollbars, true);
   scrolledContent.MoveTo(aLists);
 }
 
-const DisplayItemClip*
+Maybe<DisplayItemClip>
 ScrollFrameHelper::ComputeScrollClip(bool aIsForCaret) const
 {
-  const DisplayItemClip* ancestorClip = aIsForCaret ? mAncestorClipForCaret : mAncestorClip;
+  const Maybe<DisplayItemClip>& ancestorClip = aIsForCaret ? mAncestorClipForCaret : mAncestorClip;
   if (!mShouldBuildScrollableLayer || mIsScrollableLayerInRootContainer) {
-    return nullptr;
+    return Nothing();
   }
 
   return ancestorClip;
 }
 
 Maybe<FrameMetricsAndClip>
 ScrollFrameHelper::ComputeFrameMetrics(Layer* aLayer,
                                        nsIFrame* aContainerReferenceFrame,
@@ -3143,17 +3141,17 @@ ScrollFrameHelper::ComputeFrameMetrics(L
   }
 
   bool needsParentLayerClip = true;
   if (gfxPrefs::LayoutUseContainersForRootFrames() && !mAddClipRectToLayer) {
     // For containerful frames, the clip is on the container frame.
     needsParentLayerClip = false;
   }
 
-  const DisplayItemClip* ancestorClip = aIsForCaret ? mAncestorClipForCaret : mAncestorClip;
+  const Maybe<DisplayItemClip>& ancestorClip = aIsForCaret ? mAncestorClipForCaret : mAncestorClip;
 
   nsPoint toReferenceFrame = mOuter->GetOffsetToCrossDoc(aContainerReferenceFrame);
   bool isRootContent = mIsRoot && mOuter->PresContext()->IsRootContentDocument();
 
   Maybe<nsRect> parentLayerClip;
   if (needsParentLayerClip) {
     nsRect clip = nsRect(mScrollPort.TopLeft() + toReferenceFrame,
                          nsLayoutUtils::CalculateCompositionSizeForFrame(mOuter));
--- a/layout/generic/nsGfxScrollFrame.h
+++ b/layout/generic/nsGfxScrollFrame.h
@@ -377,17 +377,17 @@ public:
       mLastSmoothScrollOrigin = nullptr;
     }
   }
   bool WantAsyncScroll() const;
   Maybe<FrameMetricsAndClip> ComputeFrameMetrics(
     Layer* aLayer, nsIFrame* aContainerReferenceFrame,
     const ContainerLayerParameters& aParameters,
     bool aIsForCaret) const;
-  virtual const mozilla::DisplayItemClip* ComputeScrollClip(bool aIsForCaret) const;
+  virtual mozilla::Maybe<mozilla::DisplayItemClip> ComputeScrollClip(bool aIsForCaret) const;
 
   // nsIScrollbarMediator
   void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection,
                     nsIScrollbarMediator::ScrollSnapMode aSnap
                       = nsIScrollbarMediator::DISABLE_SNAP);
   void ScrollByWhole(nsScrollbarFrame* aScrollbar, int32_t aDirection,
                      nsIScrollbarMediator::ScrollSnapMode aSnap
                        = nsIScrollbarMediator::DISABLE_SNAP);
@@ -456,19 +456,19 @@ public:
 
   // The scroll position where we last updated image visibility.
   nsPoint mLastUpdateImagesPos;
 
   nsRect mPrevScrolledRect;
 
   FrameMetrics::ViewID mScrollParentID;
 
-  // The scroll port clip. Only valid during painting.
-  const DisplayItemClip* mAncestorClip;
-  const DisplayItemClip* mAncestorClipForCaret;
+  // The scroll port clip.
+  Maybe<DisplayItemClip> mAncestorClip;
+  Maybe<DisplayItemClip> mAncestorClipForCaret;
 
   bool mNeverHasVerticalScrollbar:1;
   bool mNeverHasHorizontalScrollbar:1;
   bool mHasVerticalScrollbar:1;
   bool mHasHorizontalScrollbar:1;
   bool mFrameIsUpdatingScrollbar:1;
   bool mDidHistoryRestore:1;
   // Is this the scrollframe for the document's viewport?
@@ -840,17 +840,17 @@ public:
   }
   virtual mozilla::Maybe<mozilla::FrameMetricsAndClip> ComputeFrameMetrics(
     Layer* aLayer, nsIFrame* aContainerReferenceFrame,
     const ContainerLayerParameters& aParameters,
     bool aIsForCaret) const override
   {
     return mHelper.ComputeFrameMetrics(aLayer, aContainerReferenceFrame, aParameters, aIsForCaret);
   }
-  virtual const mozilla::DisplayItemClip* ComputeScrollClip(bool aIsForCaret) const override
+  virtual mozilla::Maybe<mozilla::DisplayItemClip> ComputeScrollClip(bool aIsForCaret) const override
   {
     return mHelper.ComputeScrollClip(aIsForCaret);
   }
   virtual bool IsIgnoringViewportClipping() const override {
     return mHelper.IsIgnoringViewportClipping();
   }
   virtual void MarkScrollbarsDirtyForReflow() const override {
     mHelper.MarkScrollbarsDirtyForReflow();
@@ -1240,17 +1240,17 @@ public:
   }
   virtual mozilla::Maybe<mozilla::FrameMetricsAndClip> ComputeFrameMetrics(
     Layer* aLayer, nsIFrame* aContainerReferenceFrame,
     const ContainerLayerParameters& aParameters,
     bool aIsForCaret) const override
   {
     return mHelper.ComputeFrameMetrics(aLayer, aContainerReferenceFrame, aParameters, aIsForCaret);
   }
-  virtual const mozilla::DisplayItemClip* ComputeScrollClip(bool aIsForCaret) const override
+  virtual mozilla::Maybe<mozilla::DisplayItemClip> ComputeScrollClip(bool aIsForCaret) const override
   {
     return mHelper.ComputeScrollClip(aIsForCaret);
   }
   virtual bool IsIgnoringViewportClipping() const override {
     return mHelper.IsIgnoringViewportClipping();
   }
   virtual void MarkScrollbarsDirtyForReflow() const override {
     mHelper.MarkScrollbarsDirtyForReflow();
--- a/layout/generic/nsIScrollableFrame.h
+++ b/layout/generic/nsIScrollableFrame.h
@@ -6,16 +6,17 @@
 /*
  * interface that provides scroll APIs implemented by scrollable frames
  */
 
 #ifndef nsIScrollFrame_h___
 #define nsIScrollFrame_h___
 
 #include "nsCoord.h"
+#include "DisplayItemClip.h"
 #include "ScrollbarStyles.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/gfx/Point.h"
 #include "nsIScrollbarMediator.h"
 #include "Units.h"
 #include "FrameMetrics.h"
 
 #define NS_DEFAULT_VERTICAL_SCROLL_DISTANCE   3
@@ -27,25 +28,24 @@ class nsIFrame;
 class nsPresContext;
 class nsIContent;
 class nsRenderingContext;
 class nsIAtom;
 class nsDisplayListBuilder;
 
 namespace mozilla {
 struct ContainerLayerParameters;
-class DisplayItemClip;
 namespace layers {
 class Layer;
 } // namespace layers
 
 struct FrameMetricsAndClip
 {
   layers::FrameMetrics metrics;
-  const DisplayItemClip* clip;
+  mozilla::Maybe<DisplayItemClip> clip;
 };
 
 } // namespace mozilla
 
 /**
  * Interface for frames that are scrollable. This interface exposes
  * APIs for examining scroll state, observing changes to scroll state,
  * and triggering scrolling.
@@ -444,12 +444,12 @@ public:
   virtual void SetTransformingByAPZ(bool aTransforming) = 0;
   virtual bool IsTransformingByAPZ() const = 0;
 
   /**
    * Whether or not this frame uses containerful scrolling.
    */
   virtual bool UsesContainerScrolling() const = 0;
 
-  virtual const mozilla::DisplayItemClip* ComputeScrollClip(bool aIsForCaret) const = 0;
+  virtual mozilla::Maybe<mozilla::DisplayItemClip> ComputeScrollClip(bool aIsForCaret) const = 0;
 };
 
 #endif