--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -71,16 +71,17 @@ class nsAtom;
class nsPresContext;
class nsIPresShell;
class nsView;
class nsIWidget;
class nsISelectionController;
class nsBoxLayoutState;
class nsBoxLayout;
class nsILineIterator;
+class nsDisplayItem;
class nsDisplayListBuilder;
class nsDisplayListSet;
class nsDisplayList;
class gfxSkipChars;
class gfxSkipCharsIterator;
class gfxContext;
class nsLineList_iterator;
class nsAbsoluteContainingBlock;
@@ -598,17 +599,17 @@ public:
typedef mozilla::layout::FrameChildListIDs ChildListIDs;
typedef mozilla::layout::FrameChildListIterator ChildListIterator;
typedef mozilla::layout::FrameChildListArrayIterator ChildListArrayIterator;
typedef mozilla::gfx::DrawTarget DrawTarget;
typedef mozilla::gfx::Matrix Matrix;
typedef mozilla::gfx::Matrix4x4 Matrix4x4;
typedef mozilla::Sides Sides;
typedef mozilla::LogicalSides LogicalSides;
- typedef mozilla::SmallPointerArray<mozilla::DisplayItemData> DisplayItemArray;
+ typedef mozilla::SmallPointerArray<mozilla::DisplayItemData> DisplayItemDataArray;
typedef nsQueryFrame::ClassID ClassID;
NS_DECL_QUERYFRAME_TARGET(nsIFrame)
explicit nsIFrame(ClassID aID)
: mRect()
, mContent(nullptr)
, mStyleContext(nullptr)
@@ -1129,16 +1130,18 @@ public:
virtual nsPoint GetPositionOfChildIgnoringScrolling(nsIFrame* aChild)
{ return aChild->GetPosition(); }
nsPoint GetPositionIgnoringScrolling();
typedef AutoTArray<nsIContent*, 2> ContentArray;
static void DestroyContentArray(ContentArray* aArray);
+ typedef AutoTArray<nsDisplayItem*, 4> DisplayItemArray;
+
typedef mozilla::layers::WebRenderUserData WebRenderUserData;
typedef nsRefPtrHashtable<nsUint32HashKey, WebRenderUserData> WebRenderUserDataTable;
#define NS_DECLARE_FRAME_PROPERTY_WITH_DTOR(prop, type, dtor) \
static const mozilla::FramePropertyDescriptor<type>* prop() { \
/* Use of constexpr caused startup crashes with MSVC2015u1 PGO. */ \
static const auto descriptor = \
mozilla::FramePropertyDescriptor<type>::NewWithDestructor<dtor>(); \
@@ -1226,16 +1229,18 @@ public:
NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(BClampMarginBoxMinSizeProperty, nscoord)
NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(IBaselinePadProperty, nscoord)
NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(BBaselinePadProperty, nscoord)
NS_DECLARE_FRAME_PROPERTY_WITH_DTOR(GenConProperty, ContentArray,
DestroyContentArray)
+ NS_DECLARE_FRAME_PROPERTY_DELETABLE(DisplayItems, DisplayItemArray)
+
NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(BidiDataProperty, mozilla::FrameBidiData)
NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(PlaceholderFrameProperty, nsPlaceholderFrame)
NS_DECLARE_FRAME_PROPERTY_WITH_DTOR(WebRenderUserDataProperty, WebRenderUserDataTable, DestroyWebRenderUserDataTable)
static void DestroyWebRenderUserDataTable(WebRenderUserDataTable* aTable);
mozilla::FrameBidiData GetBidiData() const
@@ -4068,17 +4073,23 @@ public:
*/
nscoord ComputeISizeValue(gfxContext* aRenderingContext,
nscoord aContainingBlockISize,
nscoord aContentEdgeToBoxSizing,
nscoord aBoxSizingToMarginEdge,
const nsStyleCoord& aCoord,
ComputeSizeFlags aFlags = eDefault);
- DisplayItemArray& DisplayItemData() { return mDisplayItemData; }
+ DisplayItemDataArray& DisplayItemData() { return mDisplayItemData; }
+
+ void AddDisplayItem(nsDisplayItem* aItem);
+ bool RemoveDisplayItem(nsDisplayItem* aItem);
+ void RemoveDisplayItemDataForDeletion();
+ bool HasDisplayItems();
+ bool HasDisplayItem(nsDisplayItem* aItem);
void DestroyAnonymousContent(already_AddRefed<nsIContent> aContent);
bool ForceDescendIntoIfVisible() { return mForceDescendIntoIfVisible; }
void SetForceDescendIntoIfVisible(bool aForce) { mForceDescendIntoIfVisible = aForce; }
protected:
@@ -4099,17 +4110,18 @@ protected:
// Members
nsRect mRect;
nsCOMPtr<nsIContent> mContent;
RefPtr<nsStyleContext> mStyleContext;
private:
nsContainerFrame* mParent;
nsIFrame* mNextSibling; // doubly-linked list of frames
nsIFrame* mPrevSibling; // Do not touch outside SetNextSibling!
- DisplayItemArray mDisplayItemData;
+
+ DisplayItemDataArray mDisplayItemData;
void MarkAbsoluteFramesForDisplayList(nsDisplayListBuilder* aBuilder);
static void DestroyPaintedPresShellList(nsTArray<nsWeakPtr>* list) {
list->Clear();
delete list;
}
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -1783,63 +1783,83 @@ public:
, mReferenceFrame(nullptr)
, mAnimatedGeometryRoot(nullptr)
, mForceNotVisible(false)
, mDisableSubpixelAA(false)
#ifdef MOZ_DUMP_PAINTING
, mPainted(false)
#endif
{
- }
+ MOZ_COUNT_CTOR(nsDisplayItem);
+ }
+
protected:
virtual ~nsDisplayItem() {
+ MOZ_COUNT_DTOR(nsDisplayItem);
+ if (mFrame) {
+ mFrame->RemoveDisplayItem(this);
+ }
}
public:
virtual void Destroy(nsDisplayListBuilder* aBuilder)
{
DisplayItemType type = GetType();
this->~nsDisplayItem();
aBuilder->Destroy(type, this);
}
+ virtual void RemoveFrame(nsIFrame* aFrame)
+ {
+ if (aFrame == mFrame) {
+ MOZ_ASSERT(!mFrame->HasDisplayItem(this));
+ mFrame = nullptr;
+ }
+ }
+
/**
* Downcasts this item to nsDisplayWrapList, if possible.
*/
virtual const nsDisplayWrapList* AsDisplayWrapList() const { return nullptr; }
/**
* Create a clone of this item.
*/
virtual nsDisplayItem* Clone(nsDisplayListBuilder* aBuilder) const
{
return nullptr;
}
+ nsDisplayItem(const nsDisplayItem&) = delete;
/**
* The custom copy-constructor is implemented to prevent copying the saved
* state of the item.
* This is currently only used when creating temporary items for merging.
*/
- nsDisplayItem(const nsDisplayItem& aOther)
+ nsDisplayItem(nsDisplayListBuilder* aBuilder, const nsDisplayItem& aOther)
: mFrame(aOther.mFrame)
, mClipChain(aOther.mClipChain)
, mClip(aOther.mClip)
, mActiveScrolledRoot(aOther.mActiveScrolledRoot)
, mReferenceFrame(aOther.mReferenceFrame)
, mAnimatedGeometryRoot(aOther.mAnimatedGeometryRoot)
, mToReferenceFrame(aOther.mToReferenceFrame)
, mVisibleRect(aOther.mVisibleRect)
, mForceNotVisible(aOther.mForceNotVisible)
, mDisableSubpixelAA(aOther.mDisableSubpixelAA)
#ifdef MOZ_DUMP_PAINTING
, mPainted(false)
#endif
{
- }
+ MOZ_COUNT_CTOR(nsDisplayItem);
+ if (aBuilder->IsRetainingDisplayList()) {
+ mFrame->AddDisplayItem(this);
+ }
+ }
+
struct HitTestState {
explicit HitTestState() : mInPreserves3D(false) {}
~HitTestState() {
NS_ASSERTION(mItemBuffer.Length() == 0,
"mItemBuffer should have been cleared");
}
@@ -4127,18 +4147,19 @@ public:
mBaseVisibleRect = mVisibleRect;
mListPtr = &mList;
}
/**
* A custom copy-constructor that does not copy mList, as this would mutate
* the other item.
*/
- nsDisplayWrapList(const nsDisplayWrapList& aOther)
- : nsDisplayItem(aOther)
+ nsDisplayWrapList(const nsDisplayWrapList& aOther) = delete;
+ nsDisplayWrapList(nsDisplayListBuilder* aBuilder, const nsDisplayWrapList& aOther)
+ : nsDisplayItem(aBuilder, aOther)
, mList(aOther.mList.mBuilder)
, mListPtr(&mList)
, mMergedFrames(aOther.mMergedFrames)
, mBounds(aOther.mBounds)
, mBaseVisibleRect(aOther.mBaseVisibleRect)
, mOverrideZIndex(aOther.mOverrideZIndex)
, mHasZIndexOverride(aOther.mHasZIndexOverride)
{
@@ -4333,24 +4354,30 @@ protected:
* set by the stacking context root frame's 'opacity' style.
*/
class nsDisplayOpacity : public nsDisplayWrapList {
public:
nsDisplayOpacity(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
nsDisplayList* aList,
const ActiveScrolledRoot* aActiveScrolledRoot,
bool aForEventsAndPluginsOnly);
+ nsDisplayOpacity(nsDisplayListBuilder* aBuilder,
+ const nsDisplayOpacity& aOther)
+ : nsDisplayWrapList(aBuilder, aOther)
+ , mOpacity(aOther.mOpacity)
+ , mForEventsAndPluginsOnly(aOther.mForEventsAndPluginsOnly)
+ {}
#ifdef NS_BUILD_REFCNT_LOGGING
virtual ~nsDisplayOpacity();
#endif
virtual nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
{
MOZ_COUNT_CTOR(nsDisplayOpacity);
- return new (aBuilder) nsDisplayOpacity(*this);
+ return new (aBuilder) nsDisplayOpacity(aBuilder, *this);
}
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aSnap) const override;
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) override;
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
@@ -4403,24 +4430,30 @@ private:
};
class nsDisplayBlendMode : public nsDisplayWrapList {
public:
nsDisplayBlendMode(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
nsDisplayList* aList, uint8_t aBlendMode,
const ActiveScrolledRoot* aActiveScrolledRoot,
uint32_t aIndex = 0);
+ nsDisplayBlendMode(nsDisplayListBuilder* aBuilder,
+ const nsDisplayBlendMode& aOther)
+ : nsDisplayWrapList(aBuilder, aOther)
+ , mBlendMode(aOther.mBlendMode)
+ , mIndex(aOther.mIndex)
+ {}
#ifdef NS_BUILD_REFCNT_LOGGING
virtual ~nsDisplayBlendMode();
#endif
virtual nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
{
MOZ_COUNT_CTOR(nsDisplayBlendMode);
- return new (aBuilder) nsDisplayBlendMode(*this);
+ return new (aBuilder) nsDisplayBlendMode(aBuilder, *this);
}
nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aSnap) const override;
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) override;
@@ -4472,17 +4505,17 @@ public:
#ifdef NS_BUILD_REFCNT_LOGGING
virtual ~nsDisplayBlendContainer();
#endif
virtual nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
{
MOZ_COUNT_CTOR(nsDisplayBlendContainer);
- return new (aBuilder) nsDisplayBlendContainer(*this);
+ return new (aBuilder) nsDisplayBlendContainer(aBuilder, *this);
}
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) override;
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aParameters) override;
@@ -4509,16 +4542,21 @@ public:
}
NS_DISPLAY_DECL_NAME("BlendContainer", TYPE_BLEND_CONTAINER)
private:
nsDisplayBlendContainer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
nsDisplayList* aList,
const ActiveScrolledRoot* aActiveScrolledRoot,
bool aIsForBackground);
+ nsDisplayBlendContainer(nsDisplayListBuilder* aBuilder,
+ const nsDisplayBlendContainer& aOther)
+ : nsDisplayWrapList(aBuilder, aOther)
+ , mIsForBackground(aOther.mIsForBackground)
+ {}
// Used to distinguish containers created at building stacking
// context or appending background.
bool mIsForBackground;
};
/**
* A display item that has no purpose but to ensure its contents get
@@ -4555,18 +4593,18 @@ public:
const ActiveScrolledRoot* aActiveScrolledRoot,
uint32_t aFlags = 0,
ViewID aScrollTarget = mozilla::layers::FrameMetrics::NULL_SCROLL_ID,
const ScrollThumbData& aThumbData = ScrollThumbData{},
bool aForceActive = true);
#ifdef NS_BUILD_REFCNT_LOGGING
virtual ~nsDisplayOwnLayer();
#endif
- nsDisplayOwnLayer(const nsDisplayOwnLayer& aOther)
- : nsDisplayWrapList(aOther)
+ nsDisplayOwnLayer(nsDisplayListBuilder* aBuilder, const nsDisplayOwnLayer& aOther)
+ : nsDisplayWrapList(aBuilder, aOther)
, mFlags(aOther.mFlags)
, mScrollTarget(aOther.mFlags)
, mThumbData(aOther.mThumbData)
, mForceActive(aOther.mForceActive)
, mWrAnimationId(aOther.mWrAnimationId)
{
MOZ_COUNT_CTOR(nsDisplayOwnLayer);
}
@@ -4677,25 +4715,30 @@ public:
* gets its own layer and creates a stacking context, and the layer will have
* position-related metadata set on it.
*/
class nsDisplayStickyPosition : public nsDisplayOwnLayer {
public:
nsDisplayStickyPosition(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
nsDisplayList* aList,
const ActiveScrolledRoot* aActiveScrolledRoot);
+ nsDisplayStickyPosition(nsDisplayListBuilder* aBuilder,
+ const nsDisplayStickyPosition& aOther)
+ : nsDisplayOwnLayer(aBuilder, aOther)
+ {}
+
#ifdef NS_BUILD_REFCNT_LOGGING
virtual ~nsDisplayStickyPosition();
#endif
void SetClipChain(const DisplayItemClipChain* aClipChain) override;
virtual nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
{
MOZ_COUNT_CTOR(nsDisplayStickyPosition);
- return new (aBuilder) nsDisplayStickyPosition(*this);
+ return new (aBuilder) nsDisplayStickyPosition(aBuilder, *this);
}
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) override;
NS_DISPLAY_DECL_NAME("StickyPosition", TYPE_STICKY_POSITION)
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
@@ -4717,31 +4760,38 @@ public:
nsDisplayListBuilder* aDisplayListBuilder) override;
};
class nsDisplayFixedPosition : public nsDisplayOwnLayer {
public:
nsDisplayFixedPosition(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
nsDisplayList* aList,
const ActiveScrolledRoot* aActiveScrolledRoot);
+ nsDisplayFixedPosition(nsDisplayListBuilder* aBuilder,
+ const nsDisplayFixedPosition& aOther)
+ : nsDisplayOwnLayer(aBuilder, aOther)
+ , mAnimatedGeometryRootForScrollMetadata(aOther.mAnimatedGeometryRootForScrollMetadata)
+ , mIndex(aOther.mIndex)
+ , mIsFixedBackground(aOther.mIsFixedBackground)
+ {}
static nsDisplayFixedPosition* CreateForFixedBackground(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame,
nsDisplayBackgroundImage* aImage,
uint32_t aIndex);
#ifdef NS_BUILD_REFCNT_LOGGING
virtual ~nsDisplayFixedPosition();
#endif
virtual nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
{
MOZ_COUNT_CTOR(nsDisplayFixedPosition);
- return new (aBuilder) nsDisplayFixedPosition(*this);
+ return new (aBuilder) nsDisplayFixedPosition(aBuilder, *this);
}
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) override;
NS_DISPLAY_DECL_NAME("FixedPosition", TYPE_FIXED_POSITION)
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
@@ -4913,18 +4963,19 @@ public:
nsDisplayList* aList, bool aHandleOpacity,
const ActiveScrolledRoot* aActiveScrolledRoot);
nsDisplaySVGEffects(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
nsDisplayList* aList, bool aHandleOpacity);
#ifdef NS_BUILD_REFCNT_LOGGING
virtual ~nsDisplaySVGEffects();
#endif
- nsDisplaySVGEffects(const nsDisplaySVGEffects& aOther)
- : nsDisplayWrapList(aOther)
+ nsDisplaySVGEffects(nsDisplayListBuilder* aBuilder,
+ const nsDisplaySVGEffects& aOther)
+ : nsDisplayWrapList(aBuilder, aOther)
, mEffectsBounds(aOther.mEffectsBounds)
, mHandleOpacity(aOther.mHandleOpacity)
{
MOZ_COUNT_CTOR(nsDisplaySVGEffects);
}
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aSnap) const override;
@@ -4957,24 +5008,29 @@ protected:
*/
class nsDisplayMask : public nsDisplaySVGEffects {
public:
typedef mozilla::layers::ImageLayer ImageLayer;
nsDisplayMask(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
nsDisplayList* aList, bool aHandleOpacity,
const ActiveScrolledRoot* aActiveScrolledRoot);
+ nsDisplayMask(nsDisplayListBuilder* aBuilder,
+ const nsDisplayMask& aOther)
+ : nsDisplaySVGEffects(aBuilder, aOther)
+ , mDestRects(aOther.mDestRects)
+ {}
#ifdef NS_BUILD_REFCNT_LOGGING
virtual ~nsDisplayMask();
#endif
virtual nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
{
MOZ_COUNT_CTOR(nsDisplayMask);
- return new (aBuilder) nsDisplayMask(*this);
+ return new (aBuilder) nsDisplayMask(aBuilder, *this);
}
NS_DISPLAY_DECL_NAME("Mask", TYPE_MASK)
virtual bool CanMerge(const nsDisplayItem* aItem) const override;
virtual void Merge(const nsDisplayItem* aItem) override
{
@@ -5037,24 +5093,29 @@ private:
/**
* A display item to paint a stacking context with filter effects set by the
* stacking context root frame's style.
*/
class nsDisplayFilter : public nsDisplaySVGEffects {
public:
nsDisplayFilter(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
nsDisplayList* aList, bool aHandleOpacity);
+ nsDisplayFilter(nsDisplayListBuilder* aBuilder,
+ const nsDisplayFilter& aOther)
+ : nsDisplaySVGEffects(aBuilder, aOther)
+ , mEffectsBounds(aOther.mEffectsBounds)
+ {}
#ifdef NS_BUILD_REFCNT_LOGGING
virtual ~nsDisplayFilter();
#endif
virtual nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
{
MOZ_COUNT_CTOR(nsDisplayFilter);
- return new (aBuilder) nsDisplayFilter(*this);
+ return new (aBuilder) nsDisplayFilter(aBuilder, *this);
}
NS_DISPLAY_DECL_NAME("Filter", TYPE_FILTER)
virtual bool CanMerge(const nsDisplayItem* aItem) const override
{
// Items for the same content element should be merged into a single
// compositing group.
@@ -5136,22 +5197,16 @@ class nsDisplayTransform: public nsDispl
StoreList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
nsDisplayList* aList) :
nsDisplayWrapList(aBuilder, aFrame, aList) {}
StoreList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
nsDisplayItem* aItem) :
nsDisplayWrapList(aBuilder, aFrame, aItem) {}
virtual ~StoreList() {}
- // This override is needed since StoreList is only allocated from the stack.
- virtual void Destroy(nsDisplayListBuilder* aBuilder) override
- {
- mList.DeleteAll(aBuilder);
- }
-
virtual void UpdateBounds(nsDisplayListBuilder* aBuilder) override {
// For extending 3d rendering context, the bounds would be
// updated by DoUpdateBoundsPreserves3D(), not here.
if (!mFrame->Extend3DContext()) {
nsDisplayWrapList::UpdateBounds(aBuilder);
}
}
virtual void DoUpdateBoundsPreserves3D(nsDisplayListBuilder* aBuilder) override {
@@ -5198,17 +5253,17 @@ public:
virtual ~nsDisplayTransform()
{
MOZ_COUNT_DTOR(nsDisplayTransform);
}
#endif
virtual void Destroy(nsDisplayListBuilder* aBuilder) override
{
- mStoredList.Destroy(aBuilder);
+ mStoredList.GetChildren()->DeleteAll(aBuilder);
nsDisplayItem::Destroy(aBuilder);
}
NS_DISPLAY_DECL_NAME("nsDisplayTransform", TYPE_TRANSFORM)
virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) const override
{
if (mStoredList.GetComponentAlphaBounds(aBuilder).IsEmpty())