Bug 1534549 - Part 4: Shrink nsDisplayCompositorHitTestInfo r=mstange

These changes make nsDisplayCompositorHitTestInfo inherit directly from nsDisplayItem, which should shrink it slightly. This also simplifies the logic: hit testing information is now available at nsDisplayItem level as opposed to nsPaintedDisplayItem.

Differential Revision: https://phabricator.services.mozilla.com/D103773
This commit is contained in:
Miko Mynttinen 2021-02-06 22:30:57 +00:00
Родитель 538616f46e
Коммит b6b5546bc8
11 изменённых файлов: 150 добавлений и 122 удалений

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

@ -9,6 +9,13 @@
#include "nsDisplayList.h"
#define DEBUG_HITTEST_INFO 0
#if DEBUG_HITTEST_INFO
# define HITTEST_INFO_LOG(...) printf_stderr(__VA_ARGS__)
#else
# define HITTEST_INFO_LOG(...)
#endif
namespace mozilla::layers {
using ViewID = ScrollableLayerGuid::ViewID;
@ -27,8 +34,7 @@ static int32_t GetAppUnitsFromDisplayItem(nsDisplayItem* aItem) {
}
static void CreateWebRenderCommands(wr::DisplayListBuilder& aBuilder,
nsPaintedDisplayItem* aItem,
const nsRect& aArea,
nsDisplayItem* aItem, const nsRect& aArea,
const gfx::CompositorHitTestInfo& aFlags,
const ViewID& aViewId) {
const Maybe<SideBits> sideBits =
@ -45,13 +51,15 @@ static void CreateWebRenderCommands(wr::DisplayListBuilder& aBuilder,
void HitTestInfoManager::Reset() {
mArea = nsRect();
mFlags = gfx::CompositorHitTestInvisibleToHit;
HITTEST_INFO_LOG("* HitTestInfoManager::Reset\n");
}
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.
void HitTestInfoManager::ProcessItem(
nsDisplayItem* aItem, wr::DisplayListBuilder& aBuilder,
nsDisplayListBuilder* aDisplayListBuilder) {
MOZ_ASSERT(aItem);
if (!aItem->HasHitTestInfo()) {
return;
}
@ -59,7 +67,7 @@ void HitTestInfoManager::SwitchItem(nsPaintedDisplayItem* aItem,
const nsRect& area = hitTestInfo.Area();
const gfx::CompositorHitTestInfo& flags = hitTestInfo.Info();
if (area.IsEmpty() || flags == gfx::CompositorHitTestInvisibleToHit) {
if (flags == gfx::CompositorHitTestInvisibleToHit || area.IsEmpty()) {
return;
}
@ -72,9 +80,16 @@ void HitTestInfoManager::SwitchItem(nsPaintedDisplayItem* aItem,
return;
}
HITTEST_INFO_LOG("+ [%d, %d, %d, %d]: flags: 0x%x, viewId: %llu\n", area.x,
area.y, area.width, area.height, flags.serialize(), viewId);
CreateWebRenderCommands(aBuilder, aItem, area, flags, viewId);
}
/**
* Updates the current hit testing information if necessary.
* Returns true if the the hit testing information was changed.
*/
bool HitTestInfoManager::Update(const nsRect& aArea,
const gfx::CompositorHitTestInfo& aFlags,
const ViewID& aViewId,
@ -82,6 +97,9 @@ bool HitTestInfoManager::Update(const nsRect& aArea,
if (mViewId == aViewId && mFlags == aFlags && mArea.Contains(aArea) &&
mSpaceAndClipChain == aSpaceAndClip) {
// The previous hit testing information can be reused.
HITTEST_INFO_LOG("s [%d, %d, %d, %d]: flags: 0x%x, viewId: %llu\n", aArea.x,
aArea.y, aArea.width, aArea.height, aFlags.serialize(),
aViewId);
return false;
}

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

@ -43,8 +43,8 @@ class HitTestInfoManager {
* 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);
void ProcessItem(nsDisplayItem* aItem, wr::DisplayListBuilder& aBuilder,
nsDisplayListBuilder* aDisplayListBuilder);
private:
bool Update(const nsRect& aArea, const gfx::CompositorHitTestInfo& aFlags,

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

@ -788,15 +788,17 @@ struct DIGroup {
item->GetPerFrameKey(), bounds.x, bounds.y, bounds.XMost(),
bounds.YMost());
if (item->GetType() == DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO) {
if (item->HasHitTestInfo()) {
// Accumulate the hit-test info flags. In cases where there are multiple
// hittest-info display items with different flags, mHitInfo will have
// the union of all those flags. If that is the case, we will
// additionally set eIrregularArea (at the site that we use mHitInfo)
// so that downstream consumers of this (primarily APZ) will know that
// the exact shape of what gets hit with what is unknown.
mHitInfo +=
static_cast<nsDisplayCompositorHitTestInfo*>(item)->HitTestFlags();
mHitInfo += item->GetHitTestInfo().Info();
}
if (item->GetType() == DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO) {
continue;
}
@ -1231,8 +1233,7 @@ void Grouper::ConstructGroups(nsDisplayListBuilder* aDisplayListBuilder,
{
auto spaceAndClipChain = mClipManager.SwitchItem(item);
wr::SpaceAndClipChainHelper saccHelper(aBuilder, spaceAndClipChain);
mHitTestInfoManager.SwitchItem(item->AsPaintedDisplayItem(), aBuilder,
aDisplayListBuilder);
mHitTestInfoManager.ProcessItem(item, aBuilder, aDisplayListBuilder);
sIndent++;
// Note: this call to CreateWebRenderCommands can recurse back into
@ -1653,15 +1654,15 @@ void WebRenderCommandBuilder::CreateWebRenderCommands(
mozilla::wr::IpcResourceUpdateQueue& aResources,
const StackingContextHelper& aSc,
nsDisplayListBuilder* aDisplayListBuilder) {
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) {
mHitTestInfoManager.ProcessItem(aItem, aBuilder, aDisplayListBuilder);
if (aItem->GetType() == DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO) {
// The hit test information was processed above.
return;
}
auto* item = aItem->AsPaintedDisplayItem();
MOZ_RELEASE_ASSERT(item, "Tried to paint item that cannot be painted");
if (aBuilder.ReuseItem(item)) {
// No further processing should be needed, since the item was reused.
return;

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

@ -116,11 +116,12 @@ static void PrintDisplayItemTo(nsDisplayListBuilder* aBuilder,
aStream << ")";
}
if (auto* paintedItem = aItem->AsPaintedDisplayItem()) {
if (aItem->HasHitTestInfo()) {
const auto& hitTestInfo = aItem->GetHitTestInfo();
aStream << nsPrintfCString(" hitTestInfo(0x%x)",
paintedItem->HitTestFlags().serialize());
hitTestInfo.Info().serialize());
nsRect area = paintedItem->HitTestArea();
nsRect area = hitTestInfo.Area();
aStream << nsPrintfCString(" hitTestArea(%d,%d,%d,%d)", area.x, area.y,
area.width, area.height);
}

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

@ -58,6 +58,7 @@
#include "StorageObserver.h"
#include "CacheObserver.h"
#include "DisplayItemClip.h"
#include "HitTestInfo.h"
#include "ActiveLayerTracker.h"
#include "FrameLayerBuilder.h"
#include "AnimationCommon.h"
@ -389,6 +390,7 @@ void nsLayoutStatics::Shutdown() {
ContentParent::ShutDown();
DisplayItemClip::Shutdown();
HitTestInfo::Shutdown();
CacheObserver::Shutdown();

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

@ -4082,7 +4082,7 @@ void ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO) {
auto* hitTestItem =
static_cast<nsDisplayCompositorHitTestInfo*>(item);
if (hitTestItem->HitTestFlags().contains(
if (hitTestItem->GetHitTestInfo().Info().contains(
CompositorHitTestFlags::eInactiveScrollframe)) {
zIndex = std::max(zIndex, hitTestItem->ZIndex());
item->SetCantBeReused();

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

@ -683,7 +683,7 @@ class PaintedLayerData {
* need to update our regions.
* @param aVisibleRect the area of the item that's visible
*/
void Accumulate(ContainerState* aState, nsPaintedDisplayItem* aItem,
void Accumulate(ContainerState* aState, nsDisplayItem* aItem,
const nsIntRect& aVisibleRect, const nsRect& aContentRect,
const DisplayItemClip& aClip, LayerState aLayerState,
nsDisplayList* aList, DisplayItemEntryType aType,
@ -3842,18 +3842,30 @@ UniquePtr<InactiveLayerData> PaintedLayerData::CreateInactiveLayerData(
return data;
}
void PaintedLayerData::Accumulate(
ContainerState* aState, nsPaintedDisplayItem* aItem,
const nsIntRect& aVisibleRect, const nsRect& aContentRect,
const DisplayItemClip& aClip, LayerState aLayerState, nsDisplayList* aList,
DisplayItemEntryType aType, nsTArray<size_t>& aOpacityIndices,
const RefPtr<TransformClipNode>& aTransform) {
void PaintedLayerData::Accumulate(ContainerState* aState, nsDisplayItem* aItem,
const nsIntRect& aVisibleRect,
const nsRect& aContentRect,
const DisplayItemClip& aClip,
LayerState aLayerState, nsDisplayList* aList,
DisplayItemEntryType aType,
nsTArray<size_t>& aOpacityIndices,
const RefPtr<TransformClipNode>& aTransform) {
if (aItem->HasHitTestInfo()) {
AccumulateHitTestItem(aState, aItem, aClip, aTransform);
}
if (aItem->GetType() == DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO) {
// These items only carry hit test information.
return;
}
nsPaintedDisplayItem* item = aItem->AsPaintedDisplayItem();
// If aItem is nullptr, the cast to nsPaintedDisplayItem failed.
MOZ_ASSERT(aItem, "Can only accumulate display items that are painted!");
MOZ_ASSERT(item, "Can only accumulate display items that are painted!");
FLB_LOG_PAINTED_LAYER_DECISION(
this, "Accumulating dp=%s(%p), f=%p against pld=%p\n", aItem->Name(),
aItem, aItem->Frame(), this);
this, "Accumulating dp=%s(%p), f=%p against pld=%p\n", item->Name(), item,
item->Frame(), this);
const bool hasOpacity = aOpacityIndices.Length() > 0;
UpdateEffectStatus(aType, aOpacityIndices);
@ -3861,13 +3873,12 @@ void PaintedLayerData::Accumulate(
const DisplayItemClip* oldClip = mItemClip;
mItemClip = &aClip;
const bool isMerged = aItem->AsDisplayWrapList() &&
aItem->AsDisplayWrapList()->HasMergedFrames();
const bool isMerged =
item->AsDisplayWrapList() && item->AsDisplayWrapList()->HasMergedFrames();
if (IsEffectEndMarker(aType)) {
mAssignedDisplayItems.emplace_back(aItem, aLayerState, nullptr,
aContentRect, aType, hasOpacity,
aTransform, isMerged);
mAssignedDisplayItems.emplace_back(item, aLayerState, nullptr, aContentRect,
aType, hasOpacity, aTransform, isMerged);
return;
}
@ -3875,23 +3886,23 @@ void PaintedLayerData::Accumulate(
(oldClip == mItemClip) || (oldClip && *oldClip == *mItemClip);
DisplayItemData* currentData =
isMerged ? nullptr : aItem->GetDisplayItemData();
isMerged ? nullptr : item->GetDisplayItemData();
DisplayItemData* oldData = aState->mLayerBuilder->GetOldLayerForFrame(
aItem->Frame(), aItem->GetPerFrameKey(), currentData,
aItem->GetDisplayItemDataLayerManager());
item->Frame(), item->GetPerFrameKey(), currentData,
item->GetDisplayItemDataLayerManager());
mAssignedDisplayItems.emplace_back(aItem, aLayerState, oldData, aContentRect,
mAssignedDisplayItems.emplace_back(item, aLayerState, oldData, aContentRect,
aType, hasOpacity, aTransform, isMerged);
if (aLayerState != LayerState::LAYER_NONE) {
FLB_LOG_PAINTED_LAYER_DECISION(this, "Creating nested FLB for item %p\n",
aItem);
item);
mAssignedDisplayItems.back().mInactiveLayerData =
CreateInactiveLayerData(aState, aItem, oldData);
CreateInactiveLayerData(aState, item, oldData);
}
if (aState->mBuilder->NeedToForceTransparentSurfaceForItem(aItem)) {
if (aState->mBuilder->NeedToForceTransparentSurfaceForItem(item)) {
mForceTransparentSurface = true;
}
@ -3899,10 +3910,10 @@ void PaintedLayerData::Accumulate(
// Disable component alpha.
// Note that the transform (if any) on the PaintedLayer is always an integer
// translation so we don't have to factor that in here.
aItem->DisableComponentAlpha();
item->DisableComponentAlpha();
} else {
const bool needsComponentAlpha =
SetupComponentAlpha(aState, aItem, aVisibleRect, aTransform);
SetupComponentAlpha(aState, item, aVisibleRect, aTransform);
if (needsComponentAlpha) {
// This display item needs background copy when pushing opacity group.
@ -3939,7 +3950,7 @@ void PaintedLayerData::Accumulate(
// Active opacity means no opaque pixels.
if (!hasOpacity) {
opaquePixels = aState->ComputeOpaqueRect(
aItem, mAnimatedGeometryRoot, mASR, aClip, aList, &mHideAllLayersBelow,
item, mAnimatedGeometryRoot, mASR, aClip, aList, &mHideAllLayersBelow,
&mOpaqueForAnimatedGeometryRootParent);
opaquePixels.AndWith(aVisibleRect);
}
@ -3949,8 +3960,8 @@ void PaintedLayerData::Accumulate(
*/
if (nsIntRegion(aVisibleRect).Contains(mVisibleRegion) &&
opaquePixels.Contains(mVisibleRegion) &&
aItem->SupportsOptimizingToImage()) {
mImage = static_cast<nsDisplayImageContainer*>(aItem);
item->SupportsOptimizingToImage()) {
mImage = static_cast<nsDisplayImageContainer*>(item);
FLB_LOG_PAINTED_LAYER_DECISION(
this, " Tracking image: nsDisplayImageContainer covers the layer\n");
} else if (mImage) {
@ -3962,7 +3973,7 @@ void PaintedLayerData::Accumulate(
Maybe<nscolor> uniformColor;
if (!hasOpacity) {
uniformColor = aItem->IsUniform(aState->mBuilder);
uniformColor = item->IsUniform(aState->mBuilder);
}
// Some display items have to exist (so they can set forceTransparentSurface
@ -3974,7 +3985,7 @@ void PaintedLayerData::Accumulate(
// pixel-aligned (thus the item will not be truly uniform).
if (uniformColor) {
bool snap;
nsRect bounds = aItem->GetBounds(aState->mBuilder, &snap);
nsRect bounds = item->GetBounds(aState->mBuilder, &snap);
if (!aState->ScaleToInsidePixels(bounds, snap).Contains(aVisibleRect)) {
uniformColor = Nothing();
FLB_LOG_PAINTED_LAYER_DECISION(
@ -4020,7 +4031,7 @@ void PaintedLayerData::Accumulate(
// Opaque display items in chrome documents whose window is partially
// transparent are always added to the opaque region. This helps ensure
// that we get as much subpixel-AA as possible in the chrome.
if (tmp.GetNumRects() <= 4 || aItem->Frame()->PresContext()->IsChrome()) {
if (tmp.GetNumRects() <= 4 || item->Frame()->PresContext()->IsChrome()) {
mOpaqueRegion = std::move(tmp);
}
}
@ -4038,17 +4049,15 @@ void PaintedLayerData::AccumulateHitTestItem(ContainerState* aState,
nsDisplayItem* aItem,
const DisplayItemClip& aClip,
TransformClipNode* aTransform) {
auto* item = aItem->AsPaintedDisplayItem();
MOZ_ASSERT(item);
nsRect area = item->HitTestArea();
const CompositorHitTestInfo& flags = item->HitTestFlags();
const auto& hitTestInfo = aItem->GetHitTestInfo();
nsRect area = hitTestInfo.Area();
const CompositorHitTestInfo& flags = hitTestInfo.Info();
FLB_LOG_PAINTED_LAYER_DECISION(
this,
"Accumulating hit test info %p against pld=%p, "
"area: [%d, %d, %d, %d], flags: 0x%x]\n",
item, this, area.x, area.y, area.width, area.height, flags.serialize());
aItem, this, area.x, area.y, area.width, area.height, flags.serialize());
area = aClip.ApplyNonRoundedIntersection(area);
@ -4058,7 +4067,7 @@ void PaintedLayerData::AccumulateHitTestItem(ContainerState* aState,
if (area.IsEmpty()) {
FLB_LOG_PAINTED_LAYER_DECISION(
this, "Discarded empty hit test info %p for pld=%p\n", item, this);
this, "Discarded empty hit test info %p for pld=%p\n", aItem, this);
return;
}
@ -4067,7 +4076,7 @@ void PaintedLayerData::AccumulateHitTestItem(ContainerState* aState,
// 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.
nsIFrame* frame = item->Frame();
nsIFrame* frame = aItem->Frame();
bool simpleRegions = frame->HasAnyStateBits(NS_FRAME_SIMPLE_EVENT_REGIONS);
if (!simpleRegions) {
if (nsLayoutUtils::HasNonZeroCorner(frame->StyleBorder()->mBorderRadius)) {
@ -4544,15 +4553,8 @@ void ContainerState::ProcessDisplayItems(nsDisplayList* aList) {
nsDisplayItem* item = e.mItem;
MOZ_ASSERT(item);
DisplayItemType itemType = item->GetType();
bool snap = false;
nsRect itemContent = item->GetBounds(mBuilder, &snap);
if (itemType == DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO) {
itemContent = static_cast<nsPaintedDisplayItem*>(item)->HitTestArea();
}
const bool inEffect = InTransform() || InOpacity();
const bool isHitTestItem =
itemType == DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO;
NS_ASSERTION(mAppUnitsPerDevPixel == AppUnitsPerDevPixel(item),
"items in a container layer should all have the same app "
@ -4578,6 +4580,7 @@ void ContainerState::ProcessDisplayItems(nsDisplayList* aList) {
const DisplayItemClipChain* layerClipChain = nullptr;
const DisplayItemClip* itemClipPtr = &item->GetClip();
const bool inEffect = InTransform() || InOpacity();
if (mManager->IsWidgetLayerManager() && !inEffect) {
if (itemClipChain && itemClipChain->mASR == itemASR &&
itemType != DisplayItemType::TYPE_STICKY_POSITION) {
@ -4608,20 +4611,9 @@ void ContainerState::ProcessDisplayItems(nsDisplayList* aList) {
// 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);
selectedLayer->Accumulate(this, item, nsIntRect(), nsRect(), itemClip,
layerState, aList, marker, opacityIndices,
transformNode);
continue;
}
@ -4646,6 +4638,10 @@ void ContainerState::ProcessDisplayItems(nsDisplayList* aList) {
itemType == DisplayItemType::TYPE_TRANSFORM &&
static_cast<nsDisplayTransform*>(item)->MayBeAnimated(mBuilder);
bool snap = false;
nsRect itemContent = isHitTestItem ? item->GetHitTestInfo().Area()
: item->GetBounds(mBuilder, &snap);
nsIntRect itemDrawRect = ScaleToOutsidePixels(itemContent, snap);
ParentLayerIntRect clipRect;
if (itemClip.HasClip()) {
@ -4679,7 +4675,7 @@ void ContainerState::ProcessDisplayItems(nsDisplayList* aList) {
#ifdef DEBUG
nsRect bounds = itemContent;
if (inEffect) {
if (inEffect || isHitTestItem) {
bounds.SetEmpty();
}
@ -5123,19 +5119,9 @@ void ContainerState::ProcessDisplayItems(nsDisplayList* aList) {
}
MOZ_ASSERT(paintedLayerData);
if (item->AsPaintedDisplayItem()->GetHitTestInfo().Info() !=
mozilla::gfx::CompositorHitTestInvisibleToHit) {
paintedLayerData->AccumulateHitTestItem(this, item, itemClip, nullptr);
}
if (itemType == DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO) {
// The hit test info was processed above.
continue;
}
paintedLayerData->Accumulate(
this, item->AsPaintedDisplayItem(), itemVisibleRect, itemContent,
itemClip, layerState, aList, marker, opacityIndices, transformNode);
paintedLayerData->Accumulate(this, item, itemVisibleRect, itemContent,
itemClip, layerState, aList, marker,
opacityIndices, transformNode);
if (!paintedLayerData->mLayer) {
// Try to recycle the old layer of this display item.

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

@ -11,6 +11,21 @@
namespace mozilla {
static const HitTestInfo* gEmptyHitTestInfo = nullptr;
const HitTestInfo& HitTestInfo::Empty() {
if (gEmptyHitTestInfo) {
gEmptyHitTestInfo = new HitTestInfo();
}
return *gEmptyHitTestInfo;
}
void HitTestInfo::Shutdown() {
delete gEmptyHitTestInfo;
gEmptyHitTestInfo = nullptr;
}
using ViewID = layers::ScrollableLayerGuid::ViewID;
ViewID HitTestInfo::GetViewId(wr::DisplayListBuilder& aBuilder,
@ -19,8 +34,7 @@ ViewID HitTestInfo::GetViewId(wr::DisplayListBuilder& aBuilder,
return *mScrollTarget;
}
Maybe<ScrollableLayerGuid::ViewID> fixedTarget =
aBuilder.GetContainingFixedPosScrollTarget(aASR);
Maybe<ViewID> fixedTarget = aBuilder.GetContainingFixedPosScrollTarget(aASR);
if (fixedTarget) {
return *fixedTarget;

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

@ -42,6 +42,8 @@ class HitTestInfo {
const nsRect& Area() const { return mArea; }
const CompositorHitTestInfo& Info() const { return mInfo; }
static const HitTestInfo& Empty();
private:
nsRect mArea;
CompositorHitTestInfo mInfo;

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

@ -188,7 +188,7 @@ void InitializeHitTestInfo(nsDisplayListBuilder* aBuilder,
nsPaintedDisplayItem* aItem,
const DisplayItemType aType) {
if (ItemTypeSupportsHitTesting(aType)) {
aItem->GetHitTestInfo().Initialize(aBuilder, aItem->Frame());
aItem->InitializeHitTestInfo(aBuilder);
}
}
@ -4874,7 +4874,7 @@ bool nsDisplayCompositorHitTestInfo::CreateWebRenderCommands(
}
int32_t nsDisplayCompositorHitTestInfo::ZIndex() const {
return mOverrideZIndex ? *mOverrideZIndex : nsPaintedDisplayItem::ZIndex();
return mOverrideZIndex ? *mOverrideZIndex : nsDisplayItem::ZIndex();
}
void nsDisplayCompositorHitTestInfo::SetOverrideZIndex(int32_t aZIndex) {

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

@ -3081,6 +3081,10 @@ class nsDisplayItem : public nsDisplayItemBase {
return mFrame != aOther->mFrame;
}
bool HasHitTestInfo() const {
return mItemFlags.contains(ItemFlag::HasHitTestInfo);
}
bool HasSameTypeAndClip(const nsDisplayItem* aOther) const {
return GetPerFrameKey() == aOther->GetPerFrameKey() &&
GetClipChain() == aOther->GetClipChain();
@ -3101,10 +3105,15 @@ class nsDisplayItem : public nsDisplayItemBase {
return GetPaintRect();
}
virtual const mozilla::HitTestInfo& GetHitTestInfo() {
return mozilla::HitTestInfo::Empty();
}
protected:
typedef bool (*PrefFunc)(void);
bool ShouldUseAdvancedLayer(LayerManager* aManager, PrefFunc aFunc) const;
bool CanUseAdvancedLayer(LayerManager* aManager) const;
void SetHasHitTestInfo() { mItemFlags += ItemFlag::HasHitTestInfo; }
RefPtr<const DisplayItemClipChain> mClipChain;
const DisplayItemClip* mClip;
@ -3137,8 +3146,9 @@ class nsDisplayItem : public nsDisplayItemBase {
Combines3DTransformWithAncestors,
DisableSubpixelAA,
ForceNotVisible,
PaintRectValid,
HasHitTestInfo,
IsGlassItem,
PaintRectValid,
#ifdef MOZ_DUMP_PAINTING
// True if this frame has been painted.
Painted,
@ -3252,10 +3262,10 @@ 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();
const mozilla::HitTestInfo& GetHitTestInfo() final { return mHitTestInfo; }
void InitializeHitTestInfo(nsDisplayListBuilder* aBuilder) {
mHitTestInfo.Initialize(aBuilder, Frame());
SetHasHitTestInfo();
}
protected:
@ -5181,22 +5191,24 @@ class nsDisplayEventReceiver final : public nsDisplayItem {
* compositor some hit-test info for a frame. This is effectively a dummy item
* whose sole purpose is to carry the hit-test info to the compositor.
*/
class nsDisplayCompositorHitTestInfo : public nsPaintedDisplayItem {
class nsDisplayCompositorHitTestInfo final : public nsDisplayItem {
public:
nsDisplayCompositorHitTestInfo(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame)
: nsPaintedDisplayItem(aBuilder, aFrame) {
: nsDisplayItem(aBuilder, aFrame) {
MOZ_COUNT_CTOR(nsDisplayCompositorHitTestInfo);
mHitTestInfo.Initialize(aBuilder, aFrame);
SetHasHitTestInfo();
}
nsDisplayCompositorHitTestInfo(
nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, const nsRect& aArea,
const mozilla::gfx::CompositorHitTestInfo& aHitTestFlags)
: nsPaintedDisplayItem(aBuilder, aFrame) {
: nsDisplayItem(aBuilder, aFrame) {
MOZ_COUNT_CTOR(nsDisplayCompositorHitTestInfo);
mHitTestInfo.SetAreaAndInfo(aArea, aHitTestFlags);
mHitTestInfo.InitializeScrollTarget(aBuilder);
SetHasHitTestInfo();
}
MOZ_COUNTED_DTOR_OVERRIDE(nsDisplayCompositorHitTestInfo)
@ -5213,23 +5225,15 @@ class nsDisplayCompositorHitTestInfo : public nsPaintedDisplayItem {
int32_t ZIndex() const override;
void SetOverrideZIndex(int32_t aZIndex);
/**
* ApplyOpacity() is overriden for opacity flattening.
*/
void ApplyOpacity(nsDisplayListBuilder* aBuilder, float aOpacity,
const DisplayItemClipChain* aClip) override {}
/**
* CanApplyOpacity() is overriden for opacity flattening.
*/
bool CanApplyOpacity() const override { return true; }
nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const override {
*aSnap = false;
return nsRect();
}
const mozilla::HitTestInfo& GetHitTestInfo() final { return mHitTestInfo; }
private:
mozilla::HitTestInfo mHitTestInfo;
mozilla::Maybe<int32_t> mOverrideZIndex;
};