Bug 1434243 - Part 4: Do not create unnecessary nsDisplayCompositorHitTestInfo items
MozReview-Commit-ID: CNXMMCFFBmc
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -668,16 +668,18 @@ private:
DECL_GFX_PREF(Live, "layout.display-list.retain.verify.order", LayoutVerifyRetainDisplayListOrder, bool, false);
DECL_GFX_PREF(Live, "layout.display-list.rebuild-frame-limit", LayoutRebuildFrameLimit, uint32_t, 500);
DECL_GFX_PREF(Live, "layout.display-list.dump", LayoutDumpDisplayList, bool, false);
DECL_GFX_PREF(Live, "layout.display-list.dump-content", LayoutDumpDisplayListContent, bool, false);
DECL_GFX_PREF(Live, "layout.display-list.dump-parent", LayoutDumpDisplayListParent, bool, false);
DECL_GFX_PREF(Live, "layout.display-list.show-rebuild-area", LayoutDisplayListShowArea, bool, false);
DECL_GFX_PREF(Once, "layout.simple-event-region-items", SimpleEventRegionItems, bool, true);
+ DECL_GFX_PREF(Once, "layout.less-event-region-items", LessEventRegionItems, bool, true);
+
DECL_GFX_PREF(Live, "layout.event-regions.enabled", LayoutEventRegionsEnabledDoNotUseDirectly, bool, false);
DECL_GFX_PREF(Once, "layout.frame_rate", LayoutFrameRate, int32_t, -1);
DECL_GFX_PREF(Live, "layout.min-active-layer-size", LayoutMinActiveLayerSize, int, 64);
DECL_GFX_PREF(Once, "layout.paint_rects_separately", LayoutPaintRectsSeparately, bool, true);
// This and code dependent on it should be removed once containerless scrolling looks stable.
DECL_GFX_PREF(Once, "layout.scroll.root-frame-containers", LayoutUseContainersForRootFrames, bool, true);
// This pref is to be set by test code only.
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -3022,16 +3022,19 @@ nsIFrame::BuildDisplayListForStackingCon
nsDisplayLayerEventRegions* eventRegions = nullptr;
if (aBuilder->IsBuildingLayerEventRegions()) {
eventRegions = new (aBuilder) nsDisplayLayerEventRegions(aBuilder, this);
eventRegions->AddFrame(aBuilder, this);
aBuilder->SetLayerEventRegions(eventRegions);
}
+ aBuilder->BuildCompositorHitTestInfoIfNeeded(this, set.BorderBackground(),
+ false);
+
MarkAbsoluteFramesForDisplayList(aBuilder);
BuildDisplayList(aBuilder, set);
// Blend modes are a real pain for retained display lists. We build a blend
// container item if the built list contains any blend mode items within
// the current stacking context. This can change without an invalidation
// to the stacking context frame, or the blend mode frame (e.g. by moving
// an intermediate frame).
@@ -3060,16 +3063,20 @@ nsIFrame::BuildDisplayListForStackingCon
if (eventRegions) {
eventRegions->Destroy(aBuilder);
eventRegions = new (aBuilder) nsDisplayLayerEventRegions(aBuilder, this);
eventRegions->AddFrame(aBuilder, this);
aBuilder->SetLayerEventRegions(eventRegions);
}
+ aBuilder->BuildCompositorHitTestInfoIfNeeded(this,
+ set.BorderBackground(),
+ false);
+
// If this is the root frame, then the previous call to
// MarkAbsoluteFramesForDisplayList might have stored some fixed
// background data. Clear that now.
if (!GetParent()) {
aBuilder->ClearFixedBackgroundDisplayData();
}
MarkAbsoluteFramesForDisplayList(aBuilder);
@@ -3083,23 +3090,16 @@ nsIFrame::BuildDisplayListForStackingCon
if (!eventRegions->IsEmpty()) {
set.BorderBackground()->AppendToBottom(eventRegions);
} else {
aBuilder->SetLayerEventRegions(nullptr);
eventRegions->Destroy(aBuilder);
eventRegions = nullptr;
}
}
- if (aBuilder->BuildCompositorHitTestInfo()) {
- CompositorHitTestInfo info = GetCompositorHitTestInfo(aBuilder);
- if (info != CompositorHitTestInfo::eInvisibleToHitTest) {
- set.BorderBackground()->AppendToBottom(
- new (aBuilder) nsDisplayCompositorHitTestInfo(aBuilder, this, info));
- }
- }
}
if (aBuilder->IsBackgroundOnly()) {
set.BlockBorderBackgrounds()->DeleteAll(aBuilder);
set.Floats()->DeleteAll(aBuilder);
set.Content()->DeleteAll(aBuilder);
set.PositionedDescendants()->DeleteAll(aBuilder);
set.Outlines()->DeleteAll(aBuilder);
@@ -3527,23 +3527,20 @@ nsIFrame::BuildDisplayListForChild(nsDis
return;
}
nsDisplayListBuilder::AutoBuildingDisplayList
buildingForChild(aBuilder, child, visible, dirty, false);
CheckForApzAwareEventHandlers(aBuilder, child);
- if (aBuilder->BuildCompositorHitTestInfo()) {
- CompositorHitTestInfo info = child->GetCompositorHitTestInfo(aBuilder);
- if (info != CompositorHitTestInfo::eInvisibleToHitTest) {
- aLists.BorderBackground()->AppendToTop(
- new (aBuilder) nsDisplayCompositorHitTestInfo(aBuilder, child, info));
- }
- }
+ aBuilder->BuildCompositorHitTestInfoIfNeeded(child,
+ aLists.BorderBackground(),
+ false);
+
nsDisplayLayerEventRegions* eventRegions = aBuilder->GetLayerEventRegions();
if (eventRegions) {
eventRegions->AddFrame(aBuilder, child);
}
child->MarkAbsoluteFramesForDisplayList(aBuilder);
aBuilder->AdjustWindowDraggingRegion(child);
child->BuildDisplayList(aBuilder, aLists);
@@ -3756,28 +3753,22 @@ nsIFrame::BuildDisplayListForChild(nsDis
aBuilder->IntersectDirtyRect(*clipPropClip);
clipState.ClipContentDescendants(
*clipPropClip + aBuilder->ToReferenceFrame(child));
awayFromCommonPath = true;
}
child->MarkAbsoluteFramesForDisplayList(aBuilder);
- if (aBuilder->BuildCompositorHitTestInfo()) {
- CompositorHitTestInfo info = child->GetCompositorHitTestInfo(aBuilder);
- if (info != CompositorHitTestInfo::eInvisibleToHitTest) {
- nsDisplayItem* item =
- new (aBuilder) nsDisplayCompositorHitTestInfo(aBuilder, child, info);
- if (isPositioned) {
- list.AppendToTop(item);
- } else {
- aLists.BorderBackground()->AppendToTop(item);
- }
- }
- }
+ const bool differentAGR =
+ buildingForChild.IsAnimatedGeometryRoot() || isPositioned;
+ nsDisplayList* toList = isPositioned ? &list : aLists.BorderBackground();
+
+ aBuilder->BuildCompositorHitTestInfoIfNeeded(child, toList, differentAGR);
+
if (aBuilder->IsBuildingLayerEventRegions()) {
// If this frame has a different animated geometry root than its parent,
// make sure we accumulate event regions for its layer.
if (buildingForChild.IsAnimatedGeometryRoot() || isPositioned) {
nsDisplayLayerEventRegions* eventRegions =
new (aBuilder) nsDisplayLayerEventRegions(aBuilder, child);
eventRegions->AddFrame(aBuilder, child);
aBuilder->SetLayerEventRegions(eventRegions);
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -972,16 +972,17 @@ nsDisplayListBuilder::AutoCurrentActiveS
mUsed = true;
}
nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
nsDisplayListBuilderMode aMode, bool aBuildCaret, bool aRetainingDisplayList)
: mReferenceFrame(aReferenceFrame),
mIgnoreScrollFrame(nullptr),
mLayerEventRegions(nullptr),
+ mCompositorHitTestInfo(nullptr),
mCurrentTableItem(nullptr),
mCurrentActiveScrolledRoot(nullptr),
mCurrentContainerASR(nullptr),
mCurrentFrame(aReferenceFrame),
mCurrentReferenceFrame(aReferenceFrame),
mRootAGR(AnimatedGeometryRoot::CreateAGRForFrame(aReferenceFrame, nullptr, true, aRetainingDisplayList)),
mCurrentAGR(mRootAGR),
mUsedAGRBudget(0),
@@ -1029,16 +1030,18 @@ nsDisplayListBuilder::nsDisplayListBuild
MOZ_COUNT_CTOR(nsDisplayListBuilder);
const bool useWRHitTest =
gfxPrefs::WebRenderHitTest() && gfxVars::UseWebRender();
mBuildCompositorHitTestInfo = mAsyncPanZoomEnabled && IsForPainting() &&
(useWRHitTest || gfxPrefs::SimpleEventRegionItems());
+ mLessEventRegionItems = gfxPrefs::LessEventRegionItems();
+
nsPresContext* pc = aReferenceFrame->PresContext();
nsIPresShell *shell = pc->PresShell();
if (pc->IsRenderingOnlySelection()) {
nsCOMPtr<nsISelectionController> selcon(do_QueryInterface(shell));
if (selcon) {
selcon->GetSelection(nsISelectionController::SELECTION_NORMAL,
getter_AddRefs(mBoundingSelection));
}
@@ -1065,16 +1068,19 @@ void
nsDisplayListBuilder::EndFrame()
{
NS_ASSERTION(!mInInvalidSubtree, "Someone forgot to cleanup mInInvalidSubtree!");
mFrameToAnimatedGeometryRootMap.Clear();
mActiveScrolledRoots.Clear();
FreeClipChains();
FreeTemporaryItems();
nsCSSRendering::EndFrameTreesLocked();
+
+ MOZ_ASSERT(!mLayerEventRegions);
+ MOZ_ASSERT(!mCompositorHitTestInfo);
}
void
nsDisplayListBuilder::MarkFrameForDisplay(nsIFrame* aFrame, nsIFrame* aStopAtFrame)
{
mFramesMarkedForDisplay.AppendElement(aFrame);
for (nsIFrame* f = aFrame; f;
f = nsLayoutUtils::GetParentOrPlaceholderForCrossDoc(f)) {
@@ -2195,16 +2201,90 @@ nsDisplayListBuilder::ExitSVGEffectsCont
void
nsDisplayListBuilder::AppendNewScrollInfoItemForHoisting(nsDisplayScrollInfoLayer* aScrollInfoItem)
{
MOZ_ASSERT(ShouldBuildScrollInfoItemsForHoisting());
MOZ_ASSERT(mScrollInfoItemsForHoisting);
mScrollInfoItemsForHoisting->AppendToTop(aScrollInfoItem);
}
+static nsRect
+GetFrameArea(const nsDisplayListBuilder* aBuilder, const nsIFrame* aFrame)
+{
+ nsRect area;
+
+ nsIScrollableFrame* scrollFrame = nsLayoutUtils::GetScrollableFrameFor(aFrame);
+ if (scrollFrame) {
+ // If the frame is content of a scrollframe, then we need to pick up the
+ // area corresponding to the overflow rect as well. Otherwise the parts of
+ // the overflow that are not occupied by descendants get skipped and the
+ // APZ code sends touch events to the content underneath instead.
+ // See https://bugzilla.mozilla.org/show_bug.cgi?id=1127773#c15.
+ area = aFrame->GetScrollableOverflowRect();
+ } else {
+ area = nsRect(nsPoint(0, 0), aFrame->GetSize());
+ }
+
+ if (!area.IsEmpty()) {
+ return area + aBuilder->ToReferenceFrame(aFrame);
+ }
+
+ return area;
+}
+
+void
+nsDisplayListBuilder::BuildCompositorHitTestInfoIfNeeded(nsIFrame* aFrame,
+ nsDisplayList* aList,
+ const bool aBuildNew)
+{
+ MOZ_ASSERT(aFrame);
+ MOZ_ASSERT(aList);
+
+ if (!BuildCompositorHitTestInfo()) {
+ return;
+ }
+
+ CompositorHitTestInfo info = aFrame->GetCompositorHitTestInfo(this);
+ if (!ShouldBuildCompositorHitTestInfo(aFrame, info, aBuildNew)) {
+ // Either the parent hit test info can be reused, or this frame has no hit
+ // test flags set.
+ return;
+ }
+
+ nsDisplayCompositorHitTestInfo* item =
+ new (this) nsDisplayCompositorHitTestInfo(this, aFrame, info);
+
+ SetCompositorHitTestInfo(item);
+ aList->AppendToTop(item);
+}
+
+bool
+nsDisplayListBuilder::ShouldBuildCompositorHitTestInfo(const nsIFrame* aFrame,
+ const CompositorHitTestInfo& aInfo,
+ const bool aBuildNew) const
+{
+ MOZ_ASSERT(mBuildCompositorHitTestInfo);
+
+ if (aInfo == CompositorHitTestInfo::eInvisibleToHitTest) {
+ return false;
+ }
+
+ if (!mCompositorHitTestInfo || !mLessEventRegionItems || aBuildNew) {
+ return true;
+ }
+
+ if (mCompositorHitTestInfo->HitTestInfo() != aInfo) {
+ // Hit test flags are different.
+ return true;
+ }
+
+ // Create a new item if the parent does not contain the child completely.
+ return !mCompositorHitTestInfo->Area().Contains(GetFrameArea(this, aFrame));
+}
+
bool
nsDisplayListBuilder::IsBuildingLayerEventRegions()
{
if (mBuildCompositorHitTestInfo) {
// If we have webrender hit-testing enabled, then we will build the
// nsDisplayCompositorHitTestInfo items and use those instead of event
// regions, so we don't need to build the event regions.
return false;
@@ -4992,34 +5072,17 @@ nsDisplayCompositorHitTestInfo::nsDispla
// instead of the scrollframe with which the scrollbar actually moves.
MOZ_ASSERT(mHitTestInfo & CompositorHitTestInfo::eScrollbar);
mScrollTarget = Some(aBuilder->GetCurrentScrollbarTarget());
}
if (aArea.isSome()) {
mArea = *aArea;
} else {
- nsIScrollableFrame* scrollFrame = nsLayoutUtils::GetScrollableFrameFor(mFrame);
- if (scrollFrame) {
- // If the frame is content of a scrollframe, then we need to pick up the
- // area corresponding to the overflow rect as well. Otherwise the parts of
- // the overflow that are not occupied by descendants get skipped and the
- // APZ code sends touch events to the content underneath instead.
- // See https://bugzilla.mozilla.org/show_bug.cgi?id=1127773#c15.
- mArea = mFrame->GetScrollableOverflowRect();
- } else {
- mArea = nsRect(nsPoint(0, 0), mFrame->GetSize());
- }
-
- // Note that it's important to do this call to ToReferenceFrame here in the
- // nsDisplayCompositorHitTestInfo constructor, because then we'll hit the good
- // fast path (because aBuilder will already have the info we want cached).
- // This is as opposed to, say, calling it in CreateWebRenderCommands where
- // we would not hit the fast path.
- mArea += aBuilder->ToReferenceFrame(mFrame);
+ mArea = GetFrameArea(aBuilder, aFrame);
}
}
bool
nsDisplayCompositorHitTestInfo::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
mozilla::wr::IpcResourceUpdateQueue& aResources,
const StackingContextHelper& aSc,
mozilla::layers::WebRenderLayerManager* aManager,
@@ -5091,40 +5154,23 @@ nsDisplayLayerEventRegions::AddFrame(nsD
if (hitInfo == CompositorHitTestInfo::eInvisibleToHitTest) {
return;
}
// XXX handle other pointerEvents values for SVG
// XXX Do something clever here for the common case where the border box
// is obviously entirely inside mHitRegion.
- nsRect borderBox;
-
- nsIScrollableFrame* scrollFrame = nsLayoutUtils::GetScrollableFrameFor(aFrame);
- if (scrollFrame) {
- // If the frame is content of a scrollframe, then we need to pick up the
- // area corresponding to the overflow rect as well. Otherwise the parts of
- // the overflow that are not occupied by descendants get skipped and the
- // APZ code sends touch events to the content underneath instead.
- // See https://bugzilla.mozilla.org/show_bug.cgi?id=1127773#c15.
- borderBox = aFrame->GetScrollableOverflowRect();
- } else {
- borderBox = nsRect(nsPoint(0, 0), aFrame->GetSize());
- }
- if (borderBox.IsEmpty()) {
- return;
- }
+ nsRect borderBox = GetFrameArea(aBuilder, aFrame);
if (aFrame != mFrame &&
aBuilder->IsRetainingDisplayList()) {
aFrame->AddDisplayItem(this);
}
- borderBox += aBuilder->ToReferenceFrame(aFrame);
-
bool borderBoxHasRoundedCorners = false;
// use the NS_FRAME_SIMPLE_EVENT_REGIONS to avoid calling the slightly
// expensive HasNonZeroCorner function if we know from a previous run that
// the frame has zero corners.
bool simpleRegions = aFrame->HasAnyStateBits(NS_FRAME_SIMPLE_EVENT_REGIONS);
if (!simpleRegions) {
if (nsLayoutUtils::HasNonZeroCorner(aFrame->StyleBorder()->mBorderRadius)) {
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -52,16 +52,17 @@
class gfxContext;
class nsIContent;
class nsDisplayList;
class nsDisplayTableItem;
class nsISelection;
class nsIScrollableFrame;
class nsSubDocumentFrame;
+class nsDisplayCompositorHitTestInfo;
class nsDisplayLayerEventRegions;
class nsDisplayScrollInfoLayer;
class nsCaret;
enum class nsDisplayOwnLayerFlags;
namespace mozilla {
class FrameLayerBuilder;
namespace layers {
@@ -715,16 +716,36 @@ public:
bool AllowMergingAndFlattening() { return mAllowMergingAndFlattening; }
void SetAllowMergingAndFlattening(bool aAllow) { mAllowMergingAndFlattening = aAllow; }
nsDisplayLayerEventRegions* GetLayerEventRegions() { return mLayerEventRegions; }
void SetLayerEventRegions(nsDisplayLayerEventRegions* aItem)
{
mLayerEventRegions = aItem;
}
+
+ /**
+ * Sets the current compositor hit test info to |aHitTestInfo|.
+ * This is used during display list building to determine if the parent frame
+ * hit test info contains the same information that child frame needs.
+ */
+ void SetCompositorHitTestInfo(nsDisplayCompositorHitTestInfo* aHitTestInfo)
+ {
+ mCompositorHitTestInfo = aHitTestInfo;
+ }
+
+ /**
+ * Builds a new nsDisplayCompositorHitTestInfo for the frame |aFrame| if
+ * needed, and adds it to the top of |aList|. If |aBuildNew| is true, the
+ * previous hit test info will not be reused.
+ */
+ void BuildCompositorHitTestInfoIfNeeded(nsIFrame* aFrame,
+ nsDisplayList* aList,
+ const bool aBuildNew);
+
bool IsBuildingLayerEventRegions();
static bool LayerEventRegionsEnabled();
bool IsInsidePointerEventsNoneDoc()
{
return CurrentPresShellState()->mInsidePointerEventsNoneDoc;
}
bool GetAncestorHasApzAwareEventHandler() const { return mAncestorHasApzAwareEventHandler; }
@@ -1031,16 +1052,17 @@ public:
nsIFrame* aForChild,
const nsRect& aVisibleRect,
const nsRect& aDirtyRect,
bool aIsRoot)
: mBuilder(aBuilder),
mPrevFrame(aBuilder->mCurrentFrame),
mPrevReferenceFrame(aBuilder->mCurrentReferenceFrame),
mPrevLayerEventRegions(aBuilder->mLayerEventRegions),
+ mPrevCompositorHitTestInfo(aBuilder->mCompositorHitTestInfo),
mPrevOffset(aBuilder->mCurrentOffsetToReferenceFrame),
mPrevVisibleRect(aBuilder->mVisibleRect),
mPrevDirtyRect(aBuilder->mDirtyRect),
mPrevAGR(aBuilder->mCurrentAGR),
mPrevIsAtRootOfPseudoStackingContext(aBuilder->mIsAtRootOfPseudoStackingContext),
mPrevAncestorHasApzAwareEventHandler(aBuilder->mAncestorHasApzAwareEventHandler),
mPrevBuildingInvisibleItems(aBuilder->mBuildingInvisibleItems),
mPrevInInvalidSubtree(aBuilder->mInInvalidSubtree)
@@ -1083,31 +1105,33 @@ public:
}
void RestoreBuildingInvisibleItemsValue() {
mBuilder->mBuildingInvisibleItems = mPrevBuildingInvisibleItems;
}
~AutoBuildingDisplayList() {
mBuilder->mCurrentFrame = mPrevFrame;
mBuilder->mCurrentReferenceFrame = mPrevReferenceFrame;
mBuilder->mLayerEventRegions = mPrevLayerEventRegions;
+ mBuilder->mCompositorHitTestInfo = mPrevCompositorHitTestInfo;
mBuilder->mCurrentOffsetToReferenceFrame = mPrevOffset;
mBuilder->mVisibleRect = mPrevVisibleRect;
mBuilder->mDirtyRect = mPrevDirtyRect;
mBuilder->mCurrentAGR = mPrevAGR;
mBuilder->mIsAtRootOfPseudoStackingContext = mPrevIsAtRootOfPseudoStackingContext;
mBuilder->mAncestorHasApzAwareEventHandler = mPrevAncestorHasApzAwareEventHandler;
mBuilder->mBuildingInvisibleItems = mPrevBuildingInvisibleItems;
mBuilder->mInInvalidSubtree = mPrevInInvalidSubtree;
}
private:
nsDisplayListBuilder* mBuilder;
AGRState mCurrentAGRState;
const nsIFrame* mPrevFrame;
const nsIFrame* mPrevReferenceFrame;
nsDisplayLayerEventRegions* mPrevLayerEventRegions;
+ nsDisplayCompositorHitTestInfo* mPrevCompositorHitTestInfo;
nsPoint mPrevOffset;
nsRect mPrevVisibleRect;
nsRect mPrevDirtyRect;
RefPtr<AnimatedGeometryRoot> mPrevAGR;
bool mPrevIsAtRootOfPseudoStackingContext;
bool mPrevAncestorHasApzAwareEventHandler;
bool mPrevBuildingInvisibleItems;
bool mPrevInInvalidSubtree;
@@ -1779,16 +1803,25 @@ private:
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, bool& aIsAsync);
+ /**
+ * Returns true if nsDisplayCompositorHitTestInfo item should be build for
+ * |aFrame|. Otherwise returns false. If |aBuildNew| is true, reusing the
+ * previous hit test info will not be considered.
+ */
+ bool ShouldBuildCompositorHitTestInfo(const nsIFrame* aFrame,
+ const mozilla::gfx::CompositorHitTestInfo& aInfo,
+ const bool aBuildNew) const;
+
friend class nsDisplayCanvasBackgroundImage;
friend class nsDisplayBackgroundImage;
friend class nsDisplayFixedPosition;
AnimatedGeometryRoot* FindAnimatedGeometryRootFor(nsDisplayItem* aItem);
friend class nsDisplayItem;
friend class nsDisplayOwnLayer;
friend struct RetainedDisplayListBuilder;
@@ -1846,16 +1879,17 @@ private:
nsIFrame* mFrame;
uint32_t mUsage;
};
nsIFrame* const mReferenceFrame;
nsIFrame* mIgnoreScrollFrame;
nsDisplayLayerEventRegions* mLayerEventRegions;
+ nsDisplayCompositorHitTestInfo* mCompositorHitTestInfo;
nsPresArena mPool;
nsCOMPtr<nsISelection> mBoundingSelection;
AutoTArray<PresShellState,8> mPresShellStates;
AutoTArray<nsIFrame*,400> mFramesMarkedForDisplay;
AutoTArray<nsIFrame*,40> mFramesMarkedForDisplayIfVisible;
AutoTArray<nsIFrame*,20> mFramesWithOOFData;
@@ -1962,16 +1996,17 @@ private:
bool mIsBuildingForPopup;
bool mForceLayerForScrollParent;
bool mAsyncPanZoomEnabled;
bool mBuildingInvisibleItems;
bool mHitTestIsForVisibility;
bool mIsBuilding;
bool mInInvalidSubtree;
bool mBuildCompositorHitTestInfo;
+ bool mLessEventRegionItems;
};
class nsDisplayItem;
class nsDisplayList;
/**
* nsDisplayItems are put in singly-linked lists rooted in an nsDisplayList.
* nsDisplayItemLink holds the link. The lists are linked from lowest to
* highest in z-order.