From d481341bf4ee0f4774ad72736dd346d8f3efd96f Mon Sep 17 00:00:00 2001 From: Miko Mynttinen Date: Sat, 6 Feb 2021 22:30:29 +0000 Subject: [PATCH] Bug 1534549 - Part 1: Remove old FLB hit test info optimization r=mstange Differential Revision: https://phabricator.services.mozilla.com/D102514 --- layout/base/nsLayoutDebugger.cpp | 4 +- layout/generic/nsGfxScrollFrame.cpp | 3 +- layout/generic/nsIFrame.cpp | 49 +---- layout/painting/FrameLayerBuilder.cpp | 67 ++----- .../painting/RetainedDisplayListBuilder.cpp | 33 +--- layout/painting/nsDisplayList.cpp | 30 ++- layout/painting/nsDisplayList.h | 182 ++++++------------ 7 files changed, 87 insertions(+), 281 deletions(-) diff --git a/layout/base/nsLayoutDebugger.cpp b/layout/base/nsLayoutDebugger.cpp index b7ea09a5c1ce..3c7fcd41c33c 100644 --- a/layout/base/nsLayoutDebugger.cpp +++ b/layout/base/nsLayoutDebugger.cpp @@ -116,8 +116,8 @@ static void PrintDisplayItemTo(nsDisplayListBuilder* aBuilder, aStream << ")"; } - if (aItem->HasHitTestInfo()) { - auto* hitTestInfoItem = static_cast(aItem); + if (aItem->GetType() == DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO) { + auto* hitTestInfoItem = static_cast(aItem); aStream << nsPrintfCString(" hitTestInfo(0x%x)", hitTestInfoItem->HitTestFlags().serialize()); diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index 07539488926e..d55fac87fdc8 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -4084,8 +4084,7 @@ void ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder, DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO) { auto* hitTestItem = static_cast(item); - if (hitTestItem->HasHitTestInfo() && - hitTestItem->HitTestFlags().contains( + if (hitTestItem->HitTestFlags().contains( CompositorHitTestFlags::eInactiveScrollframe)) { zIndex = std::max(zIndex, hitTestItem->ZIndex()); item->SetCantBeReused(); diff --git a/layout/generic/nsIFrame.cpp b/layout/generic/nsIFrame.cpp index 7200e2cdc52f..f0052095a219 100644 --- a/layout/generic/nsIFrame.cpp +++ b/layout/generic/nsIFrame.cpp @@ -3083,28 +3083,6 @@ struct ContainerTracker { bool mCreatedContainer = false; }; -/** - * Adds hit test information |aHitTestInfo| on the container item |aContainer|, - * or if the container item is null, creates a separate hit test item that is - * added to the bottom of the display list |aList|. - */ -static void AddHitTestInfo(nsDisplayListBuilder* aBuilder, nsDisplayList* aList, - nsDisplayItem* aContainer, nsIFrame* aFrame, - mozilla::UniquePtr&& aHitTestInfo) { - nsDisplayHitTestInfoBase* hitTestItem; - - if (aContainer) { - MOZ_ASSERT(aContainer->IsHitTestItem()); - hitTestItem = static_cast(aContainer); - hitTestItem->SetHitTestInfo(std::move(aHitTestInfo)); - } else { - // No container item was created for this frame. Create a separate - // nsDisplayCompositorHitTestInfo item instead. - aList->AppendNewToBottom( - aBuilder, aFrame, std::move(aHitTestInfo)); - } -} - void nsIFrame::BuildDisplayListForStackingContext( nsDisplayListBuilder* aBuilder, nsDisplayList* aList, bool* aCreatedContainerItem) { @@ -3442,24 +3420,8 @@ void nsIFrame::BuildDisplayListForStackingContext( } aBuilder->AdjustWindowDraggingRegion(this); - - if (gfxVars::UseWebRender()) { - aBuilder->BuildCompositorHitTestInfoIfNeeded(this, set.BorderBackground(), - true); - } else { - CompositorHitTestInfo info = aBuilder->BuildCompositorHitTestInfo() - ? GetCompositorHitTestInfo(aBuilder) - : CompositorHitTestInvisibleToHit; - - if (info != CompositorHitTestInvisibleToHit) { - // Frame has hit test flags set, initialize the hit test info structure. - hitTestInfo = mozilla::MakeUnique(aBuilder, this, info); - - // Let child frames know the current hit test area and hit test flags. - aBuilder->SetCompositorHitTestInfo(hitTestInfo->mArea, - hitTestInfo->mFlags); - } - } + aBuilder->BuildCompositorHitTestInfoIfNeeded(this, set.BorderBackground(), + true); MarkAbsoluteFramesForDisplayList(aBuilder); aBuilder->Check(); @@ -3834,13 +3796,6 @@ void nsIFrame::BuildDisplayListForStackingContext( *aCreatedContainerItem = ct.mCreatedContainer; } - if (hitTestInfo) { - // WebRender support is not yet implemented. - MOZ_ASSERT(!gfxVars::UseWebRender()); - AddHitTestInfo(aBuilder, &resultList, ct.mContainer, this, - std::move(hitTestInfo)); - } - aList->AppendToTop(&resultList); } diff --git a/layout/painting/FrameLayerBuilder.cpp b/layout/painting/FrameLayerBuilder.cpp index 1a5142d72322..2567a418a6bf 100644 --- a/layout/painting/FrameLayerBuilder.cpp +++ b/layout/painting/FrameLayerBuilder.cpp @@ -1712,12 +1712,6 @@ class FLBDisplayListIterator : public FlattenedDisplayListIterator { ContainerState* aState) : FlattenedDisplayListIterator(aBuilder, aList, false), mState(aState) { MOZ_ASSERT(mState); - - if (mState->mContainerItem) { - // Add container item hit test information for processing, if needed. - AddHitTestMarkerIfNeeded(mState->mContainerItem); - } - ResolveFlattening(); } @@ -1736,12 +1730,6 @@ class FLBDisplayListIterator : public FlattenedDisplayListIterator { } private: - void AddHitTestMarkerIfNeeded(nsDisplayItem* aItem) { - if (aItem->HasHitTestInfo()) { - mMarkers.emplace_back(aItem, DisplayItemEntryType::HitTestInfo); - } - } - bool ShouldFlattenNextItem() override { if (!FlattenedDisplayListIterator::ShouldFlattenNextItem()) { return false; @@ -1784,7 +1772,6 @@ class FLBDisplayListIterator : public FlattenedDisplayListIterator { void EnterChildList(nsDisplayItem* aContainerItem) override { mFlattenedLists.AppendElement(aContainerItem); AddMarkerIfNeeded(aContainerItem, mMarkers); - AddHitTestMarkerIfNeeded(aContainerItem); } void ExitChildList() override { @@ -4052,11 +4039,10 @@ void PaintedLayerData::AccumulateHitTestItem(ContainerState* aState, nsDisplayItem* aItem, const DisplayItemClip& aClip, TransformClipNode* aTransform) { - auto* item = static_cast(aItem); - const HitTestInfo& info = item->GetHitTestInfo(); - - nsRect area = info.mArea; - const CompositorHitTestInfo& flags = info.mFlags; + MOZ_ASSERT(aItem->GetType() == DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO); + auto* item = static_cast(aItem); + nsRect area = item->HitTestArea(); + const CompositorHitTestInfo& flags = item->HitTestFlags(); FLB_LOG_PAINTED_LAYER_DECISION( this, @@ -4559,9 +4545,14 @@ void ContainerState::ProcessDisplayItems(nsDisplayList* aList) { MOZ_ASSERT(item); DisplayItemType itemType = item->GetType(); + bool snap = false; + nsRect itemContent = item->GetBounds(mBuilder, &snap); + if (itemType == DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO) { // Override the marker for nsDisplayCompositorHitTestInfo items. marker = DisplayItemEntryType::HitTestInfo; + itemContent = + static_cast(item)->HitTestArea(); } const bool inEffect = InTransform() || InOpacity(); @@ -4584,35 +4575,11 @@ void ContainerState::ProcessDisplayItems(nsDisplayList* aList) { } } - AnimatedGeometryRoot* itemAGR = nullptr; - const ActiveScrolledRoot* itemASR = nullptr; + AnimatedGeometryRoot* itemAGR = item->GetAnimatedGeometryRoot(); + const ActiveScrolledRoot* itemASR = item->GetActiveScrolledRoot(); + const DisplayItemClipChain* itemClipChain = item->GetClipChain(); const DisplayItemClipChain* layerClipChain = nullptr; - const DisplayItemClipChain* itemClipChain = nullptr; - const DisplayItemClip* itemClipPtr = nullptr; - - bool snap = false; - nsRect itemContent; - - if (marker == DisplayItemEntryType::HitTestInfo) { - MOZ_ASSERT(item->IsHitTestItem()); - const auto& hitTestInfo = - static_cast(item)->GetHitTestInfo(); - - // Override the layer selection hints for items that have hit test - // information. This is needed because container items may have different - // clipping, AGR, or ASR than the child items in them. - itemAGR = hitTestInfo.mAGR; - itemASR = hitTestInfo.mASR; - itemClipChain = hitTestInfo.mClipChain; - itemClipPtr = hitTestInfo.mClip; - itemContent = hitTestInfo.mArea; - } else { - itemAGR = item->GetAnimatedGeometryRoot(); - itemASR = item->GetActiveScrolledRoot(); - itemClipChain = item->GetClipChain(); - itemClipPtr = &item->GetClip(); - itemContent = item->GetBounds(mBuilder, &snap); - } + const DisplayItemClip* itemClipPtr = &item->GetClip(); if (mManager->IsWidgetLayerManager() && !inEffect) { if (itemClipChain && itemClipChain->mASR == itemASR && @@ -4626,13 +4593,7 @@ void ContainerState::ProcessDisplayItems(nsDisplayList* aList) { itemAGR = inEffect ? containerAGR : mContainerAnimatedGeometryRoot; itemASR = inEffect ? containerASR : mContainerASR; - if (marker == DisplayItemEntryType::HitTestInfo) { - // Items with hit test info are processed twice, once with ::HitTestInfo - // marker and then with ::Item marker. - // With ::HitTestInfo markers, fuse the clip chain of hit test struct, - // and with ::Item markers, fuse the clip chain of the actual item. - itemClipChain = mBuilder->FuseClipChainUpTo(itemClipChain, itemASR); - } else if (!IsEffectEndMarker(marker)) { + if (!IsEffectEndMarker(marker)) { // No need to fuse clip chain for effect end markers, since it was // already done for effect start markers. item->FuseClipChainUpTo(mBuilder, itemASR); diff --git a/layout/painting/RetainedDisplayListBuilder.cpp b/layout/painting/RetainedDisplayListBuilder.cpp index 8a374d987197..268a9112c912 100644 --- a/layout/painting/RetainedDisplayListBuilder.cpp +++ b/layout/painting/RetainedDisplayListBuilder.cpp @@ -344,49 +344,22 @@ static Maybe SelectContainerASR( static void UpdateASR(nsDisplayItem* aItem, Maybe& aContainerASR) { - Maybe asr; - - if (aItem->HasHitTestInfo()) { - const HitTestInfo& info = - static_cast(aItem)->GetHitTestInfo(); - asr = SelectContainerASR(info.mClipChain, info.mASR, aContainerASR); - } else { - asr = aContainerASR; - } - - if (!asr) { + if (!aContainerASR) { return; } nsDisplayWrapList* wrapList = aItem->AsDisplayWrapList(); if (!wrapList) { - aItem->SetActiveScrolledRoot(*asr); + aItem->SetActiveScrolledRoot(*aContainerASR); return; } wrapList->SetActiveScrolledRoot(ActiveScrolledRoot::PickAncestor( - wrapList->GetFrameActiveScrolledRoot(), *asr)); - - wrapList->UpdateHitTestInfoActiveScrolledRoot(*asr); + wrapList->GetFrameActiveScrolledRoot(), *aContainerASR)); } static void CopyASR(nsDisplayItem* aOld, nsDisplayItem* aNew) { - const ActiveScrolledRoot* hitTest = nullptr; - if (aOld->HasHitTestInfo()) { - MOZ_ASSERT(aNew->HasHitTestInfo()); - const HitTestInfo& info = - static_cast(aOld)->GetHitTestInfo(); - hitTest = info.mASR; - } - aNew->SetActiveScrolledRoot(aOld->GetActiveScrolledRoot()); - - // SetActiveScrolledRoot for most items will also set the hit-test info item's - // asr, so we need to manually set that again to what we saved earlier. - if (aOld->HasHitTestInfo()) { - static_cast(aNew) - ->UpdateHitTestInfoActiveScrolledRoot(hitTest); - } } OldItemInfo::OldItemInfo(nsDisplayItem* aItem) diff --git a/layout/painting/nsDisplayList.cpp b/layout/painting/nsDisplayList.cpp index 3b9556c7dddf..4c21e3c2c19a 100644 --- a/layout/painting/nsDisplayList.cpp +++ b/layout/painting/nsDisplayList.cpp @@ -1802,15 +1802,8 @@ LayoutDeviceIntRegion nsDisplayListBuilder::GetWindowDraggingRegion() const { return result; } -void nsDisplayHitTestInfoBase::AddSizeOfExcludingThis( - nsWindowSizes& aSizes) const { - nsPaintedDisplayItem::AddSizeOfExcludingThis(aSizes); - aSizes.mLayoutRetainedDisplayListSize += - aSizes.mState.mMallocSizeOf(mHitTestInfo.get()); -} - void nsDisplayTransform::AddSizeOfExcludingThis(nsWindowSizes& aSizes) const { - nsDisplayHitTestInfoBase::AddSizeOfExcludingThis(aSizes); + nsPaintedDisplayItem::AddSizeOfExcludingThis(aSizes); aSizes.mLayoutRetainedDisplayListSize += aSizes.mState.mMallocSizeOf(mTransformPreserves3D.get()); } @@ -4859,7 +4852,7 @@ nsDisplayCompositorHitTestInfo::nsDisplayCompositorHitTestInfo( nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, const mozilla::gfx::CompositorHitTestInfo& aHitTestFlags, const mozilla::Maybe& aArea) - : nsDisplayHitTestInfoBase(aBuilder, aFrame), + : nsPaintedDisplayItem(aBuilder, aFrame), mAppUnitsPerDevPixel(mFrame->PresContext()->AppUnitsPerDevPixel()) { MOZ_COUNT_CTOR(nsDisplayCompositorHitTestInfo); // We should never even create this display item if we're not building @@ -4878,7 +4871,7 @@ nsDisplayCompositorHitTestInfo::nsDisplayCompositorHitTestInfo( nsDisplayCompositorHitTestInfo::nsDisplayCompositorHitTestInfo( nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, mozilla::UniquePtr&& aHitTestInfo) - : nsDisplayHitTestInfoBase(aBuilder, aFrame), + : nsPaintedDisplayItem(aBuilder, aFrame), mAppUnitsPerDevPixel(mFrame->PresContext()->AppUnitsPerDevPixel()) { MOZ_COUNT_CTOR(nsDisplayCompositorHitTestInfo); SetHitTestInfo(std::move(aHitTestInfo)); @@ -4943,8 +4936,7 @@ bool nsDisplayCompositorHitTestInfo::CreateWebRenderCommands( } int32_t nsDisplayCompositorHitTestInfo::ZIndex() const { - return mOverrideZIndex ? *mOverrideZIndex - : nsDisplayHitTestInfoBase::ZIndex(); + return mOverrideZIndex ? *mOverrideZIndex : nsPaintedDisplayItem::ZIndex(); } void nsDisplayCompositorHitTestInfo::SetOverrideZIndex(int32_t aZIndex) { @@ -5480,7 +5472,7 @@ nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsDisplayWrapList::nsDisplayWrapList( nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsDisplayList* aList, const ActiveScrolledRoot* aActiveScrolledRoot, bool aClearClipChain) - : nsDisplayHitTestInfoBase(aBuilder, aFrame, aActiveScrolledRoot), + : nsPaintedDisplayItem(aBuilder, aFrame, aActiveScrolledRoot), mFrameActiveScrolledRoot(aBuilder->CurrentActiveScrolledRoot()), mOverrideZIndex(0), mHasZIndexOverride(false), @@ -5523,8 +5515,8 @@ nsDisplayWrapList::nsDisplayWrapList( nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsDisplayItem* aItem) - : nsDisplayHitTestInfoBase(aBuilder, aFrame, - aBuilder->CurrentActiveScrolledRoot()), + : nsPaintedDisplayItem(aBuilder, aFrame, + aBuilder->CurrentActiveScrolledRoot()), mOverrideZIndex(0), mHasZIndexOverride(false) { MOZ_COUNT_CTOR(nsDisplayWrapList); @@ -7377,7 +7369,7 @@ static_assert(sizeof(nsDisplayTransform) < 512, "nsDisplayTransform has grown"); nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsDisplayList* aList, const nsRect& aChildrenBuildingRect) - : nsDisplayHitTestInfoBase(aBuilder, aFrame), + : nsPaintedDisplayItem(aBuilder, aFrame), mTransform(Some(Matrix4x4())), mTransformGetter(nullptr), mAnimatedGeometryRootForChildren(mAnimatedGeometryRoot), @@ -7394,7 +7386,7 @@ nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsDisplayList* aList, const nsRect& aChildrenBuildingRect, PrerenderDecision aPrerenderDecision) - : nsDisplayHitTestInfoBase(aBuilder, aFrame), + : nsPaintedDisplayItem(aBuilder, aFrame), mTransformGetter(nullptr), mAnimatedGeometryRootForChildren(mAnimatedGeometryRoot), mAnimatedGeometryRootForScrollMetadata(mAnimatedGeometryRoot), @@ -7411,7 +7403,7 @@ nsDisplayTransform::nsDisplayTransform( nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsDisplayList* aList, const nsRect& aChildrenBuildingRect, ComputeTransformFunction aTransformGetter) - : nsDisplayHitTestInfoBase(aBuilder, aFrame), + : nsPaintedDisplayItem(aBuilder, aFrame), mTransformGetter(aTransformGetter), mAnimatedGeometryRootForChildren(mAnimatedGeometryRoot), mAnimatedGeometryRootForScrollMetadata(mAnimatedGeometryRoot), @@ -8673,7 +8665,7 @@ void nsDisplayTransform::WriteDebugInfo(std::stringstream& aStream) { nsDisplayPerspective::nsDisplayPerspective(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsDisplayList* aList) - : nsDisplayHitTestInfoBase(aBuilder, aFrame) { + : nsPaintedDisplayItem(aBuilder, aFrame) { mList.AppendToTop(aList); MOZ_ASSERT(mList.Count() == 1); MOZ_ASSERT(mList.GetTop()->GetType() == DisplayItemType::TYPE_TRANSFORM); diff --git a/layout/painting/nsDisplayList.h b/layout/painting/nsDisplayList.h index c2c29b89ec2a..2992bcd27e87 100644 --- a/layout/painting/nsDisplayList.h +++ b/layout/painting/nsDisplayList.h @@ -3104,12 +3104,6 @@ class nsDisplayItem : public nsDisplayItemBase { return GetPaintRect(); } - virtual bool HasHitTestInfo() const { return false; } - -#ifdef DEBUG - virtual bool IsHitTestItem() const { return false; } -#endif - protected: typedef bool (*PrefFunc)(void); bool ShouldUseAdvancedLayer(LayerManager* aManager, PrefFunc aFunc) const; @@ -3911,108 +3905,6 @@ class RetainedDisplayList : public nsDisplayList { nsTArray mOldItems; }; -struct HitTestInfo { - HitTestInfo(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, - const mozilla::gfx::CompositorHitTestInfo& aHitTestFlags) - : mArea(aFrame->GetCompositorHitTestArea(aBuilder)), - mFlags(aHitTestFlags), - mAGR(aBuilder->FindAnimatedGeometryRootFor(aFrame)), - mASR(aBuilder->CurrentActiveScrolledRoot()), - mClipChain(aBuilder->ClipState().GetCurrentCombinedClipChain(aBuilder)), - mClip(mozilla::DisplayItemClipChain::ClipForASR(mClipChain, mASR)) {} - - HitTestInfo(const nsRect& aArea, - const mozilla::gfx::CompositorHitTestInfo& aHitTestFlags) - : mArea(aArea), - mFlags(aHitTestFlags), - mAGR(nullptr), - mASR(nullptr), - mClipChain(nullptr), - mClip(nullptr) {} - - nsRect mArea; - mozilla::gfx::CompositorHitTestInfo mFlags; - - RefPtr mAGR; - RefPtr mASR; - RefPtr mClipChain; - const mozilla::DisplayItemClip* mClip; -}; - -class nsDisplayHitTestInfoBase : public nsPaintedDisplayItem { - public: - nsDisplayHitTestInfoBase(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) - : nsPaintedDisplayItem(aBuilder, aFrame) {} - - nsDisplayHitTestInfoBase(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, - const ActiveScrolledRoot* aActiveScrolledRoot) - : nsPaintedDisplayItem(aBuilder, aFrame, aActiveScrolledRoot) {} - - nsDisplayHitTestInfoBase(nsDisplayListBuilder* aBuilder, - const nsDisplayHitTestInfoBase& aOther) - : nsPaintedDisplayItem(aBuilder, aOther) {} - - const HitTestInfo& GetHitTestInfo() const { - MOZ_ASSERT(HasHitTestInfo()); - return *mHitTestInfo; - } - - void SetActiveScrolledRoot( - const ActiveScrolledRoot* aActiveScrolledRoot) override { - nsPaintedDisplayItem::SetActiveScrolledRoot(aActiveScrolledRoot); - UpdateHitTestInfoActiveScrolledRoot(aActiveScrolledRoot); - } - - /** - * Updates mASR and mClip fields using the given |aActiveScrolledRoot|. - */ - void UpdateHitTestInfoActiveScrolledRoot( - const ActiveScrolledRoot* aActiveScrolledRoot) { - if (HasHitTestInfo()) { - mHitTestInfo->mASR = aActiveScrolledRoot; - mHitTestInfo->mClip = mozilla::DisplayItemClipChain::ClipForASR( - mHitTestInfo->mClipChain, mHitTestInfo->mASR); - } - } - - void SetHitTestInfo(mozilla::UniquePtr&& aHitTestInfo) { - MOZ_ASSERT(aHitTestInfo); - MOZ_ASSERT(aHitTestInfo->mFlags != - mozilla::gfx::CompositorHitTestInvisibleToHit); - - mHitTestInfo = std::move(aHitTestInfo); - } - - void SetHitTestInfo( - const nsRect& aArea, - const mozilla::gfx::CompositorHitTestInfo& aHitTestFlags) { - MOZ_ASSERT(aHitTestFlags != mozilla::gfx::CompositorHitTestInvisibleToHit); - - mHitTestInfo = mozilla::MakeUnique(aArea, aHitTestFlags); - mHitTestInfo->mAGR = mAnimatedGeometryRoot; - mHitTestInfo->mASR = mActiveScrolledRoot; - mHitTestInfo->mClipChain = mClipChain; - mHitTestInfo->mClip = mClip; - } - - const nsRect& HitTestArea() const { return mHitTestInfo->mArea; } - - const mozilla::gfx::CompositorHitTestInfo& HitTestFlags() const { - return mHitTestInfo->mFlags; - } - - bool HasHitTestInfo() const final { return mHitTestInfo.get(); } - - void AddSizeOfExcludingThis(nsWindowSizes&) const override; - -#ifdef DEBUG - bool IsHitTestItem() const final { return true; } -#endif - - protected: - mozilla::UniquePtr mHitTestInfo; -}; - class nsDisplayContainer final : public nsDisplayItem { public: nsDisplayContainer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, @@ -5268,13 +5160,27 @@ class nsDisplayEventReceiver final : public nsDisplayItem { HitTestState* aState, nsTArray* aOutFrames) final; }; +struct HitTestInfo { + HitTestInfo(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, + const mozilla::gfx::CompositorHitTestInfo& aHitTestFlags) + : mArea(aFrame->GetCompositorHitTestArea(aBuilder)), + mFlags(aHitTestFlags) {} + + HitTestInfo(const nsRect& aArea, + const mozilla::gfx::CompositorHitTestInfo& aHitTestFlags) + : mArea(aArea), mFlags(aHitTestFlags) {} + + nsRect mArea; + mozilla::gfx::CompositorHitTestInfo mFlags; +}; + /** * Similar to nsDisplayEventReceiver in that it is used for hit-testing. However * this gets built when we're doing widget painting and we need to send the * compositor some hit-test info for a frame. This is effectively a dummy item * whose sole purpose is to carry the hit-test info to the compositor. */ -class nsDisplayCompositorHitTestInfo : public nsDisplayHitTestInfoBase { +class nsDisplayCompositorHitTestInfo : public nsPaintedDisplayItem { public: nsDisplayCompositorHitTestInfo( nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, @@ -5301,6 +5207,26 @@ class nsDisplayCompositorHitTestInfo : public nsDisplayHitTestInfoBase { int32_t ZIndex() const override; void SetOverrideZIndex(int32_t aZIndex); + void SetHitTestInfo(mozilla::UniquePtr&& aHitTestInfo) { + MOZ_ASSERT(aHitTestInfo); + MOZ_ASSERT(aHitTestInfo->mFlags != + mozilla::gfx::CompositorHitTestInvisibleToHit); + + mHitTestInfo = std::move(aHitTestInfo); + } + + void SetHitTestInfo( + const nsRect& aArea, + const mozilla::gfx::CompositorHitTestInfo& aHitTestFlags) { + MOZ_ASSERT(aHitTestFlags != mozilla::gfx::CompositorHitTestInvisibleToHit); + mHitTestInfo = mozilla::MakeUnique(aArea, aHitTestFlags); + } + + const HitTestInfo& GetHitTestInfo() const { + MOZ_ASSERT(mHitTestInfo); + return *mHitTestInfo; + } + /** * ApplyOpacity() is overriden for opacity flattening. */ @@ -5317,10 +5243,18 @@ class nsDisplayCompositorHitTestInfo : public nsDisplayHitTestInfoBase { return nsRect(); } + const nsRect& HitTestArea() const { return mHitTestInfo->mArea; } + + const mozilla::gfx::CompositorHitTestInfo& HitTestFlags() const { + return mHitTestInfo->mFlags; + } + private: mozilla::Maybe mScrollTarget; mozilla::Maybe mOverrideZIndex; int32_t mAppUnitsPerDevPixel; + + mozilla::UniquePtr mHitTestInfo; }; /** @@ -5337,7 +5271,7 @@ class nsDisplayCompositorHitTestInfo : public nsDisplayHitTestInfoBase { * we allow the frame to be nullptr. Callers to GetUnderlyingFrame must * detect and handle this case. */ -class nsDisplayWrapList : public nsDisplayHitTestInfoBase { +class nsDisplayWrapList : public nsPaintedDisplayItem { public: /** * Takes all the items from aList and puts them in our list. @@ -5354,7 +5288,7 @@ class nsDisplayWrapList : public nsDisplayHitTestInfoBase { bool aClearClipChain = false); nsDisplayWrapList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) - : nsDisplayHitTestInfoBase(aBuilder, aFrame), + : nsPaintedDisplayItem(aBuilder, aFrame), mFrameActiveScrolledRoot(aBuilder->CurrentActiveScrolledRoot()), mOverrideZIndex(0), mHasZIndexOverride(false) { @@ -5372,7 +5306,7 @@ class nsDisplayWrapList : public nsDisplayHitTestInfoBase { nsDisplayWrapList(const nsDisplayWrapList& aOther) = delete; nsDisplayWrapList(nsDisplayListBuilder* aBuilder, const nsDisplayWrapList& aOther) - : nsDisplayHitTestInfoBase(aBuilder, aOther), + : nsPaintedDisplayItem(aBuilder, aOther), mListPtr(&mList), mFrameActiveScrolledRoot(aOther.mFrameActiveScrolledRoot), mMergedFrames(aOther.mMergedFrames.Clone()), @@ -5393,7 +5327,7 @@ class nsDisplayWrapList : public nsDisplayHitTestInfoBase { void Destroy(nsDisplayListBuilder* aBuilder) override { mList.DeleteAll(aBuilder); - nsDisplayHitTestInfoBase::Destroy(aBuilder); + nsPaintedDisplayItem::Destroy(aBuilder); } /** @@ -5433,14 +5367,6 @@ class nsDisplayWrapList : public nsDisplayHitTestInfoBase { SetBuildingRect(buildingRect); } - void SetActiveScrolledRoot( - const ActiveScrolledRoot* aActiveScrolledRoot) override { - // Skip unnecessary call to - // |nsDisplayHitTestInfoBase::UpdateHitTestInfoActiveScrolledRoot()|, since - // callers will manually call that with different ASR. - nsDisplayHitTestInfoBase::SetActiveScrolledRoot(aActiveScrolledRoot); - } - void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, HitTestState* aState, nsTArray* aOutFrames) override; nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const override; @@ -5516,7 +5442,7 @@ class nsDisplayWrapList : public nsDisplayHitTestInfoBase { int32_t ZIndex() const override { return (mHasZIndexOverride) ? mOverrideZIndex - : nsDisplayHitTestInfoBase::ZIndex(); + : nsPaintedDisplayItem::ZIndex(); } void SetOverrideZIndex(int32_t aZIndex) { @@ -6774,7 +6700,7 @@ class nsDisplayFilters : public nsDisplayEffectsBase { * function. * INVARIANT: The wrapped frame is non-null. */ -class nsDisplayTransform : public nsDisplayHitTestInfoBase { +class nsDisplayTransform : public nsPaintedDisplayItem { using Matrix4x4 = mozilla::gfx::Matrix4x4; using Matrix4x4Flagged = mozilla::gfx::Matrix4x4Flagged; using Point3D = mozilla::gfx::Point3D; @@ -6812,7 +6738,7 @@ class nsDisplayTransform : public nsDisplayHitTestInfoBase { NS_DISPLAY_DECL_NAME("nsDisplayTransform", TYPE_TRANSFORM) bool RestoreState() override { - if (!nsDisplayHitTestInfoBase::RestoreState() && !mShouldFlatten) { + if (!nsPaintedDisplayItem::RestoreState() && !mShouldFlatten) { return false; } @@ -6832,7 +6758,7 @@ class nsDisplayTransform : public nsDisplayHitTestInfoBase { void Destroy(nsDisplayListBuilder* aBuilder) override { GetChildren()->DeleteAll(aBuilder); - nsDisplayHitTestInfoBase::Destroy(aBuilder); + nsPaintedDisplayItem::Destroy(aBuilder); } nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) const override; @@ -6905,7 +6831,7 @@ class nsDisplayTransform : public nsDisplayHitTestInfoBase { if (!mTransformGetter) { return mFrame; } - return nsDisplayHitTestInfoBase::ReferenceFrameForChildren(); + return nsPaintedDisplayItem::ReferenceFrameForChildren(); } AnimatedGeometryRoot* AnimatedGeometryRootForScrollMetadata() const override { @@ -7165,7 +7091,7 @@ class nsDisplayTransform : public nsDisplayHitTestInfoBase { * perspective-origin is relative to an ancestor of the transformed frame, and * APZ can scroll the child separately. */ -class nsDisplayPerspective : public nsDisplayHitTestInfoBase { +class nsDisplayPerspective : public nsPaintedDisplayItem { typedef mozilla::gfx::Point3D Point3D; public: @@ -7177,7 +7103,7 @@ class nsDisplayPerspective : public nsDisplayHitTestInfoBase { void Destroy(nsDisplayListBuilder* aBuilder) override { mList.DeleteAll(aBuilder); - nsDisplayHitTestInfoBase::Destroy(aBuilder); + nsPaintedDisplayItem::Destroy(aBuilder); } void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,