Bug 1459670 - Add frame tracking for the nsDisplayTable* classes. r=miko, a=RyanVM
authorMatt Woodrow <mwoodrow@mozilla.com>
Fri, 01 Jun 2018 14:33:15 +1200
changeset 473607 f14daaaaf1bebaadf2f2b15cd4213824cfcf1b54
parent 473606 f97d4447e80247f695362b197e0156afdf58acf2
child 473608 1bd083b09db8a190870b204b61584c1359d89d84
push id1728
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:12:27 +0000
treeherdermozilla-release@c296fde26f5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmiko, RyanVM
bugs1459670
milestone61.0
Bug 1459670 - Add frame tracking for the nsDisplayTable* classes. r=miko, a=RyanVM
layout/painting/nsDisplayList.cpp
layout/painting/nsDisplayList.h
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -4396,16 +4396,26 @@ nsDisplayBackgroundImage::GetBoundsInter
 
 nsDisplayTableBackgroundImage::nsDisplayTableBackgroundImage(nsDisplayListBuilder* aBuilder,
                                                              const InitData& aData,
                                                              nsIFrame* aCellFrame)
   : nsDisplayBackgroundImage(aBuilder, aData, aCellFrame)
   , mStyleFrame(aCellFrame)
   , mTableType(GetTableTypeFromFrame(mStyleFrame))
 {
+  if (aBuilder->IsRetainingDisplayList()) {
+    mStyleFrame->AddDisplayItem(this);
+  }
+}
+
+nsDisplayTableBackgroundImage::~nsDisplayTableBackgroundImage()
+{
+  if (mStyleFrame) {
+    mStyleFrame->RemoveDisplayItem(this);
+  }
 }
 
 bool
 nsDisplayTableBackgroundImage::IsInvalid(nsRect& aRect) const
 {
   bool result = mStyleFrame ? mStyleFrame->IsInvalid(aRect) : false;
   aRect += ToReferenceFrame();
   return result;
@@ -7459,16 +7469,19 @@ nsDisplayTableFixedPosition::nsDisplayTa
                                                          nsIFrame* aFrame,
                                                          nsDisplayList* aList,
                                                          uint32_t aIndex,
                                                          nsIFrame* aAncestorFrame)
   : nsDisplayFixedPosition(aBuilder, aFrame, aList, aIndex)
   , mAncestorFrame(aAncestorFrame)
   , mTableType(GetTableTypeFromFrame(aAncestorFrame))
 {
+  if (aBuilder->IsRetainingDisplayList()) {
+    mAncestorFrame->AddDisplayItem(this);
+  }
 }
 
 /* static */ nsDisplayTableFixedPosition*
 nsDisplayTableFixedPosition::CreateForFixedBackground(nsDisplayListBuilder* aBuilder,
                                                       nsIFrame* aFrame,
                                                       nsDisplayBackgroundImage* aImage,
                                                       uint32_t aIndex,
                                                       nsIFrame* aAncestorFrame)
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -4228,27 +4228,39 @@ TableType GetTableTypeFromFrame(nsIFrame
  * frame. And use mFrame and table type as key to generate DisplayItemData to
  * avoid sharing DisplayItemData.
  *
  * Also store ancestor frame as mStyleFrame for all rendering informations.
  */
 class nsDisplayTableBackgroundImage : public nsDisplayBackgroundImage {
 public:
   nsDisplayTableBackgroundImage(nsDisplayListBuilder* aBuilder, const InitData& aInitData, nsIFrame* aCellFrame);
+  ~nsDisplayTableBackgroundImage();
 
   virtual uint32_t GetPerFrameKey() const override {
     return (mLayer << (TYPE_BITS + static_cast<uint8_t>(TableTypeBits::COUNT))) |
            (static_cast<uint8_t>(mTableType) << TYPE_BITS) |
            nsDisplayItem::GetPerFrameKey();
   }
 
   virtual bool IsInvalid(nsRect& aRect) const override;
 
   virtual nsIFrame* FrameForInvalidation() const override { return mStyleFrame; }
 
+  virtual bool HasDeletedFrame() const override {
+    return !mStyleFrame || nsDisplayBackgroundImage::HasDeletedFrame();
+  }
+
+  virtual void RemoveFrame(nsIFrame* aFrame) override {
+    if (aFrame == mStyleFrame) {
+      mStyleFrame = nullptr;
+    }
+    nsDisplayBackgroundImage::RemoveFrame(aFrame);
+  }
+
   NS_DISPLAY_DECL_NAME("TableBackgroundImage", TYPE_TABLE_BACKGROUND_IMAGE)
 protected:
   virtual nsIFrame* StyleFrame() const override { return mStyleFrame; }
 
   nsIFrame* mStyleFrame;
   TableType mTableType;
 };
 
@@ -4326,25 +4338,45 @@ protected:
 class nsDisplayTableThemedBackground : public nsDisplayThemedBackground {
 public:
   nsDisplayTableThemedBackground(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
                                  const nsRect& aBackgroundRect,
                                  nsIFrame* aAncestorFrame)
     : nsDisplayThemedBackground(aBuilder, aFrame, aBackgroundRect)
     , mAncestorFrame(aAncestorFrame)
     , mTableType(GetTableTypeFromFrame(aAncestorFrame))
-  { }
+  {
+    if (aBuilder->IsRetainingDisplayList()) {
+      mAncestorFrame->AddDisplayItem(this);
+    }
+  }
+  ~nsDisplayTableThemedBackground() {
+    if (mAncestorFrame) {
+      mAncestorFrame->RemoveDisplayItem(this);
+    }
+  }
 
   virtual uint32_t GetPerFrameKey() const override {
     return (static_cast<uint8_t>(mTableType) << TYPE_BITS) |
            nsDisplayItem::GetPerFrameKey();
   }
 
   virtual nsIFrame* FrameForInvalidation() const override { return mAncestorFrame; }
 
+  virtual bool HasDeletedFrame() const override {
+    return !mAncestorFrame || nsDisplayThemedBackground::HasDeletedFrame();
+  }
+
+  virtual void RemoveFrame(nsIFrame* aFrame) override {
+    if (aFrame == mAncestorFrame) {
+      mAncestorFrame = nullptr;
+    }
+    nsDisplayThemedBackground::RemoveFrame(aFrame);
+  }
+
   NS_DISPLAY_DECL_NAME("TableThemedBackground", TYPE_TABLE_THEMED_BACKGROUND_IMAGE)
 protected:
   virtual nsIFrame* StyleFrame() const override { return mAncestorFrame; }
   nsIFrame* mAncestorFrame;
   TableType mTableType;
 };
 
 class nsDisplayBackgroundColor : public nsDisplayItem
@@ -4469,20 +4501,40 @@ public:
   nsDisplayTableBackgroundColor(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
                                 const nsRect& aBackgroundRect,
                                 mozilla::ComputedStyle* aBackgroundStyle,
                                 nscolor aColor,
                                 nsIFrame* aAncestorFrame)
     : nsDisplayBackgroundColor(aBuilder, aFrame, aBackgroundRect, aBackgroundStyle, aColor)
     , mAncestorFrame(aAncestorFrame)
     , mTableType(GetTableTypeFromFrame(aAncestorFrame))
-  { }
+  {
+    if (aBuilder->IsRetainingDisplayList()) {
+      mAncestorFrame->AddDisplayItem(this);
+    }
+  }
+  ~nsDisplayTableBackgroundColor() {
+    if (mAncestorFrame) {
+      mAncestorFrame->RemoveDisplayItem(this);
+    }
+  }
 
   virtual nsIFrame* FrameForInvalidation() const override { return mAncestorFrame; }
 
+  virtual bool HasDeletedFrame() const override {
+    return !mAncestorFrame || nsDisplayBackgroundColor::HasDeletedFrame();
+  }
+
+  virtual void RemoveFrame(nsIFrame* aFrame) override {
+    if (aFrame == mAncestorFrame) {
+      mAncestorFrame = nullptr;
+    }
+    nsDisplayBackgroundColor::RemoveFrame(aFrame);
+  }
+
   virtual uint32_t GetPerFrameKey() const override {
     return (static_cast<uint8_t>(mTableType) << TYPE_BITS) |
            nsDisplayItem::GetPerFrameKey();
   }
 
   NS_DISPLAY_DECL_NAME("TableBackgroundColor", TYPE_TABLE_BACKGROUND_COLOR)
 protected:
   nsIFrame* mAncestorFrame;
@@ -5459,32 +5511,56 @@ class nsDisplayTableBlendMode : public n
 public:
   nsDisplayTableBlendMode(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
                           nsDisplayList* aList, uint8_t aBlendMode,
                           const ActiveScrolledRoot* aActiveScrolledRoot,
                           uint32_t aIndex, nsIFrame* aAncestorFrame)
     : nsDisplayBlendMode(aBuilder, aFrame, aList, aBlendMode, aActiveScrolledRoot, aIndex)
     , mAncestorFrame(aAncestorFrame)
     , mTableType(GetTableTypeFromFrame(aAncestorFrame))
-  {}
+  {
+    if (aBuilder->IsRetainingDisplayList()) {
+      mAncestorFrame->AddDisplayItem(this);
+    }
+  }
 
   nsDisplayTableBlendMode(nsDisplayListBuilder* aBuilder,
                           const nsDisplayTableBlendMode& aOther)
     : nsDisplayBlendMode(aBuilder, aOther)
     , mAncestorFrame(aOther.mAncestorFrame)
     , mTableType(aOther.mTableType)
-  {}
+  {
+    if (aBuilder->IsRetainingDisplayList()) {
+      mAncestorFrame->AddDisplayItem(this);
+    }
+  }
+  ~nsDisplayTableBlendMode() {
+    if (mAncestorFrame) {
+      mAncestorFrame->RemoveDisplayItem(this);
+    }
+  }
 
   virtual nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
   {
     return MakeDisplayItem<nsDisplayTableBlendMode>(aBuilder, *this);
   }
 
   virtual nsIFrame* FrameForInvalidation() const override { return mAncestorFrame; }
 
+  virtual bool HasDeletedFrame() const override {
+    return !mAncestorFrame || nsDisplayBlendMode::HasDeletedFrame();
+  }
+
+  virtual void RemoveFrame(nsIFrame* aFrame) override {
+    if (aFrame == mAncestorFrame) {
+      mAncestorFrame = nullptr;
+    }
+    nsDisplayBlendMode::RemoveFrame(aFrame);
+  }
+
   virtual uint32_t GetPerFrameKey() const override {
     return (mIndex << (TYPE_BITS + static_cast<uint8_t>(TableTypeBits::COUNT))) |
            (static_cast<uint8_t>(mTableType) << TYPE_BITS) |
            nsDisplayItem::GetPerFrameKey();
   }
 
   NS_DISPLAY_DECL_NAME("TableBlendMode", TYPE_TABLE_BLEND_MODE)
 
@@ -5571,39 +5647,63 @@ public:
 
   virtual nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
   {
     return MakeDisplayItem<nsDisplayTableBlendContainer>(aBuilder, *this);
   }
 
   virtual nsIFrame* FrameForInvalidation() const override { return mAncestorFrame; }
 
+  virtual bool HasDeletedFrame() const override {
+    return !mAncestorFrame || nsDisplayBlendContainer::HasDeletedFrame();
+  }
+
+  virtual void RemoveFrame(nsIFrame* aFrame) override {
+    if (aFrame == mAncestorFrame) {
+      mAncestorFrame = nullptr;
+    }
+    nsDisplayBlendContainer::RemoveFrame(aFrame);
+  }
+
   virtual uint32_t GetPerFrameKey() const override {
     return (static_cast<uint8_t>(mTableType) << TYPE_BITS) |
            nsDisplayItem::GetPerFrameKey();
   }
 
   NS_DISPLAY_DECL_NAME("TableBlendContainer", TYPE_TABLE_BLEND_CONTAINER)
 
 protected:
   nsDisplayTableBlendContainer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
                                nsDisplayList* aList,
                                const ActiveScrolledRoot* aActiveScrolledRoot,
                                bool aIsForBackground, nsIFrame* aAncestorFrame)
     : nsDisplayBlendContainer(aBuilder, aFrame, aList, aActiveScrolledRoot, aIsForBackground)
     , mAncestorFrame(aAncestorFrame)
     , mTableType(GetTableTypeFromFrame(aAncestorFrame))
