Bug 1298218 - Create ActiveScrolledRoot struct. r=mattwoodrow

MozReview-Commit-ID: Bcr801WbRmS

--HG--
extra : rebase_source : bf24b4d6391ad4a07160bd68ed586aed224bd971
This commit is contained in:
Markus Stange 2017-01-27 13:09:42 +01:00
Родитель 6e2cece750
Коммит 178d1b3e53
2 изменённых файлов: 232 добавлений и 0 удалений

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

@ -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;