author | Kartikaya Gupta <kgupta@mozilla.com> |
Fri, 08 Jun 2018 17:31:27 -0400 | |
changeset 422100 | 995feb0ecd7fc92e09329116ae4d6d5fcf94392b |
parent 422099 | b5327ed6e61a6409e1a0c97df2d0a475d98c219d |
child 422101 | 5f8e35e87a21b61e5e8c59cb7055e0521fe5d675 |
push id | 34118 |
push user | apavel@mozilla.com |
push date | Sun, 10 Jun 2018 09:47:23 +0000 |
treeherder | mozilla-central@79476ed91dec [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mattwoodrow, tnikkel |
bugs | 1436409 |
milestone | 62.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/gfx/layers/wr/WebRenderCommandBuilder.cpp +++ b/gfx/layers/wr/WebRenderCommandBuilder.cpp @@ -236,17 +236,16 @@ struct Grouper // Returns whether this is an item for which complete invalidation was // reliant on LayerTreeInvalidation in the pre-webrender world. static bool IsContainerLayerItem(nsDisplayItem* aItem) { switch (aItem->GetType()) { case DisplayItemType::TYPE_TRANSFORM: - case DisplayItemType::TYPE_LAYER_EVENT_REGIONS: case DisplayItemType::TYPE_OPACITY: case DisplayItemType::TYPE_FILTER: case DisplayItemType::TYPE_BLEND_CONTAINER: case DisplayItemType::TYPE_BLEND_MODE: case DisplayItemType::TYPE_MASK: { return true; } default: { @@ -1232,20 +1231,16 @@ WebRenderCommandBuilder::CreateWebRender bool apzEnabled = mManager->AsyncPanZoomEnabled(); FlattenedDisplayItemIterator iter(aDisplayListBuilder, aDisplayList); while (nsDisplayItem* i = iter.GetNext()) { nsDisplayItem* item = i; DisplayItemType itemType = item->GetType(); - // We should never get event regions items in WR now that we always have - // WR hit-testing enabled. - MOZ_ASSERT(itemType != DisplayItemType::TYPE_LAYER_EVENT_REGIONS); - // Peek ahead to the next item and try merging with it or swapping with it // if necessary. AutoTArray<nsDisplayItem*, 1> mergedItems; mergedItems.AppendElement(item); while (nsDisplayItem* peek = iter.PeekNext()) { if (!item->CanMerge(peek)) { break; }
--- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -2816,26 +2816,21 @@ nsIFrame::BuildDisplayListForStackingCon const nsStyleDisplay* disp = StyleDisplay(); const nsStyleEffects* effects = StyleEffects(); EffectSet* effectSet = EffectSet::GetEffectSet(this); // We can stop right away if this is a zero-opacity stacking context and // we're painting, and we're not animating opacity. Don't do this // if we're going to compute plugin geometry, since opacity-0 plugins // need to have display items built for them. - bool needEventRegions = - aBuilder->IsBuildingLayerEventRegions() && - StyleUserInterface()->GetEffectivePointerEvents(this) != - NS_STYLE_POINTER_EVENTS_NONE; bool opacityItemForEventsAndPluginsOnly = false; if (effects->mOpacity == 0.0 && aBuilder->IsForPainting() && !(disp->mWillChangeBitField & NS_STYLE_WILL_CHANGE_OPACITY) && !nsLayoutUtils::HasAnimationOfProperty(effectSet, eCSSProperty_opacity)) { - if (needEventRegions || - aBuilder->WillComputePluginGeometry()) { + if (aBuilder->WillComputePluginGeometry()) { opacityItemForEventsAndPluginsOnly = true; } else { return; } } if (disp->mWillChangeBitField != 0) { aBuilder->AddToWillChangeBudget(this, GetSize()); @@ -3064,23 +3059,16 @@ nsIFrame::BuildDisplayListForStackingCon if (extend3DContext) { // Mark these first so MarkAbsoluteFramesForDisplayList knows if we are // going to be forced to descend into frames. aBuilder->MarkPreserve3DFramesForDisplayList(this); } aBuilder->AdjustWindowDraggingRegion(this); - nsDisplayLayerEventRegions* eventRegions = nullptr; - if (aBuilder->IsBuildingLayerEventRegions()) { - eventRegions = MakeDisplayItem<nsDisplayLayerEventRegions>(aBuilder, this); - eventRegions->AddFrame(aBuilder, this); - aBuilder->SetLayerEventRegions(eventRegions); - } - aBuilder->BuildCompositorHitTestInfoIfNeeded(this, set.BorderBackground(), true); MarkAbsoluteFramesForDisplayList(aBuilder); aBuilder->Check(); BuildDisplayList(aBuilder, set); aBuilder->Check(); @@ -3105,28 +3093,16 @@ nsIFrame::BuildDisplayListForStackingCon if (aBuilder->ContainsBlendMode() && aBuilder->IsRetainingDisplayList()) { if (!aBuilder->GetDirtyRect().Contains(aBuilder->GetVisibleRect())) { aBuilder->SetPartialBuildFailed(true); } else { aBuilder->SetDisablePartialUpdates(true); } } - - if (eventRegions) { - // If the event regions item ended up empty, throw it away rather than - // adding it to the display list. - if (!eventRegions->IsEmpty()) { - set.BorderBackground()->AppendToBottom(eventRegions); - } else { - aBuilder->SetLayerEventRegions(nullptr); - eventRegions->Destroy(aBuilder); - eventRegions = nullptr; - } - } } if (aBuilder->IsBackgroundOnly()) { set.BlockBorderBackgrounds()->DeleteAll(aBuilder); set.Floats()->DeleteAll(aBuilder); set.Content()->DeleteAll(aBuilder); set.PositionedDescendants()->DeleteAll(aBuilder); set.Outlines()->DeleteAll(aBuilder); @@ -3530,18 +3506,17 @@ nsIFrame::BuildDisplayListForChild(nsDis nsIFrame* child = aChild; if (child->HasAnyStateBits( NS_FRAME_TOO_DEEP_IN_FRAME_TREE | NS_FRAME_IS_NONDISPLAY)) return; aBuilder->ClearWillChangeBudget(child); const bool shortcutPossible = aBuilder->IsPaintingToWindow() && - (aBuilder->IsBuildingLayerEventRegions() || - aBuilder->BuildCompositorHitTestInfo()); + aBuilder->BuildCompositorHitTestInfo(); const bool doingShortcut = shortcutPossible && (child->GetStateBits() & NS_FRAME_SIMPLE_DISPLAYLIST) && // Animations may change the value of |HasOpacity()|. !(child->GetContent() && child->GetContent()->MayHaveAnimations()); // dirty rect in child-relative coordinates @@ -3566,21 +3541,16 @@ nsIFrame::BuildDisplayListForChild(nsDis buildingForChild(aBuilder, child, visible, dirty, false); CheckForApzAwareEventHandlers(aBuilder, child); aBuilder->BuildCompositorHitTestInfoIfNeeded(child, aLists.BorderBackground(), false); - nsDisplayLayerEventRegions* eventRegions = aBuilder->GetLayerEventRegions(); - if (eventRegions) { - eventRegions->AddFrame(aBuilder, child); - } - child->MarkAbsoluteFramesForDisplayList(aBuilder); aBuilder->AdjustWindowDraggingRegion(child); aBuilder->Check(); child->BuildDisplayList(aBuilder, aLists); aBuilder->Check(); aBuilder->DisplayCaret(child, aLists.Content()); #ifdef DEBUG DisplayDebugBorders(aBuilder, child, aLists); @@ -3780,40 +3750,16 @@ nsIFrame::BuildDisplayListForChild(nsDis aBuilder->IntersectDirtyRect(*clipPropClip); clipState.ClipContentDescendants( *clipPropClip + aBuilder->ToReferenceFrame(child)); awayFromCommonPath = true; } child->MarkAbsoluteFramesForDisplayList(aBuilder); - 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 = - MakeDisplayItem<nsDisplayLayerEventRegions>(aBuilder, child); - eventRegions->AddFrame(aBuilder, child); - aBuilder->SetLayerEventRegions(eventRegions); - - if (isPositioned) { - // We need this nsDisplayLayerEventRegions to be sorted with the positioned - // elements as positioned elements will be sorted on top of normal elements - list.AppendToTop(eventRegions); - } else { - aLists.BorderBackground()->AppendToTop(eventRegions); - } - } else { - nsDisplayLayerEventRegions* eventRegions = aBuilder->GetLayerEventRegions(); - if (eventRegions) { - eventRegions->AddFrame(aBuilder, child); - } - } - } - const bool differentAGR = buildingForChild.IsAnimatedGeometryRoot() || isPositioned; if (!awayFromCommonPath && shortcutPossible && !differentAGR && !buildingForChild.MaybeAnimatedGeometryRoot()) { // The shortcut is available for the child for next time. child->AddStateBits(NS_FRAME_SIMPLE_DISPLAYLIST); }
--- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -3716,22 +3716,16 @@ ScrollFrameHelper::BuildDisplayList(nsDi scrollbarStyles.mOverscrollBehaviorY != StyleOverscrollBehavior::Auto) { info |= CompositorHitTestInfo::eRequiresTargetConfirmation; } nsDisplayCompositorHitTestInfo* hitInfo = MakeDisplayItem<nsDisplayCompositorHitTestInfo>(aBuilder, mScrolledFrame, info, 1, Some(mScrollPort + aBuilder->ToReferenceFrame(mOuter))); AppendInternalItemToTop(scrolledContent, hitInfo, Some(INT32_MAX)); } - if (aBuilder->IsBuildingLayerEventRegions()) { - nsDisplayLayerEventRegions* inactiveRegionItem = - MakeDisplayItem<nsDisplayLayerEventRegions>(aBuilder, mScrolledFrame, 1); - inactiveRegionItem->AddInactiveScrollPort(mScrolledFrame, mScrollPort + aBuilder->ToReferenceFrame(mOuter)); - AppendInternalItemToTop(scrolledContent, inactiveRegionItem, Some(INT32_MAX)); - } } if (aBuilder->ShouldBuildScrollInfoItemsForHoisting()) { aBuilder->AppendNewScrollInfoItemForHoisting( MakeDisplayItem<nsDisplayScrollInfoLayer>(aBuilder, mScrolledFrame, mOuter)); } }
--- a/layout/painting/FrameLayerBuilder.cpp +++ b/layout/painting/FrameLayerBuilder.cpp @@ -583,24 +583,17 @@ public: AnimatedGeometryRoot* GetAnimatedGeometryRoot() { return mAnimatedGeometryRoot; } /** * A region including the horizontal pan, vertical pan, and no action regions. */ nsRegion CombinedTouchActionRegion(); /** - * Add the given hit regions to the hit regions for this PaintedLayer. - */ - void AccumulateEventRegions(ContainerState* aState, - nsDisplayLayerEventRegions* aEventRegions); - - /** - * Similar to AccumulateEventRegions() but uses different display item to - * track hit regions. + * Add the given hit test info to the hit regions for this PaintedLayer. */ void AccumulateHitTestInfo(ContainerState* aState, nsDisplayCompositorHitTestInfo* aItem); /** * If this represents only a nsDisplayImage, and the image type supports being * optimized to an ImageLayer, returns true. */ @@ -3399,17 +3392,16 @@ void ContainerState::FinishPaintedLayerD if (!layer) { // We couldn't optimize to an image layer or a color layer above. layer = data->mLayer; layer->SetClipRect(Nothing()); FLB_LOG_PAINTED_LAYER_DECISION(data, " Selected painted layer=%p\n", layer.get()); } for (auto& item : data->mAssignedDisplayItems) { - MOZ_ASSERT(item.mItem->GetType() != DisplayItemType::TYPE_LAYER_EVENT_REGIONS); MOZ_ASSERT(item.mItem->GetType() != DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO); if (item.mType == DisplayItemEntryType::POP_OPACITY) { // Do not invalidate for end markers. continue; } InvalidateForLayerChange(item.mItem, data->mLayer, item.mDisplayItemData); @@ -3819,48 +3811,16 @@ PaintedLayerData::CombinedTouchActionReg { nsRegion result; result.Or(mHorizontalPanRegion, mVerticalPanRegion); result.OrWith(mNoActionRegion); return result; } void -PaintedLayerData::AccumulateEventRegions(ContainerState* aState, nsDisplayLayerEventRegions* aEventRegions) -{ - FLB_LOG_PAINTED_LAYER_DECISION(this, "Accumulating event regions %p against pld=%p\n", aEventRegions, this); - - mHitRegion.OrWith(aEventRegions->HitRegion()); - mMaybeHitRegion.OrWith(aEventRegions->MaybeHitRegion()); - mDispatchToContentHitRegion.OrWith(aEventRegions->DispatchToContentHitRegion()); - - // See the comment in nsDisplayList::AddFrame, where the touch action regions - // are handled. The same thing applies here. - bool alreadyHadRegions = !mNoActionRegion.IsEmpty() || - !mHorizontalPanRegion.IsEmpty() || - !mVerticalPanRegion.IsEmpty(); - mNoActionRegion.OrWith(aEventRegions->NoActionRegion()); - mHorizontalPanRegion.OrWith(aEventRegions->HorizontalPanRegion()); - mVerticalPanRegion.OrWith(aEventRegions->VerticalPanRegion()); - if (alreadyHadRegions) { - mDispatchToContentHitRegion.OrWith(CombinedTouchActionRegion()); - } - - // Avoid quadratic performance as a result of the region growing to include - // and arbitrarily large number of rects, which can happen on some pages. - mMaybeHitRegion.SimplifyOutward(8); - mDispatchToContentHitRegion.SimplifyOutward(8); - - // Calculate scaled versions of the bounds of mHitRegion and mMaybeHitRegion - // for quick access in FindPaintedLayerFor(). - mScaledHitRegionBounds = aState->ScaleToOutsidePixels(mHitRegion.GetBounds()); - mScaledMaybeHitRegionBounds = aState->ScaleToOutsidePixels(mMaybeHitRegion.GetBounds()); -} - -void PaintedLayerData::AccumulateHitTestInfo(ContainerState* aState, nsDisplayCompositorHitTestInfo* aItem) { FLB_LOG_PAINTED_LAYER_DECISION(this, "Accumulating hit test info %p against pld=%p\n", aItem, this); const mozilla::DisplayItemClip& clip = aItem->GetClip(); const nsRect area = clip.ApplyNonRoundedIntersection(aItem->Area()); @@ -4292,21 +4252,16 @@ ContainerState::ProcessDisplayItems(nsDi { AUTO_PROFILER_LABEL("ContainerState::ProcessDisplayItems", GRAPHICS); nsPoint topLeft(0,0); int32_t maxLayers = gfxPrefs::MaxActiveLayers(); int layerCount = 0; -#ifdef DEBUG - bool hadLayerEventRegions = false; - bool hadCompositorHitTestInfo = false; -#endif - if (!mManager->IsWidgetLayerManager()) { mPaintedLayerDataTree.InitializeForInactiveLayer(mContainerAnimatedGeometryRoot); } AnimatedGeometryRoot* lastAnimatedGeometryRoot = nullptr; nsPoint lastTopLeft; // Tracks the PaintedLayerData that the item will be accumulated in, if it is @@ -4319,45 +4274,25 @@ ContainerState::ProcessDisplayItems(nsDi nsDisplayItem* i = e.mItem; DisplayItemEntryType marker = e.mType; nsDisplayItem* item = i; MOZ_ASSERT(item); DisplayItemType itemType = item->GetType(); - // If the item is a event regions item, but is empty (has no regions in it) - // then we should just throw it out - if (itemType == DisplayItemType::TYPE_LAYER_EVENT_REGIONS) { -#ifdef DEBUG - hadLayerEventRegions = true; -#endif - nsDisplayLayerEventRegions* eventRegions = - static_cast<nsDisplayLayerEventRegions*>(item); - - if (eventRegions->IsEmpty()) { - continue; - } - } - if (itemType == DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO) { -#ifdef DEBUG - hadCompositorHitTestInfo = true; -#endif nsDisplayCompositorHitTestInfo* hitTestInfo = static_cast<nsDisplayCompositorHitTestInfo*>(item); if (hitTestInfo->Area().IsEmpty()) { continue; } } - // Only allow either LayerEventRegions or CompositorHitTestInfo items. - MOZ_ASSERT(!(hadLayerEventRegions && hadCompositorHitTestInfo)); - if (marker == DisplayItemEntryType::ITEM) { // Peek ahead to the next item and see if it can be merged with the // current item. nsDisplayItem* peek = iter.PeekNext(); if (peek && item->CanMerge(peek)) { // Create a list of consecutive items that can be merged together. AutoTArray<nsDisplayItem*, 2> mergedItems { item }; while ((peek = iter.PeekNext())) { @@ -4384,18 +4319,17 @@ ContainerState::ProcessDisplayItems(nsDi NS_ASSERTION(mAppUnitsPerDevPixel == AppUnitsPerDevPixel(item), "items in a container layer should all have the same app units per dev pixel"); if (mBuilder->NeedToForceTransparentSurfaceForItem(item)) { aList->SetNeedsTransparentSurface(); } if (mParameters.mForEventsAndPluginsOnly && !item->GetChildren() && - (itemType != DisplayItemType::TYPE_LAYER_EVENT_REGIONS && - itemType != DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO && + (itemType != DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO && itemType != DisplayItemType::TYPE_PLUGIN)) { continue; } LayerState layerState = LAYER_NONE; if (marker == DisplayItemEntryType::ITEM) { layerState = item->GetLayerState(mBuilder, mManager, mParameters); @@ -4435,26 +4369,21 @@ ContainerState::ProcessDisplayItems(nsDi lastAnimatedGeometryRoot = animatedGeometryRoot; } const ActiveScrolledRoot* scrollMetadataASR = layerClipChain ? ActiveScrolledRoot::PickDescendant(itemASR, layerClipChain->mASR) : itemASR; bool snap; nsRect itemContent = item->GetBounds(mBuilder, &snap); - if (itemType == DisplayItemType::TYPE_LAYER_EVENT_REGIONS) { - nsDisplayLayerEventRegions* eventRegions = - static_cast<nsDisplayLayerEventRegions*>(item); - itemContent = eventRegions->GetHitRegionBounds(mBuilder, &snap); - } if (itemType == DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO) { - nsDisplayCompositorHitTestInfo* eventRegions = + nsDisplayCompositorHitTestInfo* hitInfo = static_cast<nsDisplayCompositorHitTestInfo*>(item); - itemContent = eventRegions->Area(); + itemContent = hitInfo->Area(); } nsIntRect itemDrawRect = ScaleToOutsidePixels(itemContent, snap); bool prerenderedTransform = itemType == DisplayItemType::TYPE_TRANSFORM && static_cast<nsDisplayTransform*>(item)->MayBeAnimated(mBuilder); ParentLayerIntRect clipRect; const DisplayItemClip& itemClip = item->GetClip(); if (itemClip.HasClip()) { @@ -4463,18 +4392,17 @@ ContainerState::ProcessDisplayItems(nsDi if (!prerenderedTransform && !IsScrollThumbLayer(item)) { itemDrawRect.IntersectRect(itemDrawRect, clipRect.ToUnknownRect()); } clipRect.MoveBy(ViewAs<ParentLayerPixel>(mParameters.mOffset)); } #ifdef DEBUG nsRect bounds = itemContent; - if (itemType == DisplayItemType::TYPE_LAYER_EVENT_REGIONS || - itemType == DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO) { + if (itemType == DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO) { bounds.SetEmpty(); } if (!bounds.IsEmpty()) { if (itemASR != mContainerASR) { if (Maybe<nsRect> clip = item->GetClipWithRespectToASR(mBuilder, mContainerASR)) { bounds = clip.ref(); } @@ -4839,21 +4767,17 @@ ContainerState::ProcessDisplayItems(nsDi [&](PaintedLayerData* aData) { NewPaintedLayerData(aData, animatedGeometryRoot, itemASR, layerClipChain, scrollMetadataASR, topLeft, referenceFrame, backfaceHidden); }); } MOZ_ASSERT(paintedLayerData); - if (itemType == DisplayItemType::TYPE_LAYER_EVENT_REGIONS) { - nsDisplayLayerEventRegions* eventRegions = - static_cast<nsDisplayLayerEventRegions*>(item); - paintedLayerData->AccumulateEventRegions(this, eventRegions); - } else if (itemType == DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO) { + if (itemType == DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO) { nsDisplayCompositorHitTestInfo* hitTestInfo = static_cast<nsDisplayCompositorHitTestInfo*>(item); paintedLayerData->AccumulateHitTestInfo(this, hitTestInfo); } else { paintedLayerData->Accumulate(this, item, itemVisibleRect, itemContent, itemClip, layerState, aList, marker); if (!paintedLayerData->mLayer) {
--- a/layout/painting/nsDisplayItemTypesList.h +++ b/layout/painting/nsDisplayItemTypesList.h @@ -27,17 +27,16 @@ DECLARE_DISPLAY_ITEM_TYPE(CANVAS_FOCUS, DECLARE_DISPLAY_ITEM_TYPE(CARET, TYPE_RENDERS_NO_IMAGES) DECLARE_DISPLAY_ITEM_TYPE(CHECKED_CHECKBOX, TYPE_RENDERS_NO_IMAGES) DECLARE_DISPLAY_ITEM_TYPE(CHECKED_RADIOBUTTON, TYPE_RENDERS_NO_IMAGES) DECLARE_DISPLAY_ITEM_TYPE(CLEAR_BACKGROUND, TYPE_RENDERS_NO_IMAGES) DECLARE_DISPLAY_ITEM_TYPE(COLUMN_RULE, TYPE_RENDERS_NO_IMAGES) DECLARE_DISPLAY_ITEM_TYPE(COMBOBOX_FOCUS, TYPE_RENDERS_NO_IMAGES) DECLARE_DISPLAY_ITEM_TYPE(COMPOSITOR_HITTEST_INFO, TYPE_RENDERS_NO_IMAGES) DECLARE_DISPLAY_ITEM_TYPE(EVENT_RECEIVER, TYPE_RENDERS_NO_IMAGES) -DECLARE_DISPLAY_ITEM_TYPE(LAYER_EVENT_REGIONS, TYPE_RENDERS_NO_IMAGES) DECLARE_DISPLAY_ITEM_TYPE(FIELDSET_BORDER_BACKGROUND, 0) DECLARE_DISPLAY_ITEM_TYPE(FIXED_POSITION, TYPE_RENDERS_NO_IMAGES) DECLARE_DISPLAY_ITEM_TYPE(STICKY_POSITION, TYPE_RENDERS_NO_IMAGES) DECLARE_DISPLAY_ITEM_TYPE(FRAMESET_BORDER, TYPE_RENDERS_NO_IMAGES) DECLARE_DISPLAY_ITEM_TYPE(FRAMESET_BLANK, TYPE_RENDERS_NO_IMAGES) DECLARE_DISPLAY_ITEM_TYPE(HEADER_FOOTER, TYPE_RENDERS_NO_IMAGES) DECLARE_DISPLAY_ITEM_TYPE(IMAGE, 0) DECLARE_DISPLAY_ITEM_TYPE(LIST_FOCUS, TYPE_RENDERS_NO_IMAGES)
--- a/layout/painting/nsDisplayList.cpp +++ b/layout/painting/nsDisplayList.cpp @@ -976,17 +976,16 @@ 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), @@ -1071,17 +1070,16 @@ 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; @@ -1370,17 +1368,16 @@ nsDisplayListBuilder::EnterPresShell(nsI } // A non-blank paint is a paint that does not just contain the canvas background. static bool DisplayListIsNonBlank(nsDisplayList* aList) { for (nsDisplayItem* i = aList->GetBottom(); i != nullptr; i = i->GetAbove()) { switch (i->GetType()) { - case DisplayItemType::TYPE_LAYER_EVENT_REGIONS: case DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO: case DisplayItemType::TYPE_CANVAS_BACKGROUND_COLOR: case DisplayItemType::TYPE_CANVAS_BACKGROUND_IMAGE: continue; case DisplayItemType::TYPE_SOLID_COLOR: case DisplayItemType::TYPE_BACKGROUND: case DisplayItemType::TYPE_BACKGROUND_COLOR: if (i->Frame()->IsCanvasFrame()) { @@ -2286,31 +2283,16 @@ nsDisplayListBuilder::ShouldBuildComposi // 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; - } - if (IsPaintingToWindow()) { - return mAsyncPanZoomEnabled; - } - return false; -} - void nsDisplayListSet::MoveTo(const nsDisplayListSet& aDestination) const { aDestination.BorderBackground()->AppendToTop(BorderBackground()); aDestination.BlockBorderBackgrounds()->AppendToTop(BlockBorderBackgrounds()); aDestination.Floats()->AppendToTop(Floats()); aDestination.Content()->AppendToTop(Content()); aDestination.PositionedDescendants()->AppendToTop(PositionedDescendants()); aDestination.Outlines()->AppendToTop(Outlines()); @@ -2377,17 +2359,16 @@ nsDisplayList::ComputeVisibilityForRoot( } static nsRegion TreatAsOpaque(nsDisplayItem* aItem, nsDisplayListBuilder* aBuilder) { bool snap; nsRegion opaque = aItem->GetOpaqueRegion(aBuilder, &snap); if (aBuilder->IsForPluginGeometry() && - aItem->GetType() != DisplayItemType::TYPE_LAYER_EVENT_REGIONS && aItem->GetType() != DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO) { // Treat all leaf chrome items as opaque, unless their frames are opacity:0. // Since opacity:0 frames generate an nsDisplayOpacity, that item will // not be treated as opaque here, so opacity:0 chrome content will be // effectively ignored, as it should be. // We treat leaf chrome items as opaque to ensure that they cover // content plugins, for security reasons. @@ -5134,213 +5115,16 @@ nsDisplayCompositorHitTestInfo::ZIndex() } void nsDisplayCompositorHitTestInfo::SetOverrideZIndex(int32_t aZIndex) { mOverrideZIndex = Some(aZIndex); } -void -nsDisplayLayerEventRegions::AddFrame(nsDisplayListBuilder* aBuilder, - nsIFrame* aFrame) -{ - NS_ASSERTION(aBuilder->FindReferenceFrameFor(aFrame) == aBuilder->FindReferenceFrameFor(mFrame), - "Reference frame mismatch"); - CompositorHitTestInfo hitInfo = - aFrame->GetCompositorHitTestInfo(aBuilder); - 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 = GetFrameArea(aBuilder, aFrame); - - if (aFrame != mFrame && - aBuilder->IsRetainingDisplayList()) { - aFrame->AddDisplayItem(this); - } - - 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)) { - borderBoxHasRoundedCorners = true; - } else { - aFrame->AddStateBits(NS_FRAME_SIMPLE_EVENT_REGIONS); - } - } - - const DisplayItemClip* clip = DisplayItemClipChain::ClipForASR( - aBuilder->ClipState().GetCurrentCombinedClipChain(aBuilder), - aBuilder->CurrentActiveScrolledRoot()); - if (clip) { - borderBox = clip->ApplyNonRoundedIntersection(borderBox); - if (clip->GetRoundedRectCount() > 0) { - borderBoxHasRoundedCorners = true; - } - } - - if (borderBoxHasRoundedCorners || - (aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT)) { - mMaybeHitRegion.Add(aFrame, borderBox); - } else { - mHitRegion.Add(aFrame, borderBox); - } - - if (hitInfo & CompositorHitTestInfo::eDispatchToContent) { - mDispatchToContentHitRegion.Add(aFrame, borderBox); - } - - // Touch action region - - auto touchFlags = hitInfo & CompositorHitTestInfo::eTouchActionMask; - if (touchFlags) { - // something was disabled - if (touchFlags == CompositorHitTestInfo::eTouchActionMask) { - // everything was disabled, so touch-action:none - mNoActionRegion.Add(aFrame, borderBox); - } else { - // The event regions code does not store enough information to actually - // represent all the different states. Prior to the introduction of - // CompositorHitTestInfo here in bug 1389149, the following two cases - // were effectively getting collapsed: - // (1) touch-action: auto - // (2) touch-action: manipulation - // In both of these cases, none of {mNoActionRegion, mHorizontalPanRegion, - // mVerticalPanRegion} were modified, and so the fact that case (2) should - // have prevented double-tap-zooming was getting lost. - // With CompositorHitTestInfo we can now represent that case correctly, - // but only if we use CompositorHitTestInfo all the way to the compositor - // (i.e. in the WebRender-enabled case). In the non-WebRender case where - // we still use the event regions, we must collapse these two cases back - // together. Or add another region to the event regions to fix this - // properly. - if (touchFlags == CompositorHitTestInfo::eTouchActionDoubleTapZoomDisabled) { - // the touch-action: manipulation case described above. To preserve the - // existing behaviour, don't touch either mHorizontalPanRegion or - // mVerticalPanRegion - } else { - if (!(hitInfo & CompositorHitTestInfo::eTouchActionPanXDisabled)) { - // pan-x is allowed - mHorizontalPanRegion.Add(aFrame, borderBox); - } - if (!(hitInfo & CompositorHitTestInfo::eTouchActionPanYDisabled)) { - // pan-y is allowed - mVerticalPanRegion.Add(aFrame, borderBox); - } - } - } - } -} - -static void -RemoveFrameFromFrameRects(nsDisplayLayerEventRegions::FrameRects& aFrameRects, nsIFrame* aFrame) -{ - uint32_t i = 0; - uint32_t length = aFrameRects.mFrames.Length(); - while (i < length) { - if (aFrameRects.mFrames[i] == aFrame) { - aFrameRects.mFrames[i] = aFrameRects.mFrames[length - 1]; - aFrameRects.mBoxes[i] = aFrameRects.mBoxes[length - 1]; - length--; - } else { - i++; - } - } - aFrameRects.mFrames.SetLength(length); - aFrameRects.mBoxes.SetLength(length); -} - -void -nsDisplayLayerEventRegions::RemoveFrame(nsIFrame* aFrame) -{ - RemoveFrameFromFrameRects(mHitRegion, aFrame); - RemoveFrameFromFrameRects(mMaybeHitRegion, aFrame); - RemoveFrameFromFrameRects(mDispatchToContentHitRegion, aFrame); - RemoveFrameFromFrameRects(mNoActionRegion, aFrame); - RemoveFrameFromFrameRects(mHorizontalPanRegion, aFrame); - RemoveFrameFromFrameRects(mVerticalPanRegion, aFrame); - - nsDisplayItem::RemoveFrame(aFrame); -} - -void -nsDisplayLayerEventRegions::AddInactiveScrollPort(nsIFrame* aFrame, const nsRect& aRect) -{ - mHitRegion.Add(aFrame, aRect); - mDispatchToContentHitRegion.Add(aFrame, aRect); -} - -bool -nsDisplayLayerEventRegions::IsEmpty() const -{ - // If the hit region and maybe-hit region are empty, then the rest - // must be empty too. - if (mHitRegion.IsEmpty() && mMaybeHitRegion.IsEmpty()) { - MOZ_ASSERT(mDispatchToContentHitRegion.IsEmpty()); - MOZ_ASSERT(mNoActionRegion.IsEmpty()); - MOZ_ASSERT(mHorizontalPanRegion.IsEmpty()); - MOZ_ASSERT(mVerticalPanRegion.IsEmpty()); - return true; - } - return false; -} - -nsRegion -nsDisplayLayerEventRegions::CombinedTouchActionRegion() -{ - nsRegion result; - result.Or(HorizontalPanRegion(), VerticalPanRegion()); - result.OrWith(NoActionRegion()); - return result; -} - -int32_t -nsDisplayLayerEventRegions::ZIndex() const -{ - return mOverrideZIndex ? *mOverrideZIndex : nsDisplayItem::ZIndex(); -} - -void -nsDisplayLayerEventRegions::SetOverrideZIndex(int32_t aZIndex) -{ - mOverrideZIndex = Some(aZIndex); -} - -void -nsDisplayLayerEventRegions::WriteDebugInfo(std::stringstream& aStream) -{ - if (!mHitRegion.IsEmpty()) { - AppendToString(aStream, HitRegion(), " (hitRegion ", ")"); - } - if (!mMaybeHitRegion.IsEmpty()) { - AppendToString(aStream, MaybeHitRegion(), " (maybeHitRegion ", ")"); - } - if (!mDispatchToContentHitRegion.IsEmpty()) { - AppendToString(aStream, DispatchToContentHitRegion(), " (dispatchToContentRegion ", ")"); - } - if (!mNoActionRegion.IsEmpty()) { - AppendToString(aStream, NoActionRegion(), " (noActionRegion ", ")"); - } - if (!mHorizontalPanRegion.IsEmpty()) { - AppendToString(aStream, HorizontalPanRegion(), " (horizPanRegion ", ")"); - } - if (!mVerticalPanRegion.IsEmpty()) { - AppendToString(aStream, VerticalPanRegion(), " (vertPanRegion ", ")"); - } -} - nsDisplayCaret::nsDisplayCaret(nsDisplayListBuilder* aBuilder, nsIFrame* aCaretFrame) : nsDisplayItem(aBuilder, aCaretFrame) , mCaret(aBuilder->GetCaret()) , mBounds(aBuilder->GetCaretRect() + ToReferenceFrame()) { MOZ_COUNT_CTOR(nsDisplayCaret); } @@ -6574,18 +6358,17 @@ CollectItemsWithOpacity(nsDisplayList* a // Descend only into wraplists. if (type == DisplayItemType::TYPE_WRAP_LIST && children) { // The current display item has children, process them first. if (!CollectItemsWithOpacity(children, aArray, aMaxChildCount)) { return false; } } - if (type == DisplayItemType::TYPE_LAYER_EVENT_REGIONS || - type == DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO || + if (type == DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO || type == DisplayItemType::TYPE_WRAP_LIST) { continue; } if (!i->CanApplyOpacity() || aArray.Length() == aMaxChildCount) { return false; }
--- a/layout/painting/nsDisplayList.h +++ b/layout/painting/nsDisplayList.h @@ -57,17 +57,16 @@ class gfxContext; class nsIContent; class nsDisplayList; class nsDisplayTableItem; class nsIScrollableFrame; class nsSubDocumentFrame; class nsDisplayCompositorHitTestInfo; -class nsDisplayLayerEventRegions; class nsDisplayScrollInfoLayer; class nsCaret; enum class nsDisplayOwnLayerFlags; namespace mozilla { class FrameLayerBuilder; namespace layers { class Layer; @@ -721,22 +720,16 @@ public: /** * Returns true if merging and flattening of display lists should be * performed while computing visibility. */ 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; @@ -746,17 +739,16 @@ public: * 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(); bool IsInsidePointerEventsNoneDoc() { return CurrentPresShellState()->mInsidePointerEventsNoneDoc; } bool GetAncestorHasApzAwareEventHandler() const { return mAncestorHasApzAwareEventHandler; } void SetAncestorHasApzAwareEventHandler(bool aValue) { @@ -1070,17 +1062,16 @@ public: AutoBuildingDisplayList(nsDisplayListBuilder* aBuilder, 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), @@ -1123,33 +1114,31 @@ public: return mCurrentAGRState == AGR_MAYBE; } 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; @@ -1722,18 +1711,16 @@ public: void SetHitTestIsForVisibility(bool aHitTestIsForVisibility) { mHitTestIsForVisibility = aHitTestIsForVisibility; } /** * Represents a region composed of frame/rect pairs. * WeakFrames are used to track whether a rect still belongs to the region. * Modified frames and rects are removed and re-added to the region if needed. - * nsDisplayLayerEventRegions::FrameRects implements the same functionality - * with nsIFrames. */ struct WeakFrameRegion { std::vector<WeakFrame> mFrames; nsTArray<pixman_box32_t> mRects; void Add(nsIFrame* aFrame, const nsRect& aRect) { mFrames.emplace_back(aFrame); @@ -1853,17 +1840,16 @@ private: {} nsIFrame* mFrame; uint32_t mUsage; }; nsIFrame* const mReferenceFrame; nsIFrame* mIgnoreScrollFrame; - nsDisplayLayerEventRegions* mLayerEventRegions; nsDisplayCompositorHitTestInfo* mCompositorHitTestInfo; nsPresArena mPool; RefPtr<mozilla::dom::Selection> mBoundingSelection; AutoTArray<PresShellState,8> mPresShellStates; AutoTArray<nsIFrame*,400> mFramesMarkedForDisplay; AutoTArray<nsIFrame*,40> mFramesMarkedForDisplayIfVisible; @@ -4827,234 +4813,16 @@ private: mozilla::Maybe<mozilla::layers::FrameMetrics::ViewID> mScrollTarget; nsRect mArea; uint32_t mIndex; mozilla::Maybe<int32_t> mOverrideZIndex; int32_t mAppUnitsPerDevPixel; }; /** - * A display item that tracks event-sensitive regions which will be set - * on the ContainerLayer that eventually contains this item. - * - * One of these is created for each stacking context and pseudo-stacking-context. - * It accumulates regions for event targets contributed by the border-boxes of - * frames in its (pseudo) stacking context. A nsDisplayLayerEventRegions - * eventually contributes its regions to the PaintedLayer it is placed in by - * FrameLayerBuilder. (We don't create a display item for every frame that - * could be an event target (i.e. almost all frames), because that would be - * high overhead.) - * - * We always make leaf layers other than PaintedLayers transparent to events. - * For example, an event targeting a canvas or video will actually target the - * background of that element, which is logically in the PaintedLayer behind the - * CanvasFrame or ImageFrame. We only need to create a - * nsDisplayLayerEventRegions when an element's background could be in front - * of a lower z-order element with its own layer. - */ -class nsDisplayLayerEventRegions final : public nsDisplayItem { -public: - nsDisplayLayerEventRegions(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, uint32_t aIndex = 0) - : nsDisplayItem(aBuilder, aFrame) - , mIndex(aIndex) - { - MOZ_COUNT_CTOR(nsDisplayLayerEventRegions); - } - - virtual void Destroy(nsDisplayListBuilder* aBuilder) override - { - if (!aBuilder->IsRetainingDisplayList()) { - nsDisplayItem::Destroy(aBuilder); - return; - } - - RemoveItemFromFrames(mHitRegion); - RemoveItemFromFrames(mMaybeHitRegion); - RemoveItemFromFrames(mDispatchToContentHitRegion); - RemoveItemFromFrames(mNoActionRegion); - RemoveItemFromFrames(mHorizontalPanRegion); - RemoveItemFromFrames(mVerticalPanRegion); - nsDisplayItem::Destroy(aBuilder); - } - - virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, - bool* aSnap) const override - { - *aSnap = false; - return nsRect(); - } - nsRect GetHitRegionBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) - { - *aSnap = false; - // TODO: This constructs the two regions, but we're also doing the same - // work in AccumulateEventRegions. We should avoid doing it twice. - return HitRegion().GetBounds().Union(MaybeHitRegion().GetBounds()); - } - - virtual void ApplyOpacity(nsDisplayListBuilder* aBuilder, - float aOpacity, - const DisplayItemClipChain* aClip) override - { - NS_ASSERTION(CanApplyOpacity(), "ApplyOpacity should be allowed"); - } - virtual bool CanApplyOpacity() const override - { - return true; - } - - NS_DISPLAY_DECL_NAME("LayerEventRegions", TYPE_LAYER_EVENT_REGIONS) - - // Indicate that aFrame's border-box contributes to the event regions for - // this layer. aFrame must have the same reference frame as mFrame. - void AddFrame(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame); - - // Indicate that an inactive scrollframe's scrollport should be added to the - // dispatch-to-content region, to ensure that APZ lets content create a - // displayport. - void AddInactiveScrollPort(nsIFrame* aFrame, const nsRect& aRect); - - bool IsEmpty() const; - - int32_t ZIndex() const override; - void SetOverrideZIndex(int32_t aZIndex); - - virtual uint32_t GetPerFrameKey() const override - { - return (mIndex << TYPE_BITS) | nsDisplayItem::GetPerFrameKey(); - } - - const nsRegion HitRegion() - { - return nsRegion(mozilla::gfx::ArrayView<pixman_box32_t>(mHitRegion.mBoxes)); - } - const nsRegion MaybeHitRegion() - { - nsRegion result(mozilla::gfx::ArrayView<pixman_box32_t>(mMaybeHitRegion.mBoxes)); - - // Avoid quadratic performance as a result of the region growing to include - // an arbitrarily large number of rects, which can happen on some pages. - // TODO: It would be nice if we could ask the initial construction above - // to include simplification. - result.SimplifyOutward(8); - return result; - } - const nsRegion DispatchToContentHitRegion() - { - nsRegion result(mozilla::gfx::ArrayView<pixman_box32_t>(mDispatchToContentHitRegion.mBoxes)); - - // If this frame has touch-action areas, and there were already - // touch-action areas from some other element on this same event regions, - // then all we know is that there are multiple elements with touch-action - // properties. In particular, we don't know what the relationship is - // between those elements in terms of DOM ancestry, and so we don't know - // how to combine the regions properly. Instead, we just add all the areas - // to the dispatch-to-content region, so that the APZ knows to check with - // the main thread. XXX we need to come up with a better way to do this, - // see bug 1287829. - uint32_t touchActionCount = - mNoActionRegion.mBoxes.Length() + - mHorizontalPanRegion.mBoxes.Length() + - mVerticalPanRegion.mBoxes.Length(); - if (touchActionCount > 1) { - result.OrWith(NoActionRegion()); - result.OrWith(HorizontalPanRegion()); - result.OrWith(VerticalPanRegion()); - } - - result.SimplifyOutward(8); - return result; - } - const nsRegion NoActionRegion() - { - return nsRegion(mozilla::gfx::ArrayView<pixman_box32_t>(mNoActionRegion.mBoxes)); - } - const nsRegion HorizontalPanRegion() - { - return nsRegion(mozilla::gfx::ArrayView<pixman_box32_t>(mHorizontalPanRegion.mBoxes)); - } - const nsRegion VerticalPanRegion() - { - return nsRegion(mozilla::gfx::ArrayView<pixman_box32_t>(mVerticalPanRegion.mBoxes)); - } - nsRegion CombinedTouchActionRegion(); - - virtual void WriteDebugInfo(std::stringstream& aStream) override; - - // TODO: nsTArray (vector) might not be a great data structure - // choice since we need to remove elements from the middle. - // Should profile and try figure out the best approach - // here. - struct FrameRects { - void Add(nsIFrame* aFrame, const nsRect& aRect) { - mBoxes.AppendElement(nsRegion::RectToBox(aRect)); - mFrames.AppendElement(aFrame); - } - void Add(nsIFrame* aFrame, const pixman_box32& aBox) { - mBoxes.AppendElement(aBox); - mFrames.AppendElement(aFrame); - } - void Add(const FrameRects& aOther) { - mBoxes.AppendElements(aOther.mBoxes); - mFrames.AppendElements(aOther.mFrames); - } - - bool IsEmpty() const { - return mBoxes.IsEmpty(); - } - - nsTArray<pixman_box32_t> mBoxes; - nsTArray<nsIFrame*> mFrames; - }; - - virtual void RemoveFrame(nsIFrame* aFrame) override; - -private: - virtual ~nsDisplayLayerEventRegions() - { - MOZ_COUNT_DTOR(nsDisplayLayerEventRegions); - } - - void RemoveItemFromFrames(FrameRects& aFrameRects) - { - for (nsIFrame* f : aFrameRects.mFrames) { - if (f != mFrame) { - f->RemoveDisplayItem(this); - } - } - } - - friend bool MergeLayerEventRegions(nsDisplayItem*, nsDisplayItem*); - - // Relative to aFrame's reference frame. - // These are the points that are definitely in the hit region. - FrameRects mHitRegion; - // These are points that may or may not be in the hit region. Only main-thread - // event handling can tell for sure (e.g. because complex shapes are present). - FrameRects mMaybeHitRegion; - // These are points that need to be dispatched to the content thread for - // resolution. Always contained in the union of mHitRegion and mMaybeHitRegion. - FrameRects mDispatchToContentHitRegion; - // These are points where panning is disabled, as determined by the touch-action - // property. Always contained in the union of mHitRegion and mMaybeHitRegion. - FrameRects mNoActionRegion; - // These are points where panning is horizontal, as determined by the touch-action - // property. Always contained in the union of mHitRegion and mMaybeHitRegion. - FrameRects mHorizontalPanRegion; - // These are points where panning is vertical, as determined by the touch-action - // property. Always contained in the union of mHitRegion and mMaybeHitRegion. - FrameRects mVerticalPanRegion; - // If these event regions are for an inactive scroll frame, the z-index of - // this display item is overridden to be the largest z-index of the content - // in the scroll frame. This ensures that the event regions item remains on - // top of the content after sorting items by z-index. - mozilla::Maybe<int32_t> mOverrideZIndex; - uint32_t mIndex; -}; - -/** * A class that lets you wrap a display list as a display item. * * GetUnderlyingFrame() is troublesome for wrapped lists because if the wrapped * list has many items, it's not clear which one has the 'underlying frame'. * Thus we force the creator to specify what the underlying frame is. The * underlying frame should be the root of a stacking context, because sorting * a list containing this item will not get at the children. *