Bug 1418387 - Add CompositorHitTestInfo bits for scrollbars. r=mstange

MozReview-Commit-ID: KTfpXoESOxF

--HG--
extra : rebase_source : d1db8909b1b075f885b08c86ebca7ef51fd250e0
This commit is contained in:
Kartikaya Gupta 2017-11-24 16:23:06 -05:00
parent 4f10904eb2
commit c82aeb4865
5 changed files with 73 additions and 15 deletions

View File

@ -34,6 +34,17 @@ enum class CompositorHitTestInfo : uint16_t {
eTouchActionDoubleTapZoomDisabled = 1 << 5,
// Mask to check for all the touch-action flags at once
eTouchActionMask = (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5),
// The frame is a scrollbar or a subframe inside a scrollbar (including
// scroll thumbs)
eScrollbar = 1 << 6,
// The frame is a scrollthumb. If this is set then eScrollbar will also be
// set, unless gecko somehow generates a scroll thumb without a containing
// scrollbar.
eScrollbarThumb = 1 << 7,
// If eScrollbar is set, this flag indicates if the scrollbar is a vertical
// one (if set) or a horizontal one (if not set)
eScrollbarVertical = 1 << 8,
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(CompositorHitTestInfo)

View File

@ -11286,6 +11286,23 @@ nsIFrame::GetCompositorHitTestInfo(nsDisplayListBuilder* aBuilder)
}
}
nsDisplayOwnLayerFlags flags = aBuilder->GetCurrentScrollbarFlags();
if (flags != nsDisplayOwnLayerFlags::eNone) {
if (GetContent()->IsXULElement(nsGkAtoms::thumb)) {
result |= CompositorHitTestInfo::eScrollbarThumb;
}
// The only flags that get set in nsDisplayListBuilder::mCurrentScrollbarFlags
// are the scrollbar direction flags
if (flags == nsDisplayOwnLayerFlags::eVerticalScrollbar) {
result |= CompositorHitTestInfo::eScrollbarVertical;
} else {
MOZ_ASSERT(flags == nsDisplayOwnLayerFlags::eHorizontalScrollbar);
}
// includes the ScrollbarFrame, SliderFrame, anything else that
// might be inside the xul:scrollbar
result |= CompositorHitTestInfo::eScrollbar;
}
return result;
}

View File

@ -4146,6 +4146,13 @@ public:
bool BuiltBlendContainer() { return mBuiltBlendContainer; }
void SetBuiltBlendContainer(bool aBuilt) { mBuiltBlendContainer = aBuilt; }
/**
* Returns the set of flags indicating the properties of the frame that the
* compositor might care about for hit-testing purposes. Note that this function
* must be called during Gecko display list construction time (i.e while the
* frame tree is being traversed) because that is when the display list builder
* has the necessary state set up correctly.
*/
mozilla::gfx::CompositorHitTestInfo GetCompositorHitTestInfo(nsDisplayListBuilder* aBuilder);
protected:

View File

@ -4868,6 +4868,27 @@ nsDisplayEventReceiver::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder&
return true;
}
nsDisplayCompositorHitTestInfo::nsDisplayCompositorHitTestInfo(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame,
mozilla::gfx::CompositorHitTestInfo aHitTestInfo)
: nsDisplayEventReceiver(aBuilder, aFrame)
, mHitTestInfo(aHitTestInfo)
{
MOZ_COUNT_CTOR(nsDisplayCompositorHitTestInfo);
// We should never even create this display item if we're not building
// compositor hit-test info or if the computed hit info indicated the
// frame is invisible to hit-testing
MOZ_ASSERT(aBuilder->BuildCompositorHitTestInfo());
MOZ_ASSERT(mHitTestInfo != mozilla::gfx::CompositorHitTestInfo::eInvisibleToHitTest);
if (aBuilder->GetCurrentScrollbarFlags() != nsDisplayOwnLayerFlags::eNone) {
// In the case of scrollbar frames, we use the scrollbar's target scrollframe
// instead of the scrollframe with which the scrollbar actually moves.
MOZ_ASSERT(mHitTestInfo & CompositorHitTestInfo::eScrollbar);
mScrollTarget = Some(aBuilder->GetCurrentScrollbarTarget());
}
}
bool
nsDisplayCompositorHitTestInfo::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
mozilla::wr::IpcResourceUpdateQueue& aResources,
@ -4902,10 +4923,13 @@ nsDisplayCompositorHitTestInfo::CreateWebRenderCommands(mozilla::wr::DisplayList
// we don't need to do it as often, and so that we can do it for other
// display item types as well (reducing the need for as many instances of
// this display item).
FrameMetrics::ViewID scrollId = FrameMetrics::NULL_SCROLL_ID;
if (const ActiveScrolledRoot* asr = GetActiveScrolledRoot()) {
scrollId = asr->GetViewId();
}
FrameMetrics::ViewID scrollId = mScrollTarget.valueOrFrom(
[&]() -> FrameMetrics::ViewID {
if (const ActiveScrolledRoot* asr = GetActiveScrolledRoot()) {
return asr->GetViewId();
}
return FrameMetrics::NULL_SCROLL_ID;
});
// Insert a transparent rectangle with the hit-test info
aBuilder.SetHitTestInfo(scrollId, mHitTestInfo);
@ -6934,6 +6958,12 @@ nsDisplayOwnLayer::UpdateScrollData(mozilla::layers::WebRenderScrollData* aData,
return ret;
}
void
nsDisplayOwnLayer::WriteDebugInfo(std::stringstream& aStream)
{
aStream << nsPrintfCString(" (flags 0x%x) (scrolltarget %" PRIu64 ")", (int)mFlags, mScrollTarget).get();
}
nsDisplaySubDocument::nsDisplaySubDocument(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame,
nsSubDocumentFrame* aSubDocFrame,

View File

@ -4343,17 +4343,7 @@ public:
class nsDisplayCompositorHitTestInfo : public nsDisplayEventReceiver {
public:
nsDisplayCompositorHitTestInfo(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
mozilla::gfx::CompositorHitTestInfo aHitTestInfo)
: nsDisplayEventReceiver(aBuilder, aFrame)
, mHitTestInfo(aHitTestInfo)
{
MOZ_COUNT_CTOR(nsDisplayCompositorHitTestInfo);
// We should never even create this display item if we're not building
// compositor hit-test info or if the computed hit info indicated the
// frame is invisible to hit-testing
MOZ_ASSERT(aBuilder->BuildCompositorHitTestInfo());
MOZ_ASSERT(mHitTestInfo != mozilla::gfx::CompositorHitTestInfo::eInvisibleToHitTest);
}
mozilla::gfx::CompositorHitTestInfo aHitTestInfo);
#ifdef NS_BUILD_REFCNT_LOGGING
virtual ~nsDisplayCompositorHitTestInfo()
@ -4375,6 +4365,7 @@ public:
private:
mozilla::gfx::CompositorHitTestInfo mHitTestInfo;
mozilla::Maybe<mozilla::layers::FrameMetrics::ViewID> mScrollTarget;
};
/**
@ -5156,6 +5147,8 @@ public:
return false;
}
void WriteDebugInfo(std::stringstream& aStream) override;
nsDisplayOwnLayerFlags GetFlags() { return mFlags; }
bool IsScrollThumbLayer() const;
NS_DISPLAY_DECL_NAME("OwnLayer", TYPE_OWN_LAYER)