-  {}
+  {
+    if (aBuilder->IsRetainingDisplayList()) {
+      mAncestorFrame->AddDisplayItem(this);
+    }
+  }
 
   nsDisplayTableBlendContainer(nsDisplayListBuilder* aBuilder,
                                const nsDisplayTableBlendContainer& aOther)
     : nsDisplayBlendContainer(aBuilder, aOther)
     , mAncestorFrame(aOther.mAncestorFrame)
     , mTableType(aOther.mTableType)
-  {}
+  {
+    if (aBuilder->IsRetainingDisplayList()) {
+      mAncestorFrame->AddDisplayItem(this);
+    }
+  }
+  ~nsDisplayTableBlendContainer() {
+    if (mAncestorFrame) {
+      mAncestorFrame->RemoveDisplayItem(this);
+    }
+  }
 
   nsIFrame* mAncestorFrame;
   TableType mTableType;
 };
 
 
 /**
  * nsDisplayOwnLayer constructor flags. If we nest this class inside
@@ -5928,16 +6028,27 @@ public:
 
   virtual nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
   {
     return MakeDisplayItem<nsDisplayTableFixedPosition>(aBuilder, *this);
   }
 
   virtual nsIFrame* FrameForInvalidation() const override { return mAncestorFrame; }
 
+  virtual bool HasDeletedFrame() const override {
+    return !mAncestorFrame || nsDisplayFixedPosition::HasDeletedFrame();
+  }
+
+  virtual void RemoveFrame(nsIFrame* aFrame) override {
+    if (aFrame == mAncestorFrame) {
+      mAncestorFrame = nullptr;
+    }
+    nsDisplayFixedPosition::RemoveFrame(aFrame);
+  }
+
   virtual uint32_t GetPerFrameKey() const override {
     return (mIndex << (TYPE_BITS + static_cast<uint8_t>(TableTypeBits::COUNT))) |
            (static_cast<uint8_t>(mTableType) << TYPE_BITS) |
            nsDisplayItem::GetPerFrameKey();
   }
 
   NS_DISPLAY_DECL_NAME("TableFixedPosition", TYPE_TABLE_FIXED_POSITION)
 protected:
@@ -5945,17 +6056,26 @@ protected:
                               nsDisplayList* aList, uint32_t aIndex,
                               nsIFrame* aAncestorFrame);
 
   nsDisplayTableFixedPosition(nsDisplayListBuilder* aBuilder,
                               const nsDisplayTableFixedPosition& aOther)
     : nsDisplayFixedPosition(aBuilder, aOther)
     , mAncestorFrame(aOther.mAncestorFrame)
     , mTableType(aOther.mTableType)
-  {}
+  {
+    if (aBuilder->IsRetainingDisplayList()) {
+      mAncestorFrame->AddDisplayItem(this);
+    }
+  }
+  ~nsDisplayTableFixedPosition() {
+    if (mAncestorFrame) {
+      mAncestorFrame->RemoveDisplayItem(this);
+    }
+  }
 
   nsIFrame* mAncestorFrame;
   TableType mTableType;
 };
 
 /**
  * This creates an empty scrollable layer. It has no child layers.
  * It is used to record the existence of a scrollable frame in the layer