--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -4771,17 +4771,17 @@ PresShell::ClipListToRange(nsDisplayList
const ActiveScrolledRoot* asr = i->GetActiveScrolledRoot();
DisplayItemClip newClip;
newClip.SetTo(textRect);
const DisplayItemClipChain* newClipChain =
aBuilder->AllocateDisplayItemClipChain(newClip, asr, nullptr);
- i->IntersectClip(aBuilder, newClipChain);
+ i->IntersectClip(aBuilder, newClipChain, true);
itemToInsert = i;
}
}
// Don't try to descend into subdocuments.
// If this ever changes we'd need to add handling for subdocuments with
// different zoom levels.
else if (content->GetUncomposedDoc() ==
aRange->GetStartContainer()->GetUncomposedDoc()) {
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -3247,19 +3247,19 @@ ClipItemsExceptCaret(nsDisplayList* aLis
if (!ShouldBeClippedByFrame(aClipFrame, i->Frame())) {
continue;
}
if (i->GetType() != DisplayItemType::TYPE_CARET) {
const DisplayItemClipChain* clip = i->GetClipChain();
const DisplayItemClipChain* intersection = nullptr;
if (aCache.Get(clip, &intersection)) {
- i->SetClipChain(intersection);
+ i->SetClipChain(intersection, true);
} else {
- i->IntersectClip(aBuilder, aExtraClip);
+ i->IntersectClip(aBuilder, aExtraClip, true);
aCache.Put(clip, i->GetClipChain());
}
}
nsDisplayList* children = i->GetSameCoordinateSystemChildren();
if (children) {
ClipItemsExceptCaret(children, aBuilder, aClipFrame, aExtraClip, aCache);
}
}
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -4942,16 +4942,22 @@ public:
nsDisplayText(nsDisplayListBuilder* aBuilder, nsTextFrame* aFrame,
const Maybe<bool>& aIsSelected);
#ifdef NS_BUILD_REFCNT_LOGGING
virtual ~nsDisplayText() {
MOZ_COUNT_DTOR(nsDisplayText);
}
#endif
+ virtual void RestoreState() override
+ {
+ nsCharClipDisplayItem::RestoreState();
+ mOpacity = 1.0f;
+ }
+
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
bool* aSnap) const override
{
*aSnap = false;
return mBounds;
}
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState,
@@ -5013,17 +5019,17 @@ public:
}
void ApplyOpacity(nsDisplayListBuilder* aBuilder,
float aOpacity,
const DisplayItemClipChain* aClip) override
{
NS_ASSERTION(CanApplyOpacity(), "ApplyOpacity should be allowed");
mOpacity = aOpacity;
- IntersectClip(aBuilder, aClip);
+ IntersectClip(aBuilder, aClip, false);
}
void WriteDebugInfo(std::stringstream& aStream) override
{
#ifdef DEBUG
aStream << " (\"";
nsTextFrame* f = static_cast<nsTextFrame*>(mFrame);
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -2094,25 +2094,25 @@ nsDisplayList::ComputeVisibilityForSubli
bool anyVisible = false;
AutoTArray<nsDisplayItem*, 512> elements;
MoveListTo(this, &elements);
for (int32_t i = elements.Length() - 1; i >= 0; --i) {
nsDisplayItem* item = elements[i];
- if (item->mForceNotVisible && !item->GetSameCoordinateSystemChildren()) {
- NS_ASSERTION(item->mVisibleRect.IsEmpty(),
+ if (item->ForceNotVisible() && !item->GetSameCoordinateSystemChildren()) {
+ NS_ASSERTION(item->GetVisibleRect().IsEmpty(),
"invisible items should have empty vis rect");
} else {
nsRect bounds = item->GetClippedBounds(aBuilder);
nsRegion itemVisible;
itemVisible.And(*aVisibleRegion, bounds);
- item->mVisibleRect = itemVisible.GetBounds();
+ item->SetVisibleRect(itemVisible.GetBounds(), false);
}
if (item->ComputeVisibility(aBuilder, aVisibleRegion)) {
anyVisible = true;
nsRegion opaque = TreatAsOpaque(item, aBuilder);
// Subtract opaque item from the visible region
aBuilder->SubtractFromVisibleRegion(aVisibleRegion, opaque);
@@ -2701,18 +2701,16 @@ void nsDisplayList::SortByContentOrder(n
nsDisplayItem::nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
: nsDisplayItem(aBuilder, aFrame,
aBuilder->CurrentActiveScrolledRoot())
{}
nsDisplayItem::nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
const ActiveScrolledRoot* aActiveScrolledRoot)
: mFrame(aFrame)
- , mClipChain(aBuilder->ClipState().GetCurrentCombinedClipChain(aBuilder))
- , mClip(DisplayItemClipChain::ClipForASR(mClipChain, aActiveScrolledRoot))
, mActiveScrolledRoot(aActiveScrolledRoot)
, mAnimatedGeometryRoot(nullptr)
, mForceNotVisible(aBuilder->IsBuildingInvisibleItems())
, mDisableSubpixelAA(false)
#ifdef MOZ_DUMP_PAINTING
, mPainted(false)
#endif
{
@@ -2724,20 +2722,23 @@ nsDisplayItem::nsDisplayItem(nsDisplayLi
// This can return the wrong result if the item override ShouldFixToViewport(),
// the item needs to set it again in its constructor.
mAnimatedGeometryRoot = aBuilder->FindAnimatedGeometryRootFor(aFrame);
MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(aBuilder->RootReferenceFrame(),
*mAnimatedGeometryRoot), "Bad");
NS_ASSERTION(aBuilder->GetVisibleRect().width >= 0 ||
!aBuilder->IsForPainting(), "visible rect not set");
+ SetClipChain(aBuilder->ClipState().GetCurrentCombinedClipChain(aBuilder), true);
+
// The visible rect is for mCurrentFrame, so we have to use
// mCurrentOffsetToReferenceFrame
- mVisibleRect = aBuilder->GetVisibleRect() +
+ nsRect visible = aBuilder->GetVisibleRect() +
aBuilder->GetCurrentFrameOffsetToReferenceFrame();
+ SetVisibleRect(visible, true);
}
/* static */ bool
nsDisplayItem::ForceActiveLayers()
{
static bool sForce = false;
static bool sForceCached = false;
@@ -2785,41 +2786,48 @@ nsDisplayItem::RecomputeVisibility(nsDis
// render those, so we don't need this check in that case.
NS_ASSERTION(mVisibleRect.IsEmpty(),
"invisible items without children should have empty vis rect");
} else {
nsRect bounds = GetClippedBounds(aBuilder);
nsRegion itemVisible;
itemVisible.And(*aVisibleRegion, bounds);
- mVisibleRect = itemVisible.GetBounds();
+ SetVisibleRect(itemVisible.GetBounds(), false);
}
// When we recompute visibility within layers we don't need to
// expand the visible region for content behind plugins (the plugin
// is not in the layer).
if (!ComputeVisibility(aBuilder, aVisibleRegion)) {
- mVisibleRect = nsRect();
+ SetVisibleRect(nsRect(), false);
return false;
}
nsRegion opaque = TreatAsOpaque(this, aBuilder);
aBuilder->SubtractFromVisibleRegion(aVisibleRegion, opaque);
return true;
}
void
-nsDisplayItem::SetClipChain(const DisplayItemClipChain* aClipChain)
+nsDisplayItem::SetClipChain(const DisplayItemClipChain* aClipChain,
+ bool aStore)
{
mClipChain = aClipChain;
mClip = DisplayItemClipChain::ClipForASR(aClipChain, mActiveScrolledRoot);
+
+ if (aStore) {
+ mState.mClipChain = mClipChain;
+ mState.mClip = mClip;
+ }
}
void
-nsDisplayItem::FuseClipChainUpTo(nsDisplayListBuilder* aBuilder, const ActiveScrolledRoot* aASR)
+nsDisplayItem::FuseClipChainUpTo(nsDisplayListBuilder* aBuilder,
+ const ActiveScrolledRoot* aASR)
{
const DisplayItemClipChain* sc = mClipChain;
DisplayItemClip mergedClip;
while (sc && ActiveScrolledRoot::PickDescendant(aASR, sc->mASR) == sc->mASR) {
mergedClip.IntersectWith(sc->mClip);
sc = sc->mParent;
}
if (mergedClip.HasClip()) {
@@ -2872,30 +2880,33 @@ FindCommonAncestorClipForIntersection(co
return aOne;
}
}
return nullptr;
}
void
nsDisplayItem::IntersectClip(nsDisplayListBuilder* aBuilder,
- const DisplayItemClipChain* aOther)
+ const DisplayItemClipChain* aOther,
+ bool aStore)
{
if (!aOther) {
return;
}
// aOther might be a reference to a clip on the stack. We need to make sure
// that CreateClipChainIntersection will allocate the actual intersected
// clip in the builder's arena, so for the mClipChain == nullptr case,
// we supply nullptr as the common ancestor so that CreateClipChainIntersection
// clones the whole chain.
const DisplayItemClipChain* ancestorClip =
mClipChain ? FindCommonAncestorClipForIntersection(mClipChain, aOther) : nullptr;
- SetClipChain(aBuilder->CreateClipChainIntersection(ancestorClip, mClipChain, aOther));
+
+ SetClipChain(aBuilder->CreateClipChainIntersection(ancestorClip, mClipChain, aOther),
+ aStore);
}
nsRect
nsDisplayItem::GetClippedBounds(nsDisplayListBuilder* aBuilder) const
{
bool snap;
nsRect r = GetBounds(aBuilder, &snap);
return GetClip().ApplyNonRoundedIntersection(r);
@@ -3152,17 +3163,17 @@ nsDisplayBackgroundImage::nsDisplayBackg
mBounds = GetBoundsInternal(aInitData.builder);
if (mShouldFixToViewport) {
mAnimatedGeometryRoot = aInitData.builder->FindAnimatedGeometryRootFor(this);
// Expand the item's visible rect to cover the entire bounds, limited to the
// viewport rect. This is necessary because the background's clip can move
// asynchronously.
if (Maybe<nsRect> viewportRect = GetViewportRectRelativeToReferenceFrame(aInitData.builder, mFrame)) {
- mVisibleRect = mBounds.Intersect(*viewportRect);
+ SetVisibleRect(mBounds.Intersect(*viewportRect), true);
}
}
}
nsDisplayBackgroundImage::~nsDisplayBackgroundImage()
{
#ifdef NS_BUILD_REFCNT_LOGGING
MOZ_COUNT_DTOR(nsDisplayBackgroundImage);
@@ -4258,17 +4269,17 @@ nsDisplayImageContainer::CanOptimizeToIm
void
nsDisplayBackgroundColor::ApplyOpacity(nsDisplayListBuilder* aBuilder,
float aOpacity,
const DisplayItemClipChain* aClip)
{
NS_ASSERTION(CanApplyOpacity(), "ApplyOpacity should be allowed");
mColor.a = mColor.a * aOpacity;
- IntersectClip(aBuilder, aClip);
+ IntersectClip(aBuilder, aClip, false);
}
bool
nsDisplayBackgroundColor::CanApplyOpacity() const
{
return true;
}
@@ -5316,17 +5327,16 @@ nsDisplayBoxShadowOuter::IsInvisibleInRe
bool
nsDisplayBoxShadowOuter::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) {
if (!nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion)) {
return false;
}
- // Store the actual visible region
mVisibleRegion.And(*aVisibleRegion, mVisibleRect);
return true;
}
LayerState
nsDisplayBoxShadowOuter::GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
@@ -5674,17 +5684,16 @@ nsDisplayBoxShadowInner::CreateWebRender
bool
nsDisplayBoxShadowInner::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) {
if (!nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion)) {
return false;
}
- // Store the actual visible region
mVisibleRegion.And(*aVisibleRegion, mVisibleRect);
return true;
}
nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame, nsDisplayList* aList)
: nsDisplayWrapList(aBuilder, aFrame, aList,
aBuilder->CurrentActiveScrolledRoot())
@@ -5722,18 +5731,20 @@ nsDisplayWrapList::nsDisplayWrapList(nsD
// handles this explictly).
nsDisplayItem *i = mListPtr->GetBottom();
if (i && (!i->GetAbove() || i->GetType() == DisplayItemType::TYPE_TRANSFORM) &&
i->Frame() == mFrame) {
mReferenceFrame = i->ReferenceFrame();
mToReferenceFrame = i->ToReferenceFrame();
}
- mVisibleRect = aBuilder->GetVisibleRect() +
+ nsRect visible = aBuilder->GetVisibleRect() +
aBuilder->GetCurrentFrameOffsetToReferenceFrame();
+
+ SetVisibleRect(visible, true);
}
nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame, nsDisplayItem* aItem)
: nsDisplayItem(aBuilder, aFrame)
, mList(aBuilder)
, mOverrideZIndex(0)
, mHasZIndexOverride(false)
@@ -5751,18 +5762,20 @@ nsDisplayWrapList::nsDisplayWrapList(nsD
}
// See the previous nsDisplayWrapList constructor
if (aItem->Frame() == aFrame) {
mReferenceFrame = aItem->ReferenceFrame();
mToReferenceFrame = aItem->ToReferenceFrame();
}
- mVisibleRect = aBuilder->GetVisibleRect() +
+ nsRect visible = aBuilder->GetVisibleRect() +
aBuilder->GetCurrentFrameOffsetToReferenceFrame();
+
+ SetVisibleRect(visible, true);
}
nsDisplayWrapList::~nsDisplayWrapList() {
MOZ_COUNT_DTOR(nsDisplayWrapList);
}
void
nsDisplayWrapList::MergeDisplayListFromItem(nsDisplayListBuilder* aBuilder,
@@ -5909,22 +5922,16 @@ nsRect nsDisplayWrapList::GetComponentAl
nsRect bounds;
for (nsDisplayItem* i = mListPtr->GetBottom(); i; i = i->GetAbove()) {
bounds.UnionRect(bounds, i->GetComponentAlphaBounds(aBuilder));
}
return bounds;
}
void
-nsDisplayWrapList::SetVisibleRect(const nsRect& aRect)
-{
- mVisibleRect = aRect;
-}
-
-void
nsDisplayWrapList::SetReferenceFrame(const nsIFrame* aFrame)
{
mReferenceFrame = aFrame;
mToReferenceFrame = mFrame->GetOffsetToCrossDoc(mReferenceFrame);
}
bool
nsDisplayWrapList::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
@@ -6016,16 +6023,17 @@ nsDisplayOpacity::nsDisplayOpacity(nsDis
nsIFrame* aFrame, nsDisplayList* aList,
const ActiveScrolledRoot* aActiveScrolledRoot,
bool aForEventsAndPluginsOnly)
: nsDisplayWrapList(aBuilder, aFrame, aList, aActiveScrolledRoot)
, mOpacity(aFrame->StyleEffects()->mOpacity)
, mForEventsAndPluginsOnly(aForEventsAndPluginsOnly)
{
MOZ_COUNT_CTOR(nsDisplayOpacity);
+ mState.mOpacity = mOpacity;
}
#ifdef NS_BUILD_REFCNT_LOGGING
nsDisplayOpacity::~nsDisplayOpacity() {
MOZ_COUNT_DTOR(nsDisplayOpacity);
}
#endif
@@ -6090,17 +6098,17 @@ nsDisplayOpacity::NeedsActiveLayer(nsDis
void
nsDisplayOpacity::ApplyOpacity(nsDisplayListBuilder* aBuilder,
float aOpacity,
const DisplayItemClipChain* aClip)
{
NS_ASSERTION(CanApplyOpacity(), "ApplyOpacity should be allowed");
mOpacity = mOpacity * aOpacity;
- IntersectClip(aBuilder, aClip);
+ IntersectClip(aBuilder, aClip, false);
}
bool
nsDisplayOpacity::CanApplyOpacity() const
{
return true;
}
@@ -6975,24 +6983,31 @@ nsDisplayTableFixedPosition::CreateForFi
nsDisplayStickyPosition::nsDisplayStickyPosition(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame,
nsDisplayList* aList,
const ActiveScrolledRoot* aActiveScrolledRoot)
: nsDisplayOwnLayer(aBuilder, aFrame, aList, aActiveScrolledRoot)
{
MOZ_COUNT_CTOR(nsDisplayStickyPosition);
- mClip = nullptr;
}
void
-nsDisplayStickyPosition::SetClipChain(const DisplayItemClipChain* aClipChain)
+nsDisplayStickyPosition::SetClipChain(const DisplayItemClipChain* aClipChain,
+ bool aStore)
{
mClipChain = aClipChain;
+ mClip = nullptr;
+
MOZ_ASSERT(!mClip, "There should never be a clip on this item because no clip moves with it.");
+
+ if (aStore) {
+ mState.mClipChain = aClipChain;
+ mState.mClip = mClip;
+ }
}
#ifdef NS_BUILD_REFCNT_LOGGING
nsDisplayStickyPosition::~nsDisplayStickyPosition() {
MOZ_COUNT_DTOR(nsDisplayStickyPosition);
}
#endif
@@ -7386,25 +7401,26 @@ nsDisplayTransform::SetReferenceFrameToA
// If we're an animated transform then we want the same AGR as our children
// so that FrameLayerBuilder knows that this layer moves with the transform
// and won't compute occlusions. If we're not animated then use our parent
// AGR so that inactive transform layers can go in the same PaintedLayer as
// surrounding content.
mAnimatedGeometryRoot = mAnimatedGeometryRoot->mParentAGR;
}
}
- mVisibleRect = aBuilder->GetDirtyRect() + mToReferenceFrame;
+
+ SetVisibleRect(aBuilder->GetVisibleRect() + mToReferenceFrame, true);
}
void
nsDisplayTransform::Init(nsDisplayListBuilder* aBuilder)
{
mHasBounds = false;
- mStoredList.SetClipChain(nullptr);
- mStoredList.SetVisibleRect(mChildrenVisibleRect);
+ mStoredList.SetClipChain(nullptr, true);
+ mStoredList.SetVisibleRect(mChildrenVisibleRect, true);
}
nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
nsIFrame *aFrame, nsDisplayList *aList,
const nsRect& aChildrenVisibleRect,
uint32_t aIndex,
bool aAllowAsyncAnimation)
: nsDisplayItem(aBuilder, aFrame)
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -1802,16 +1802,24 @@ public:
virtual void Destroy(nsDisplayListBuilder* aBuilder)
{
DisplayItemType type = GetType();
this->~nsDisplayItem();
aBuilder->Destroy(type, this);
}
+ virtual void RestoreState()
+ {
+ mVisibleRect = mState.mVisibleRect;
+ mClipChain = mState.mClipChain;
+ mClip = mState.mClip;
+ mDisableSubpixelAA = false;
+ }
+
virtual void RemoveFrame(nsIFrame* aFrame)
{
if (aFrame == mFrame) {
MOZ_ASSERT(!mFrame->HasDisplayItem(this));
mFrame = nullptr;
}
}
@@ -2318,16 +2326,25 @@ public:
*/
virtual nsDisplayList* GetChildren() const { return nullptr; }
/**
* Returns the visible rect.
*/
const nsRect& GetVisibleRect() const { return mVisibleRect; }
+ void SetVisibleRect(const nsRect& aVisibleRect, bool aStore)
+ {
+ mVisibleRect = aVisibleRect;
+
+ if (aStore) {
+ mState.mVisibleRect = mVisibleRect;
+ }
+ }
+
/**
* Returns the visible rect for the children, relative to their
* reference frame. Can be different from mVisibleRect for nsDisplayTransform,
* since the reference frame for the children is different from the reference
* frame for the item itself.
*/
virtual const nsRect& GetVisibleRectForChildren() const { return mVisibleRect; }
@@ -2423,22 +2440,23 @@ public:
}
virtual bool SupportsOptimizingToImage() const { return false; }
const DisplayItemClip& GetClip() const
{
return mClip ? *mClip : DisplayItemClip::NoClip();
}
- void IntersectClip(nsDisplayListBuilder* aBuilder, const DisplayItemClipChain* aOther);
+ void IntersectClip(nsDisplayListBuilder* aBuilder, const DisplayItemClipChain* aOther, bool aStore);
void SetActiveScrolledRoot(const ActiveScrolledRoot* aActiveScrolledRoot) { mActiveScrolledRoot = aActiveScrolledRoot; }
const ActiveScrolledRoot* GetActiveScrolledRoot() const { return mActiveScrolledRoot; }
- virtual void SetClipChain(const DisplayItemClipChain* aClipChain);
+ virtual void SetClipChain(const DisplayItemClipChain* aClipChain,
+ bool aStore);
const DisplayItemClipChain* GetClipChain() const { return mClipChain; }
/**
* Intersect all clips in our clip chain up to (and including) aASR and set
* set the intersection as this item's clip.
*/
void FuseClipChainUpTo(nsDisplayListBuilder* aBuilder,
const ActiveScrolledRoot* aASR);
@@ -2457,17 +2475,16 @@ public:
}
bool HasSameContent(const nsDisplayItem* aOther) const
{
return mFrame->GetContent() == aOther->Frame()->GetContent();
}
protected:
- friend class nsDisplayList;
nsDisplayItem() = delete;
typedef bool (*PrefFunc)(void);
bool ShouldUseAdvancedLayer(LayerManager* aManager, PrefFunc aFunc) const;
bool CanUseAdvancedLayer(LayerManager* aManager) const;
nsIFrame* mFrame;
const DisplayItemClipChain* mClipChain;
@@ -2486,16 +2503,22 @@ protected:
// Guaranteed to be contained in GetBounds().
nsRect mVisibleRect;
bool mForceNotVisible;
bool mDisableSubpixelAA;
#ifdef MOZ_DUMP_PAINTING
// True if this frame has been painted.
bool mPainted;
#endif
+
+ struct {
+ nsRect mVisibleRect;
+ const DisplayItemClipChain* mClipChain;
+ const DisplayItemClip* mClip;
+ } mState;
};
/**
* Manages a singly-linked list of display list items.
*
* mSentinel is the sentinel list value, the first value in the null-terminated
* linked list of items. mTop is the last item in the list (whose 'above'
* pointer is null). This class has no virtual methods. So list objects are just
@@ -2804,16 +2827,22 @@ public:
mIsOpaque = true;
}
void SetNeedsTransparentSurface()
{
mForceTransparentSurface = true;
}
nsDisplayListBuilder* mBuilder;
+
+ void RestoreState() {
+ mIsOpaque = false;
+ mForceTransparentSurface = false;
+ }
+
private:
// This class is only used on stack, so we don't have to worry about leaking
// it. Don't let us be heap-allocated!
void* operator new(size_t sz) CPP_THROW_NEW;
nsDisplayItemLink mSentinel;
nsDisplayItemLink* mTop;
@@ -3692,17 +3721,25 @@ public:
nsDisplayBackgroundColor(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
const nsRect& aBackgroundRect,
const nsStyleBackground* aBackgroundStyle,
nscolor aColor)
: nsDisplayItem(aBuilder, aFrame)
, mBackgroundRect(aBackgroundRect)
, mBackgroundStyle(aBackgroundStyle)
, mColor(Color::FromABGR(aColor))
- { }
+ {
+ mState.mColor = mColor;
+ }
+
+ virtual void RestoreState() override
+ {
+ nsDisplayItem::RestoreState();
+ mColor = mState.mColor;
+ }
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aParameters) override;
virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) override;
@@ -3749,16 +3786,19 @@ public:
NS_DISPLAY_DECL_NAME("BackgroundColor", TYPE_BACKGROUND_COLOR)
virtual void WriteDebugInfo(std::stringstream& aStream) override;
protected:
const nsRect mBackgroundRect;
const nsStyleBackground* mBackgroundStyle;
mozilla::gfx::Color mColor;
+ struct {
+ mozilla::gfx::Color mColor;
+ } mState;
};
class nsDisplayTableBackgroundColor : public nsDisplayBackgroundColor
{
public:
nsDisplayTableBackgroundColor(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
const nsRect& aBackgroundRect,
const nsStyleBackground* aBackgroundStyle,
@@ -3851,23 +3891,30 @@ public:
nsRegion* aInvalidRegion) const override;
virtual void ApplyOpacity(nsDisplayListBuilder* aBuilder,
float aOpacity,
const DisplayItemClipChain* aClip) override
{
NS_ASSERTION(CanApplyOpacity(), "ApplyOpacity should be allowed");
mOpacity = aOpacity;
- IntersectClip(aBuilder, aClip);
+ IntersectClip(aBuilder, aClip, false);
}
virtual bool CanApplyOpacity() const override
{
return true;
}
+ virtual void RestoreState() override
+ {
+ nsDisplayItem::RestoreState();
+ mVisibleRegion.SetEmpty();
+ mOpacity = 1.0f;
+ }
+
virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override
{
return new nsDisplayBoxShadowOuterGeometry(this, aBuilder, mOpacity);
}
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aParameters) override;
@@ -3899,16 +3946,22 @@ public:
MOZ_COUNT_CTOR(nsDisplayBoxShadowInner);
}
#ifdef NS_BUILD_REFCNT_LOGGING
virtual ~nsDisplayBoxShadowInner() {
MOZ_COUNT_DTOR(nsDisplayBoxShadowInner);
}
#endif
+ virtual void RestoreState() override
+ {
+ nsDisplayItem::RestoreState();
+ mVisibleRegion.SetEmpty();
+ }
+
virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) override;
NS_DISPLAY_DECL_NAME("BoxShadowInner", TYPE_BOX_SHADOW_INNER)
virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override
{
return new nsDisplayBoxShadowInnerGeometry(this, aBuilder);
@@ -4197,16 +4250,17 @@ public:
// The display list may contain content that's visible outside the visible
// rect (i.e. the current dirty rect) passed in when the item was created.
// This happens when the dirty rect has been restricted to the visual
// overflow rect of a frame for some reason (e.g. when setting up dirty
// rects in nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay), but that
// frame contains placeholders for out-of-flows that aren't descendants of
// the frame.
mVisibleRect.UnionRect(mBaseVisibleRect, visibleRect);
+ mState.mVisibleRect = mVisibleRect;
}
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) override;
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
bool* aSnap) const override;
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aSnap) const override;
virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) const override;
@@ -4272,18 +4326,16 @@ public:
}
void SetOverrideZIndex(int32_t aZIndex)
{
mHasZIndexOverride = true;
mOverrideZIndex = aZIndex;
}
- void SetVisibleRect(const nsRect& aRect);
-
void SetReferenceFrame(const nsIFrame* aFrame);
/**
* This creates a copy of this item, but wrapping aItem instead of
* our existing list. Only gets called if this item returned nullptr
* for GetUnderlyingFrame(). aItem is guaranteed to return non-null from
* GetUnderlyingFrame().
*/
@@ -4364,16 +4416,22 @@ public:
: nsDisplayWrapList(aBuilder, aOther)
, mOpacity(aOther.mOpacity)
, mForEventsAndPluginsOnly(aOther.mForEventsAndPluginsOnly)
{}
#ifdef NS_BUILD_REFCNT_LOGGING
virtual ~nsDisplayOpacity();
#endif
+ virtual void RestoreState() override
+ {
+ nsDisplayItem::RestoreState();
+ mOpacity = mState.mOpacity;
+ }
+
virtual nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
{
MOZ_COUNT_CTOR(nsDisplayOpacity);
return new (aBuilder) nsDisplayOpacity(aBuilder, *this);
}
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aSnap) const override;
@@ -4422,16 +4480,20 @@ public:
mozilla::wr::IpcResourceUpdateQueue& aResources,
const StackingContextHelper& aSc,
mozilla::layers::WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder) override;
private:
float mOpacity;
bool mForEventsAndPluginsOnly;
+
+ struct {
+ float mOpacity;
+ } mState;
};
class nsDisplayBlendMode : public nsDisplayWrapList {
public:
nsDisplayBlendMode(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
nsDisplayList* aList, uint8_t aBlendMode,
const ActiveScrolledRoot* aActiveScrolledRoot,
uint32_t aIndex = 0);
@@ -4724,17 +4786,17 @@ public:
const nsDisplayStickyPosition& aOther)
: nsDisplayOwnLayer(aBuilder, aOther)
{}
#ifdef NS_BUILD_REFCNT_LOGGING
virtual ~nsDisplayStickyPosition();
#endif
- void SetClipChain(const DisplayItemClipChain* aClipChain) override;
+ void SetClipChain(const DisplayItemClipChain* aClipChain, bool aStore) override;
virtual nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
{
MOZ_COUNT_CTOR(nsDisplayStickyPosition);
return new (aBuilder) nsDisplayStickyPosition(aBuilder, *this);
}
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
@@ -5251,16 +5313,23 @@ public:
#ifdef NS_BUILD_REFCNT_LOGGING
virtual ~nsDisplayTransform()
{
MOZ_COUNT_DTOR(nsDisplayTransform);
}
#endif
+ virtual void UpdateBounds(nsDisplayListBuilder* aBuilder) override
+ {
+ mStoredList.UpdateBounds(aBuilder);
+ mHasBounds = false;
+ UpdateBoundsFor3D(aBuilder);
+ }
+
virtual void Destroy(nsDisplayListBuilder* aBuilder) override
{
mStoredList.GetChildren()->DeleteAll(aBuilder);
nsDisplayItem::Destroy(aBuilder);
}
NS_DISPLAY_DECL_NAME("nsDisplayTransform", TYPE_TRANSFORM)
@@ -5600,16 +5669,21 @@ public:
}
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
bool* aSnap) const override
{
return mList.GetBounds(aBuilder, aSnap);
}
+ virtual void UpdateBounds(nsDisplayListBuilder* aBuilder) override
+ {
+ mList.UpdateBounds(aBuilder);
+ }
+
virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion* aInvalidRegion) const override
{}
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aSnap) const override
{
@@ -5702,16 +5776,22 @@ private:
class nsCharClipDisplayItem : public nsDisplayItem {
public:
nsCharClipDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
: nsDisplayItem(aBuilder, aFrame), mVisIStartEdge(0), mVisIEndEdge(0) {}
explicit nsCharClipDisplayItem(nsIFrame* aFrame)
: nsDisplayItem(aFrame), mVisIStartEdge(0), mVisIEndEdge(0) {}
+ virtual void RestoreState() override
+ {
+ nsDisplayItem::RestoreState();
+ mIsFrameSelected.reset();
+ }
+
virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override;
virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion* aInvalidRegion) const override;
struct ClipEdges {
ClipEdges(const nsDisplayItem& aItem,