зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1298218 - Create ActiveScrolledRoot struct. r=mattwoodrow
MozReview-Commit-ID: Bcr801WbRmS --HG-- extra : rebase_source : bf24b4d6391ad4a07160bd68ed586aed224bd971
This commit is contained in:
Родитель
6e2cece750
Коммит
178d1b3e53
|
@ -120,6 +120,40 @@ AnimatedGeometryRoot::operator new(size_t aSize, nsDisplayListBuilder* aBuilder)
|
|||
return aBuilder->Allocate(aSize);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
ActiveScrolledRoot::IsAncestor(const ActiveScrolledRoot* aAncestor,
|
||||
const ActiveScrolledRoot* aDescendant)
|
||||
{
|
||||
if (!aAncestor) {
|
||||
// nullptr is the root
|
||||
return true;
|
||||
}
|
||||
if (Depth(aAncestor) > Depth(aDescendant)) {
|
||||
return false;
|
||||
}
|
||||
const ActiveScrolledRoot* asr = aDescendant;
|
||||
while (asr) {
|
||||
if (asr == aAncestor) {
|
||||
return true;
|
||||
}
|
||||
asr = asr->mParent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* static */ nsCString
|
||||
ActiveScrolledRoot::ToString(const ActiveScrolledRoot* aActiveScrolledRoot)
|
||||
{
|
||||
nsAutoCString str;
|
||||
for (auto* asr = aActiveScrolledRoot; asr; asr = asr->mParent) {
|
||||
str.AppendPrintf("<0x%p>", asr->mScrollableFrame);
|
||||
if (asr->mParent) {
|
||||
str.Append(", ");
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
static inline CSSAngle
|
||||
MakeCSSAngle(const nsCSSValue& aValue)
|
||||
{
|
||||
|
@ -791,12 +825,38 @@ nsDisplayListBuilder::AddAnimationsAndTransitionsToLayer(Layer* aLayer,
|
|||
aLayer, data, pending);
|
||||
}
|
||||
|
||||
void
|
||||
nsDisplayListBuilder::AutoCurrentActiveScrolledRootSetter::InsertScrollFrame(nsIScrollableFrame* aScrollableFrame)
|
||||
{
|
||||
MOZ_ASSERT(!mUsed);
|
||||
size_t descendantsEndIndex = mBuilder->mActiveScrolledRoots.Length();
|
||||
const ActiveScrolledRoot* parentASR = mBuilder->mCurrentActiveScrolledRoot;
|
||||
const ActiveScrolledRoot* asr = mBuilder->AllocateActiveScrolledRoot(parentASR, aScrollableFrame);
|
||||
mBuilder->mCurrentActiveScrolledRoot = asr;
|
||||
|
||||
// All child ASRs of parentASR that were created while this
|
||||
// AutoCurrentActiveScrolledRootSetter object was on the stack belong to us
|
||||
// now. Reparent them to asr.
|
||||
for (size_t i = mDescendantsStartIndex; i < descendantsEndIndex; i++) {
|
||||
ActiveScrolledRoot* descendantASR = mBuilder->mActiveScrolledRoots[i];
|
||||
if (ActiveScrolledRoot::IsAncestor(parentASR, descendantASR)) {
|
||||
descendantASR->IncrementDepth();
|
||||
if (descendantASR->mParent == parentASR) {
|
||||
descendantASR->mParent = asr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mUsed = true;
|
||||
}
|
||||
|
||||
nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
|
||||
nsDisplayListBuilderMode aMode, bool aBuildCaret)
|
||||
: mReferenceFrame(aReferenceFrame),
|
||||
mIgnoreScrollFrame(nullptr),
|
||||
mLayerEventRegions(nullptr),
|
||||
mCurrentTableItem(nullptr),
|
||||
mCurrentActiveScrolledRoot(nullptr),
|
||||
mCurrentFrame(aReferenceFrame),
|
||||
mCurrentReferenceFrame(aReferenceFrame),
|
||||
mCurrentAGR(&mRootAGR),
|
||||
|
@ -1013,6 +1073,9 @@ nsDisplayListBuilder::~nsDisplayListBuilder() {
|
|||
for (DisplayItemScrollClip* c : mScrollClipsToDestroy) {
|
||||
c->DisplayItemScrollClip::~DisplayItemScrollClip();
|
||||
}
|
||||
for (ActiveScrolledRoot* asr : mActiveScrolledRoots) {
|
||||
asr->ActiveScrolledRoot::~ActiveScrolledRoot();
|
||||
}
|
||||
|
||||
PL_FinishArenaPool(&mPool);
|
||||
MOZ_COUNT_DTOR(nsDisplayListBuilder);
|
||||
|
@ -1228,6 +1291,17 @@ nsDisplayListBuilder::Allocate(size_t aSize)
|
|||
return tmp;
|
||||
}
|
||||
|
||||
ActiveScrolledRoot*
|
||||
nsDisplayListBuilder::AllocateActiveScrolledRoot(const ActiveScrolledRoot* aParent,
|
||||
nsIScrollableFrame* aScrollableFrame)
|
||||
{
|
||||
void* p = Allocate(sizeof(ActiveScrolledRoot));
|
||||
ActiveScrolledRoot* asr =
|
||||
new (KnownNotNull, p) ActiveScrolledRoot(aParent, aScrollableFrame);
|
||||
mActiveScrolledRoots.AppendElement(asr);
|
||||
return asr;
|
||||
}
|
||||
|
||||
const DisplayItemClip*
|
||||
nsDisplayListBuilder::AllocateDisplayItemClip(const DisplayItemClip& aOriginal)
|
||||
{
|
||||
|
|
|
@ -153,6 +153,68 @@ struct AnimatedGeometryRoot
|
|||
AnimatedGeometryRoot* mParentAGR;
|
||||
};
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
/**
|
||||
* An active scrolled root (ASR) is similar to an animated geometry root (AGR).
|
||||
* The differences are:
|
||||
* - ASRs are only created for async-scrollable scroll frames. This is a
|
||||
* (hopefully) temporary restriction. In the future we will want to create
|
||||
* ASRs for all the things that are currently creating AGRs, and then
|
||||
* replace AGRs with ASRs and rename them from "active scrolled root" to
|
||||
* "animated geometry root".
|
||||
* - ASR objects are created during display list construction by the nsIFrames
|
||||
* that induce ASRs. This is done using AutoCurrentActiveScrolledRootSetter.
|
||||
* The current ASR is returned by nsDisplayListBuilder::CurrentActiveScrolledRoot().
|
||||
* - There is no way to go from an nsIFrame pointer to the ASR of that frame.
|
||||
* If you need to look up an ASR after display list construction, you need
|
||||
* to store it while the AutoCurrentActiveScrolledRootSetter that creates it
|
||||
* is on the stack.
|
||||
*/
|
||||
struct ActiveScrolledRoot {
|
||||
ActiveScrolledRoot(const ActiveScrolledRoot* aParent,
|
||||
nsIScrollableFrame* aScrollableFrame)
|
||||
: mParent(aParent)
|
||||
, mScrollableFrame(aScrollableFrame)
|
||||
, mDepth(mParent ? mParent->mDepth + 1 : 1)
|
||||
{
|
||||
}
|
||||
|
||||
static const ActiveScrolledRoot* PickAncestor(const ActiveScrolledRoot* aOne,
|
||||
const ActiveScrolledRoot* aTwo)
|
||||
{
|
||||
MOZ_ASSERT(IsAncestor(aOne, aTwo) || IsAncestor(aTwo, aOne));
|
||||
return Depth(aOne) <= Depth(aTwo) ? aOne : aTwo;
|
||||
}
|
||||
|
||||
static const ActiveScrolledRoot* PickDescendant(const ActiveScrolledRoot* aOne,
|
||||
const ActiveScrolledRoot* aTwo)
|
||||
{
|
||||
MOZ_ASSERT(IsAncestor(aOne, aTwo) || IsAncestor(aTwo, aOne));
|
||||
return Depth(aOne) >= Depth(aTwo) ? aOne : aTwo;
|
||||
}
|
||||
|
||||
static bool IsAncestor(const ActiveScrolledRoot* aAncestor,
|
||||
const ActiveScrolledRoot* aDescendant);
|
||||
|
||||
static nsCString ToString(const mozilla::ActiveScrolledRoot* aActiveScrolledRoot);
|
||||
|
||||
// Call this when inserting an ancestor.
|
||||
void IncrementDepth() { mDepth++; }
|
||||
|
||||
const ActiveScrolledRoot* mParent;
|
||||
nsIScrollableFrame* mScrollableFrame;
|
||||
|
||||
private:
|
||||
static uint32_t Depth(const ActiveScrolledRoot* aActiveScrolledRoot) {
|
||||
return aActiveScrolledRoot ? aActiveScrolledRoot->mDepth : 0;
|
||||
}
|
||||
|
||||
uint32_t mDepth;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
enum class nsDisplayListBuilderMode : uint8_t {
|
||||
PAINTING,
|
||||
EVENT_DELIVERY,
|
||||
|
@ -219,6 +281,7 @@ public:
|
|||
typedef mozilla::DisplayItemClip DisplayItemClip;
|
||||
typedef mozilla::DisplayListClipState DisplayListClipState;
|
||||
typedef mozilla::DisplayItemScrollClip DisplayItemScrollClip;
|
||||
typedef mozilla::ActiveScrolledRoot ActiveScrolledRoot;
|
||||
typedef nsIWidget::ThemeGeometry ThemeGeometry;
|
||||
typedef mozilla::layers::Layer Layer;
|
||||
typedef mozilla::layers::FrameMetrics FrameMetrics;
|
||||
|
@ -663,6 +726,13 @@ public:
|
|||
*/
|
||||
void* Allocate(size_t aSize);
|
||||
|
||||
/**
|
||||
* Allocate a new ActiveScrolledRoot in the arena. Will be cleaned up
|
||||
* automatically when the arena goes away.
|
||||
*/
|
||||
ActiveScrolledRoot* AllocateActiveScrolledRoot(const ActiveScrolledRoot* aParent,
|
||||
nsIScrollableFrame* aScrollableFrame);
|
||||
|
||||
/**
|
||||
* Allocate a new DisplayItemClip in the arena. Will be cleaned up
|
||||
* automatically when the arena goes away.
|
||||
|
@ -871,6 +941,88 @@ public:
|
|||
bool mCanBeScrollParent;
|
||||
};
|
||||
|
||||
/**
|
||||
* Used to update the current active scrolled root on the display list
|
||||
* builder, and to create new active scrolled roots.
|
||||
*/
|
||||
class AutoCurrentActiveScrolledRootSetter;
|
||||
friend class AutoCurrentActiveScrolledRootSetter;
|
||||
class AutoCurrentActiveScrolledRootSetter {
|
||||
public:
|
||||
explicit AutoCurrentActiveScrolledRootSetter(nsDisplayListBuilder* aBuilder)
|
||||
: mBuilder(aBuilder)
|
||||
, mSavedActiveScrolledRoot(aBuilder->mCurrentActiveScrolledRoot)
|
||||
, mDescendantsStartIndex(aBuilder->mActiveScrolledRoots.Length())
|
||||
, mUsed(false)
|
||||
{
|
||||
}
|
||||
|
||||
~AutoCurrentActiveScrolledRootSetter()
|
||||
{
|
||||
mBuilder->mCurrentActiveScrolledRoot = mSavedActiveScrolledRoot;
|
||||
}
|
||||
|
||||
void SetCurrentActiveScrolledRoot(const ActiveScrolledRoot* aActiveScrolledRoot)
|
||||
{
|
||||
MOZ_ASSERT(!mUsed);
|
||||
mBuilder->mCurrentActiveScrolledRoot = aActiveScrolledRoot;
|
||||
mBuilder->mCurrentContainerASR = ActiveScrolledRoot::PickAncestor(
|
||||
mBuilder->mCurrentContainerASR, aActiveScrolledRoot);
|
||||
mUsed = true;
|
||||
}
|
||||
|
||||
void EnterScrollFrame(nsIScrollableFrame* aScrollableFrame)
|
||||
{
|
||||
MOZ_ASSERT(!mUsed);
|
||||
ActiveScrolledRoot* asr = mBuilder->AllocateActiveScrolledRoot(
|
||||
mBuilder->mCurrentActiveScrolledRoot, aScrollableFrame);
|
||||
mBuilder->mCurrentActiveScrolledRoot = asr;
|
||||
mUsed = true;
|
||||
}
|
||||
|
||||
void InsertScrollFrame(nsIScrollableFrame* aScrollableFrame);
|
||||
|
||||
private:
|
||||
nsDisplayListBuilder* mBuilder;
|
||||
const ActiveScrolledRoot* mSavedActiveScrolledRoot;
|
||||
size_t mDescendantsStartIndex;
|
||||
bool mUsed;
|
||||
};
|
||||
|
||||
/**
|
||||
* Keeps track of the innermost ASR that can be used as the ASR for a
|
||||
* container item that wraps all items that were created while this
|
||||
* object was on the stack.
|
||||
* The rule is: all child items of the container item need to have
|
||||
* clipped bounds with respect to the container ASR.
|
||||
*/
|
||||
class AutoContainerASRTracker;
|
||||
friend class AutoContainerASRTracker;
|
||||
class AutoContainerASRTracker {
|
||||
public:
|
||||
explicit AutoContainerASRTracker(nsDisplayListBuilder* aBuilder)
|
||||
: mBuilder(aBuilder)
|
||||
, mSavedContainerASR(aBuilder->mCurrentContainerASR)
|
||||
{
|
||||
mBuilder->mCurrentContainerASR = mBuilder->mCurrentActiveScrolledRoot;
|
||||
}
|
||||
|
||||
const ActiveScrolledRoot* GetContainerASR()
|
||||
{
|
||||
return mBuilder->mCurrentContainerASR;
|
||||
}
|
||||
|
||||
~AutoContainerASRTracker()
|
||||
{
|
||||
mBuilder->mCurrentContainerASR = ActiveScrolledRoot::PickAncestor(
|
||||
mBuilder->mCurrentContainerASR, mSavedContainerASR);
|
||||
}
|
||||
|
||||
private:
|
||||
nsDisplayListBuilder* mBuilder;
|
||||
const ActiveScrolledRoot* mSavedContainerASR;
|
||||
};
|
||||
|
||||
/**
|
||||
* A helper class to temporarily set the value of mCurrentScrollbarTarget
|
||||
* and mCurrentScrollbarFlags.
|
||||
|
@ -1072,6 +1224,8 @@ public:
|
|||
uint32_t AllocatePerspectiveItemIndex() { return mPerspectiveItemIndex++; }
|
||||
|
||||
DisplayListClipState& ClipState() { return mClipState; }
|
||||
const ActiveScrolledRoot* CurrentActiveScrolledRoot() { return mCurrentActiveScrolledRoot; }
|
||||
const ActiveScrolledRoot* CurrentAncestorASRStackingContextContents() { return mCurrentContainerASR; }
|
||||
|
||||
/**
|
||||
* Add the current frame to the will-change budget if possible and
|
||||
|
@ -1217,6 +1371,8 @@ private:
|
|||
AutoTArray<ThemeGeometry,2> mThemeGeometries;
|
||||
nsDisplayTableItem* mCurrentTableItem;
|
||||
DisplayListClipState mClipState;
|
||||
const ActiveScrolledRoot* mCurrentActiveScrolledRoot;
|
||||
const ActiveScrolledRoot* mCurrentContainerASR;
|
||||
// mCurrentFrame is the frame that we're currently calling (or about to call)
|
||||
// BuildDisplayList on.
|
||||
const nsIFrame* mCurrentFrame;
|
||||
|
@ -1257,6 +1413,7 @@ private:
|
|||
nsDisplayList* mScrollInfoItemsForHoisting;
|
||||
nsTArray<DisplayItemScrollClip*> mScrollClipsToDestroy;
|
||||
nsTArray<DisplayItemClip*> mDisplayItemClipsToDestroy;
|
||||
nsTArray<ActiveScrolledRoot*> mActiveScrolledRoots;
|
||||
nsDisplayListBuilderMode mMode;
|
||||
ViewID mCurrentScrollParentId;
|
||||
ViewID mCurrentScrollbarTarget;
|
||||
|
@ -1334,6 +1491,7 @@ public:
|
|||
typedef mozilla::ContainerLayerParameters ContainerLayerParameters;
|
||||
typedef mozilla::DisplayItemClip DisplayItemClip;
|
||||
typedef mozilla::DisplayItemScrollClip DisplayItemScrollClip;
|
||||
typedef mozilla::ActiveScrolledRoot ActiveScrolledRoot;
|
||||
typedef mozilla::layers::FrameMetrics FrameMetrics;
|
||||
typedef mozilla::layers::ScrollMetadata ScrollMetadata;
|
||||
typedef mozilla::layers::FrameMetrics::ViewID ViewID;
|
||||
|
|
Загрузка…
Ссылка в новой задаче