зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
538616f46e
Коммит
b6b5546bc8
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче