зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1222880 - Build a tree of AnimatedGeometryRoots to speed up traversal of ancestors. r=roc,tn
This commit is contained in:
Родитель
83ffe1f565
Коммит
41a4ad2285
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче