Bug 1455182 - Additional cleanup to nsDisplayOwnLayer and ScrollbarData. r=botond

--HG--
extra : rebase_source : d0dd9840dab41e6a2dbd3427fafbf03b741441a1
This commit is contained in:
Daniel Zielas 2018-05-25 07:20:39 +02:00
Родитель 2fa797d756
Коммит 6e81464d99
6 изменённых файлов: 110 добавлений и 90 удалений

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

@ -24,10 +24,12 @@ enum class ScrollbarLayerType : uint8_t { None, Thumb, Container };
* It stores data for scroll thumb layer or container layers.
*/
struct ScrollbarData {
ScrollbarData() = default;
private:
/**
* This constructor is for Thumb layer type.
*/
ScrollbarData(ScrollDirection aDirection,
ScrollbarLayerType aScrollbarLayerType,
float aThumbRatio,
CSSCoord aThumbStart,
CSSCoord aThumbLength,
@ -36,7 +38,7 @@ struct ScrollbarData {
CSSCoord aScrollTrackLength,
uint64_t aTargetViewId)
: mDirection(Some(aDirection))
, mScrollbarLayerType(aScrollbarLayerType)
, mScrollbarLayerType(ScrollbarLayerType::Thumb)
, mThumbRatio(aThumbRatio)
, mThumbStart(aThumbStart)
, mThumbLength(aThumbLength)
@ -46,6 +48,45 @@ struct ScrollbarData {
, mTargetViewId(aTargetViewId)
{}
/**
* This constructor is for Container layer type.
*/
ScrollbarData(const Maybe<ScrollDirection>& aDirection,
uint64_t aTargetViewId)
: mDirection(aDirection)
, mScrollbarLayerType(ScrollbarLayerType::Container)
, mTargetViewId(aTargetViewId)
{}
public:
ScrollbarData() = default;
static ScrollbarData CreateForThumb(ScrollDirection aDirection,
float aThumbRatio,
CSSCoord aThumbStart,
CSSCoord aThumbLength,
bool aThumbIsAsyncDraggable,
CSSCoord aScrollTrackStart,
CSSCoord aScrollTrackLength,
uint64_t aTargetViewId)
{
return ScrollbarData(aDirection,
aThumbRatio,
aThumbStart,
aThumbLength,
aThumbIsAsyncDraggable,
aScrollTrackStart,
aScrollTrackLength,
aTargetViewId);
}
static ScrollbarData CreateForScrollbarContainer(const Maybe<ScrollDirection>& aDirection,
uint64_t aTargetViewId)
{
return ScrollbarData(aDirection,
aTargetViewId);
}
/**
* The mDirection contains a direction if mScrollbarLayerType is Thumb
* or Container, otherwise it's empty.

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

@ -11304,7 +11304,7 @@ nsIFrame::GetCompositorHitTestInfo(nsDisplayListBuilder* aBuilder)
// are the event targets for any regions viewport frames may cover.
return result;
}
uint8_t pointerEvents = StyleUserInterface()->GetEffectivePointerEvents(this);
const uint8_t pointerEvents = StyleUserInterface()->GetEffectivePointerEvents(this);
if (pointerEvents == NS_STYLE_POINTER_EVENTS_NONE) {
return result;
}
@ -11336,7 +11336,7 @@ nsIFrame::GetCompositorHitTestInfo(nsDisplayListBuilder* aBuilder)
if (nsIScrollableFrame* scrollFrame = nsLayoutUtils::GetScrollableFrameFor(this)) {
touchActionFrame = do_QueryFrame(scrollFrame);
}
uint32_t touchAction = nsLayoutUtils::GetTouchActionFromFrame(touchActionFrame);
const uint32_t touchAction = nsLayoutUtils::GetTouchActionFromFrame(touchActionFrame);
// The CSS allows the syntax auto | none | [pan-x || pan-y] | manipulation
// so we can eliminate some combinations of things.
if (touchAction == NS_STYLE_TOUCH_ACTION_AUTO) {
@ -11362,10 +11362,10 @@ nsIFrame::GetCompositorHitTestInfo(nsDisplayListBuilder* aBuilder)
}
}
nsDisplayOwnLayerFlags flags = aBuilder->GetCurrentScrollbarFlags();
if (flags != nsDisplayOwnLayerFlags::eNone) {
const Maybe<ScrollDirection> scrollDirection = aBuilder->GetCurrentScrollbarDirection();
if (scrollDirection.isSome()) {
if (GetContent()->IsXULElement(nsGkAtoms::thumb)) {
bool thumbGetsLayer = aBuilder->GetCurrentScrollbarTarget() !=
const bool thumbGetsLayer = aBuilder->GetCurrentScrollbarTarget() !=
layers::FrameMetrics::NULL_SCROLL_ID;
if (thumbGetsLayer) {
result |= CompositorHitTestInfo::eScrollbarThumb;
@ -11373,13 +11373,11 @@ nsIFrame::GetCompositorHitTestInfo(nsDisplayListBuilder* aBuilder)
result |= CompositorHitTestInfo::eDispatchToContent;
}
}
// The only flags that get set in nsDisplayListBuilder::mCurrentScrollbarFlags
// are the scrollbar direction flags
if (flags == nsDisplayOwnLayerFlags::eVerticalScrollbar) {
if (*scrollDirection == ScrollDirection::eVertical) {
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;

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

@ -3024,21 +3024,15 @@ AppendToTop(nsDisplayListBuilder* aBuilder, const nsDisplayListSet& aLists,
nsDisplayWrapList* newItem;
const ActiveScrolledRoot* asr = aBuilder->CurrentActiveScrolledRoot();
if (aFlags & APPEND_OWN_LAYER) {
nsDisplayOwnLayerFlags flags = aBuilder->GetCurrentScrollbarFlags();
// The flags here should be at most one scrollbar direction and nothing else
MOZ_ASSERT(flags == nsDisplayOwnLayerFlags::eNone ||
flags == nsDisplayOwnLayerFlags::eVerticalScrollbar ||
flags == nsDisplayOwnLayerFlags::eHorizontalScrollbar);
ScrollbarData scrollbarData;
if (aFlags & APPEND_SCROLLBAR_CONTAINER) {
scrollbarData.mTargetViewId = aBuilder->GetCurrentScrollbarTarget();
// The flags here should be exactly one scrollbar direction
MOZ_ASSERT(flags != nsDisplayOwnLayerFlags::eNone);
flags |= nsDisplayOwnLayerFlags::eScrollbarContainer;
scrollbarData = ScrollbarData::CreateForScrollbarContainer(aBuilder->GetCurrentScrollbarDirection(),
aBuilder->GetCurrentScrollbarTarget());
// Direction should be set
MOZ_ASSERT(scrollbarData.mDirection.isSome());
}
newItem = MakeDisplayItem<nsDisplayOwnLayer>(aBuilder, aSourceFrame, aSource, asr, flags, scrollbarData);
newItem = MakeDisplayItem<nsDisplayOwnLayer>(aBuilder, aSourceFrame, aSource, asr, nsDisplayOwnLayerFlags::eNone, scrollbarData);
} else {
// Build the wrap list with an index of 1, since the scrollbar frame itself might have already
// built an nsDisplayWrapList.
@ -3088,7 +3082,7 @@ ScrollFrameHelper::AppendScrollPartsTo(nsDisplayListBuilder* aBuilder,
bool aCreateLayer,
bool aPositioned)
{
bool overlayScrollbars =
const bool overlayScrollbars =
LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars) != 0;
AutoTArray<nsIFrame*, 3> scrollParts;
@ -3107,7 +3101,7 @@ ScrollFrameHelper::AppendScrollPartsTo(nsDisplayListBuilder* aBuilder,
// We can't check will-change budget during display list building phase.
// This means that we will build scroll bar layers for out of budget
// will-change: scroll position.
mozilla::layers::FrameMetrics::ViewID scrollTargetId = IsMaybeScrollingActive()
const mozilla::layers::FrameMetrics::ViewID scrollTargetId = IsMaybeScrollingActive()
? nsLayoutUtils::FindOrCreateIDFor(mScrolledFrame->GetContent())
: mozilla::layers::FrameMetrics::NULL_SCROLL_ID;
@ -3123,14 +3117,15 @@ ScrollFrameHelper::AppendScrollPartsTo(nsDisplayListBuilder* aBuilder,
}
for (uint32_t i = 0; i < scrollParts.Length(); ++i) {
nsDisplayOwnLayerFlags flags = nsDisplayOwnLayerFlags::eNone;
Maybe<ScrollDirection> scrollDirection;
uint32_t appendToTopFlags = 0;
if (scrollParts[i] == mVScrollbarBox) {
flags |= nsDisplayOwnLayerFlags::eVerticalScrollbar;
scrollDirection.emplace(ScrollDirection::eVertical);
appendToTopFlags |= APPEND_SCROLLBAR_CONTAINER;
}
if (scrollParts[i] == mHScrollbarBox) {
flags |= nsDisplayOwnLayerFlags::eHorizontalScrollbar;
MOZ_ASSERT(!scrollDirection.isSome());
scrollDirection.emplace(ScrollDirection::eHorizontal);
appendToTopFlags |= APPEND_SCROLLBAR_CONTAINER;
}
if (scrollParts[i] == mResizerBox &&
@ -3142,20 +3137,20 @@ ScrollFrameHelper::AppendScrollPartsTo(nsDisplayListBuilder* aBuilder,
// include all of the scrollbars if we are in a RCD-RSF. We only do
// this for the root scrollframe of the root content document, which is
// zoomable, and where the scrollbar sizes are bounded by the widget.
nsRect visible = mIsRoot && mOuter->PresContext()->IsRootContentDocument()
const nsRect visible = mIsRoot && mOuter->PresContext()->IsRootContentDocument()
? scrollParts[i]->GetVisualOverflowRectRelativeToParent()
: aBuilder->GetVisibleRect();
if (visible.IsEmpty()) {
continue;
}
nsRect dirty = mIsRoot && mOuter->PresContext()->IsRootContentDocument()
const nsRect dirty = mIsRoot && mOuter->PresContext()->IsRootContentDocument()
? scrollParts[i]->GetVisualOverflowRectRelativeToParent()
: aBuilder->GetDirtyRect();
// Always create layers for overlay scrollbars so that we don't create a
// giant layer covering the whole scrollport if both scrollbars are visible.
bool isOverlayScrollbar = (flags != nsDisplayOwnLayerFlags::eNone) && overlayScrollbars;
bool createLayer = aCreateLayer || isOverlayScrollbar ||
const bool isOverlayScrollbar = scrollDirection.isSome() && overlayScrollbars;
const bool createLayer = aCreateLayer || isOverlayScrollbar ||
gfxPrefs::AlwaysLayerizeScrollbarTrackTestOnly();
nsDisplayListCollection partList(aBuilder);
@ -3165,7 +3160,7 @@ ScrollFrameHelper::AppendScrollPartsTo(nsDisplayListBuilder* aBuilder,
visible, dirty, true);
nsDisplayListBuilder::AutoCurrentScrollbarInfoSetter
infoSetter(aBuilder, scrollTargetId, flags, createLayer);
infoSetter(aBuilder, scrollTargetId, scrollDirection, createLayer);
mOuter->BuildDisplayListForChild(
aBuilder, scrollParts[i], partList,
nsIFrame::DISPLAY_CHILD_FORCE_STACKING_CONTEXT);
@ -3194,7 +3189,7 @@ ScrollFrameHelper::AppendScrollPartsTo(nsDisplayListBuilder* aBuilder,
visible + mOuter->GetOffsetTo(scrollParts[i]),
dirty + mOuter->GetOffsetTo(scrollParts[i]), true);
nsDisplayListBuilder::AutoCurrentScrollbarInfoSetter
infoSetter(aBuilder, scrollTargetId, flags, createLayer);
infoSetter(aBuilder, scrollTargetId, scrollDirection, createLayer);
// DISPLAY_CHILD_FORCE_STACKING_CONTEXT put everything into
// partList.PositionedDescendants().
::AppendToTop(aBuilder, aLists,

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

@ -998,7 +998,6 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
mMode(aMode),
mCurrentScrollParentId(FrameMetrics::NULL_SCROLL_ID),
mCurrentScrollbarTarget(FrameMetrics::NULL_SCROLL_ID),
mCurrentScrollbarFlags(nsDisplayOwnLayerFlags::eNone),
mPerspectiveItemIndex(0),
mSVGEffectsBuildingDepth(0),
mFilterASR(nullptr),
@ -5063,7 +5062,7 @@ nsDisplayCompositorHitTestInfo::nsDisplayCompositorHitTestInfo(nsDisplayListBuil
MOZ_ASSERT(aBuilder->BuildCompositorHitTestInfo());
MOZ_ASSERT(mHitTestInfo != mozilla::gfx::CompositorHitTestInfo::eInvisibleToHitTest);
if (aBuilder->GetCurrentScrollbarFlags() != nsDisplayOwnLayerFlags::eNone) {
if (aBuilder->GetCurrentScrollbarDirection().isSome()) {
// 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);
@ -7016,6 +7015,12 @@ nsDisplayOwnLayer::IsScrollThumbLayer() const
return mScrollbarData.mScrollbarLayerType == layers::ScrollbarLayerType::Thumb;
}
bool
nsDisplayOwnLayer::IsScrollbarContainer() const
{
return mScrollbarData.mScrollbarLayerType == layers::ScrollbarLayerType::Container;
}
bool
nsDisplayOwnLayer::ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) const
{
@ -7035,14 +7040,7 @@ nsDisplayOwnLayer::BuildLayer(nsDisplayListBuilder* aBuilder,
aContainerParameters, nullptr,
FrameLayerBuilder::CONTAINER_ALLOW_PULL_BACKGROUND_COLOR);
if (IsScrollThumbLayer()) {
layer->SetScrollbarData(mScrollbarData);
} else if (mFlags & nsDisplayOwnLayerFlags::eScrollbarContainer) {
mScrollbarData.mScrollbarLayerType = ScrollbarLayerType::Container;
mScrollbarData.mDirection = (mFlags & nsDisplayOwnLayerFlags::eVerticalScrollbar)
? Some(ScrollDirection::eVertical)
: Some(ScrollDirection::eHorizontal);
if (IsScrollThumbLayer() || IsScrollbarContainer()) {
layer->SetScrollbarData(mScrollbarData);
}
@ -7090,20 +7088,14 @@ nsDisplayOwnLayer::UpdateScrollData(mozilla::layers::WebRenderScrollData* aData,
mozilla::layers::WebRenderLayerScrollData* aLayerData)
{
bool ret = false;
if (IsScrollThumbLayer()) {
if (IsScrollThumbLayer() || IsScrollbarContainer()) {
ret = true;
if (aLayerData) {
aLayerData->SetScrollbarData(mScrollbarData);
aLayerData->SetScrollbarAnimationId(mWrAnimationId);
}
} else if (mFlags & nsDisplayOwnLayerFlags::eScrollbarContainer) {
ret = true;
if (aLayerData) {
mScrollbarData.mScrollbarLayerType = ScrollbarLayerType::Container;
mScrollbarData.mDirection = (mFlags & nsDisplayOwnLayerFlags::eVerticalScrollbar)
? Some(ScrollDirection::eVertical)
: Some(ScrollDirection::eHorizontal);
aLayerData->SetScrollbarData(mScrollbarData);
if (IsScrollThumbLayer()) {
aLayerData->SetScrollbarAnimationId(mWrAnimationId);
}
}
}
return ret;

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

@ -440,6 +440,7 @@ public:
typedef mozilla::layers::FrameMetrics FrameMetrics;
typedef mozilla::layers::FrameMetrics::ViewID ViewID;
typedef mozilla::gfx::Matrix4x4 Matrix4x4;
typedef mozilla::Maybe<mozilla::layers::ScrollDirection> MaybeScrollDirection;
/**
* @param aReferenceFrame the frame at the root of the subtree; its origin
@ -621,7 +622,7 @@ public:
* which we are building display items at the moment.
*/
ViewID GetCurrentScrollbarTarget() const { return mCurrentScrollbarTarget; }
nsDisplayOwnLayerFlags GetCurrentScrollbarFlags() const { return mCurrentScrollbarFlags; }
MaybeScrollDirection GetCurrentScrollbarDirection() const { return mCurrentScrollbarDirection; }
/**
* Returns true if building a scrollbar, and the scrollbar will not be
* layerized.
@ -1363,18 +1364,18 @@ public:
class AutoCurrentScrollbarInfoSetter {
public:
AutoCurrentScrollbarInfoSetter(nsDisplayListBuilder* aBuilder, ViewID aScrollTargetID,
nsDisplayOwnLayerFlags aScrollbarFlags, bool aWillHaveLayer)
const MaybeScrollDirection& aScrollbarDirection, bool aWillHaveLayer)
: mBuilder(aBuilder) {
aBuilder->mIsBuildingScrollbar = true;
aBuilder->mCurrentScrollbarTarget = aScrollTargetID;
aBuilder->mCurrentScrollbarFlags = aScrollbarFlags;
aBuilder->mCurrentScrollbarDirection = aScrollbarDirection;
aBuilder->mCurrentScrollbarWillHaveLayer = aWillHaveLayer;
}
~AutoCurrentScrollbarInfoSetter() {
// No need to restore old values because scrollbars cannot be nested.
mBuilder->mIsBuildingScrollbar = false;
mBuilder->mCurrentScrollbarTarget = FrameMetrics::NULL_SCROLL_ID;
mBuilder->mCurrentScrollbarFlags = (nsDisplayOwnLayerFlags)0;
mBuilder->mCurrentScrollbarDirection.reset();
mBuilder->mCurrentScrollbarWillHaveLayer = false;
}
private:
@ -1960,7 +1961,7 @@ private:
nsDisplayListBuilderMode mMode;
ViewID mCurrentScrollParentId;
ViewID mCurrentScrollbarTarget;
nsDisplayOwnLayerFlags mCurrentScrollbarFlags;
MaybeScrollDirection mCurrentScrollbarDirection;
Preserves3DContext mPreserves3DCtx;
uint32_t mPerspectiveItemIndex;
int32_t mSVGEffectsBuildingDepth;
@ -5634,10 +5635,7 @@ protected:
enum class nsDisplayOwnLayerFlags {
eNone = 0,
eGenerateSubdocInvalidations = 1 << 0,
eVerticalScrollbar = 1 << 1,
eHorizontalScrollbar = 1 << 2,
eGenerateScrollableLayer = 1 << 3,
eScrollbarContainer = 1 << 4,
eGenerateScrollableLayer = 1 << 1,
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(nsDisplayOwnLayerFlags)
@ -5713,6 +5711,7 @@ public:
nsDisplayOwnLayerFlags GetFlags() { return mFlags; }
bool IsScrollThumbLayer() const;
bool IsScrollbarContainer() const;
NS_DISPLAY_DECL_NAME("OwnLayer", TYPE_OWN_LAYER)
protected:
nsDisplayOwnLayerFlags mFlags;

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

@ -374,20 +374,16 @@ nsSliderFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder,
// that the event region that gets created for the thumb is included in
// the nsDisplayOwnLayer contents.
nsDisplayOwnLayerFlags flags = aBuilder->GetCurrentScrollbarFlags();
mozilla::layers::FrameMetrics::ViewID scrollTargetId =
const mozilla::layers::FrameMetrics::ViewID scrollTargetId =
aBuilder->GetCurrentScrollbarTarget();
bool thumbGetsLayer = (scrollTargetId != layers::FrameMetrics::NULL_SCROLL_ID);
const bool thumbGetsLayer = (scrollTargetId != layers::FrameMetrics::NULL_SCROLL_ID);
if (thumbGetsLayer) {
MOZ_ASSERT((flags & nsDisplayOwnLayerFlags::eHorizontalScrollbar) ||
(flags & nsDisplayOwnLayerFlags::eVerticalScrollbar));
bool isHorizontal = bool(flags & nsDisplayOwnLayerFlags::eHorizontalScrollbar);
ScrollDirection scrollDirection = isHorizontal
? ScrollDirection::eHorizontal
: ScrollDirection::eVertical;
const Maybe<ScrollDirection> scrollDirection = aBuilder->GetCurrentScrollbarDirection();
MOZ_ASSERT(scrollDirection.isSome());
const bool isHorizontal = *scrollDirection == ScrollDirection::eHorizontal;
const float appUnitsPerCss = float(AppUnitsPerCSSPixel());
CSSCoord thumbLength = NSAppUnitsToFloatPixels(
const CSSCoord thumbLength = NSAppUnitsToFloatPixels(
isHorizontal ? thumbRect.width : thumbRect.height, appUnitsPerCss);
nsIFrame* scrollbarBox = GetScrollbar();
@ -403,16 +399,16 @@ nsSliderFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder,
// This rect is the range in which the scroll thumb can slide in.
sliderTrack = sliderTrack + GetRect().TopLeft() + scrollbarBox->GetPosition() -
scrollPortOrigin;
CSSCoord sliderTrackStart = NSAppUnitsToFloatPixels(
const CSSCoord sliderTrackStart = NSAppUnitsToFloatPixels(
isHorizontal ? sliderTrack.x : sliderTrack.y, appUnitsPerCss);
CSSCoord sliderTrackLength = NSAppUnitsToFloatPixels(
const CSSCoord sliderTrackLength = NSAppUnitsToFloatPixels(
isHorizontal ? sliderTrack.width : sliderTrack.height, appUnitsPerCss);
CSSCoord thumbStart = NSAppUnitsToFloatPixels(
const CSSCoord thumbStart = NSAppUnitsToFloatPixels(
isHorizontal ? thumbRect.x : thumbRect.y, appUnitsPerCss);
nsRect overflow = thumb->GetVisualOverflowRectRelativeToParent();
const nsRect overflow = thumb->GetVisualOverflowRectRelativeToParent();
nsSize refSize = aBuilder->RootReferenceFrame()->GetSize();
gfxSize scale = nsLayoutUtils::GetTransformToAncestorScale(thumb);
const gfxSize scale = nsLayoutUtils::GetTransformToAncestorScale(thumb);
if (scale.width != 0 && scale.height != 0) {
refSize.width /= scale.width;
refSize.height /= scale.height;
@ -459,16 +455,15 @@ nsSliderFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder,
const ActiveScrolledRoot* ownLayerASR = contASRTracker.GetContainerASR();
aLists.Content()->AppendToTop(
MakeDisplayItem<nsDisplayOwnLayer>(aBuilder, this, &masterList, ownLayerASR,
flags,
ScrollbarData{scrollDirection,
layers::ScrollbarLayerType::Thumb,
GetThumbRatio(),
thumbStart,
thumbLength,
isAsyncDraggable,
sliderTrackStart,
sliderTrackLength,
scrollTargetId}));
nsDisplayOwnLayerFlags::eNone,
ScrollbarData::CreateForThumb(*scrollDirection,
GetThumbRatio(),
thumbStart,
thumbLength,
isAsyncDraggable,
sliderTrackStart,
sliderTrackLength,
scrollTargetId)));
return;
}