Bug 1222880 - Build a tree of AnimatedGeometryRoots to speed up traversal of ancestors. r=roc,tn

This commit is contained in:
Matt Woodrow 2015-11-25 11:53:51 +13:00
Родитель 83ffe1f565
Коммит 41a4ad2285
8 изменённых файлов: 319 добавлений и 342 удалений

Просмотреть файл

@ -454,7 +454,7 @@ public:
const nsIntRect& aVisibleRect,
const DisplayItemClip& aClip,
LayerState aLayerState);
const nsIFrame* GetAnimatedGeometryRoot() { return mAnimatedGeometryRoot; }
AnimatedGeometryRoot* GetAnimatedGeometryRoot() { return mAnimatedGeometryRoot; }
/**
* Add the given hit regions to the hit regions to the hit retions for this
@ -537,11 +537,11 @@ public:
* be non-null; all content in a PaintedLayer must have the same
* active scrolled root.
*/
const nsIFrame* mAnimatedGeometryRoot;
AnimatedGeometryRoot* mAnimatedGeometryRoot;
/**
* See NewLayerEntry::mAnimatedGeometryRootForScrollMetadata.
*/
const nsIFrame* mAnimatedGeometryRootForScrollMetadata;
AnimatedGeometryRoot* mAnimatedGeometryRootForScrollMetadata;
/**
* The offset between mAnimatedGeometryRoot and the reference frame.
*/
@ -679,13 +679,13 @@ struct NewLayerEntry {
// mLayer is null if the previous entry is for a PaintedLayer that hasn't
// been optimized to some other form (yet).
RefPtr<Layer> mLayer;
const nsIFrame* mAnimatedGeometryRoot;
AnimatedGeometryRoot* mAnimatedGeometryRoot;
// For fixed background layers, mAnimatedGeometryRoot is the animated geometry
// root of the viewport frame it's fixed to, but we need to annotate it with
// scroll metadata starting from the animated geometry root of the element
// it's the background of, so that during async scrolling we can correctly
// transform the fixed layer's clip.
const nsIFrame* mAnimatedGeometryRootForScrollMetadata;
AnimatedGeometryRoot* mAnimatedGeometryRootForScrollMetadata;
const nsIFrame* mFixedPosFrameForLayerData;
// If non-null, this FrameMetrics is set to the be the first FrameMetrics
// on the layer.
@ -745,10 +745,10 @@ class PaintedLayerDataNode {
public:
PaintedLayerDataNode(PaintedLayerDataTree& aTree,
PaintedLayerDataNode* aParent,
const nsIFrame* aAnimatedGeometryRoot);
AnimatedGeometryRoot* aAnimatedGeometryRoot);
~PaintedLayerDataNode();
const nsIFrame* AnimatedGeometryRoot() const { return mAnimatedGeometryRoot; }
AnimatedGeometryRoot* GetAnimatedGeometryRoot() const { return mAnimatedGeometryRoot; }
/**
* Whether this node's contents can potentially intersect aRect.
@ -761,7 +761,7 @@ public:
* Create a PaintedLayerDataNode for aAnimatedGeometryRoot, add it to our
* children, and return it.
*/
PaintedLayerDataNode* AddChildNodeFor(const nsIFrame* aAnimatedGeometryRoot);
PaintedLayerDataNode* AddChildNodeFor(AnimatedGeometryRoot* aAnimatedGeometryRoot);
/**
* Find a PaintedLayerData in our mPaintedLayerDataStack that aItem can be
@ -843,7 +843,7 @@ protected:
PaintedLayerDataTree& mTree;
PaintedLayerDataNode* mParent;
const nsIFrame* mAnimatedGeometryRoot;
AnimatedGeometryRoot* mAnimatedGeometryRoot;
/**
* Our contents: a PaintedLayerData stack and our child nodes.
@ -933,7 +933,7 @@ public:
* color that can be pulled into the background of the added content, or
* transparent if that is not possible.
*/
void AddingOwnLayer(const nsIFrame* aAnimatedGeometryRoot,
void AddingOwnLayer(AnimatedGeometryRoot* aAnimatedGeometryRoot,
const nsIntRect* aRect,
nscolor* aOutUniformBackgroundColor);
@ -943,7 +943,7 @@ public:
* created by a call out to aNewPaintedLayerCallback.
*/
template<typename NewPaintedLayerCallbackType>
PaintedLayerData* FindPaintedLayerFor(const nsIFrame* aAnimatedGeometryRoot,
PaintedLayerData* FindPaintedLayerFor(AnimatedGeometryRoot* aAnimatedGeometryRoot,
const nsIntRect& aVisibleRect,
bool aForceOwnLayer,
bool aBackfaceidden,
@ -960,7 +960,7 @@ public:
* that's aAnimatedGeometryRoot itself, then it's the animated geometry
* root for aAnimatedGeometryRoot's cross-doc parent frame.
*/
const nsIFrame* GetParentAnimatedGeometryRoot(const nsIFrame* aAnimatedGeometryRoot);
AnimatedGeometryRoot* GetParentAnimatedGeometryRoot(AnimatedGeometryRoot* aAnimatedGeometryRoot);
/**
* Whether aAnimatedGeometryRoot has an intrinsic clip that doesn't move with
@ -971,14 +971,14 @@ public:
* where we have easy access to a display list builder, which we use to get
* the clip rect result into the right coordinate space.
*/
bool IsClippedWithRespectToParentAnimatedGeometryRoot(const nsIFrame* aAnimatedGeometryRoot,
bool IsClippedWithRespectToParentAnimatedGeometryRoot(AnimatedGeometryRoot* aAnimatedGeometryRoot,
nsIntRect* aOutClip);
/**
* Called by PaintedLayerDataNode when it is finished, so that we can drop
* our pointers to it.
*/
void NodeWasFinished(const nsIFrame* aAnimatedGeometryRoot);
void NodeWasFinished(AnimatedGeometryRoot* aAnimatedGeometryRoot);
nsDisplayListBuilder* Builder() const;
ContainerState& ContState() const { return mContainerState; }
@ -990,14 +990,14 @@ protected:
* that doesn't move with respect to aAnimatedGeometryRoot.
* If aRect is null, *aRect will be considered infinite.
*/
void FinishPotentiallyIntersectingNodes(const nsIFrame* aAnimatedGeometryRoot,
void FinishPotentiallyIntersectingNodes(AnimatedGeometryRoot* aAnimatedGeometryRoot,
const nsIntRect* aRect);
/**
* Make sure that there is a node for aAnimatedGeometryRoot and all of its
* ancestor geometry roots. Return the node for aAnimatedGeometryRoot.
*/
PaintedLayerDataNode* EnsureNodeFor(const nsIFrame* aAnimatedGeometryRoot);
PaintedLayerDataNode* EnsureNodeFor(AnimatedGeometryRoot* aAnimatedGeometryRoot);
/**
* Find an existing node in the tree for an ancestor of aAnimatedGeometryRoot.
@ -1006,8 +1006,8 @@ protected:
* geometry root of the result, if neither are null.
*/
PaintedLayerDataNode*
FindNodeForAncestorAnimatedGeometryRoot(const nsIFrame* aAnimatedGeometryRoot,
const nsIFrame** aOutAncestorChild);
FindNodeForAncestorAnimatedGeometryRoot(AnimatedGeometryRoot* aAnimatedGeometryRoot,
AnimatedGeometryRoot** aOutAncestorChild);
ContainerState& mContainerState;
UniquePtr<PaintedLayerDataNode> mRoot;
@ -1024,7 +1024,7 @@ protected:
* A hash map for quick access the node belonging to a particular animated
* geometry root.
*/
nsDataHashtable<nsPtrHashKey<const nsIFrame>, PaintedLayerDataNode*> mNodes;
nsDataHashtable<nsPtrHashKey<AnimatedGeometryRoot>, PaintedLayerDataNode*> mNodes;
};
/**
@ -1060,11 +1060,11 @@ public:
bool isAtRoot = !aContainerItem || (aContainerItem->Frame() == mBuilder->RootReferenceFrame());
MOZ_ASSERT_IF(isAtRoot, mContainerReferenceFrame == mBuilder->RootReferenceFrame());
mContainerAnimatedGeometryRoot = isAtRoot
? mContainerReferenceFrame
: aContainerItem->AnimatedGeometryRoot();
? aBuilder->GetRootAnimatedGeometryRoot()
: aContainerItem->GetAnimatedGeometryRoot();
MOZ_ASSERT(!mBuilder->IsPaintingToWindow() ||
nsLayoutUtils::IsAncestorFrameCrossDoc(mBuilder->RootReferenceFrame(),
mContainerAnimatedGeometryRoot));
*mContainerAnimatedGeometryRoot));
NS_ASSERTION(!aContainerItem || !aContainerItem->ShouldFixToViewport(mBuilder),
"Container items never return true for ShouldFixToViewport");
mContainerFixedPosFrame =
@ -1188,7 +1188,7 @@ protected:
friend class PaintedLayerData;
LayerManager::PaintedLayerCreationHint
GetLayerCreationHint(const nsIFrame* aAnimatedGeometryRoot);
GetLayerCreationHint(AnimatedGeometryRoot* aAnimatedGeometryRoot);
/**
* Creates a new PaintedLayer and sets up the transform on the PaintedLayer
@ -1200,14 +1200,14 @@ protected:
* Find a PaintedLayer for recycling, recycle it and prepare it for use, or
* return null if no suitable layer was found.
*/
already_AddRefed<PaintedLayer> AttemptToRecyclePaintedLayer(const nsIFrame* aAnimatedGeometryRoot,
already_AddRefed<PaintedLayer> AttemptToRecyclePaintedLayer(AnimatedGeometryRoot* aAnimatedGeometryRoot,
nsDisplayItem* aItem,
const nsPoint& aTopLeft);
/**
* Recycle aLayer and do any necessary invalidation.
*/
PaintedDisplayItemLayerUserData* RecyclePaintedLayer(PaintedLayer* aLayer,
const nsIFrame* aAnimatedGeometryRoot,
AnimatedGeometryRoot* aAnimatedGeometryRoot,
bool& didResetScrollPositionForLayerPixelAlignment);
/**
@ -1217,7 +1217,7 @@ protected:
*/
void PreparePaintedLayerForUse(PaintedLayer* aLayer,
PaintedDisplayItemLayerUserData* aData,
const nsIFrame* aAnimatedGeometryRoot,
AnimatedGeometryRoot* aAnimatedGeometryRoot,
const nsIFrame* aReferenceFrame,
const nsPoint& aTopLeft,
bool aDidResetScrollPositionForLayerPixelAlignment);
@ -1277,7 +1277,7 @@ protected:
* This can return the actual viewport frame for layers whose display items
* are directly on the viewport (e.g. background-attachment:fixed backgrounds).
*/
const nsIFrame* FindFixedPosFrameForLayerData(const nsIFrame* aAnimatedGeometryRoot,
const nsIFrame* FindFixedPosFrameForLayerData(AnimatedGeometryRoot* aAnimatedGeometryRoot,
bool aDisplayItemFixedToViewport);
/**
* Set fixed-pos layer metadata on aLayer according to the data for aFixedPosFrame.
@ -1317,7 +1317,7 @@ protected:
* permanently invisible.
*/
nsIntRegion ComputeOpaqueRect(nsDisplayItem* aItem,
const nsIFrame* aAnimatedGeometryRoot,
AnimatedGeometryRoot* aAnimatedGeometryRoot,
const nsIFrame* aFixedPosFrame,
const DisplayItemClip& aClip,
nsDisplayList* aList,
@ -1343,8 +1343,8 @@ protected:
*/
PaintedLayerData NewPaintedLayerData(nsDisplayItem* aItem,
const nsIntRect& aVisibleRect,
const nsIFrame* aAnimatedGeometryRoot,
const nsIFrame* aAnimatedGeometryRootForScrollMetadata,
AnimatedGeometryRoot* aAnimatedGeometryRoot,
AnimatedGeometryRoot* aAnimatedGeometryRootForScrollMetadata,
const nsPoint& aTopLeft,
bool aShouldFixToViewport);
@ -1370,14 +1370,14 @@ protected:
uint32_t aRoundedRectClipCount = UINT32_MAX);
bool ChooseAnimatedGeometryRoot(const nsDisplayList& aList,
const nsIFrame **aAnimatedGeometryRoot);
AnimatedGeometryRoot **aAnimatedGeometryRoot);
nsDisplayListBuilder* mBuilder;
LayerManager* mManager;
FrameLayerBuilder* mLayerBuilder;
nsIFrame* mContainerFrame;
nsIFrame* mContainerReferenceFrame;
const nsIFrame* mContainerAnimatedGeometryRoot;
AnimatedGeometryRoot* mContainerAnimatedGeometryRoot;
const nsIFrame* mContainerFixedPosFrame;
ContainerLayer* mContainerLayer;
nsRect mContainerBounds;
@ -2087,16 +2087,16 @@ RoundToMatchResidual(double aValue, double aOldResidual)
}
static void
ResetScrollPositionForLayerPixelAlignment(const nsIFrame* aAnimatedGeometryRoot)
ResetScrollPositionForLayerPixelAlignment(AnimatedGeometryRoot* aAnimatedGeometryRoot)
{
nsIScrollableFrame* sf = nsLayoutUtils::GetScrollableFrameFor(aAnimatedGeometryRoot);
nsIScrollableFrame* sf = nsLayoutUtils::GetScrollableFrameFor(*aAnimatedGeometryRoot);
if (sf) {
sf->ResetScrollPositionForLayerPixelAlignment();
}
}
static void
InvalidateEntirePaintedLayer(PaintedLayer* aLayer, const nsIFrame* aAnimatedGeometryRoot, const char *aReason)
InvalidateEntirePaintedLayer(PaintedLayer* aLayer, AnimatedGeometryRoot* aAnimatedGeometryRoot, const char *aReason)
{
#ifdef MOZ_DUMP_PAINTING
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
@ -2110,18 +2110,17 @@ InvalidateEntirePaintedLayer(PaintedLayer* aLayer, const nsIFrame* aAnimatedGeom
}
LayerManager::PaintedLayerCreationHint
ContainerState::GetLayerCreationHint(const nsIFrame* aAnimatedGeometryRoot)
ContainerState::GetLayerCreationHint(AnimatedGeometryRoot* aAnimatedGeometryRoot)
{
// Check whether the layer will be scrollable. This is used as a hint to
// influence whether tiled layers are used or not.
// Check whether there's any active scroll frame on the animated geometry
// root chain.
nsIFrame* fParent;
for (const nsIFrame* f = aAnimatedGeometryRoot;
f != mContainerAnimatedGeometryRoot;
f = nsLayoutUtils::GetAnimatedGeometryRootForFrame(mBuilder, fParent)) {
fParent = nsLayoutUtils::GetCrossDocParentFrame(f);
for (AnimatedGeometryRoot* agr = aAnimatedGeometryRoot;
agr != mContainerAnimatedGeometryRoot;
agr = agr->mParentAGR) {
nsIFrame* fParent = nsLayoutUtils::GetCrossDocParentFrame(*agr);
if (!fParent) {
break;
}
@ -2142,7 +2141,7 @@ ContainerState::GetLayerCreationHint(const nsIFrame* aAnimatedGeometryRoot)
}
already_AddRefed<PaintedLayer>
ContainerState::AttemptToRecyclePaintedLayer(const nsIFrame* aAnimatedGeometryRoot,
ContainerState::AttemptToRecyclePaintedLayer(AnimatedGeometryRoot* aAnimatedGeometryRoot,
nsDisplayItem* aItem,
const nsPoint& aTopLeft)
{
@ -2199,7 +2198,7 @@ ContainerState::CreatePaintedLayer(PaintedLayerData* aData)
PaintedDisplayItemLayerUserData*
ContainerState::RecyclePaintedLayer(PaintedLayer* aLayer,
const nsIFrame* aAnimatedGeometryRoot,
AnimatedGeometryRoot* aAnimatedGeometryRoot,
bool& didResetScrollPositionForLayerPixelAlignment)
{
// Clear clip rect and mask layer so we don't accidentally stay clipped.
@ -2253,7 +2252,7 @@ ContainerState::RecyclePaintedLayer(PaintedLayer* aLayer,
static void
ComputeAndSetIgnoreInvalidationRect(PaintedLayer* aLayer,
PaintedDisplayItemLayerUserData* aData,
const nsIFrame* aAnimatedGeometryRoot,
AnimatedGeometryRoot* aAnimatedGeometryRoot,
nsDisplayListBuilder* aBuilder,
const nsIntPoint& aLayerTranslation)
{
@ -2262,7 +2261,7 @@ ComputeAndSetIgnoreInvalidationRect(PaintedLayer* aLayer,
return;
}
const nsIFrame* parentFrame = aAnimatedGeometryRoot->GetParent();
const nsIFrame* parentFrame = (*aAnimatedGeometryRoot)->GetParent();
// GetDirtyRectForScrolledContents will return an empty rect if parentFrame
// is not a scrollable frame.
@ -2336,7 +2335,7 @@ ComputeAndSetIgnoreInvalidationRect(PaintedLayer* aLayer,
void
ContainerState::PreparePaintedLayerForUse(PaintedLayer* aLayer,
PaintedDisplayItemLayerUserData* aData,
const nsIFrame* aAnimatedGeometryRoot,
AnimatedGeometryRoot* aAnimatedGeometryRoot,
const nsIFrame* aReferenceFrame,
const nsPoint& aTopLeft,
bool didResetScrollPositionForLayerPixelAlignment)
@ -2352,8 +2351,8 @@ ContainerState::PreparePaintedLayerForUse(PaintedLayer* aLayer,
// Set up transform so that 0,0 in the PaintedLayer corresponds to the
// (pixel-snapped) top-left of the aAnimatedGeometryRoot.
nsPoint offset = aAnimatedGeometryRoot->GetOffsetToCrossDoc(aReferenceFrame);
nscoord appUnitsPerDevPixel = aAnimatedGeometryRoot->PresContext()->AppUnitsPerDevPixel();
nsPoint offset = (*aAnimatedGeometryRoot)->GetOffsetToCrossDoc(aReferenceFrame);
nscoord appUnitsPerDevPixel = (*aAnimatedGeometryRoot)->PresContext()->AppUnitsPerDevPixel();
gfxPoint scaledOffset(
NSAppUnitsToDoublePixels(offset.x, appUnitsPerDevPixel)*mParameters.mXScale,
NSAppUnitsToDoublePixels(offset.y, appUnitsPerDevPixel)*mParameters.mYScale);
@ -2638,13 +2637,13 @@ PaintedLayerData::GetContainerForImageLayer(nsDisplayListBuilder* aBuilder)
PaintedLayerDataNode::PaintedLayerDataNode(PaintedLayerDataTree& aTree,
PaintedLayerDataNode* aParent,
const nsIFrame* aAnimatedGeometryRoot)
AnimatedGeometryRoot* aAnimatedGeometryRoot)
: mTree(aTree)
, mParent(aParent)
, mAnimatedGeometryRoot(aAnimatedGeometryRoot)
, mAllDrawingAboveBackground(false)
{
MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(mTree.Builder()->RootReferenceFrame(), mAnimatedGeometryRoot));
MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(mTree.Builder()->RootReferenceFrame(), *mAnimatedGeometryRoot));
mHasClip = mTree.IsClippedWithRespectToParentAnimatedGeometryRoot(mAnimatedGeometryRoot, &mClipRect);
}
@ -2655,9 +2654,9 @@ PaintedLayerDataNode::~PaintedLayerDataNode()
}
PaintedLayerDataNode*
PaintedLayerDataNode::AddChildNodeFor(const nsIFrame* aAnimatedGeometryRoot)
PaintedLayerDataNode::AddChildNodeFor(AnimatedGeometryRoot* aAnimatedGeometryRoot)
{
MOZ_ASSERT(mTree.GetParentAnimatedGeometryRoot(aAnimatedGeometryRoot) == mAnimatedGeometryRoot);
MOZ_ASSERT(aAnimatedGeometryRoot->mParentAGR == mAnimatedGeometryRoot);
UniquePtr<PaintedLayerDataNode> child =
MakeUnique<PaintedLayerDataNode>(mTree, this, aAnimatedGeometryRoot);
mChildren.AppendElement(Move(child));
@ -2790,31 +2789,6 @@ PaintedLayerDataTree::Builder() const
return mContainerState.Builder();
}
const nsIFrame*
PaintedLayerDataTree::GetParentAnimatedGeometryRoot(const nsIFrame* aAnimatedGeometryRoot)
{
MOZ_ASSERT(aAnimatedGeometryRoot);
MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(Builder()->RootReferenceFrame(), aAnimatedGeometryRoot));
if (aAnimatedGeometryRoot == Builder()->RootReferenceFrame()) {
return nullptr;
}
nsIFrame* agr = Builder()->FindAnimatedGeometryRootFor(
const_cast<nsIFrame*>(aAnimatedGeometryRoot));
MOZ_ASSERT_IF(agr, nsLayoutUtils::IsAncestorFrameCrossDoc(Builder()->RootReferenceFrame(), agr));
if (agr != aAnimatedGeometryRoot) {
return agr;
}
// aAnimatedGeometryRoot is its own animated geometry root.
// Find the animated geometry root for its cross-doc parent frame.
nsIFrame* parent = nsLayoutUtils::GetCrossDocParentFrame(aAnimatedGeometryRoot);
if (!parent) {
return nullptr;
}
return Builder()->FindAnimatedGeometryRootFor(parent);
}
void
PaintedLayerDataTree::Finish()
{
@ -2826,13 +2800,13 @@ PaintedLayerDataTree::Finish()
}
void
PaintedLayerDataTree::NodeWasFinished(const nsIFrame* aAnimatedGeometryRoot)
PaintedLayerDataTree::NodeWasFinished(AnimatedGeometryRoot* aAnimatedGeometryRoot)
{
mNodes.Remove(aAnimatedGeometryRoot);
}
void
PaintedLayerDataTree::AddingOwnLayer(const nsIFrame* aAnimatedGeometryRoot,
PaintedLayerDataTree::AddingOwnLayer(AnimatedGeometryRoot* aAnimatedGeometryRoot,
const nsIntRect* aRect,
nscolor* aOutUniformBackgroundColor)
{
@ -2853,7 +2827,7 @@ PaintedLayerDataTree::AddingOwnLayer(const nsIFrame* aAnimatedGeometryRoot,
template<typename NewPaintedLayerCallbackType>
PaintedLayerData*
PaintedLayerDataTree::FindPaintedLayerFor(const nsIFrame* aAnimatedGeometryRoot,
PaintedLayerDataTree::FindPaintedLayerFor(AnimatedGeometryRoot* aAnimatedGeometryRoot,
const nsIntRect& aVisibleRect,
bool aForceOwnLayer,
bool aBackfaceHidden,
@ -2873,10 +2847,10 @@ PaintedLayerDataTree::FindPaintedLayerFor(const nsIFrame* aAnimatedGeometryRoot,
}
void
PaintedLayerDataTree::FinishPotentiallyIntersectingNodes(const nsIFrame* aAnimatedGeometryRoot,
PaintedLayerDataTree::FinishPotentiallyIntersectingNodes(AnimatedGeometryRoot* aAnimatedGeometryRoot,
const nsIntRect* aRect)
{
const nsIFrame* ancestorThatIsChildOfCommonAncestor = nullptr;
AnimatedGeometryRoot* ancestorThatIsChildOfCommonAncestor = nullptr;
PaintedLayerDataNode* ancestorNode =
FindNodeForAncestorAnimatedGeometryRoot(aAnimatedGeometryRoot,
&ancestorThatIsChildOfCommonAncestor);
@ -2887,7 +2861,7 @@ PaintedLayerDataTree::FinishPotentiallyIntersectingNodes(const nsIFrame* aAnimat
return;
}
if (ancestorNode->AnimatedGeometryRoot() == aAnimatedGeometryRoot) {
if (ancestorNode->GetAnimatedGeometryRoot() == aAnimatedGeometryRoot) {
// aAnimatedGeometryRoot already has a node in the tree.
// This is the common case.
MOZ_ASSERT(!ancestorThatIsChildOfCommonAncestor);
@ -2904,8 +2878,8 @@ PaintedLayerDataTree::FinishPotentiallyIntersectingNodes(const nsIFrame* aAnimat
// ancestorThatIsChildOfCommonAncestor is the last animated geometry root
// encountered on the way up from aAnimatedGeometryRoot to ancestorNode.
MOZ_ASSERT(ancestorThatIsChildOfCommonAncestor);
MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(ancestorThatIsChildOfCommonAncestor, aAnimatedGeometryRoot));
MOZ_ASSERT(GetParentAnimatedGeometryRoot(ancestorThatIsChildOfCommonAncestor) == ancestorNode->AnimatedGeometryRoot());
MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(*ancestorThatIsChildOfCommonAncestor, *aAnimatedGeometryRoot));
MOZ_ASSERT(ancestorThatIsChildOfCommonAncestor->mParentAGR == ancestorNode->GetAnimatedGeometryRoot());
// ancestorThatIsChildOfCommonAncestor is not in the tree yet!
MOZ_ASSERT(!mNodes.Get(ancestorThatIsChildOfCommonAncestor));
@ -2921,7 +2895,7 @@ PaintedLayerDataTree::FinishPotentiallyIntersectingNodes(const nsIFrame* aAnimat
}
PaintedLayerDataNode*
PaintedLayerDataTree::EnsureNodeFor(const nsIFrame* aAnimatedGeometryRoot)
PaintedLayerDataTree::EnsureNodeFor(AnimatedGeometryRoot* aAnimatedGeometryRoot)
{
MOZ_ASSERT(aAnimatedGeometryRoot);
PaintedLayerDataNode* node = mNodes.Get(aAnimatedGeometryRoot);
@ -2929,10 +2903,10 @@ PaintedLayerDataTree::EnsureNodeFor(const nsIFrame* aAnimatedGeometryRoot)
return node;
}
const nsIFrame* parentAnimatedGeometryRoot = GetParentAnimatedGeometryRoot(aAnimatedGeometryRoot);
AnimatedGeometryRoot* parentAnimatedGeometryRoot = aAnimatedGeometryRoot->mParentAGR;
if (!parentAnimatedGeometryRoot) {
MOZ_ASSERT(!mRoot);
MOZ_ASSERT(aAnimatedGeometryRoot == Builder()->RootReferenceFrame());
MOZ_ASSERT(*aAnimatedGeometryRoot == Builder()->RootReferenceFrame());
mRoot = MakeUnique<PaintedLayerDataNode>(*this, nullptr, aAnimatedGeometryRoot);
node = mRoot.get();
} else {
@ -2946,10 +2920,10 @@ PaintedLayerDataTree::EnsureNodeFor(const nsIFrame* aAnimatedGeometryRoot)
}
bool
PaintedLayerDataTree::IsClippedWithRespectToParentAnimatedGeometryRoot(const nsIFrame* aAnimatedGeometryRoot,
PaintedLayerDataTree::IsClippedWithRespectToParentAnimatedGeometryRoot(AnimatedGeometryRoot* aAnimatedGeometryRoot,
nsIntRect* aOutClip)
{
nsIScrollableFrame* scrollableFrame = nsLayoutUtils::GetScrollableFrameFor(aAnimatedGeometryRoot);
nsIScrollableFrame* scrollableFrame = nsLayoutUtils::GetScrollableFrameFor(*aAnimatedGeometryRoot);
if (!scrollableFrame) {
return false;
}
@ -2960,8 +2934,8 @@ PaintedLayerDataTree::IsClippedWithRespectToParentAnimatedGeometryRoot(const nsI
}
PaintedLayerDataNode*
PaintedLayerDataTree::FindNodeForAncestorAnimatedGeometryRoot(const nsIFrame* aAnimatedGeometryRoot,
const nsIFrame** aOutAncestorChild)
PaintedLayerDataTree::FindNodeForAncestorAnimatedGeometryRoot(AnimatedGeometryRoot* aAnimatedGeometryRoot,
AnimatedGeometryRoot** aOutAncestorChild)
{
if (!aAnimatedGeometryRoot) {
return nullptr;
@ -2971,12 +2945,11 @@ PaintedLayerDataTree::FindNodeForAncestorAnimatedGeometryRoot(const nsIFrame* aA
return node;
}
*aOutAncestorChild = aAnimatedGeometryRoot;
return FindNodeForAncestorAnimatedGeometryRoot(
GetParentAnimatedGeometryRoot(aAnimatedGeometryRoot), aOutAncestorChild);
return FindNodeForAncestorAnimatedGeometryRoot(aAnimatedGeometryRoot->mParentAGR, aOutAncestorChild);
}
const nsIFrame*
ContainerState::FindFixedPosFrameForLayerData(const nsIFrame* aAnimatedGeometryRoot,
ContainerState::FindFixedPosFrameForLayerData(AnimatedGeometryRoot* aAnimatedGeometryRoot,
bool aDisplayItemFixedToViewport)
{
if (!mManager->IsWidgetLayerManager()) {
@ -2987,7 +2960,7 @@ ContainerState::FindFixedPosFrameForLayerData(const nsIFrame* aAnimatedGeometryR
nsPresContext* presContext = mContainerFrame->PresContext();
nsIFrame* viewport = presContext->PresShell()->GetRootFrame();
if (viewport == aAnimatedGeometryRoot && aDisplayItemFixedToViewport &&
if (viewport == *aAnimatedGeometryRoot && aDisplayItemFixedToViewport &&
nsLayoutUtils::ViewportHasDisplayPort(presContext)) {
// Probably a background-attachment:fixed item
return viewport;
@ -2996,7 +2969,7 @@ ContainerState::FindFixedPosFrameForLayerData(const nsIFrame* aAnimatedGeometryR
if (!viewport->GetFirstChild(nsIFrame::kFixedList)) {
return nullptr;
}
for (const nsIFrame* f = aAnimatedGeometryRoot; f; f = f->GetParent()) {
for (const nsIFrame* f = *aAnimatedGeometryRoot; f; f = f->GetParent()) {
if (nsLayoutUtils::IsFixedPosFrameInDisplayPort(f)) {
return f;
}
@ -3593,8 +3566,8 @@ PaintedLayerData::AccumulateEventRegions(ContainerState* aState, nsDisplayLayerE
PaintedLayerData
ContainerState::NewPaintedLayerData(nsDisplayItem* aItem,
const nsIntRect& aVisibleRect,
const nsIFrame* aAnimatedGeometryRoot,
const nsIFrame* aAnimatedGeometryRootForScrollMetadata,
AnimatedGeometryRoot* aAnimatedGeometryRoot,
AnimatedGeometryRoot* aAnimatedGeometryRootForScrollMetadata,
const nsPoint& aTopLeft,
bool aShouldFixToViewport)
{
@ -3704,7 +3677,7 @@ PaintInactiveLayer(nsDisplayListBuilder* aBuilder,
*/
bool
ContainerState::ChooseAnimatedGeometryRoot(const nsDisplayList& aList,
const nsIFrame **aAnimatedGeometryRoot)
AnimatedGeometryRoot **aAnimatedGeometryRoot)
{
for (nsDisplayItem* item = aList.GetBottom(); item; item = item->GetAbove()) {
LayerState layerState = item->GetLayerState(mBuilder, mManager, mParameters);
@ -3716,7 +3689,7 @@ ContainerState::ChooseAnimatedGeometryRoot(const nsDisplayList& aList,
// Try using the actual active scrolled root of the backmost item, as that
// should result in the least invalidation when scrolling.
*aAnimatedGeometryRoot = item->AnimatedGeometryRoot();
*aAnimatedGeometryRoot = item->GetAnimatedGeometryRoot();
return true;
}
return false;
@ -3724,7 +3697,7 @@ ContainerState::ChooseAnimatedGeometryRoot(const nsDisplayList& aList,
nsIntRegion
ContainerState::ComputeOpaqueRect(nsDisplayItem* aItem,
const nsIFrame* aAnimatedGeometryRoot,
AnimatedGeometryRoot* aAnimatedGeometryRoot,
const nsIFrame* aFixedPosFrame,
const DisplayItemClip& aClip,
nsDisplayList* aList,
@ -3755,11 +3728,11 @@ ContainerState::ComputeOpaqueRect(nsDisplayItem* aItem,
}
opaquePixels = ScaleRegionToInsidePixels(opaqueClipped, snapOpaque);
nsIScrollableFrame* sf = nsLayoutUtils::GetScrollableFrameFor(aAnimatedGeometryRoot);
nsIScrollableFrame* sf = nsLayoutUtils::GetScrollableFrameFor(*aAnimatedGeometryRoot);
if (sf) {
nsRect displayport;
bool usingDisplayport =
nsLayoutUtils::GetDisplayPort(aAnimatedGeometryRoot->GetContent(), &displayport);
nsLayoutUtils::GetDisplayPort((*aAnimatedGeometryRoot)->GetContent(), &displayport);
if (!usingDisplayport) {
// No async scrolling, so all that matters is that the layer contents
// cover the scrollport.
@ -3783,15 +3756,15 @@ IsCaretWithCustomClip(nsDisplayItem* aItem, nsDisplayItem::Type aItemType)
}
static DisplayItemClip
GetScrollClipIntersection(nsDisplayListBuilder* aBuilder, const nsIFrame* aAnimatedGeometryRoot,
const nsIFrame* aStopAtAnimatedGeometryRoot, bool aIsCaret)
GetScrollClipIntersection(nsDisplayListBuilder* aBuilder, AnimatedGeometryRoot* aAnimatedGeometryRoot,
AnimatedGeometryRoot* aStopAtAnimatedGeometryRoot, bool aIsCaret)
{
DisplayItemClip resultClip;
nsIFrame* fParent;
for (const nsIFrame* f = aAnimatedGeometryRoot;
f != aStopAtAnimatedGeometryRoot;
f = nsLayoutUtils::GetAnimatedGeometryRootForFrame(aBuilder, fParent)) {
fParent = nsLayoutUtils::GetCrossDocParentFrame(f);
for (AnimatedGeometryRoot* agr = aAnimatedGeometryRoot;
agr != aStopAtAnimatedGeometryRoot;
agr = agr->mParentAGR) {
fParent = nsLayoutUtils::GetCrossDocParentFrame(*agr);
if (!fParent) {
// This means aStopAtAnimatedGeometryRoot was not an ancestor
// of aAnimatedGeometryRoot. This is a weird case but it
@ -3801,7 +3774,7 @@ GetScrollClipIntersection(nsDisplayListBuilder* aBuilder, const nsIFrame* aAnima
return DisplayItemClip();
}
nsIScrollableFrame* scrollFrame = nsLayoutUtils::GetScrollableFrameFor(f);
nsIScrollableFrame* scrollFrame = nsLayoutUtils::GetScrollableFrameFor(*agr);
if (!scrollFrame) {
continue;
}
@ -3834,7 +3807,7 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
PROFILER_LABEL("ContainerState", "ProcessDisplayItems",
js::ProfileEntry::Category::GRAPHICS);
const nsIFrame* lastAnimatedGeometryRoot = mContainerReferenceFrame;
AnimatedGeometryRoot* lastAnimatedGeometryRoot = mContainerAnimatedGeometryRoot;
nsPoint topLeft(0,0);
// When NO_COMPONENT_ALPHA is set, items will be flattened into a single
@ -3842,7 +3815,7 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
// items.
if (mFlattenToSingleLayer) {
if (ChooseAnimatedGeometryRoot(*aList, &lastAnimatedGeometryRoot)) {
topLeft = lastAnimatedGeometryRoot->GetOffsetToCrossDoc(mContainerReferenceFrame);
topLeft = (*lastAnimatedGeometryRoot)->GetOffsetToCrossDoc(mContainerReferenceFrame);
}
}
@ -3896,9 +3869,9 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
}
bool forceInactive;
const nsIFrame* animatedGeometryRoot;
const nsIFrame* animatedGeometryRootForScrollMetadata = nullptr;
const nsIFrame* realAnimatedGeometryRootOfItem = item->AnimatedGeometryRoot();
AnimatedGeometryRoot* animatedGeometryRoot;
AnimatedGeometryRoot* animatedGeometryRootForScrollMetadata = nullptr;
AnimatedGeometryRoot* realAnimatedGeometryRootOfItem = item->GetAnimatedGeometryRoot();
if (mFlattenToSingleLayer) {
forceInactive = true;
animatedGeometryRoot = lastAnimatedGeometryRoot;
@ -3906,11 +3879,7 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
forceInactive = false;
if (mManager->IsWidgetLayerManager()) {
animatedGeometryRoot = realAnimatedGeometryRootOfItem;
// Unlike GetAnimatedGeometryRootFor(), GetAnimatedGeometryRootForFrame() does not
// take ShouldFixToViewport() into account, so it will return something different
// for fixed background items.
animatedGeometryRootForScrollMetadata = nsLayoutUtils::GetAnimatedGeometryRootFor(
item, mBuilder, nsLayoutUtils::AGR_IGNORE_BACKGROUND_ATTACHMENT_FIXED);
animatedGeometryRootForScrollMetadata = item->AnimatedGeometryRootForScrollMetadata();
} else {
// For inactive layer subtrees, splitting content into PaintedLayers
// based on animated geometry roots is pointless. It's more efficient
@ -3918,10 +3887,7 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
animatedGeometryRoot = mContainerAnimatedGeometryRoot;
}
if (animatedGeometryRoot != lastAnimatedGeometryRoot) {
lastAnimatedGeometryRoot = animatedGeometryRoot;
topLeft = animatedGeometryRoot->GetOffsetToCrossDoc(mContainerReferenceFrame);
}
topLeft = (*animatedGeometryRoot)->GetOffsetToCrossDoc(mContainerReferenceFrame);
}
if (!animatedGeometryRootForScrollMetadata) {
animatedGeometryRootForScrollMetadata = animatedGeometryRoot;
@ -3937,7 +3903,7 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
item->SetClip(mBuilder, clip);
}
bool shouldFixToViewport = !animatedGeometryRoot->GetParent() &&
bool shouldFixToViewport = !(*animatedGeometryRoot)->GetParent() &&
item->ShouldFixToViewport(mBuilder);
// For items that are fixed to the viewport, remove their clip at the
@ -4056,13 +4022,11 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
clipRectUntyped = layerClipRect.ToUnknownRect();
clipPtr = &clipRectUntyped;
}
if (animatedGeometryRoot == item->Frame() &&
animatedGeometryRoot != mBuilder->RootReferenceFrame()) {
if (*animatedGeometryRoot == item->Frame() &&
*animatedGeometryRoot != mBuilder->RootReferenceFrame()) {
// This is the case for scrollbar thumbs, for example. In that case the
// clip we care about is the overflow:hidden clip on the scrollbar.
const nsIFrame* clipAnimatedGeometryRoot =
mPaintedLayerDataTree.GetParentAnimatedGeometryRoot(animatedGeometryRoot);
mPaintedLayerDataTree.AddingOwnLayer(clipAnimatedGeometryRoot,
mPaintedLayerDataTree.AddingOwnLayer(animatedGeometryRoot->mParentAGR,
clipPtr,
uniformColorPtr);
} else if (prerenderedTransform) {
@ -4718,14 +4682,14 @@ ContainerState::CollectOldLayers()
}
struct OpaqueRegionEntry {
const nsIFrame* mAnimatedGeometryRoot;
AnimatedGeometryRoot* mAnimatedGeometryRoot;
const nsIFrame* mFixedPosFrameForLayerData;
nsIntRegion mOpaqueRegion;
};
static OpaqueRegionEntry*
FindOpaqueRegionEntry(nsTArray<OpaqueRegionEntry>& aEntries,
const nsIFrame* aAnimatedGeometryRoot,
AnimatedGeometryRoot* aAnimatedGeometryRoot,
const nsIFrame* aFixedPosFrameForLayerData)
{
for (uint32_t i = 0; i < aEntries.Length(); ++i) {
@ -4767,10 +4731,10 @@ ContainerState::SetupScrollingMetadata(NewLayerEntry* aEntry)
nsTArray<RefPtr<Layer>> maskLayers;
nsIFrame* fParent;
for (const nsIFrame* f = aEntry->mAnimatedGeometryRootForScrollMetadata;
f != mContainerAnimatedGeometryRoot;
f = nsLayoutUtils::GetAnimatedGeometryRootForFrame(this->mBuilder, fParent)) {
fParent = nsLayoutUtils::GetCrossDocParentFrame(f);
for (AnimatedGeometryRoot* agr = aEntry->mAnimatedGeometryRootForScrollMetadata;
agr != mContainerAnimatedGeometryRoot;
agr = agr->mParentAGR) {
fParent = nsLayoutUtils::GetCrossDocParentFrame(*agr);
if (!fParent) {
// This means mContainerAnimatedGeometryRoot was not an ancestor
// of aEntry->mAnimatedGeometryRoot. This is a weird case but it
@ -4784,7 +4748,7 @@ ContainerState::SetupScrollingMetadata(NewLayerEntry* aEntry)
return;
}
nsIScrollableFrame* scrollFrame = nsLayoutUtils::GetScrollableFrameFor(f);
nsIScrollableFrame* scrollFrame = nsLayoutUtils::GetScrollableFrameFor(*agr);
if (!scrollFrame) {
continue;
}
@ -4881,7 +4845,7 @@ ContainerState::PostprocessRetainedLayers(nsIntRegion* aOpaqueRegionForContainer
// If mFlattenToSingleLayer is true, there isn't going to be any
// async scrolling so we can apply all our opaqueness to the same
// entry, the entry for mContainerAnimatedGeometryRoot.
const nsIFrame* animatedGeometryRootForOpaqueness =
AnimatedGeometryRoot* animatedGeometryRootForOpaqueness =
mFlattenToSingleLayer ? mContainerAnimatedGeometryRoot : e->mAnimatedGeometryRoot;
OpaqueRegionEntry* data = FindOpaqueRegionEntry(opaqueRegions,
animatedGeometryRootForOpaqueness, e->mFixedPosFrameForLayerData);
@ -4911,10 +4875,9 @@ ContainerState::PostprocessRetainedLayers(nsIntRegion* aOpaqueRegionForContainer
}
if (!e->mOpaqueRegion.IsEmpty()) {
const nsIFrame* animatedGeometryRootToCover = animatedGeometryRootForOpaqueness;
AnimatedGeometryRoot* animatedGeometryRootToCover = animatedGeometryRootForOpaqueness;
if (e->mOpaqueForAnimatedGeometryRootParent &&
nsLayoutUtils::GetAnimatedGeometryRootForFrame(mBuilder, e->mAnimatedGeometryRoot->GetParent())
== mContainerAnimatedGeometryRoot) {
e->mAnimatedGeometryRoot->mParentAGR == mContainerAnimatedGeometryRoot) {
animatedGeometryRootToCover = mContainerAnimatedGeometryRoot;
data = FindOpaqueRegionEntry(opaqueRegions,
animatedGeometryRootToCover, e->mFixedPosFrameForLayerData);

Просмотреть файл

@ -105,6 +105,12 @@ SpammyLayoutWarningsEnabled()
}
#endif
void*
AnimatedGeometryRoot::operator new(size_t aSize, nsDisplayListBuilder* aBuilder)
{
return aBuilder->Allocate(aSize);
}
static inline CSSAngle
MakeCSSAngle(const nsCSSValue& aValue)
{
@ -615,7 +621,8 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
mCurrentTableItem(nullptr),
mCurrentFrame(aReferenceFrame),
mCurrentReferenceFrame(aReferenceFrame),
mCurrentAnimatedGeometryRoot(nullptr),
mCurrentAGR(&mRootAGR),
mRootAGR(aReferenceFrame, nullptr),
mDirtyRect(-1,-1,-1,-1),
mGlassDisplayItem(nullptr),
mPendingScrollInfoItems(nullptr),
@ -652,7 +659,6 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
MOZ_COUNT_CTOR(nsDisplayListBuilder);
PL_InitArenaPool(&mPool, "displayListArena", 1024,
std::max(NS_ALIGNMENT_OF(void*),NS_ALIGNMENT_OF(double))-1);
RecomputeCurrentAnimatedGeometryRoot();
nsPresContext* pc = aReferenceFrame->PresContext();
nsIPresShell *shell = pc->PresShell();
@ -664,6 +670,8 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
}
}
mFrameToAnimatedGeometryRootMap.Put(aReferenceFrame, &mRootAGR);
nsCSSRendering::BeginFrameTreesLocked();
PR_STATIC_ASSERT(nsDisplayItem::TYPE_MAX < (1 << nsDisplayItem::TYPE_BITS));
}
@ -692,6 +700,68 @@ bool nsDisplayListBuilder::NeedToForceTransparentSurfaceForItem(nsDisplayItem* a
return aItem == mGlassDisplayItem || aItem->ClearsBackground();
}
AnimatedGeometryRoot*
nsDisplayListBuilder::WrapAGRForFrame(nsIFrame* aAnimatedGeometryRoot,
AnimatedGeometryRoot* aParent /* = nullptr */)
{
MOZ_ASSERT(IsAnimatedGeometryRoot(aAnimatedGeometryRoot));
AnimatedGeometryRoot* result = nullptr;
if (!mFrameToAnimatedGeometryRootMap.Get(aAnimatedGeometryRoot, &result)) {
MOZ_ASSERT(aAnimatedGeometryRoot != RootReferenceFrame());
AnimatedGeometryRoot* parent = aParent;
if (!parent) {
nsIFrame* parentFrame = nsLayoutUtils::GetCrossDocParentFrame(aAnimatedGeometryRoot);
if (parentFrame) {
nsIFrame* parentAGRFrame = FindAnimatedGeometryRootFrameFor(parentFrame);
parent = WrapAGRForFrame(parentAGRFrame);
}
}
result = new (this) AnimatedGeometryRoot(aAnimatedGeometryRoot, parent);
mFrameToAnimatedGeometryRootMap.Put(aAnimatedGeometryRoot, result);
}
MOZ_ASSERT(!aParent || result->mParentAGR == aParent);
return result;
}
AnimatedGeometryRoot*
nsDisplayListBuilder::FindAnimatedGeometryRootFor(nsIFrame* aFrame)
{
if (!IsForPainting()) {
return &mRootAGR;
}
if (aFrame == mCurrentFrame) {
return mCurrentAGR;
}
AnimatedGeometryRoot* result = nullptr;
if (mFrameToAnimatedGeometryRootMap.Get(aFrame, &result)) {
return result;
}
nsIFrame* agrFrame = FindAnimatedGeometryRootFrameFor(aFrame);
result = WrapAGRForFrame(agrFrame);
mFrameToAnimatedGeometryRootMap.Put(aFrame, result);
return result;
}
AnimatedGeometryRoot*
nsDisplayListBuilder::FindAnimatedGeometryRootFor(nsDisplayItem* aItem)
{
if (aItem->ShouldFixToViewport(this)) {
// Make its active scrolled root be the active scrolled root of
// the enclosing viewport, since it shouldn't be scrolled by scrolled
// frames in its document. InvalidateFixedBackgroundFramesFromList in
// nsGfxScrollFrame will not repaint this item when scrolling occurs.
nsIFrame* viewportFrame =
nsLayoutUtils::GetClosestFrameOfType(aItem->Frame(), nsGkAtoms::viewportFrame, RootReferenceFrame());
if (viewportFrame) {
return FindAnimatedGeometryRootFor(viewportFrame);
}
}
return FindAnimatedGeometryRootFor(aItem->Frame());
}
void nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame,
nsIFrame* aFrame,
const nsRect& aDirtyRect)
@ -1031,6 +1101,8 @@ IsStickyFrameActive(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsIFrame*
bool
nsDisplayListBuilder::IsAnimatedGeometryRoot(nsIFrame* aFrame, nsIFrame** aParent)
{
if (aFrame == mReferenceFrame)
return true;
if (nsLayoutUtils::IsPopup(aFrame))
return true;
if (ActiveLayerTracker::IsOffsetOrMarginStyleAnimated(aFrame))
@ -1080,57 +1152,43 @@ nsDisplayListBuilder::IsAnimatedGeometryRoot(nsIFrame* aFrame, nsIFrame** aParen
return false;
}
bool
nsDisplayListBuilder::GetCachedAnimatedGeometryRoot(const nsIFrame* aFrame,
nsIFrame** aOutResult)
{
return mAnimatedGeometryRootCache.Get(const_cast<nsIFrame*>(aFrame), aOutResult);
}
static nsIFrame*
ComputeAnimatedGeometryRootFor(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
bool aUseCache = false)
nsIFrame*
nsDisplayListBuilder::FindAnimatedGeometryRootFrameFor(nsIFrame* aFrame)
{
nsIFrame* cursor = aFrame;
while (cursor != aBuilder->RootReferenceFrame()) {
if (aUseCache) {
nsIFrame* result;
if (aBuilder->GetCachedAnimatedGeometryRoot(cursor, &result)) {
return result;
}
}
while (cursor != RootReferenceFrame()) {
nsIFrame* next;
if (aBuilder->IsAnimatedGeometryRoot(cursor, &next))
if (IsAnimatedGeometryRoot(cursor, &next))
return cursor;
cursor = next;
}
return cursor;
}
nsIFrame*
nsDisplayListBuilder::FindAnimatedGeometryRootFor(nsIFrame* aFrame)
{
if (aFrame == mCurrentFrame) {
return mCurrentAnimatedGeometryRoot;
}
nsIFrame* result = ComputeAnimatedGeometryRootFor(this, aFrame, true);
mAnimatedGeometryRootCache.Put(aFrame, result);
return result;
}
void
nsDisplayListBuilder::RecomputeCurrentAnimatedGeometryRoot()
{
// technically we only need to clear any part of the cache that relies on
// the AGR of mCurrentFrame (i.e. all entries in mAnimatedGeometryRootCache
// where the key frame is a descendant of mCurrentFrame) but doing that is
// complicated so we just clear the whole thing.
mAnimatedGeometryRootCache.Clear();
if (*mCurrentAGR != mCurrentFrame &&
IsAnimatedGeometryRoot(const_cast<nsIFrame*>(mCurrentFrame))) {
AnimatedGeometryRoot* oldAGR = mCurrentAGR;
mCurrentAGR = WrapAGRForFrame(const_cast<nsIFrame*>(mCurrentFrame), mCurrentAGR);
mCurrentAnimatedGeometryRoot = ComputeAnimatedGeometryRootFor(this, const_cast<nsIFrame *>(mCurrentFrame));
MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(RootReferenceFrame(), mCurrentAnimatedGeometryRoot));
mAnimatedGeometryRootCache.Put(const_cast<nsIFrame*>(mCurrentFrame), mCurrentAnimatedGeometryRoot);
// Iterate the AGR cache and look for any objects that reference the old AGR and check
// to see if they need to be updated. AGRs can be in the cache multiple times, so we may
// end up doing the work multiple times for AGRs that don't change.
for (auto iter = mFrameToAnimatedGeometryRootMap.Iter(); !iter.Done(); iter.Next()) {
AnimatedGeometryRoot* cached = iter.UserData();
if (cached->mParentAGR == oldAGR && cached != mCurrentAGR) {
// It's possible that this cached AGR struct that has the old AGR as a parent
// should instead have mCurrentFrame has a parent.
nsIFrame* parent = FindAnimatedGeometryRootFrameFor(*cached);
MOZ_ASSERT(parent == mCurrentFrame || parent == *oldAGR);
if (parent == mCurrentFrame) {
cached->mParentAGR = mCurrentAGR;
}
}
}
}
}
void
@ -2036,9 +2094,9 @@ nsDisplayItem::nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
mReferenceFrame = aBuilder->FindReferenceFrameFor(aFrame, &mToReferenceFrame);
// This can return the wrong result if the item override ShouldFixToViewport(),
// the item needs to set it again in its constructor.
mAnimatedGeometryRoot = nsLayoutUtils::GetAnimatedGeometryRootForInit(this, aBuilder);
mAnimatedGeometryRoot = aBuilder->FindAnimatedGeometryRootFor(aFrame);
MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(aBuilder->RootReferenceFrame(),
mAnimatedGeometryRoot), "Bad");
*mAnimatedGeometryRoot), "Bad");
NS_ASSERTION(aBuilder->GetDirtyRect().width >= 0 ||
!aBuilder->IsForPainting(), "dirty rect not set");
// The dirty rect is for mCurrentFrame, so we have to use
@ -2173,6 +2231,7 @@ nsDisplayBackgroundImage::nsDisplayBackgroundImage(nsDisplayListBuilder* aBuilde
const nsStyleBackground* aBackgroundStyle)
: nsDisplayImageContainer(aBuilder, aFrame)
, mBackgroundStyle(aBackgroundStyle)
, mAnimatedGeometryRootForScrollMetadata(mAnimatedGeometryRoot)
, mLayer(aLayer)
{
MOZ_COUNT_CTOR(nsDisplayBackgroundImage);
@ -2180,7 +2239,7 @@ nsDisplayBackgroundImage::nsDisplayBackgroundImage(nsDisplayListBuilder* aBuilde
mBounds = GetBoundsInternal(aBuilder);
mDestArea = GetDestAreaInternal(aBuilder);
if (ShouldFixToViewport(aBuilder)) {
mAnimatedGeometryRoot = nsLayoutUtils::GetAnimatedGeometryRootFor(this, aBuilder);
mAnimatedGeometryRoot = aBuilder->FindAnimatedGeometryRootFor(this);
}
}
@ -3822,12 +3881,12 @@ RequiredLayerStateForChildren(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aParameters,
const nsDisplayList& aList,
nsIFrame* aExpectedAnimatedGeometryRootForChildren)
AnimatedGeometryRoot* aExpectedAnimatedGeometryRootForChildren)
{
LayerState result = LAYER_INACTIVE;
for (nsDisplayItem* i = aList.GetBottom(); i; i = i->GetAbove()) {
if (result == LAYER_INACTIVE &&
i->AnimatedGeometryRoot() != aExpectedAnimatedGeometryRootForChildren) {
i->GetAnimatedGeometryRoot() != aExpectedAnimatedGeometryRootForChildren) {
result = LAYER_ACTIVE;
}
@ -4106,7 +4165,7 @@ nsDisplayOpacity::GetLayerState(nsDisplayListBuilder* aBuilder,
if (NeedsActiveLayer(aBuilder))
return LAYER_ACTIVE;
return RequiredLayerStateForChildren(aBuilder, aManager, aParameters, mList, AnimatedGeometryRoot());
return RequiredLayerStateForChildren(aBuilder, aManager, aParameters, mList, GetAnimatedGeometryRoot());
}
bool
@ -4838,15 +4897,16 @@ nsDisplayTransform::SetReferenceFrameToAncestor(nsDisplayListBuilder* aBuilder)
mReferenceFrame =
aBuilder->FindReferenceFrameFor(outerFrame);
mToReferenceFrame = mFrame->GetOffsetToCrossDoc(mReferenceFrame);
mAnimatedGeometryRootForChildren = mAnimatedGeometryRoot;
if (nsLayoutUtils::IsFixedPosFrameInDisplayPort(mFrame)) {
// This is an odd special case. If we are both IsFixedPosFrameInDisplayPort
// and transformed that we are our own AGR parent.
// We want our frame to be our AGR because FrameLayerBuilder uses our AGR to
// determine if we are inside a fixed pos subtree. If we use the outer AGR
// from outside the fixed pos subtree FLB can't tell that we are fixed pos.
mAnimatedGeometryRoot = mFrame;
mAnimatedGeometryRoot = mAnimatedGeometryRootForChildren;
} else {
mAnimatedGeometryRoot = nsLayoutUtils::GetAnimatedGeometryRootForFrame(aBuilder, outerFrame);
mAnimatedGeometryRoot = mAnimatedGeometryRoot->mParentAGR;
}
mVisibleRect = aBuilder->GetDirtyRect() + mToReferenceFrame;
}
@ -5571,7 +5631,7 @@ nsDisplayTransform::GetLayerState(nsDisplayListBuilder* aBuilder,
// different animated geometry root, we'll make this an active layer so the
// animation can be accelerated.
return RequiredLayerStateForChildren(aBuilder, aManager, aParameters,
*mStoredList.GetChildren(), Frame());
*mStoredList.GetChildren(), mAnimatedGeometryRootForChildren);
}
bool nsDisplayTransform::ComputeVisibility(nsDisplayListBuilder *aBuilder,

Просмотреть файл

@ -107,6 +107,47 @@ typedef mozilla::EnumSet<mozilla::gfx::CompositionOp> BlendModeSet;
virtual const char* Name() override { return n; } \
virtual Type GetType() override { return e; }
/**
* Represents a frame that is considered to have (or will have) "animated geometry"
* for itself and descendant frames.
*
* For example the scrolled frames of scrollframes which are actively being scrolled
* fall into this category. Frames with certain CSS properties that are being animated
* (e.g. 'left'/'top' etc) are also placed in this category. Frames with different
* active geometry roots are in different PaintedLayers, so that we can animate the
* geometry root by changing its transform (either on the main thread or in the
* compositor).
*
* nsDisplayListBuilder constructs a tree of these (for fast traversals) and assigns
* one for each display item.
*
* The animated geometry root for a display item is required to be a descendant (or
* equal to) the item's ReferenceFrame(), which means that we will fall back to
* returning aItem->ReferenceFrame() when we can't find another animated geometry root.
*
* The animated geometry root isn't strongly defined for a frame as transforms and
* background-attachment:fixed can cause it to vary between display items for a given
* frame.
*/
struct AnimatedGeometryRoot
{
AnimatedGeometryRoot(nsIFrame* aFrame, AnimatedGeometryRoot* aParent)
: mFrame(aFrame)
, mParentAGR(aParent)
{}
operator nsIFrame*() { return mFrame; }
nsIFrame* operator ->() const { return mFrame; }
void* operator new(size_t aSize,
nsDisplayListBuilder* aBuilder) CPP_THROW_NEW;
nsIFrame* mFrame;
AnimatedGeometryRoot* mParentAGR;
};
/**
* This manages a display list and is passed as a parameter to
* nsIFrame::BuildDisplayList.
@ -178,7 +219,7 @@ public:
EVENT_DELIVERY,
PLUGIN_GEOMETRY,
IMAGE_VISIBILITY,
OTHER
TRANSFORM_COMPUTATION
};
nsDisplayListBuilder(nsIFrame* aReferenceFrame, Mode aMode, bool aBuildCaret);
~nsDisplayListBuilder();
@ -250,18 +291,6 @@ public:
const nsIFrame* FindReferenceFrameFor(const nsIFrame *aFrame,
nsPoint* aOffset = nullptr);
/**
* Returns whether a frame acts as an animated geometry root, optionally
* returning the next ancestor to check.
*/
bool IsAnimatedGeometryRoot(nsIFrame* aFrame, nsIFrame** aParent = nullptr);
/**
* Returns the nearest ancestor frame to aFrame that is considered to have
* (or will have) animated geometry. This can return aFrame.
*/
nsIFrame* FindAnimatedGeometryRootFor(nsIFrame* aFrame);
/**
* @return the root of the display list's frame (sub)tree, whose origin
* establishes the coordinate system for the display list
@ -377,9 +406,13 @@ public:
const nsIFrame* GetCurrentFrame() { return mCurrentFrame; }
const nsIFrame* GetCurrentReferenceFrame() { return mCurrentReferenceFrame; }
const nsPoint& GetCurrentFrameOffsetToReferenceFrame() { return mCurrentOffsetToReferenceFrame; }
const nsIFrame* GetCurrentAnimatedGeometryRoot() {
return mCurrentAnimatedGeometryRoot;
AnimatedGeometryRoot* GetCurrentAnimatedGeometryRoot() {
return mCurrentAGR;
}
AnimatedGeometryRoot* GetRootAnimatedGeometryRoot() {
return &mRootAGR;
}
void RecomputeCurrentAnimatedGeometryRoot();
/**
@ -606,6 +639,7 @@ public:
nsDisplayItem* aItem,
nsIFrame* aFrame,
nsCSSProperty aProperty);
/**
* A helper class to temporarily set the value of
* mIsAtRootOfPseudoStackingContext, and temporarily
@ -622,10 +656,10 @@ public:
: mBuilder(aBuilder),
mPrevFrame(aBuilder->mCurrentFrame),
mPrevReferenceFrame(aBuilder->mCurrentReferenceFrame),
mPrevAnimatedGeometryRoot(mBuilder->mCurrentAnimatedGeometryRoot),
mPrevLayerEventRegions(aBuilder->mLayerEventRegions),
mPrevOffset(aBuilder->mCurrentOffsetToReferenceFrame),
mPrevDirtyRect(aBuilder->mDirtyRect),
mPrevAGR(aBuilder->mCurrentAGR),
mPrevIsAtRootOfPseudoStackingContext(aBuilder->mIsAtRootOfPseudoStackingContext),
mPrevAncestorHasApzAwareEventHandler(aBuilder->mAncestorHasApzAwareEventHandler)
{
@ -641,14 +675,12 @@ public:
}
if (aBuilder->mCurrentFrame == aForChild->GetParent()) {
if (aBuilder->IsAnimatedGeometryRoot(aForChild)) {
aBuilder->mCurrentAnimatedGeometryRoot = aForChild;
aBuilder->mCurrentAGR = aBuilder->WrapAGRForFrame(aForChild, aBuilder->mCurrentAGR);
}
} else {
aBuilder->mCurrentAnimatedGeometryRoot =
aBuilder->FindAnimatedGeometryRootFor(aForChild);
} else if (aForChild != aBuilder->mCurrentFrame) {
aBuilder->mCurrentAGR = aBuilder->FindAnimatedGeometryRootFor(aForChild);
}
MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(aBuilder->RootReferenceFrame(),
aBuilder->mCurrentAnimatedGeometryRoot));
MOZ_ASSERT(nsLayoutUtils::IsAncestorFrameCrossDoc(aBuilder->RootReferenceFrame(), *aBuilder->mCurrentAGR));
aBuilder->mCurrentFrame = aForChild;
aBuilder->mDirtyRect = aDirtyRect;
aBuilder->mIsAtRootOfPseudoStackingContext = aIsRoot;
@ -665,15 +697,19 @@ public:
const nsIFrame* GetPrevAnimatedGeometryRoot() const {
return mPrevAnimatedGeometryRoot;
}
bool IsAnimatedGeometryRoot() const {
return *mBuilder->mCurrentAGR == mBuilder->mCurrentFrame;
}
~AutoBuildingDisplayList() {
mBuilder->mCurrentFrame = mPrevFrame;
mBuilder->mCurrentReferenceFrame = mPrevReferenceFrame;
mBuilder->mLayerEventRegions = mPrevLayerEventRegions;
mBuilder->mCurrentOffsetToReferenceFrame = mPrevOffset;
mBuilder->mDirtyRect = mPrevDirtyRect;
mBuilder->mCurrentAGR = mPrevAGR;
mBuilder->mIsAtRootOfPseudoStackingContext = mPrevIsAtRootOfPseudoStackingContext;
mBuilder->mAncestorHasApzAwareEventHandler = mPrevAncestorHasApzAwareEventHandler;
mBuilder->mCurrentAnimatedGeometryRoot = mPrevAnimatedGeometryRoot;
}
private:
nsDisplayListBuilder* mBuilder;
@ -683,6 +719,7 @@ public:
nsDisplayLayerEventRegions* mPrevLayerEventRegions;
nsPoint mPrevOffset;
nsRect mPrevDirtyRect;
AnimatedGeometryRoot* mPrevAGR;
bool mPrevIsAtRootOfPseudoStackingContext;
bool mPrevAncestorHasApzAwareEventHandler;
};
@ -975,14 +1012,6 @@ public:
*/
bool IsInWillChangeBudget(nsIFrame* aFrame, const nsSize& aSize);
/**
* Look up the cached animated geometry root for aFrame subject Store the
* nsIFrame* result into *aOutResult, and return true if the cache was hit.
* Return false if the cache was not hit.
*/
bool GetCachedAnimatedGeometryRoot(const nsIFrame* aFrame,
nsIFrame** aOutResult);
void SetCommittedScrollInfoItemList(nsDisplayList* aScrollInfoItemStorage) {
mCommittedScrollInfoItems = aScrollInfoItemStorage;
}
@ -1066,6 +1095,30 @@ private:
void MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, nsIFrame* aFrame,
const nsRect& aDirtyRect);
/**
* Returns whether a frame acts as an animated geometry root, optionally
* returning the next ancestor to check.
*/
bool IsAnimatedGeometryRoot(nsIFrame* aFrame, nsIFrame** aParent = nullptr);
/**
* Returns the nearest ancestor frame to aFrame that is considered to have
* (or will have) animated geometry. This can return aFrame.
*/
nsIFrame* FindAnimatedGeometryRootFrameFor(nsIFrame* aFrame);
friend class nsDisplayCanvasBackgroundImage;
friend class nsDisplayBackgroundImage;
AnimatedGeometryRoot* FindAnimatedGeometryRootFor(nsDisplayItem* aItem);
AnimatedGeometryRoot* WrapAGRForFrame(nsIFrame* aAnimatedGeometryRoot,
AnimatedGeometryRoot* aParent = nullptr);
friend class nsDisplayItem;
AnimatedGeometryRoot* FindAnimatedGeometryRootFor(nsIFrame* aFrame);
nsDataHashtable<nsPtrHashKey<nsIFrame>, AnimatedGeometryRoot*> mFrameToAnimatedGeometryRootMap;
struct PresShellState {
nsIPresShell* mPresShell;
nsIFrame* mCaretFrame;
@ -1092,7 +1145,7 @@ private:
uint32_t mBudget;
};
nsIFrame* mReferenceFrame;
nsIFrame* const mReferenceFrame;
nsIFrame* mIgnoreScrollFrame;
nsDisplayLayerEventRegions* mLayerEventRegions;
PLArenaPool mPool;
@ -1109,11 +1162,10 @@ private:
const nsIFrame* mCurrentReferenceFrame;
// The offset from mCurrentFrame to mCurrentReferenceFrame.
nsPoint mCurrentOffsetToReferenceFrame;
// The animated geometry root for mCurrentFrame.
nsIFrame* mCurrentAnimatedGeometryRoot;
// Cache for storing animated geometry roots for arbitrary frames
nsDataHashtable<nsPtrHashKey<nsIFrame>, nsIFrame*> mAnimatedGeometryRootCache;
AnimatedGeometryRoot* mCurrentAGR;
AnimatedGeometryRoot mRootAGR;
// will-change budget tracker
nsDataHashtable<nsPtrHashKey<nsPresContext>, DocumentWillChangeBudget>
mWillChangeBudget;
@ -1695,11 +1747,15 @@ public:
*/
virtual const nsIFrame* ReferenceFrameForChildren() const { return mReferenceFrame; }
nsIFrame* AnimatedGeometryRoot() const {
AnimatedGeometryRoot* GetAnimatedGeometryRoot() const {
MOZ_ASSERT(mAnimatedGeometryRoot, "Must have cached AGR before accessing it!");
return mAnimatedGeometryRoot;
}
virtual struct AnimatedGeometryRoot* AnimatedGeometryRootForScrollMetadata() const {
return GetAnimatedGeometryRoot();
}
/**
* Checks if this display item (or any children) contains content that might
* be rendered with component alpha (e.g. subpixel antialiasing). Returns the
@ -1759,7 +1815,7 @@ protected:
const DisplayItemClip* mClip;
// Result of FindReferenceFrameFor(mFrame), if mFrame is non-null
const nsIFrame* mReferenceFrame;
nsIFrame* mAnimatedGeometryRoot;
struct AnimatedGeometryRoot* mAnimatedGeometryRoot;
// Result of ToReferenceFrame(mFrame), if mFrame is non-null
nsPoint mToReferenceFrame;
// This is the rectangle that needs to be painted.
@ -2599,6 +2655,10 @@ public:
virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder) override;
AnimatedGeometryRoot* AnimatedGeometryRootForScrollMetadata() const override {
return mAnimatedGeometryRootForScrollMetadata;
}
protected:
typedef class mozilla::layers::ImageContainer ImageContainer;
typedef class mozilla::layers::ImageLayer ImageLayer;
@ -2630,6 +2690,7 @@ protected:
nsCOMPtr<imgIContainer> mImage;
RefPtr<ImageContainer> mImageContainer;
LayoutDeviceRect mImageLayerDestRect;
AnimatedGeometryRoot* mAnimatedGeometryRootForScrollMetadata;
/* Bounds of this display item */
nsRect mBounds;
nsRect mDestArea;
@ -3948,15 +4009,6 @@ public:
mFrame->Combines3DTransformWithAncestors()));
}
/**
* Whether this transform item forms a reference frame boundary.
* In other words, the reference frame of the contained items is our frame,
* and the reference frame of this item is some ancestor of our frame.
*/
bool IsReferenceFrameBoundary() {
return !mTransformGetter && !mIsTransformSeparator;
}
private:
void ComputeBounds(nsDisplayListBuilder* aBuilder);
void SetReferenceFrameToAncestor(nsDisplayListBuilder* aBuilder);
@ -3975,6 +4027,7 @@ private:
// Accumulated transform of ancestors on the preserves-3d chain.
Matrix4x4 mTransformPreserves3D;
ComputeTransformFunction mTransformGetter;
AnimatedGeometryRoot* mAnimatedGeometryRootForChildren;
nsRect mChildrenVisibleRect;
uint32_t mIndex;
nsRect mBounds;

Просмотреть файл

@ -162,7 +162,7 @@ PrintDisplayItemTo(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem,
}
bool snap;
nsRect rect = aItem->GetBounds(aBuilder, &snap);
nsRect layerRect = rect - aItem->AnimatedGeometryRoot()->GetOffsetToCrossDoc(aItem->ReferenceFrame());
nsRect layerRect = rect - (*aItem->GetAnimatedGeometryRoot())->GetOffsetToCrossDoc(aItem->ReferenceFrame());
nscolor color;
nsRect vis = aItem->GetVisibleRect();
nsRect component = aItem->GetComponentAlphaBounds(aBuilder);
@ -186,7 +186,7 @@ PrintDisplayItemTo(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem,
component.x, component.y, component.width, component.height,
clip.ToString().get(),
aItem->IsUniform(aBuilder, &color) ? " uniform" : "",
aItem->ReferenceFrame(), aItem->AnimatedGeometryRoot());
aItem->ReferenceFrame(), *aItem->GetAnimatedGeometryRoot());
nsRegionRectIterator iter(opaque);
for (const nsRect* r = iter.Next(); r; r = iter.Next()) {

Просмотреть файл

@ -1932,61 +1932,6 @@ nsLayoutUtils::IsScrollbarThumbLayerized(nsIFrame* aThumbFrame)
return reinterpret_cast<intptr_t>(aThumbFrame->Properties().Get(ScrollbarThumbLayerized()));
}
nsIFrame*
nsLayoutUtils::GetAnimatedGeometryRootForFrame(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame)
{
return aBuilder->FindAnimatedGeometryRootFor(aFrame);
}
nsIFrame*
nsLayoutUtils::GetAnimatedGeometryRootFor(nsDisplayItem* aItem,
nsDisplayListBuilder* aBuilder,
uint32_t aFlags)
{
nsIFrame* f = aItem->Frame();
if (!(aFlags & AGR_IGNORE_BACKGROUND_ATTACHMENT_FIXED) &&
aItem->ShouldFixToViewport(aBuilder)) {
// Make its active scrolled root be the active scrolled root of
// the enclosing viewport, since it shouldn't be scrolled by scrolled
// frames in its document. InvalidateFixedBackgroundFramesFromList in
// nsGfxScrollFrame will not repaint this item when scrolling occurs.
nsIFrame* viewportFrame =
nsLayoutUtils::GetClosestFrameOfType(f, nsGkAtoms::viewportFrame, aBuilder->RootReferenceFrame());
if (viewportFrame) {
return GetAnimatedGeometryRootForFrame(aBuilder, viewportFrame);
}
}
if (aItem->GetType() == nsDisplayItem::TYPE_TRANSFORM &&
static_cast<nsDisplayTransform*>(aItem)->IsReferenceFrameBoundary() &&
f != aBuilder->RootReferenceFrame()) {
nsIFrame* parent = nsLayoutUtils::GetCrossDocParentFrame(f);
if (parent) {
return GetAnimatedGeometryRootForFrame(aBuilder, parent);
}
}
return GetAnimatedGeometryRootForFrame(aBuilder, f);
}
nsIFrame*
nsLayoutUtils::GetAnimatedGeometryRootForInit(nsDisplayItem* aItem,
nsDisplayListBuilder* aBuilder)
{
nsIFrame* f = aItem->Frame();
if (aItem->ShouldFixToViewport(aBuilder)) {
// Make its active scrolled root be the active scrolled root of
// the enclosing viewport, since it shouldn't be scrolled by scrolled
// frames in its document. InvalidateFixedBackgroundFramesFromList in
// nsGfxScrollFrame will not repaint this item when scrolling occurs.
nsIFrame* viewportFrame =
nsLayoutUtils::GetClosestFrameOfType(f, nsGkAtoms::viewportFrame, aBuilder->RootReferenceFrame());
if (viewportFrame) {
return GetAnimatedGeometryRootForFrame(aBuilder, viewportFrame);
}
}
return GetAnimatedGeometryRootForFrame(aBuilder, f);
}
// static
nsIScrollableFrame*
nsLayoutUtils::GetNearestScrollableFrameForDirection(nsIFrame* aFrame,
@ -2789,7 +2734,7 @@ nsLayoutUtils::GetLayerTransformForFrame(nsIFrame* aFrame,
return true;
}
nsDisplayListBuilder builder(root, nsDisplayListBuilder::OTHER,
nsDisplayListBuilder builder(root, nsDisplayListBuilder::TRANSFORM_COMPUTATION,
false/*don't build caret*/);
nsDisplayList list;
nsDisplayTransform* item =

Просмотреть файл

@ -539,46 +539,6 @@ public:
*/
static bool IsScrollbarThumbLayerized(nsIFrame* aThumbFrame);
/**
* Finds the nearest ancestor frame to aItem that is considered to have (or
* will have) "animated geometry". For example the scrolled frames of
* scrollframes which are actively being scrolled fall into this category.
* Frames with certain CSS properties that are being animated (e.g.
* 'left'/'top' etc) are also placed in this category.
* Frames with different active geometry roots are in different PaintedLayers,
* so that we can animate the geometry root by changing its transform (either
* on the main thread or in the compositor).
* The animated geometry root is required to be a descendant (or equal to)
* aItem's ReferenceFrame(), which means that we will fall back to
* returning aItem->ReferenceFrame() when we can't find another animated
* geometry root.
*/
enum {
/**
* If the AGR_IGNORE_BACKGROUND_ATTACHMENT_FIXED flag is set, then we
* do not do any special processing for background attachment fixed items,
* instead treating them like any other frame.
*/
AGR_IGNORE_BACKGROUND_ATTACHMENT_FIXED = 0x01
};
static nsIFrame* GetAnimatedGeometryRootFor(nsDisplayItem* aItem,
nsDisplayListBuilder* aBuilder,
uint32_t aFlags = 0);
/**
* Version of GetAnimatedGeometryRootFor that can be called in nsDisplayItem
* constructor, and only from there. Not valid for transform items, but they
* set their AGR in their constructor.
*/
static nsIFrame* GetAnimatedGeometryRootForInit(nsDisplayItem* aItem,
nsDisplayListBuilder* aBuilder);
/**
* Finds the nearest ancestor frame to aFrame that is considered to have (or
* will have) "animated geometry". This could be aFrame.
*/
static nsIFrame* GetAnimatedGeometryRootForFrame(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame);
/**
* GetScrollableFrameFor returns the scrollable frame for a scrolled frame
*/

Просмотреть файл

@ -241,7 +241,7 @@ public:
: nsDisplayBackgroundImage(aBuilder, aFrame, aLayer, aBg)
{
if (ShouldFixToViewport(aBuilder)) {
mAnimatedGeometryRoot = nsLayoutUtils::GetAnimatedGeometryRootFor(this, aBuilder);
mAnimatedGeometryRoot = aBuilder->FindAnimatedGeometryRootFor(this);
}
}

Просмотреть файл

@ -2508,13 +2508,9 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
// return early.
if (aBuilder->IsBuildingLayerEventRegions()) {
MOZ_ASSERT(buildingForChild.GetPrevAnimatedGeometryRoot() ==
aBuilder->FindAnimatedGeometryRootFor(child->GetParent()));
// If this frame has a different animated geometry root than its parent,
// make sure we accumulate event regions for its layer.
nsIFrame *animatedGeometryRoot = aBuilder->FindAnimatedGeometryRootFor(child);
if (animatedGeometryRoot != buildingForChild.GetPrevAnimatedGeometryRoot()) {
if (buildingForChild.IsAnimatedGeometryRoot()) {
nsDisplayLayerEventRegions* eventRegions =
new (aBuilder) nsDisplayLayerEventRegions(aBuilder, child);
eventRegions->AddFrame(aBuilder, child);