mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 10:44:56 +00:00
Bug 1534549 - Part 2: Allow all display items to carry hit testing information r=mstange
Differential Revision: https://phabricator.services.mozilla.com/D102515
This commit is contained in:
parent
d481341bf4
commit
cf0c7ae9e3
@ -266,6 +266,7 @@ EXPORTS.mozilla.layers += [
|
||||
"wr/AsyncImagePipelineManager.h",
|
||||
"wr/ClipManager.h",
|
||||
"wr/DisplayItemCache.h",
|
||||
"wr/HitTestInfoManager.h",
|
||||
"wr/IpcResourceUpdateQueue.h",
|
||||
"wr/OMTAController.h",
|
||||
"wr/OMTASampler.h",
|
||||
@ -545,6 +546,7 @@ UNIFIED_SOURCES += [
|
||||
"wr/AsyncImagePipelineManager.cpp",
|
||||
"wr/ClipManager.cpp",
|
||||
"wr/DisplayItemCache.cpp",
|
||||
"wr/HitTestInfoManager.cpp",
|
||||
"wr/IpcResourceUpdateQueue.cpp",
|
||||
"wr/OMTAController.cpp",
|
||||
"wr/OMTASampler.cpp",
|
||||
|
95
gfx/layers/wr/HitTestInfoManager.cpp
Normal file
95
gfx/layers/wr/HitTestInfoManager.cpp
Normal file
@ -0,0 +1,95 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "HitTestInfoManager.h"
|
||||
#include "HitTestInfo.h"
|
||||
|
||||
#include "nsDisplayList.h"
|
||||
|
||||
namespace mozilla::layers {
|
||||
|
||||
using ViewID = ScrollableLayerGuid::ViewID;
|
||||
|
||||
/**
|
||||
* TODO(miko): This used to be a performance bottle-neck, but it does not show
|
||||
* up in profiles anymore, see bugs 1424637 and 1424968.
|
||||
* A better way of doing this would be to store current app units per dev pixel
|
||||
* in wr::DisplayListBuilder, and update it whenever display items that separate
|
||||
* presshell boundaries are encountered.
|
||||
*/
|
||||
static int32_t GetAppUnitsFromDisplayItem(nsDisplayItem* aItem) {
|
||||
nsIFrame* frame = aItem->Frame();
|
||||
MOZ_ASSERT(frame);
|
||||
return frame->PresContext()->AppUnitsPerDevPixel();
|
||||
}
|
||||
|
||||
static void CreateWebRenderCommands(wr::DisplayListBuilder& aBuilder,
|
||||
nsPaintedDisplayItem* aItem,
|
||||
const nsRect& aArea,
|
||||
const gfx::CompositorHitTestInfo& aFlags,
|
||||
const ViewID& aViewId) {
|
||||
const Maybe<SideBits> sideBits =
|
||||
aBuilder.GetContainingFixedPosSideBits(aItem->GetActiveScrolledRoot());
|
||||
|
||||
const LayoutDeviceRect devRect =
|
||||
LayoutDeviceRect::FromAppUnits(aArea, GetAppUnitsFromDisplayItem(aItem));
|
||||
const wr::LayoutRect rect = wr::ToLayoutRect(devRect);
|
||||
|
||||
aBuilder.PushHitTest(rect, rect, !aItem->BackfaceIsHidden(), aViewId, aFlags,
|
||||
sideBits.valueOr(SideBits::eNone));
|
||||
}
|
||||
|
||||
void HitTestInfoManager::Reset() {
|
||||
mArea = nsRect();
|
||||
mFlags = gfx::CompositorHitTestInvisibleToHit;
|
||||
}
|
||||
|
||||
void HitTestInfoManager::SwitchItem(nsPaintedDisplayItem* aItem,
|
||||
wr::DisplayListBuilder& aBuilder,
|
||||
nsDisplayListBuilder* aDisplayListBuilder) {
|
||||
if (!aItem || aItem->HasChildren()) {
|
||||
// Either the item is not a painted display item, or it is a container item.
|
||||
return;
|
||||
}
|
||||
|
||||
const HitTestInfo& hitTestInfo = aItem->GetHitTestInfo();
|
||||
const nsRect& area = hitTestInfo.Area();
|
||||
const gfx::CompositorHitTestInfo& flags = hitTestInfo.Info();
|
||||
|
||||
if (area.IsEmpty() || flags == gfx::CompositorHitTestInvisibleToHit) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto viewId =
|
||||
hitTestInfo.GetViewId(aBuilder, aItem->GetActiveScrolledRoot());
|
||||
const auto spaceAndClipChain = aBuilder.CurrentSpaceAndClipChain();
|
||||
|
||||
if (!Update(area, flags, viewId, spaceAndClipChain)) {
|
||||
// The previous hit test information is still valid.
|
||||
return;
|
||||
}
|
||||
|
||||
CreateWebRenderCommands(aBuilder, aItem, area, flags, viewId);
|
||||
}
|
||||
|
||||
bool HitTestInfoManager::Update(const nsRect& aArea,
|
||||
const gfx::CompositorHitTestInfo& aFlags,
|
||||
const ViewID& aViewId,
|
||||
const wr::WrSpaceAndClipChain& aSpaceAndClip) {
|
||||
if (mViewId == aViewId && mFlags == aFlags && mArea.Contains(aArea) &&
|
||||
mSpaceAndClipChain == aSpaceAndClip) {
|
||||
// The previous hit testing information can be reused.
|
||||
return false;
|
||||
}
|
||||
|
||||
mArea = aArea;
|
||||
mFlags = aFlags;
|
||||
mViewId = aViewId;
|
||||
mSpaceAndClipChain = aSpaceAndClip;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace mozilla::layers
|
63
gfx/layers/wr/HitTestInfoManager.h
Normal file
63
gfx/layers/wr/HitTestInfoManager.h
Normal file
@ -0,0 +1,63 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef GFX_HITTESTINFOMANAGER_H
|
||||
#define GFX_HITTESTINFOMANAGER_H
|
||||
|
||||
#include "mozilla/gfx/CompositorHitTestInfo.h"
|
||||
#include "mozilla/layers/ScrollableLayerGuid.h"
|
||||
#include "mozilla/webrender/WebRenderAPI.h"
|
||||
#include "nsRect.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
class nsPaintedDisplayItem;
|
||||
class nsDisplayListBuilder;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace wr {
|
||||
class DisplayListBuilder;
|
||||
}
|
||||
|
||||
namespace layers {
|
||||
|
||||
/**
|
||||
* This class extracts the hit testing information (area, flags, ViewId) from
|
||||
* Gecko display items and pushes them into WebRender display list.
|
||||
*
|
||||
* The hit testing information is deduplicated: a new hit test item is only
|
||||
* added if the new area is not contained in the previous area, or if the flags,
|
||||
* ViewId, or current spatial id is different.
|
||||
*/
|
||||
class HitTestInfoManager {
|
||||
public:
|
||||
/**
|
||||
* Resets the previous hit testing information.
|
||||
*/
|
||||
void Reset();
|
||||
|
||||
/**
|
||||
* Extracts the hit testing information from |aItem|, and if necessary, adds
|
||||
* a new WebRender hit test item using |aBuilder|.
|
||||
*/
|
||||
void SwitchItem(nsPaintedDisplayItem* aItem, wr::DisplayListBuilder& aBuilder,
|
||||
nsDisplayListBuilder* aDisplayListBuilder);
|
||||
|
||||
private:
|
||||
bool Update(const nsRect& aArea, const gfx::CompositorHitTestInfo& aFlags,
|
||||
const ScrollableLayerGuid::ViewID& aViewId,
|
||||
const wr::WrSpaceAndClipChain& aSpaceAndClip);
|
||||
|
||||
nsRect mArea;
|
||||
gfx::CompositorHitTestInfo mFlags;
|
||||
ScrollableLayerGuid::ViewID mViewId;
|
||||
wr::WrSpaceAndClipChain mSpaceAndClipChain;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
@ -207,6 +207,7 @@ struct Grouper {
|
||||
int32_t mAppUnitsPerDevPixel;
|
||||
nsDisplayListBuilder* mDisplayListBuilder;
|
||||
ClipManager& mClipManager;
|
||||
HitTestInfoManager mHitTestInfoManager;
|
||||
Matrix mTransform;
|
||||
|
||||
// Paint the list of aChildren display items.
|
||||
@ -1230,17 +1231,19 @@ void Grouper::ConstructGroups(nsDisplayListBuilder* aDisplayListBuilder,
|
||||
{
|
||||
auto spaceAndClipChain = mClipManager.SwitchItem(item);
|
||||
wr::SpaceAndClipChainHelper saccHelper(aBuilder, spaceAndClipChain);
|
||||
mHitTestInfoManager.SwitchItem(item->AsPaintedDisplayItem(), aBuilder,
|
||||
aDisplayListBuilder);
|
||||
|
||||
sIndent++;
|
||||
// Note: this call to CreateWebRenderCommands can recurse back into
|
||||
// this function.
|
||||
bool createdWRCommands = item->CreateWebRenderCommands(
|
||||
aBuilder, aResources, aSc, manager, mDisplayListBuilder);
|
||||
sIndent--;
|
||||
MOZ_RELEASE_ASSERT(
|
||||
createdWRCommands,
|
||||
"active transforms should always succeed at creating "
|
||||
"WebRender commands");
|
||||
sIndent--;
|
||||
}
|
||||
|
||||
currentGroup = &groupData->mFollowingGroup;
|
||||
@ -1412,6 +1415,7 @@ void WebRenderCommandBuilder::DoGroupingForDisplayList(
|
||||
GP("DoGroupingForDisplayList\n");
|
||||
|
||||
mClipManager.BeginList(aSc);
|
||||
mHitTestInfoManager.Reset();
|
||||
Grouper g(mClipManager);
|
||||
|
||||
int32_t appUnitsPerDevPixel =
|
||||
@ -1566,6 +1570,8 @@ void WebRenderCommandBuilder::BuildWebRenderCommands(
|
||||
aScrollData = WebRenderScrollData(mManager, aDisplayListBuilder);
|
||||
MOZ_ASSERT(mLayerScrollData.empty());
|
||||
mClipManager.BeginBuild(mManager, aBuilder);
|
||||
mHitTestInfoManager.Reset();
|
||||
|
||||
mBuilderDumpIndex = 0;
|
||||
mLastCanvasDatas.Clear();
|
||||
mLastLocalCanvasDatas.Clear();
|
||||
@ -1650,6 +1656,12 @@ void WebRenderCommandBuilder::CreateWebRenderCommands(
|
||||
auto* item = aItem->AsPaintedDisplayItem();
|
||||
MOZ_RELEASE_ASSERT(item, "Tried to paint item that cannot be painted");
|
||||
|
||||
mHitTestInfoManager.SwitchItem(item, aBuilder, aDisplayListBuilder);
|
||||
if (item->GetType() == DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO) {
|
||||
// The hit test information was processed above.
|
||||
return;
|
||||
}
|
||||
|
||||
if (aBuilder.ReuseItem(item)) {
|
||||
// No further processing should be needed, since the item was reused.
|
||||
return;
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "mozilla/webrender/WebRenderAPI.h"
|
||||
#include "mozilla/layers/ClipManager.h"
|
||||
#include "mozilla/layers/HitTestInfoManager.h"
|
||||
#include "mozilla/layers/WebRenderMessages.h"
|
||||
#include "mozilla/layers/WebRenderScrollData.h"
|
||||
#include "mozilla/layers/WebRenderUserData.h"
|
||||
@ -178,6 +179,7 @@ class WebRenderCommandBuilder final {
|
||||
nsDisplayListBuilder* aDisplayListBuilder);
|
||||
|
||||
ClipManager mClipManager;
|
||||
HitTestInfoManager mHitTestInfoManager;
|
||||
|
||||
// We use this as a temporary data structure while building the mScrollData
|
||||
// inside a layers-free transaction.
|
||||
|
@ -116,13 +116,11 @@ static void PrintDisplayItemTo(nsDisplayListBuilder* aBuilder,
|
||||
aStream << ")";
|
||||
}
|
||||
|
||||
if (aItem->GetType() == DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO) {
|
||||
auto* hitTestInfoItem = static_cast<nsDisplayCompositorHitTestInfo*>(aItem);
|
||||
|
||||
if (auto* paintedItem = aItem->AsPaintedDisplayItem()) {
|
||||
aStream << nsPrintfCString(" hitTestInfo(0x%x)",
|
||||
hitTestInfoItem->HitTestFlags().serialize());
|
||||
paintedItem->HitTestFlags().serialize());
|
||||
|
||||
nsRect area = hitTestInfoItem->HitTestArea();
|
||||
nsRect area = paintedItem->HitTestArea();
|
||||
aStream << nsPrintfCString(" hitTestArea(%d,%d,%d,%d)", area.x, area.y,
|
||||
area.width, area.height);
|
||||
}
|
||||
|
@ -385,8 +385,12 @@ nsresult nsButtonFrameRenderer::DisplayButton(nsDisplayListBuilder* aBuilder,
|
||||
nsRect buttonRect =
|
||||
mFrame->GetRectRelativeToSelf() + aBuilder->ToReferenceFrame(mFrame);
|
||||
|
||||
nsDisplayBackgroundImage::AppendBackgroundItemsToTop(aBuilder, mFrame,
|
||||
buttonRect, aBackground);
|
||||
const AppendedBackgroundType result =
|
||||
nsDisplayBackgroundImage::AppendBackgroundItemsToTop(
|
||||
aBuilder, mFrame, buttonRect, aBackground);
|
||||
if (result == AppendedBackgroundType::None) {
|
||||
aBuilder->BuildCompositorHitTestInfoIfNeeded(GetFrame(), aBackground);
|
||||
}
|
||||
|
||||
aBackground->AppendNewToTop<nsDisplayButtonBorder>(aBuilder, GetFrame(),
|
||||
this);
|
||||
|
@ -3852,10 +3852,9 @@ void ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
if (info != CompositorHitTestInvisibleToHit) {
|
||||
auto* hitInfo =
|
||||
MakeDisplayItemWithIndex<nsDisplayCompositorHitTestInfo>(
|
||||
aBuilder, mScrolledFrame, 1, info);
|
||||
aBuilder, mScrolledFrame, 1);
|
||||
if (hitInfo) {
|
||||
aBuilder->SetCompositorHitTestInfo(hitInfo->HitTestArea(),
|
||||
hitInfo->HitTestFlags());
|
||||
aBuilder->SetCompositorHitTestInfo(info);
|
||||
set.BorderBackground()->AppendToTop(hitInfo);
|
||||
}
|
||||
}
|
||||
@ -4072,37 +4071,36 @@ void ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
|
||||
// Make sure that APZ will dispatch events back to content so we can
|
||||
// create a displayport for this frame. We'll add the item later on.
|
||||
if (!mWillBuildScrollableLayer) {
|
||||
if (aBuilder->BuildCompositorHitTestInfo()) {
|
||||
int32_t zIndex = MaxZIndexInListOfItemsContainedInFrame(
|
||||
scrolledContent.PositionedDescendants(), mOuter);
|
||||
if (aBuilder->IsPartialUpdate()) {
|
||||
if (auto* items =
|
||||
mScrolledFrame->GetProperty(nsIFrame::DisplayItems())) {
|
||||
for (nsDisplayItemBase* item : *items) {
|
||||
if (item->GetType() ==
|
||||
DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO) {
|
||||
auto* hitTestItem =
|
||||
static_cast<nsDisplayCompositorHitTestInfo*>(item);
|
||||
if (hitTestItem->HitTestFlags().contains(
|
||||
CompositorHitTestFlags::eInactiveScrollframe)) {
|
||||
zIndex = std::max(zIndex, hitTestItem->ZIndex());
|
||||
item->SetCantBeReused();
|
||||
}
|
||||
if (!mWillBuildScrollableLayer && aBuilder->BuildCompositorHitTestInfo()) {
|
||||
int32_t zIndex = MaxZIndexInListOfItemsContainedInFrame(
|
||||
scrolledContent.PositionedDescendants(), mOuter);
|
||||
if (aBuilder->IsPartialUpdate()) {
|
||||
if (auto* items =
|
||||
mScrolledFrame->GetProperty(nsIFrame::DisplayItems())) {
|
||||
for (nsDisplayItemBase* item : *items) {
|
||||
if (item->GetType() ==
|
||||
DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO) {
|
||||
auto* hitTestItem =
|
||||
static_cast<nsDisplayCompositorHitTestInfo*>(item);
|
||||
if (hitTestItem->HitTestFlags().contains(
|
||||
CompositorHitTestFlags::eInactiveScrollframe)) {
|
||||
zIndex = std::max(zIndex, hitTestItem->ZIndex());
|
||||
item->SetCantBeReused();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Make sure the z-index of the inactive item is at least zero.
|
||||
// Otherwise, it will end up behind non-positioned items in the scrolled
|
||||
// content.
|
||||
zIndex = std::max(zIndex, 0);
|
||||
nsDisplayCompositorHitTestInfo* hitInfo =
|
||||
MakeDisplayItemWithIndex<nsDisplayCompositorHitTestInfo>(
|
||||
aBuilder, mScrolledFrame, 1, info, Some(area));
|
||||
if (hitInfo) {
|
||||
AppendInternalItemToTop(scrolledContent, hitInfo, Some(zIndex));
|
||||
}
|
||||
}
|
||||
// Make sure the z-index of the inactive item is at least zero.
|
||||
// Otherwise, it will end up behind non-positioned items in the scrolled
|
||||
// content.
|
||||
zIndex = std::max(zIndex, 0);
|
||||
nsDisplayCompositorHitTestInfo* hitInfo =
|
||||
MakeDisplayItemWithIndex<nsDisplayCompositorHitTestInfo>(
|
||||
aBuilder, mScrolledFrame, 1, area, info);
|
||||
if (hitInfo) {
|
||||
AppendInternalItemToTop(scrolledContent, hitInfo, Some(zIndex));
|
||||
aBuilder->SetCompositorHitTestInfo(info);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2584,19 +2584,26 @@ bool nsIFrame::DisplayBackgroundUnconditional(nsDisplayListBuilder* aBuilder,
|
||||
return false;
|
||||
}
|
||||
|
||||
AppendedBackgroundType result = AppendedBackgroundType::None;
|
||||
|
||||
// Here we don't try to detect background propagation. Frames that might
|
||||
// receive a propagated background should just set aForceBackground to
|
||||
// true.
|
||||
if (hitTesting || aForceBackground ||
|
||||
!StyleBackground()->IsTransparent(this) ||
|
||||
StyleDisplay()->HasAppearance()) {
|
||||
return nsDisplayBackgroundImage::AppendBackgroundItemsToTop(
|
||||
result = nsDisplayBackgroundImage::AppendBackgroundItemsToTop(
|
||||
aBuilder, this,
|
||||
GetRectRelativeToSelf() + aBuilder->ToReferenceFrame(this),
|
||||
aLists.BorderBackground());
|
||||
}
|
||||
|
||||
return false;
|
||||
if (result == AppendedBackgroundType::None) {
|
||||
aBuilder->BuildCompositorHitTestInfoIfNeeded(this,
|
||||
aLists.BorderBackground());
|
||||
}
|
||||
|
||||
return result == AppendedBackgroundType::ThemedBackground;
|
||||
}
|
||||
|
||||
void nsIFrame::DisplayBorderBackgroundOutline(nsDisplayListBuilder* aBuilder,
|
||||
@ -2875,6 +2882,19 @@ static void CheckForApzAwareEventHandlers(nsDisplayListBuilder* aBuilder,
|
||||
}
|
||||
}
|
||||
|
||||
static void UpdateCurrentHitTestInfo(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aFrame) {
|
||||
if (!aBuilder->BuildCompositorHitTestInfo()) {
|
||||
// Compositor hit test info is not used.
|
||||
return;
|
||||
}
|
||||
|
||||
CheckForApzAwareEventHandlers(aBuilder, aFrame);
|
||||
|
||||
const CompositorHitTestInfo info = aFrame->GetCompositorHitTestInfo(aBuilder);
|
||||
aBuilder->SetCompositorHitTestInfo(info);
|
||||
}
|
||||
|
||||
/**
|
||||
* True if aDescendant participates the context aAncestor participating.
|
||||
*/
|
||||
@ -3287,6 +3307,8 @@ void nsIFrame::BuildDisplayListForStackingContext(
|
||||
nsDisplayListBuilder::AutoBuildingDisplayList buildingDisplayList(
|
||||
aBuilder, this, visibleRect, dirtyRect, isTransformed);
|
||||
|
||||
UpdateCurrentHitTestInfo(aBuilder, this);
|
||||
|
||||
// Depending on the effects that are applied to this frame, we can create
|
||||
// multiple container display items and wrap them around our contents.
|
||||
// This enum lists all the potential container display items, in the order
|
||||
@ -3376,8 +3398,6 @@ void nsIFrame::BuildDisplayListForStackingContext(
|
||||
ApplyClipProp(transformedCssClip);
|
||||
}
|
||||
|
||||
mozilla::UniquePtr<HitTestInfo> hitTestInfo;
|
||||
|
||||
nsDisplayListCollection set(aBuilder);
|
||||
Maybe<nsRect> clipForMask;
|
||||
bool insertBackdropRoot;
|
||||
@ -3390,8 +3410,6 @@ void nsIFrame::BuildDisplayListForStackingContext(
|
||||
nsDisplayListBuilder::AutoInEventsOnly inEventsSetter(
|
||||
aBuilder, opacityItemForEventsOnly);
|
||||
|
||||
CheckForApzAwareEventHandlers(aBuilder, this);
|
||||
|
||||
// If we have a mask, compute a clip to bound the masked content.
|
||||
// This is necessary in case the content moves with an ancestor
|
||||
// ASR of the mask.
|
||||
@ -3420,8 +3438,6 @@ void nsIFrame::BuildDisplayListForStackingContext(
|
||||
}
|
||||
|
||||
aBuilder->AdjustWindowDraggingRegion(this);
|
||||
aBuilder->BuildCompositorHitTestInfoIfNeeded(this, set.BorderBackground(),
|
||||
true);
|
||||
|
||||
MarkAbsoluteFramesForDisplayList(aBuilder);
|
||||
aBuilder->Check();
|
||||
@ -3950,11 +3966,7 @@ void nsIFrame::BuildDisplayListForSimpleChild(nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayListBuilder::AutoBuildingDisplayList buildingForChild(
|
||||
aBuilder, aChild, visible, dirty, false);
|
||||
|
||||
CheckForApzAwareEventHandlers(aBuilder, aChild);
|
||||
|
||||
aBuilder->BuildCompositorHitTestInfoIfNeeded(
|
||||
aChild, aLists.BorderBackground(),
|
||||
buildingForChild.IsAnimatedGeometryRoot());
|
||||
UpdateCurrentHitTestInfo(aBuilder, aChild);
|
||||
|
||||
aChild->MarkAbsoluteFramesForDisplayList(aBuilder);
|
||||
aBuilder->AdjustWindowDraggingRegion(aChild);
|
||||
@ -4168,9 +4180,11 @@ void nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
||||
|
||||
nsDisplayListBuilder::AutoBuildingDisplayList buildingForChild(
|
||||
aBuilder, child, visible, dirty);
|
||||
|
||||
UpdateCurrentHitTestInfo(aBuilder, child);
|
||||
|
||||
DisplayListClipState::AutoClipMultiple clipState(aBuilder);
|
||||
nsDisplayListBuilder::AutoCurrentActiveScrolledRootSetter asrSetter(aBuilder);
|
||||
CheckForApzAwareEventHandlers(aBuilder, child);
|
||||
|
||||
if (savedOutOfFlowData) {
|
||||
aBuilder->SetBuildingInvisibleItems(false);
|
||||
@ -4241,8 +4255,6 @@ void nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
||||
|
||||
child->MarkAbsoluteFramesForDisplayList(aBuilder);
|
||||
|
||||
const bool differentAGR = buildingForChild.IsAnimatedGeometryRoot();
|
||||
|
||||
if (!awayFromCommonPath &&
|
||||
// Some SVG frames might change opacity without invalidating the frame,
|
||||
// so exclude them from the fast-path.
|
||||
@ -4255,10 +4267,6 @@ void nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
||||
// THIS IS THE COMMON CASE.
|
||||
// Not a pseudo or real stacking context. Do the simple thing and
|
||||
// return early.
|
||||
|
||||
aBuilder->BuildCompositorHitTestInfoIfNeeded(
|
||||
child, aLists.BorderBackground(), differentAGR);
|
||||
|
||||
aBuilder->AdjustWindowDraggingRegion(child);
|
||||
aBuilder->Check();
|
||||
child->BuildDisplayList(aBuilder, aLists);
|
||||
@ -4276,16 +4284,6 @@ void nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
||||
// z-index:non-auto
|
||||
nsDisplayListCollection pseudoStack(aBuilder);
|
||||
|
||||
// If this frame has z-index != 0, then the display item might get sorted
|
||||
// into a different place in the list, and we can't rely on the previous
|
||||
// hit test info to still be behind us. Force a new hit test info for this
|
||||
// item, and for the item after it, so that we always have the right hit
|
||||
// test info.
|
||||
const bool mayBeSorted = ZIndex().valueOr(0) != 0;
|
||||
|
||||
aBuilder->BuildCompositorHitTestInfoIfNeeded(
|
||||
child, pseudoStack.BorderBackground(), differentAGR || mayBeSorted);
|
||||
|
||||
aBuilder->AdjustWindowDraggingRegion(child);
|
||||
nsDisplayListBuilder::AutoContainerASRTracker contASRTracker(aBuilder);
|
||||
aBuilder->Check();
|
||||
@ -4294,16 +4292,6 @@ void nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
||||
if (aBuilder->DisplayCaret(child, pseudoStack.Outlines())) {
|
||||
builtContainerItem = false;
|
||||
}
|
||||
|
||||
// If we forced a new hit-test info because this frame is going to be
|
||||
// sorted, then clear the 'previous' data on the builder so that the next
|
||||
// item also gets a new hit test info. That way we're guaranteeing hit-test
|
||||
// info before and after each item that might get moved to a different spot.
|
||||
if (mayBeSorted) {
|
||||
aBuilder->SetCompositorHitTestInfo(
|
||||
nsRect(), CompositorHitTestFlags::eVisibleToHitTest);
|
||||
}
|
||||
|
||||
wrapListASR = contASRTracker.GetContainerASR();
|
||||
|
||||
list.AppendToTop(pseudoStack.BorderBackground());
|
||||
@ -11202,7 +11190,7 @@ CompositorHitTestInfo nsIFrame::GetCompositorHitTestInfo(
|
||||
// that code, but woven into the top-down recursive display list building
|
||||
// process.
|
||||
CompositorHitTestInfo inheritedTouchAction =
|
||||
aBuilder->GetHitTestInfo() & CompositorHitTestTouchActionMask;
|
||||
aBuilder->GetCompositorHitTestInfo() & CompositorHitTestTouchActionMask;
|
||||
|
||||
nsIFrame* touchActionFrame = this;
|
||||
if (nsIScrollableFrame* scrollFrame =
|
||||
|
@ -1737,7 +1737,6 @@ class FLBDisplayListIterator : public FlattenedDisplayListIterator {
|
||||
|
||||
nsDisplayItem* next = PeekNext();
|
||||
const DisplayItemType type = next->GetType();
|
||||
|
||||
if (type == DisplayItemType::TYPE_SVG_WRAPPER) {
|
||||
// We mark SetContainsSVG for the CONTENT_FRAME_TIME_WITH_SVG metric
|
||||
if (RefPtr<LayerManager> lm = mState->mBuilder->GetWidgetLayerManager()) {
|
||||
@ -4039,8 +4038,9 @@ void PaintedLayerData::AccumulateHitTestItem(ContainerState* aState,
|
||||
nsDisplayItem* aItem,
|
||||
const DisplayItemClip& aClip,
|
||||
TransformClipNode* aTransform) {
|
||||
MOZ_ASSERT(aItem->GetType() == DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO);
|
||||
auto* item = static_cast<nsDisplayCompositorHitTestInfo*>(aItem);
|
||||
auto* item = aItem->AsPaintedDisplayItem();
|
||||
MOZ_ASSERT(item);
|
||||
|
||||
nsRect area = item->HitTestArea();
|
||||
const CompositorHitTestInfo& flags = item->HitTestFlags();
|
||||
|
||||
@ -4549,10 +4549,7 @@ void ContainerState::ProcessDisplayItems(nsDisplayList* aList) {
|
||||
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<nsDisplayCompositorHitTestInfo*>(item)->HitTestArea();
|
||||
itemContent = static_cast<nsPaintedDisplayItem*>(item)->HitTestArea();
|
||||
}
|
||||
|
||||
const bool inEffect = InTransform() || InOpacity();
|
||||
@ -4606,18 +4603,22 @@ void ContainerState::ProcessDisplayItems(nsDisplayList* aList) {
|
||||
const DisplayItemClip& itemClip =
|
||||
itemClipPtr ? *itemClipPtr : DisplayItemClip::NoClip();
|
||||
|
||||
if (inEffect && marker == DisplayItemEntryType::HitTestInfo) {
|
||||
// Fast-path for hit test items inside flattened inactive layers.
|
||||
MOZ_ASSERT(selectedLayer);
|
||||
selectedLayer->AccumulateHitTestItem(this, item, itemClip, transformNode);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (inEffect && marker == DisplayItemEntryType::Item) {
|
||||
// Fast-path for items inside flattened inactive layers. This works
|
||||
// because the layer state of the item cannot be active, otherwise the
|
||||
// parent item would not have been flattened.
|
||||
MOZ_ASSERT(selectedLayer);
|
||||
|
||||
if (item->AsPaintedDisplayItem()->GetHitTestInfo().Info() !=
|
||||
mozilla::gfx::CompositorHitTestInvisibleToHit) {
|
||||
selectedLayer->AccumulateHitTestItem(this, item, itemClip, nullptr);
|
||||
}
|
||||
|
||||
if (itemType == DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO) {
|
||||
// The hit test info was processed above.
|
||||
continue;
|
||||
}
|
||||
|
||||
selectedLayer->Accumulate(this, item->AsPaintedDisplayItem(), nsIntRect(),
|
||||
nsRect(), itemClip, layerState, aList, marker,
|
||||
opacityIndices, transformNode);
|
||||
@ -4678,7 +4679,7 @@ void ContainerState::ProcessDisplayItems(nsDisplayList* aList) {
|
||||
#ifdef DEBUG
|
||||
nsRect bounds = itemContent;
|
||||
|
||||
if (marker == DisplayItemEntryType::HitTestInfo || inEffect) {
|
||||
if (inEffect) {
|
||||
bounds.SetEmpty();
|
||||
}
|
||||
|
||||
@ -5109,9 +5110,6 @@ void ContainerState::ProcessDisplayItems(nsDisplayList* aList) {
|
||||
? mContainerReferenceFrame
|
||||
: item->ReferenceFrame();
|
||||
|
||||
MOZ_ASSERT(item != mContainerItem ||
|
||||
marker == DisplayItemEntryType::HitTestInfo);
|
||||
|
||||
PaintedLayerData* paintedLayerData = selectedLayer;
|
||||
|
||||
if (!paintedLayerData) {
|
||||
@ -5125,31 +5123,36 @@ void ContainerState::ProcessDisplayItems(nsDisplayList* aList) {
|
||||
}
|
||||
MOZ_ASSERT(paintedLayerData);
|
||||
|
||||
if (marker == DisplayItemEntryType::HitTestInfo) {
|
||||
MOZ_ASSERT(!transformNode);
|
||||
if (item->AsPaintedDisplayItem()->GetHitTestInfo().Info() !=
|
||||
mozilla::gfx::CompositorHitTestInvisibleToHit) {
|
||||
paintedLayerData->AccumulateHitTestItem(this, item, itemClip, nullptr);
|
||||
} else {
|
||||
paintedLayerData->Accumulate(
|
||||
this, item->AsPaintedDisplayItem(), itemVisibleRect, itemContent,
|
||||
itemClip, layerState, aList, marker, opacityIndices, transformNode);
|
||||
}
|
||||
|
||||
if (!paintedLayerData->mLayer) {
|
||||
// Try to recycle the old layer of this display item.
|
||||
RefPtr<PaintedLayer> layer = AttemptToRecyclePaintedLayer(
|
||||
itemAGR, item, topLeft,
|
||||
inEffect ? containerReferenceFrame : referenceFrame);
|
||||
if (layer) {
|
||||
paintedLayerData->mLayer = layer;
|
||||
if (itemType == DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO) {
|
||||
// The hit test info was processed above.
|
||||
continue;
|
||||
}
|
||||
|
||||
auto* userData = GetPaintedDisplayItemLayerUserData(layer);
|
||||
paintedLayerData->mAssignedDisplayItems.reserve(
|
||||
userData->mLastItemCount);
|
||||
paintedLayerData->Accumulate(
|
||||
this, item->AsPaintedDisplayItem(), itemVisibleRect, itemContent,
|
||||
itemClip, layerState, aList, marker, opacityIndices, transformNode);
|
||||
|
||||
NS_ASSERTION(FindIndexOfLayerIn(mNewChildLayers, layer) < 0,
|
||||
"Layer already in list???");
|
||||
mNewChildLayers[paintedLayerData->mNewChildLayersIndex].mLayer =
|
||||
std::move(layer);
|
||||
}
|
||||
if (!paintedLayerData->mLayer) {
|
||||
// Try to recycle the old layer of this display item.
|
||||
RefPtr<PaintedLayer> layer = AttemptToRecyclePaintedLayer(
|
||||
itemAGR, item, topLeft,
|
||||
inEffect ? containerReferenceFrame : referenceFrame);
|
||||
if (layer) {
|
||||
paintedLayerData->mLayer = layer;
|
||||
|
||||
auto* userData = GetPaintedDisplayItemLayerUserData(layer);
|
||||
paintedLayerData->mAssignedDisplayItems.reserve(
|
||||
userData->mLastItemCount);
|
||||
|
||||
NS_ASSERTION(FindIndexOfLayerIn(mNewChildLayers, layer) < 0,
|
||||
"Layer already in list???");
|
||||
mNewChildLayers[paintedLayerData->mNewChildLayersIndex].mLayer =
|
||||
std::move(layer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,6 @@ enum class DisplayItemEntryType : uint8_t {
|
||||
PopOpacity,
|
||||
PushTransform,
|
||||
PopTransform,
|
||||
HitTestInfo,
|
||||
};
|
||||
|
||||
/**
|
||||
|
58
layout/painting/HitTestInfo.cpp
Normal file
58
layout/painting/HitTestInfo.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "HitTestInfo.h"
|
||||
#include "mozilla/webrender/WebRenderAPI.h"
|
||||
#include "nsDisplayList.h"
|
||||
#include "nsIFrame.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
using ViewID = layers::ScrollableLayerGuid::ViewID;
|
||||
|
||||
ViewID HitTestInfo::GetViewId(wr::DisplayListBuilder& aBuilder,
|
||||
const ActiveScrolledRoot* aASR) const {
|
||||
if (mScrollTarget) {
|
||||
return *mScrollTarget;
|
||||
}
|
||||
|
||||
Maybe<ScrollableLayerGuid::ViewID> fixedTarget =
|
||||
aBuilder.GetContainingFixedPosScrollTarget(aASR);
|
||||
|
||||
if (fixedTarget) {
|
||||
return *fixedTarget;
|
||||
}
|
||||
|
||||
if (aASR) {
|
||||
return aASR->GetViewId();
|
||||
}
|
||||
|
||||
return ScrollableLayerGuid::NULL_SCROLL_ID;
|
||||
}
|
||||
|
||||
void HitTestInfo::Initialize(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) {
|
||||
if (!aBuilder->BuildCompositorHitTestInfo()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mInfo = aFrame->GetCompositorHitTestInfo(aBuilder);
|
||||
if (mInfo != gfx::CompositorHitTestInvisibleToHit) {
|
||||
mArea = aFrame->GetCompositorHitTestArea(aBuilder);
|
||||
InitializeScrollTarget(aBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
void HitTestInfo::InitializeScrollTarget(nsDisplayListBuilder* aBuilder) {
|
||||
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(Info().contains(CompositorHitTestFlags::eScrollbar));
|
||||
mScrollTarget = Some(aBuilder->GetCurrentScrollbarTarget());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
53
layout/painting/HitTestInfo.h
Normal file
53
layout/painting/HitTestInfo.h
Normal file
@ -0,0 +1,53 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef GFX_HITTESTINFO_H
|
||||
#define GFX_HITTESTINFO_H
|
||||
|
||||
#include "mozilla/gfx/CompositorHitTestInfo.h"
|
||||
#include "mozilla/layers/ScrollableLayerGuid.h"
|
||||
#include "nsRect.h"
|
||||
|
||||
class nsIFrame;
|
||||
class nsDisplayListBuilder;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
struct ActiveScrolledRoot;
|
||||
|
||||
/**
|
||||
* A helper class that manages compositor hit testing information.
|
||||
*/
|
||||
class HitTestInfo {
|
||||
public:
|
||||
using CompositorHitTestInfo = gfx::CompositorHitTestInfo;
|
||||
using ViewID = layers::ScrollableLayerGuid::ViewID;
|
||||
|
||||
ViewID GetViewId(wr::DisplayListBuilder& aBuilder,
|
||||
const ActiveScrolledRoot* aASR) const;
|
||||
|
||||
void Initialize(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame);
|
||||
void InitializeScrollTarget(nsDisplayListBuilder* aBuilder);
|
||||
|
||||
void SetAreaAndInfo(const nsRect& aArea, const CompositorHitTestInfo& aInfo) {
|
||||
mArea = aArea;
|
||||
mInfo = aInfo;
|
||||
}
|
||||
|
||||
static void Shutdown();
|
||||
|
||||
const nsRect& Area() const { return mArea; }
|
||||
const CompositorHitTestInfo& Info() const { return mInfo; }
|
||||
|
||||
private:
|
||||
nsRect mArea;
|
||||
CompositorHitTestInfo mInfo;
|
||||
mozilla::Maybe<ViewID> mScrollTarget;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
@ -13,6 +13,7 @@ EXPORTS += [
|
||||
"DisplayItemClipChain.h",
|
||||
"DisplayListClipState.h",
|
||||
"FrameLayerBuilder.h",
|
||||
"HitTestInfo.h",
|
||||
"LayerState.h",
|
||||
"MatrixStack.h",
|
||||
"nsCSSRenderingBorders.h",
|
||||
@ -40,6 +41,7 @@ UNIFIED_SOURCES += [
|
||||
"DisplayListClipState.cpp",
|
||||
"DottedCornerFinder.cpp",
|
||||
"FrameLayerBuilder.cpp",
|
||||
"HitTestInfo.cpp",
|
||||
"MaskLayerImageCache.cpp",
|
||||
"nsCSSRendering.cpp",
|
||||
"nsCSSRenderingBorders.cpp",
|
||||
|
@ -173,6 +173,25 @@ void UpdateDisplayItemData(nsPaintedDisplayItem* aItem) {
|
||||
}
|
||||
}
|
||||
|
||||
static bool ItemTypeSupportsHitTesting(const DisplayItemType aType) {
|
||||
switch (aType) {
|
||||
case DisplayItemType::TYPE_BACKGROUND:
|
||||
case DisplayItemType::TYPE_BACKGROUND_COLOR:
|
||||
case DisplayItemType::TYPE_THEMED_BACKGROUND:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void InitializeHitTestInfo(nsDisplayListBuilder* aBuilder,
|
||||
nsPaintedDisplayItem* aItem,
|
||||
const DisplayItemType aType) {
|
||||
if (ItemTypeSupportsHitTesting(aType)) {
|
||||
aItem->GetHitTestInfo().Initialize(aBuilder, aItem->Frame());
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<ActiveScrolledRoot> ActiveScrolledRoot::CreateASRForFrame(
|
||||
const ActiveScrolledRoot* aParent, nsIScrollableFrame* aScrollableFrame,
|
||||
@ -613,9 +632,7 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
|
||||
mBuildAsyncZoomContainer(false),
|
||||
mContainsBackdropFilter(false),
|
||||
mIsRelativeToLayoutViewport(false),
|
||||
mUseOverlayScrollbars(false),
|
||||
mHitTestArea(),
|
||||
mHitTestInfo(CompositorHitTestInvisibleToHit) {
|
||||
mUseOverlayScrollbars(false) {
|
||||
MOZ_COUNT_CTOR(nsDisplayListBuilder);
|
||||
|
||||
mBuildCompositorHitTestInfo = mAsyncPanZoomEnabled && IsForPainting();
|
||||
@ -2085,7 +2102,7 @@ void nsDisplayListBuilder::AppendNewScrollInfoItemForHoisting(
|
||||
}
|
||||
|
||||
void nsDisplayListBuilder::BuildCompositorHitTestInfoIfNeeded(
|
||||
nsIFrame* aFrame, nsDisplayList* aList, const bool aBuildNew) {
|
||||
nsIFrame* aFrame, nsDisplayList* aList) {
|
||||
MOZ_ASSERT(aFrame);
|
||||
MOZ_ASSERT(aList);
|
||||
|
||||
@ -2094,22 +2111,9 @@ void nsDisplayListBuilder::BuildCompositorHitTestInfoIfNeeded(
|
||||
}
|
||||
|
||||
const CompositorHitTestInfo info = aFrame->GetCompositorHitTestInfo(this);
|
||||
if (info == CompositorHitTestInvisibleToHit) {
|
||||
return;
|
||||
if (info != CompositorHitTestInvisibleToHit) {
|
||||
aList->AppendNewToTop<nsDisplayCompositorHitTestInfo>(this, aFrame);
|
||||
}
|
||||
|
||||
const nsRect area = aFrame->GetCompositorHitTestArea(this);
|
||||
if (!aBuildNew && GetHitTestInfo() == info &&
|
||||
GetHitTestArea().Contains(area)) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* item = MakeDisplayItem<nsDisplayCompositorHitTestInfo>(
|
||||
this, aFrame, info, Some(area));
|
||||
MOZ_ASSERT(item);
|
||||
|
||||
SetCompositorHitTestInfo(area, info);
|
||||
aList->AppendToTop(item);
|
||||
}
|
||||
|
||||
void nsDisplayListSet::MoveTo(const nsDisplayListSet& aDestination) const {
|
||||
@ -3545,7 +3549,7 @@ static nsDisplayBackgroundColor* CreateBackgroundColor(
|
||||
}
|
||||
|
||||
/*static*/
|
||||
bool nsDisplayBackgroundImage::AppendBackgroundItemsToTop(
|
||||
AppendedBackgroundType nsDisplayBackgroundImage::AppendBackgroundItemsToTop(
|
||||
nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
||||
const nsRect& aBackgroundRect, nsDisplayList* aList,
|
||||
bool aAllowWillPaintBorderOptimization, ComputedStyle* aComputedStyle,
|
||||
@ -3591,7 +3595,7 @@ bool nsDisplayBackgroundImage::AppendBackgroundItemsToTop(
|
||||
|
||||
if (SpecialCutoutRegionCase(aBuilder, aFrame, aBackgroundRect, aList,
|
||||
color)) {
|
||||
return false;
|
||||
return AppendedBackgroundType::None;
|
||||
}
|
||||
|
||||
const nsStyleBorder* borderStyle = aFrame->StyleBorder();
|
||||
@ -3660,13 +3664,21 @@ bool nsDisplayBackgroundImage::AppendBackgroundItemsToTop(
|
||||
bgItemList.AppendToTop(bgItem);
|
||||
}
|
||||
|
||||
aList->AppendToTop(&bgItemList);
|
||||
return true;
|
||||
if (!bgItemList.IsEmpty()) {
|
||||
aList->AppendToTop(&bgItemList);
|
||||
return AppendedBackgroundType::ThemedBackground;
|
||||
}
|
||||
|
||||
return AppendedBackgroundType::None;
|
||||
}
|
||||
|
||||
if (!bg || !drawBackgroundImage) {
|
||||
aList->AppendToTop(&bgItemList);
|
||||
return false;
|
||||
if (!bgItemList.IsEmpty()) {
|
||||
aList->AppendToTop(&bgItemList);
|
||||
return AppendedBackgroundType::Background;
|
||||
}
|
||||
|
||||
return AppendedBackgroundType::None;
|
||||
}
|
||||
|
||||
const ActiveScrolledRoot* asr = aBuilder->CurrentActiveScrolledRoot();
|
||||
@ -3783,8 +3795,12 @@ bool nsDisplayBackgroundImage::AppendBackgroundItemsToTop(
|
||||
aBuilder, aFrame, aSecondaryReferenceFrame, &bgItemList, asr));
|
||||
}
|
||||
|
||||
aList->AppendToTop(&bgItemList);
|
||||
return false;
|
||||
if (!bgItemList.IsEmpty()) {
|
||||
aList->AppendToTop(&bgItemList);
|
||||
return AppendedBackgroundType::Background;
|
||||
}
|
||||
|
||||
return AppendedBackgroundType::None;
|
||||
}
|
||||
|
||||
// Check that the rounded border of aFrame, added to aToReferenceFrame,
|
||||
@ -4848,90 +4864,12 @@ void nsDisplayEventReceiver::HitTest(nsDisplayListBuilder* aBuilder,
|
||||
aOutFrames->AppendElement(mFrame);
|
||||
}
|
||||
|
||||
nsDisplayCompositorHitTestInfo::nsDisplayCompositorHitTestInfo(
|
||||
nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
||||
const mozilla::gfx::CompositorHitTestInfo& aHitTestFlags,
|
||||
const mozilla::Maybe<nsRect>& aArea)
|
||||
: nsPaintedDisplayItem(aBuilder, aFrame),
|
||||
mAppUnitsPerDevPixel(mFrame->PresContext()->AppUnitsPerDevPixel()) {
|
||||
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(aHitTestFlags != CompositorHitTestInvisibleToHit);
|
||||
|
||||
const nsRect& area =
|
||||
aArea.isSome() ? *aArea : aFrame->GetCompositorHitTestArea(aBuilder);
|
||||
|
||||
SetHitTestInfo(area, aHitTestFlags);
|
||||
InitializeScrollTarget(aBuilder);
|
||||
}
|
||||
|
||||
nsDisplayCompositorHitTestInfo::nsDisplayCompositorHitTestInfo(
|
||||
nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
||||
mozilla::UniquePtr<HitTestInfo>&& aHitTestInfo)
|
||||
: nsPaintedDisplayItem(aBuilder, aFrame),
|
||||
mAppUnitsPerDevPixel(mFrame->PresContext()->AppUnitsPerDevPixel()) {
|
||||
MOZ_COUNT_CTOR(nsDisplayCompositorHitTestInfo);
|
||||
SetHitTestInfo(std::move(aHitTestInfo));
|
||||
InitializeScrollTarget(aBuilder);
|
||||
}
|
||||
|
||||
void nsDisplayCompositorHitTestInfo::InitializeScrollTarget(
|
||||
nsDisplayListBuilder* aBuilder) {
|
||||
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(HitTestFlags().contains(CompositorHitTestFlags::eScrollbar));
|
||||
mScrollTarget = mozilla::Some(aBuilder->GetCurrentScrollbarTarget());
|
||||
}
|
||||
}
|
||||
|
||||
bool nsDisplayCompositorHitTestInfo::CreateWebRenderCommands(
|
||||
mozilla::wr::DisplayListBuilder& aBuilder,
|
||||
mozilla::wr::IpcResourceUpdateQueue& aResources,
|
||||
const StackingContextHelper& aSc,
|
||||
mozilla::layers::RenderRootStateManager* aManager,
|
||||
nsDisplayListBuilder* aDisplayListBuilder) {
|
||||
if (HitTestArea().IsEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// XXX: eventually this scrollId computation and the SetHitTestInfo
|
||||
// call will get moved out into the WR display item iteration code so that
|
||||
// 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).
|
||||
ScrollableLayerGuid::ViewID scrollId =
|
||||
mScrollTarget.valueOrFrom([&]() -> ScrollableLayerGuid::ViewID {
|
||||
const ActiveScrolledRoot* asr = GetActiveScrolledRoot();
|
||||
Maybe<ScrollableLayerGuid::ViewID> fixedTarget =
|
||||
aBuilder.GetContainingFixedPosScrollTarget(asr);
|
||||
if (fixedTarget) {
|
||||
return *fixedTarget;
|
||||
}
|
||||
if (asr) {
|
||||
return asr->GetViewId();
|
||||
}
|
||||
return ScrollableLayerGuid::NULL_SCROLL_ID;
|
||||
});
|
||||
|
||||
Maybe<SideBits> sideBits =
|
||||
aBuilder.GetContainingFixedPosSideBits(GetActiveScrolledRoot());
|
||||
|
||||
// Insert a transparent rectangle with the hit-test info
|
||||
const LayoutDeviceRect devRect =
|
||||
LayoutDeviceRect::FromAppUnits(HitTestArea(), mAppUnitsPerDevPixel);
|
||||
|
||||
const wr::LayoutRect rect = wr::ToLayoutRect(devRect);
|
||||
|
||||
aBuilder.StartGroup(this);
|
||||
aBuilder.PushHitTest(rect, rect, !BackfaceIsHidden(), scrollId,
|
||||
HitTestFlags(), sideBits.valueOr(SideBits::eNone));
|
||||
aBuilder.FinishGroup();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -7363,7 +7301,8 @@ bool nsDisplayAsyncZoom::UpdateScrollData(
|
||||
//
|
||||
|
||||
#ifndef DEBUG
|
||||
static_assert(sizeof(nsDisplayTransform) < 512, "nsDisplayTransform has grown");
|
||||
static_assert(sizeof(nsDisplayTransform) <= 512,
|
||||
"nsDisplayTransform has grown");
|
||||
#endif
|
||||
|
||||
nsDisplayTransform::nsDisplayTransform(nsDisplayListBuilder* aBuilder,
|
||||
@ -10231,13 +10170,12 @@ nsDisplayListBuilder::AutoBuildingDisplayList::AutoBuildingDisplayList(
|
||||
: mBuilder(aBuilder),
|
||||
mPrevFrame(aBuilder->mCurrentFrame),
|
||||
mPrevReferenceFrame(aBuilder->mCurrentReferenceFrame),
|
||||
mPrevHitTestArea(aBuilder->mHitTestArea),
|
||||
mPrevHitTestInfo(aBuilder->mHitTestInfo),
|
||||
mPrevOffset(aBuilder->mCurrentOffsetToReferenceFrame),
|
||||
mPrevAdditionalOffset(aBuilder->mAdditionalOffset),
|
||||
mPrevVisibleRect(aBuilder->mVisibleRect),
|
||||
mPrevDirtyRect(aBuilder->mDirtyRect),
|
||||
mPrevAGR(aBuilder->mCurrentAGR),
|
||||
mPrevCompositorHitTestInfo(aBuilder->mCompositorHitTestInfo),
|
||||
mPrevAncestorHasApzAwareEventHandler(
|
||||
aBuilder->mAncestorHasApzAwareEventHandler),
|
||||
mPrevBuildingInvisibleItems(aBuilder->mBuildingInvisibleItems),
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "DisplayListClipState.h"
|
||||
#include "LayerState.h"
|
||||
#include "FrameMetrics.h"
|
||||
#include "HitTestInfo.h"
|
||||
#include "ImgDrawResult.h"
|
||||
#include "mozilla/dom/EffectsInfo.h"
|
||||
#include "mozilla/dom/RemoteBrowser.h"
|
||||
@ -680,29 +681,20 @@ class nsDisplayListBuilder {
|
||||
mAllowMergingAndFlattening = aAllow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current compositor hit test area and info to |aHitTestArea| and
|
||||
* |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(const nsRect& aHitTestArea,
|
||||
const CompositorHitTestInfo& aHitTestInfo) {
|
||||
mHitTestArea = aHitTestArea;
|
||||
mHitTestInfo = aHitTestInfo;
|
||||
void SetCompositorHitTestInfo(const CompositorHitTestInfo& aInfo) {
|
||||
mCompositorHitTestInfo = aInfo;
|
||||
}
|
||||
|
||||
const nsRect& GetHitTestArea() const { return mHitTestArea; }
|
||||
const CompositorHitTestInfo& GetHitTestInfo() const { return mHitTestInfo; }
|
||||
const CompositorHitTestInfo& GetCompositorHitTestInfo() const {
|
||||
return mCompositorHitTestInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* needed, and adds it to the top of |aList|.
|
||||
*/
|
||||
void BuildCompositorHitTestInfoIfNeeded(nsIFrame* aFrame,
|
||||
nsDisplayList* aList,
|
||||
const bool aBuildNew);
|
||||
nsDisplayList* aList);
|
||||
|
||||
bool IsInsidePointerEventsNoneDoc() {
|
||||
return CurrentPresShellState()->mInsidePointerEventsNoneDoc;
|
||||
@ -1134,8 +1126,6 @@ class nsDisplayListBuilder {
|
||||
~AutoBuildingDisplayList() {
|
||||
mBuilder->mCurrentFrame = mPrevFrame;
|
||||
mBuilder->mCurrentReferenceFrame = mPrevReferenceFrame;
|
||||
mBuilder->mHitTestArea = mPrevHitTestArea;
|
||||
mBuilder->mHitTestInfo = mPrevHitTestInfo;
|
||||
mBuilder->mCurrentOffsetToReferenceFrame = mPrevOffset;
|
||||
mBuilder->mVisibleRect = mPrevVisibleRect;
|
||||
mBuilder->mDirtyRect = mPrevDirtyRect;
|
||||
@ -1145,6 +1135,7 @@ class nsDisplayListBuilder {
|
||||
mBuilder->mBuildingInvisibleItems = mPrevBuildingInvisibleItems;
|
||||
mBuilder->mInInvalidSubtree = mPrevInInvalidSubtree;
|
||||
mBuilder->mAdditionalOffset = mPrevAdditionalOffset;
|
||||
mBuilder->mCompositorHitTestInfo = mPrevCompositorHitTestInfo;
|
||||
}
|
||||
|
||||
private:
|
||||
@ -1152,13 +1143,12 @@ class nsDisplayListBuilder {
|
||||
AGRState mCurrentAGRState;
|
||||
const nsIFrame* mPrevFrame;
|
||||
const nsIFrame* mPrevReferenceFrame;
|
||||
nsRect mPrevHitTestArea;
|
||||
CompositorHitTestInfo mPrevHitTestInfo;
|
||||
nsPoint mPrevOffset;
|
||||
mozilla::Maybe<nsPoint> mPrevAdditionalOffset;
|
||||
nsRect mPrevVisibleRect;
|
||||
nsRect mPrevDirtyRect;
|
||||
RefPtr<AnimatedGeometryRoot> mPrevAGR;
|
||||
CompositorHitTestInfo mPrevCompositorHitTestInfo;
|
||||
bool mPrevAncestorHasApzAwareEventHandler;
|
||||
bool mPrevBuildingInvisibleItems;
|
||||
bool mPrevInInvalidSubtree;
|
||||
@ -1832,7 +1822,6 @@ class nsDisplayListBuilder {
|
||||
friend class nsDisplayItem;
|
||||
friend class nsDisplayOwnLayer;
|
||||
friend struct RetainedDisplayListBuilder;
|
||||
friend struct HitTestInfo;
|
||||
AnimatedGeometryRoot* FindAnimatedGeometryRootFor(nsIFrame* aFrame);
|
||||
|
||||
AnimatedGeometryRoot* WrapAGRForFrame(
|
||||
@ -2029,8 +2018,7 @@ class nsDisplayListBuilder {
|
||||
bool mUseOverlayScrollbars;
|
||||
|
||||
mozilla::Maybe<float> mVisibleThreshold;
|
||||
nsRect mHitTestArea;
|
||||
CompositorHitTestInfo mHitTestInfo;
|
||||
mozilla::gfx::CompositorHitTestInfo mCompositorHitTestInfo;
|
||||
};
|
||||
|
||||
class nsDisplayItem;
|
||||
@ -2083,8 +2071,18 @@ void AssertUniqueItem(nsDisplayItem* aItem);
|
||||
*/
|
||||
bool ShouldBuildItemForEvents(const DisplayItemType aType);
|
||||
|
||||
/**
|
||||
* Updates the item DisplayItemData if needed.
|
||||
*/
|
||||
void UpdateDisplayItemData(nsPaintedDisplayItem* aItem);
|
||||
|
||||
/**
|
||||
* Initializes the hit test information of |aItem| if the item type supports it.
|
||||
*/
|
||||
void InitializeHitTestInfo(nsDisplayListBuilder* aBuilder,
|
||||
nsPaintedDisplayItem* aItem,
|
||||
const DisplayItemType aType);
|
||||
|
||||
template <typename T, typename F, typename... Args>
|
||||
MOZ_ALWAYS_INLINE T* MakeDisplayItemWithIndex(nsDisplayListBuilder* aBuilder,
|
||||
F* aFrame, const uint16_t aIndex,
|
||||
@ -2112,6 +2110,7 @@ MOZ_ALWAYS_INLINE T* MakeDisplayItemWithIndex(nsDisplayListBuilder* aBuilder,
|
||||
nsPaintedDisplayItem* paintedItem = item->AsPaintedDisplayItem();
|
||||
if (paintedItem) {
|
||||
UpdateDisplayItemData(paintedItem);
|
||||
InitializeHitTestInfo(aBuilder, paintedItem, type);
|
||||
}
|
||||
|
||||
if (aBuilder->InInvalidSubtree() ||
|
||||
@ -2164,8 +2163,6 @@ class nsDisplayItemLink {
|
||||
friend class nsDisplayList;
|
||||
};
|
||||
|
||||
class nsPaintedDisplayItem;
|
||||
|
||||
/*
|
||||
* nsDisplayItemBase is a base-class for all display items. It is mainly
|
||||
* responsible for handling the frame-display item 1:n relationship, as well as
|
||||
@ -3255,9 +3252,16 @@ class nsPaintedDisplayItem : public nsDisplayItem {
|
||||
mCacheIndex = mozilla::Nothing();
|
||||
}
|
||||
|
||||
mozilla::HitTestInfo& GetHitTestInfo() { return mHitTestInfo; }
|
||||
const nsRect& HitTestArea() const { return mHitTestInfo.Area(); }
|
||||
const mozilla::gfx::CompositorHitTestInfo& HitTestFlags() const {
|
||||
return mHitTestInfo.Info();
|
||||
}
|
||||
|
||||
protected:
|
||||
nsPaintedDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
|
||||
: nsDisplayItem(aBuilder, aFrame) {}
|
||||
: nsPaintedDisplayItem(aBuilder, aFrame,
|
||||
aBuilder->CurrentActiveScrolledRoot()) {}
|
||||
|
||||
nsPaintedDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
||||
const ActiveScrolledRoot* aActiveScrolledRoot)
|
||||
@ -3265,12 +3269,15 @@ class nsPaintedDisplayItem : public nsDisplayItem {
|
||||
|
||||
nsPaintedDisplayItem(nsDisplayListBuilder* aBuilder,
|
||||
const nsPaintedDisplayItem& aOther)
|
||||
: nsDisplayItem(aBuilder, aOther) {}
|
||||
: nsDisplayItem(aBuilder, aOther), mHitTestInfo(aOther.mHitTestInfo) {}
|
||||
|
||||
private:
|
||||
mozilla::DisplayItemData* mDisplayItemData = nullptr;
|
||||
mozilla::layers::LayerManager* mDisplayItemDataLayerManager = nullptr;
|
||||
mozilla::Maybe<uint16_t> mCacheIndex;
|
||||
|
||||
protected:
|
||||
mozilla::HitTestInfo mHitTestInfo;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -4438,6 +4445,12 @@ class nsDisplaySolidColorRegion : public nsPaintedDisplayItem {
|
||||
sRGBColor mColor;
|
||||
};
|
||||
|
||||
enum class AppendedBackgroundType : uint8_t {
|
||||
None,
|
||||
Background,
|
||||
ThemedBackground,
|
||||
};
|
||||
|
||||
/**
|
||||
* A display item to paint one background-image for a frame. Each background
|
||||
* image layer gets its own nsDisplayBackgroundImage.
|
||||
@ -4483,12 +4496,14 @@ class nsDisplayBackgroundImage : public nsDisplayImageContainer {
|
||||
|
||||
NS_DISPLAY_DECL_NAME("Background", TYPE_BACKGROUND)
|
||||
|
||||
// This will create and append new items for all the layers of the
|
||||
// background. Returns whether we appended a themed background.
|
||||
// aAllowWillPaintBorderOptimization should usually be left at true, unless
|
||||
// aFrame has special border drawing that causes opaque borders to not
|
||||
// actually be opaque.
|
||||
static bool AppendBackgroundItemsToTop(
|
||||
/**
|
||||
* This will create and append new items for all the layers of the
|
||||
* background. Returns the type of background that was appended.
|
||||
* aAllowWillPaintBorderOptimization should usually be left at true, unless
|
||||
* aFrame has special border drawing that causes opaque borders to not
|
||||
* actually be opaque.
|
||||
*/
|
||||
static AppendedBackgroundType AppendBackgroundItemsToTop(
|
||||
nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
||||
const nsRect& aBackgroundRect, nsDisplayList* aList,
|
||||
bool aAllowWillPaintBorderOptimization = true,
|
||||
@ -5160,20 +5175,6 @@ class nsDisplayEventReceiver final : public nsDisplayItem {
|
||||
HitTestState* aState, nsTArray<nsIFrame*>* 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
|
||||
@ -5182,21 +5183,26 @@ struct HitTestInfo {
|
||||
*/
|
||||
class nsDisplayCompositorHitTestInfo : public nsPaintedDisplayItem {
|
||||
public:
|
||||
nsDisplayCompositorHitTestInfo(
|
||||
nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
||||
const mozilla::gfx::CompositorHitTestInfo& aHitTestFlags,
|
||||
const mozilla::Maybe<nsRect>& aArea = mozilla::Nothing());
|
||||
nsDisplayCompositorHitTestInfo(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aFrame)
|
||||
: nsPaintedDisplayItem(aBuilder, aFrame) {
|
||||
MOZ_COUNT_CTOR(nsDisplayCompositorHitTestInfo);
|
||||
mHitTestInfo.Initialize(aBuilder, aFrame);
|
||||
}
|
||||
|
||||
nsDisplayCompositorHitTestInfo(
|
||||
nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
||||
mozilla::UniquePtr<HitTestInfo>&& aHitTestInfo);
|
||||
nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, const nsRect& aArea,
|
||||
const mozilla::gfx::CompositorHitTestInfo& aHitTestFlags)
|
||||
: nsPaintedDisplayItem(aBuilder, aFrame) {
|
||||
MOZ_COUNT_CTOR(nsDisplayCompositorHitTestInfo);
|
||||
mHitTestInfo.SetAreaAndInfo(aArea, aHitTestFlags);
|
||||
mHitTestInfo.InitializeScrollTarget(aBuilder);
|
||||
}
|
||||
|
||||
MOZ_COUNTED_DTOR_OVERRIDE(nsDisplayCompositorHitTestInfo)
|
||||
|
||||
NS_DISPLAY_DECL_NAME("CompositorHitTestInfo", TYPE_COMPOSITOR_HITTEST_INFO)
|
||||
|
||||
void InitializeScrollTarget(nsDisplayListBuilder* aBuilder);
|
||||
|
||||
bool CreateWebRenderCommands(
|
||||
mozilla::wr::DisplayListBuilder& aBuilder,
|
||||
mozilla::wr::IpcResourceUpdateQueue& aResources,
|
||||
@ -5207,26 +5213,6 @@ class nsDisplayCompositorHitTestInfo : public nsPaintedDisplayItem {
|
||||
int32_t ZIndex() const override;
|
||||
void SetOverrideZIndex(int32_t aZIndex);
|
||||
|
||||
void SetHitTestInfo(mozilla::UniquePtr<HitTestInfo>&& 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<HitTestInfo>(aArea, aHitTestFlags);
|
||||
}
|
||||
|
||||
const HitTestInfo& GetHitTestInfo() const {
|
||||
MOZ_ASSERT(mHitTestInfo);
|
||||
return *mHitTestInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* ApplyOpacity() is overriden for opacity flattening.
|
||||
*/
|
||||
@ -5243,18 +5229,8 @@ class nsDisplayCompositorHitTestInfo : public nsPaintedDisplayItem {
|
||||
return nsRect();
|
||||
}
|
||||
|
||||
const nsRect& HitTestArea() const { return mHitTestInfo->mArea; }
|
||||
|
||||
const mozilla::gfx::CompositorHitTestInfo& HitTestFlags() const {
|
||||
return mHitTestInfo->mFlags;
|
||||
}
|
||||
|
||||
private:
|
||||
mozilla::Maybe<mozilla::layers::ScrollableLayerGuid::ViewID> mScrollTarget;
|
||||
mozilla::Maybe<int32_t> mOverrideZIndex;
|
||||
int32_t mAppUnitsPerDevPixel;
|
||||
|
||||
mozilla::UniquePtr<HitTestInfo> mHitTestInfo;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -215,6 +215,9 @@ void SVGGeometryFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
styleSVG->mMarkerMid.IsNone() && styleSVG->mMarkerStart.IsNone()) {
|
||||
return;
|
||||
}
|
||||
|
||||
aBuilder->BuildCompositorHitTestInfoIfNeeded(this,
|
||||
aLists.BorderBackground());
|
||||
}
|
||||
|
||||
DisplayOutline(aBuilder, aLists);
|
||||
|
@ -765,6 +765,8 @@ void SVGOuterSVGFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
contentList, contentList);
|
||||
BuildDisplayListForNonBlockChildren(aBuilder, set);
|
||||
} else if (IsVisibleForPainting() || !aBuilder->IsForPainting()) {
|
||||
aBuilder->BuildCompositorHitTestInfoIfNeeded(this,
|
||||
aLists.BorderBackground());
|
||||
aLists.Content()->AppendNewToTop<nsDisplayOuterSVG>(aBuilder, this);
|
||||
}
|
||||
}
|
||||
|
@ -463,13 +463,19 @@ void nsTableCellFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
nsRect bgRect = GetRectRelativeToSelf() + aBuilder->ToReferenceFrame(this);
|
||||
|
||||
// display background if we need to.
|
||||
AppendedBackgroundType result = AppendedBackgroundType::None;
|
||||
if (aBuilder->IsForEventDelivery() ||
|
||||
!StyleBackground()->IsTransparent(this) ||
|
||||
StyleDisplay()->HasAppearance()) {
|
||||
nsDisplayBackgroundImage::AppendBackgroundItemsToTop(
|
||||
result = nsDisplayBackgroundImage::AppendBackgroundItemsToTop(
|
||||
aBuilder, this, bgRect, aLists.BorderBackground());
|
||||
}
|
||||
|
||||
if (result == AppendedBackgroundType::None) {
|
||||
aBuilder->BuildCompositorHitTestInfoIfNeeded(this,
|
||||
aLists.BorderBackground());
|
||||
}
|
||||
|
||||
// display inset box-shadows if we need to.
|
||||
if (hasBoxShadow) {
|
||||
aLists.BorderBackground()->AppendNewToTop<nsDisplayBoxShadowInner>(
|
||||
|
Loading…
Reference in New Issue
Block a user