From cf334596a821ba83834e044b28169560500e848c Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Mon, 9 Jun 2014 16:47:59 +1200 Subject: [PATCH] Bug 1022612. Part 6: Set the initial mVisibleRect for each display item to the dirty rect when we create the item. r=mattwoodrow --HG-- extra : rebase_source : 23fb5aefd5de004ca89037724aff7b34e1a5864e --- layout/base/nsDisplayList.cpp | 77 +++++++++++++++++++---------------- layout/base/nsDisplayList.h | 17 ++++---- 2 files changed, 50 insertions(+), 44 deletions(-) diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index c227ab152dda..2665f76aaf55 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -3016,28 +3016,28 @@ nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder, mReferenceFrame = aBuilder->FindReferenceFrameFor(GetTransformRootFrame(aFrame)); mToReferenceFrame = aFrame->GetOffsetToCrossDoc(mReferenceFrame); - return; - } - - // If we're a transformed frame, then we need to find out if we're inside - // the nsDisplayTransform or outside of it. Frames inside the transform - // need mReferenceFrame == mFrame, outside needs the next ancestor - // reference frame. - // If we're inside the transform, then the nsDisplayItem constructor - // will have done the right thing. - // If we're outside the transform, then we should have only one child - // (since nsDisplayTransform wraps all actual content), and that child - // will have the correct reference frame set (since nsDisplayTransform - // handles this explictly). - // - // Preserve-3d can cause us to have multiple nsDisplayTransform - // children. - nsDisplayItem *i = mList.GetBottom(); - if (i && (!i->GetAbove() || i->GetType() == TYPE_TRANSFORM) && - i->Frame() == mFrame) { - mReferenceFrame = i->ReferenceFrame(); - mToReferenceFrame = i->ToReferenceFrame(); + } else { + // If we're a transformed frame, then we need to find out if we're inside + // the nsDisplayTransform or outside of it. Frames inside the transform + // need mReferenceFrame == mFrame, outside needs the next ancestor + // reference frame. + // If we're inside the transform, then the nsDisplayItem constructor + // will have done the right thing. + // If we're outside the transform, then we should have only one child + // (since nsDisplayTransform wraps all actual content), and that child + // will have the correct reference frame set (since nsDisplayTransform + // handles this explictly). + // + // Preserve-3d can cause us to have multiple nsDisplayTransform + // children. + nsDisplayItem *i = mList.GetBottom(); + if (i && (!i->GetAbove() || i->GetType() == TYPE_TRANSFORM) && + i->Frame() == mFrame) { + mReferenceFrame = i->ReferenceFrame(); + mToReferenceFrame = i->ToReferenceFrame(); + } } + mVisibleRect = aBuilder->GetDirtyRect() + mToReferenceFrame; } nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder, @@ -3056,14 +3056,14 @@ nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder, mReferenceFrame = aBuilder->FindReferenceFrameFor(GetTransformRootFrame(aFrame)); mToReferenceFrame = aFrame->GetOffsetToCrossDoc(mReferenceFrame); - return; - } - - // See the previous nsDisplayWrapList constructor - if (aItem->Frame() == aFrame) { - mReferenceFrame = aItem->ReferenceFrame(); - mToReferenceFrame = aItem->ToReferenceFrame(); + } else { + // See the previous nsDisplayWrapList constructor + if (aItem->Frame() == aFrame) { + mReferenceFrame = aItem->ReferenceFrame(); + mToReferenceFrame = aItem->ToReferenceFrame(); + } } + mVisibleRect = aBuilder->GetDirtyRect() + mToReferenceFrame; } nsDisplayWrapList::~nsDisplayWrapList() { @@ -4336,6 +4336,15 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame mStoredList.SetClip(aBuilder, DisplayItemClip::NoClip()); } +void +nsDisplayTransform::SetReferenceFrameToAncestor(nsDisplayListBuilder* aBuilder) +{ + mReferenceFrame = + aBuilder->FindReferenceFrameFor(GetTransformRootFrame(mFrame)); + mToReferenceFrame = mFrame->GetOffsetToCrossDoc(mReferenceFrame); + mVisibleRect = aBuilder->GetDirtyRect() + mToReferenceFrame; +} + nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame, nsDisplayList *aList, uint32_t aIndex) : nsDisplayItem(aBuilder, aFrame) @@ -4345,9 +4354,7 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame { MOZ_COUNT_CTOR(nsDisplayTransform); NS_ABORT_IF_FALSE(aFrame, "Must have a frame!"); - mReferenceFrame = - aBuilder->FindReferenceFrameFor(GetTransformRootFrame(aFrame)); - mToReferenceFrame = aFrame->GetOffsetToCrossDoc(mReferenceFrame); + SetReferenceFrameToAncestor(aBuilder); mStoredList.SetClip(aBuilder, DisplayItemClip::NoClip()); } @@ -4360,9 +4367,7 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame { MOZ_COUNT_CTOR(nsDisplayTransform); NS_ABORT_IF_FALSE(aFrame, "Must have a frame!"); - mReferenceFrame = - aBuilder->FindReferenceFrameFor(GetTransformRootFrame(aFrame)); - mToReferenceFrame = aFrame->GetOffsetToCrossDoc(mReferenceFrame); + SetReferenceFrameToAncestor(aBuilder); mStoredList.SetClip(aBuilder, DisplayItemClip::NoClip()); } @@ -5051,7 +5056,7 @@ nsRegion nsDisplayTransform::GetOpaqueRegion(nsDisplayListBuilder *aBuilder, if (matrix.Is2D(&matrix2d) && matrix2d.PreservesAxisAlignedRectangles() && mStoredList.GetOpaqueRegion(aBuilder, &tmpSnap).Contains(untransformedVisible)) { - result = mVisibleRect; + result = mVisibleRect.Intersect(GetBounds(aBuilder, &tmpSnap)); } return result; } @@ -5111,7 +5116,7 @@ nsDisplayTransform::TryMerge(nsDisplayListBuilder *aBuilder, /* Now, move everything over to this frame and signal that * we merged things! */ - mStoredList.MergeFrom(&static_cast(aItem)->mStoredList); + mStoredList.MergeFromTrackingMergedFrames(&static_cast(aItem)->mStoredList); return true; } diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index 217356b9fe78..714fc07ac6d3 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -867,8 +867,10 @@ public: , mPainted(false) #endif { - mReferenceFrame = aBuilder->FindReferenceFrameFor(aFrame); - mToReferenceFrame = aBuilder->ToReferenceFrame(aFrame); + mReferenceFrame = aBuilder->FindReferenceFrameFor(aFrame, &mToReferenceFrame); + NS_ASSERTION(aBuilder->GetDirtyRect().width >= 0 || + !aBuilder->IsForPainting(), "dirty rect not set"); + mVisibleRect = aBuilder->GetDirtyRect() + mToReferenceFrame; } /** * This constructor is only used in rare cases when we need to construct @@ -885,7 +887,7 @@ public: { } virtual ~nsDisplayItem() {} - + void* operator new(size_t aSize, nsDisplayListBuilder* aBuilder) CPP_THROW_NEW { return aBuilder->Allocate(aSize); @@ -2679,14 +2681,11 @@ public: protected: nsDisplayWrapList() {} - void MergeFrom(nsDisplayWrapList* aOther) + void MergeFromTrackingMergedFrames(nsDisplayWrapList* aOther) { mList.AppendToBottom(&aOther->mList); mBounds.UnionRect(mBounds, aOther->mBounds); - } - void MergeFromTrackingMergedFrames(nsDisplayWrapList* aOther) - { - MergeFrom(aOther); + mVisibleRect.UnionRect(mVisibleRect, aOther->mVisibleRect); mMergedFrames.AppendElement(aOther->mFrame); mMergedFrames.MoveElementsFrom(aOther->mMergedFrames); } @@ -3428,6 +3427,8 @@ public: virtual void WriteDebugInfo(nsACString& aTo) MOZ_OVERRIDE; #endif private: + void SetReferenceFrameToAncestor(nsDisplayListBuilder* aBuilder); + static gfx3DMatrix GetResultingTransformMatrixInternal(const FrameTransformProperties& aProperties, const nsPoint& aOrigin, float aAppUnitsPerPixel,