зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1728050 - Move opacity flattening to be part of WR DL serialization. r=miko
Differential Revision: https://phabricator.services.mozilla.com/D124005
This commit is contained in:
Родитель
02eb7bf7e3
Коммит
7e0f7ff766
|
@ -180,6 +180,12 @@ Maybe<uint16_t> DisplayItemCache::CanReuseItem(
|
|||
return Nothing();
|
||||
}
|
||||
|
||||
if (mSuppressed) {
|
||||
slot.mOccupied = false;
|
||||
slotIndex = Nothing();
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
if (!(aSpaceAndClip == slot.mSpaceAndClip)) {
|
||||
// Spatial id and clip id can change between display lists, if items that
|
||||
// generate them change their order.
|
||||
|
|
|
@ -100,9 +100,9 @@ class DisplayItemCache final {
|
|||
/**
|
||||
* Suppress display item caching. This doesn't clear any existing cached
|
||||
* items or change the underlying capacity, it just makes IsEnabled() return
|
||||
* false. It is not meant to be flipped in the middle of a display list build,
|
||||
* but rather set before the display list build starts to suppress use of the
|
||||
* cache for that display list build.
|
||||
* false.
|
||||
* It will also make CanReuseItem return false for the duration of the
|
||||
* suppression.
|
||||
*/
|
||||
bool SetSuppressed(bool aSuppressed) {
|
||||
if (aSuppressed == mSuppressed) {
|
||||
|
|
|
@ -2484,6 +2484,8 @@ Maybe<wr::ImageMask> WebRenderCommandBuilder::BuildWrMaskImage(
|
|||
|
||||
nsPoint maskOffset = aMaskItem->ToReferenceFrame() - bounds.TopLeft();
|
||||
|
||||
bool shouldHandleOpacity = aBuilder.GetInheritedOpacity() != 1.0f;
|
||||
|
||||
nsRect dirtyRect;
|
||||
// If this mask item is being painted for the first time, some members of
|
||||
// WebRenderMaskData are still default initialized. This is intentional.
|
||||
|
@ -2491,7 +2493,7 @@ Maybe<wr::ImageMask> WebRenderCommandBuilder::BuildWrMaskImage(
|
|||
!itemRect.IsEqualInterior(maskData->mItemRect) ||
|
||||
!(aMaskItem->Frame()->StyleSVGReset()->mMask == maskData->mMaskStyle) ||
|
||||
maskOffset != maskData->mMaskOffset || !sameScale ||
|
||||
aMaskItem->ShouldHandleOpacity() != maskData->mShouldHandleOpacity) {
|
||||
shouldHandleOpacity != maskData->mShouldHandleOpacity) {
|
||||
IntSize size = itemRect.Size().ToUnknownSize();
|
||||
|
||||
if (!Factory::AllowedSurfaceSize(size)) {
|
||||
|
@ -2535,8 +2537,8 @@ Maybe<wr::ImageMask> WebRenderCommandBuilder::BuildWrMaskImage(
|
|||
.PreScale(scale.width, scale.height));
|
||||
|
||||
bool maskPainted = false;
|
||||
bool maskIsComplete =
|
||||
aMaskItem->PaintMask(aDisplayListBuilder, context, &maskPainted);
|
||||
bool maskIsComplete = aMaskItem->PaintMask(
|
||||
aDisplayListBuilder, context, shouldHandleOpacity, &maskPainted);
|
||||
if (!maskPainted) {
|
||||
return Nothing();
|
||||
}
|
||||
|
@ -2587,7 +2589,7 @@ Maybe<wr::ImageMask> WebRenderCommandBuilder::BuildWrMaskImage(
|
|||
maskData->mMaskOffset = maskOffset;
|
||||
maskData->mScale = scale;
|
||||
maskData->mMaskStyle = aMaskItem->Frame()->StyleSVGReset()->mMask;
|
||||
maskData->mShouldHandleOpacity = aMaskItem->ShouldHandleOpacity();
|
||||
maskData->mShouldHandleOpacity = shouldHandleOpacity;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -684,6 +684,17 @@ class DisplayListBuilder final {
|
|||
mClipChainLeaf = aClipRect;
|
||||
}
|
||||
|
||||
// Used for opacity flattening. When we flatten away an opacity item,
|
||||
// we push the opacity value onto the builder.
|
||||
// Descendant items should pull the inherited opacity during
|
||||
// their CreateWebRenderCommands implementation. This can only happen if all
|
||||
// descendant items reported supporting this functionality, via
|
||||
// nsDisplayItem::CanApplyOpacity.
|
||||
float GetInheritedOpacity() { return mInheritedOpacity; }
|
||||
void SetInheritedOpacity(float aOpacity) { mInheritedOpacity = aOpacity; }
|
||||
|
||||
layers::DisplayItemCache* GetDisplayItemCache() { return mDisplayItemCache; }
|
||||
|
||||
// A chain of RAII objects, each holding a (ASR, ViewID, SideBits) tuple of
|
||||
// data. The topmost object is pointed to by the mActiveFixedPosTracker
|
||||
// pointer in the wr::DisplayListBuilder.
|
||||
|
@ -750,6 +761,7 @@ class DisplayListBuilder final {
|
|||
|
||||
layers::DisplayItemCache* mDisplayItemCache;
|
||||
Maybe<uint16_t> mCurrentCacheSlot;
|
||||
float mInheritedOpacity = 1.0f;
|
||||
|
||||
friend class WebRenderAPI;
|
||||
friend class SpaceAndClipChainHelper;
|
||||
|
|
|
@ -1487,6 +1487,30 @@ struct ClipChainItem {
|
|||
const ActiveScrolledRoot* asr;
|
||||
};
|
||||
|
||||
static const DisplayItemClipChain* FindCommonAncestorClipForIntersection(
|
||||
const DisplayItemClipChain* aOne, const DisplayItemClipChain* aTwo) {
|
||||
for (const ActiveScrolledRoot* asr =
|
||||
ActiveScrolledRoot::PickDescendant(aOne->mASR, aTwo->mASR);
|
||||
asr; asr = asr->mParent) {
|
||||
if (aOne == aTwo) {
|
||||
return aOne;
|
||||
}
|
||||
if (aOne->mASR == asr) {
|
||||
aOne = aOne->mParent;
|
||||
}
|
||||
if (aTwo->mASR == asr) {
|
||||
aTwo = aTwo->mParent;
|
||||
}
|
||||
if (!aOne) {
|
||||
return aTwo;
|
||||
}
|
||||
if (!aTwo) {
|
||||
return aOne;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const DisplayItemClipChain* nsDisplayListBuilder::CreateClipChainIntersection(
|
||||
const DisplayItemClipChain* aAncestor,
|
||||
const DisplayItemClipChain* aLeafClip1,
|
||||
|
@ -1535,6 +1559,21 @@ const DisplayItemClipChain* nsDisplayListBuilder::CreateClipChainIntersection(
|
|||
return parentSC;
|
||||
}
|
||||
|
||||
const DisplayItemClipChain* nsDisplayListBuilder::CreateClipChainIntersection(
|
||||
const DisplayItemClipChain* aLeafClip1,
|
||||
const DisplayItemClipChain* aLeafClip2) {
|
||||
// aLeafClip2 might be a reference to a clip on the stack. We need to make
|
||||
// sure that CreateClipChainIntersection will allocate the actual intersected
|
||||
// clip in the builder's arena, so for the aLeafClip1 == nullptr case,
|
||||
// we supply nullptr as the common ancestor so that
|
||||
// CreateClipChainIntersection clones the whole chain.
|
||||
const DisplayItemClipChain* ancestorClip =
|
||||
aLeafClip1 ? FindCommonAncestorClipForIntersection(aLeafClip1, aLeafClip2)
|
||||
: nullptr;
|
||||
|
||||
return CreateClipChainIntersection(ancestorClip, aLeafClip1, aLeafClip2);
|
||||
}
|
||||
|
||||
const DisplayItemClipChain* nsDisplayListBuilder::CopyWholeChain(
|
||||
const DisplayItemClipChain* aClipChain) {
|
||||
return CreateClipChainIntersection(nullptr, aClipChain, nullptr);
|
||||
|
@ -2821,30 +2860,6 @@ void nsDisplayItem::FuseClipChainUpTo(nsDisplayListBuilder* aBuilder,
|
|||
}
|
||||
}
|
||||
|
||||
static const DisplayItemClipChain* FindCommonAncestorClipForIntersection(
|
||||
const DisplayItemClipChain* aOne, const DisplayItemClipChain* aTwo) {
|
||||
for (const ActiveScrolledRoot* asr =
|
||||
ActiveScrolledRoot::PickDescendant(aOne->mASR, aTwo->mASR);
|
||||
asr; asr = asr->mParent) {
|
||||
if (aOne == aTwo) {
|
||||
return aOne;
|
||||
}
|
||||
if (aOne->mASR == asr) {
|
||||
aOne = aOne->mParent;
|
||||
}
|
||||
if (aTwo->mASR == asr) {
|
||||
aTwo = aTwo->mParent;
|
||||
}
|
||||
if (!aOne) {
|
||||
return aTwo;
|
||||
}
|
||||
if (!aTwo) {
|
||||
return aOne;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void nsDisplayItem::IntersectClip(nsDisplayListBuilder* aBuilder,
|
||||
const DisplayItemClipChain* aOther,
|
||||
bool aStore) {
|
||||
|
@ -3099,9 +3114,7 @@ nsDisplayBackgroundImage::nsDisplayBackgroundImage(
|
|||
mDestRect(aInitData.destArea),
|
||||
mLayer(aInitData.layer),
|
||||
mIsRasterImage(aInitData.isRasterImage),
|
||||
mShouldFixToViewport(aInitData.shouldFixToViewport),
|
||||
mImageFlags(0),
|
||||
mOpacity(1.0f) {
|
||||
mShouldFixToViewport(aInitData.shouldFixToViewport) {
|
||||
MOZ_COUNT_CTOR(nsDisplayBackgroundImage);
|
||||
#ifdef DEBUG
|
||||
if (mBackgroundStyle && mBackgroundStyle != mFrame->Style()) {
|
||||
|
@ -3588,16 +3601,13 @@ static void CheckForBorderItem(nsDisplayItem* aItem, uint32_t& aFlags) {
|
|||
}
|
||||
|
||||
bool nsDisplayBackgroundImage::CanBuildWebRenderDisplayItems(
|
||||
WebRenderLayerManager* aManager, nsDisplayListBuilder* aBuilder) {
|
||||
if (aBuilder) {
|
||||
mImageFlags = aBuilder->GetBackgroundPaintFlags();
|
||||
}
|
||||
|
||||
WebRenderLayerManager* aManager, nsDisplayListBuilder* aBuilder) const {
|
||||
return mBackgroundStyle->StyleBackground()->mImage.mLayers[mLayer].mClip !=
|
||||
StyleGeometryBox::Text &&
|
||||
nsCSSRendering::CanBuildWebRenderDisplayItemsForStyleImageLayer(
|
||||
aManager, *StyleFrame()->PresContext(), StyleFrame(),
|
||||
mBackgroundStyle->StyleBackground(), mLayer, mImageFlags);
|
||||
mBackgroundStyle->StyleBackground(), mLayer,
|
||||
aBuilder->GetBackgroundPaintFlags());
|
||||
}
|
||||
|
||||
bool nsDisplayBackgroundImage::CreateWebRenderCommands(
|
||||
|
@ -3609,11 +3619,14 @@ bool nsDisplayBackgroundImage::CreateWebRenderCommands(
|
|||
return false;
|
||||
}
|
||||
|
||||
CheckForBorderItem(this, mImageFlags);
|
||||
uint32_t paintFlags = aDisplayListBuilder->GetBackgroundPaintFlags();
|
||||
|
||||
CheckForBorderItem(this, paintFlags);
|
||||
nsCSSRendering::PaintBGParams params =
|
||||
nsCSSRendering::PaintBGParams::ForSingleLayer(
|
||||
*StyleFrame()->PresContext(), GetPaintRect(), mBackgroundRect,
|
||||
StyleFrame(), mImageFlags, mLayer, CompositionOp::OP_OVER, mOpacity);
|
||||
StyleFrame(), paintFlags, mLayer, CompositionOp::OP_OVER,
|
||||
aBuilder.GetInheritedOpacity());
|
||||
params.bgClipRect = &mBounds;
|
||||
ImgDrawResult result =
|
||||
nsCSSRendering::BuildWebRenderDisplayItemsForStyleImageLayer(
|
||||
|
@ -3666,7 +3679,7 @@ nsRegion nsDisplayBackgroundImage::GetOpaqueRegion(
|
|||
nsRegion result;
|
||||
*aSnap = false;
|
||||
|
||||
if (!mBackgroundStyle || mOpacity != 1.0f) {
|
||||
if (!mBackgroundStyle) {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -3755,7 +3768,8 @@ void nsDisplayBackgroundImage::PaintInternal(nsDisplayListBuilder* aBuilder,
|
|||
nsCSSRendering::PaintBGParams params =
|
||||
nsCSSRendering::PaintBGParams::ForSingleLayer(
|
||||
*StyleFrame()->PresContext(), aBounds, mBackgroundRect, StyleFrame(),
|
||||
mImageFlags, mLayer, CompositionOp::OP_OVER, mOpacity);
|
||||
aBuilder->GetBackgroundPaintFlags(), mLayer, CompositionOp::OP_OVER,
|
||||
1.0f);
|
||||
params.bgClipRect = aClipRect;
|
||||
ImgDrawResult result = nsCSSRendering::PaintStyleImageLayer(params, *aCtx);
|
||||
|
||||
|
@ -4012,15 +4026,8 @@ void nsDisplayReflowCount::Paint(nsDisplayListBuilder* aBuilder,
|
|||
}
|
||||
#endif
|
||||
|
||||
void nsDisplayBackgroundColor::ApplyOpacity(nsDisplayListBuilder* aBuilder,
|
||||
float aOpacity,
|
||||
const DisplayItemClipChain* aClip) {
|
||||
NS_ASSERTION(CanApplyOpacity(), "ApplyOpacity should be allowed");
|
||||
mColor.a = mColor.a * aOpacity;
|
||||
IntersectClip(aBuilder, aClip, false);
|
||||
}
|
||||
|
||||
bool nsDisplayBackgroundColor::CanApplyOpacity() const {
|
||||
bool nsDisplayBackgroundColor::CanApplyOpacity(
|
||||
WebRenderLayerManager* aManager, nsDisplayListBuilder* aBuilder) const {
|
||||
// Don't apply opacity if the background color is animated since the color is
|
||||
// going to be changed on the compositor.
|
||||
return !EffectCompositor::HasAnimationsForCompositor(
|
||||
|
@ -4031,7 +4038,10 @@ bool nsDisplayBackgroundColor::CreateWebRenderCommands(
|
|||
wr::DisplayListBuilder& aBuilder, wr::IpcResourceUpdateQueue& aResources,
|
||||
const StackingContextHelper& aSc, RenderRootStateManager* aManager,
|
||||
nsDisplayListBuilder* aDisplayListBuilder) {
|
||||
if (mColor == sRGBColor() &&
|
||||
gfx::sRGBColor color = mColor;
|
||||
color.a *= aBuilder.GetInheritedOpacity();
|
||||
|
||||
if (color == sRGBColor() &&
|
||||
!EffectCompositor::HasAnimationsForCompositor(
|
||||
mFrame, DisplayItemType::TYPE_BACKGROUND_COLOR)) {
|
||||
return true;
|
||||
|
@ -4058,11 +4068,11 @@ bool nsDisplayBackgroundColor::CreateWebRenderCommands(
|
|||
animationsId,
|
||||
};
|
||||
aBuilder.PushRectWithAnimation(r, r, !BackfaceIsHidden(),
|
||||
wr::ToColorF(ToDeviceColor(mColor)), &prop);
|
||||
wr::ToColorF(ToDeviceColor(color)), &prop);
|
||||
} else {
|
||||
aBuilder.StartGroup(this);
|
||||
aBuilder.PushRect(r, r, !BackfaceIsHidden(),
|
||||
wr::ToColorF(ToDeviceColor(mColor)));
|
||||
wr::ToColorF(ToDeviceColor(color)));
|
||||
aBuilder.FinishGroup();
|
||||
}
|
||||
|
||||
|
@ -4492,7 +4502,7 @@ void nsDisplayBoxShadowOuter::Paint(nsDisplayListBuilder* aBuilder,
|
|||
AUTO_PROFILER_LABEL("nsDisplayBoxShadowOuter::Paint", GRAPHICS);
|
||||
|
||||
nsCSSRendering::PaintBoxShadowOuter(presContext, *aCtx, mFrame, borderRect,
|
||||
GetPaintRect(aBuilder, aCtx), mOpacity);
|
||||
GetPaintRect(aBuilder, aCtx), 1.0f);
|
||||
}
|
||||
|
||||
nsRect nsDisplayBoxShadowOuter::GetBounds(nsDisplayListBuilder* aBuilder,
|
||||
|
@ -4524,7 +4534,7 @@ bool nsDisplayBoxShadowOuter::IsInvisibleInRect(const nsRect& aRect) const {
|
|||
return RoundedRectContainsRect(frameRect, twipsRadii, aRect);
|
||||
}
|
||||
|
||||
bool nsDisplayBoxShadowOuter::CanBuildWebRenderDisplayItems() {
|
||||
bool nsDisplayBoxShadowOuter::CanBuildWebRenderDisplayItems() const {
|
||||
auto shadows = mFrame->StyleEffects()->mBoxShadow.AsSpan();
|
||||
if (shadows.IsEmpty()) {
|
||||
return false;
|
||||
|
@ -4583,8 +4593,8 @@ bool nsDisplayBoxShadowOuter::CreateWebRenderCommands(
|
|||
|
||||
float blurRadius =
|
||||
float(shadow.base.blur.ToAppUnits()) / float(appUnitsPerDevPixel);
|
||||
gfx::sRGBColor shadowColor =
|
||||
nsCSSRendering::GetShadowColor(shadow.base, mFrame, mOpacity);
|
||||
gfx::sRGBColor shadowColor = nsCSSRendering::GetShadowColor(
|
||||
shadow.base, mFrame, aBuilder.GetInheritedOpacity());
|
||||
|
||||
// We don't move the shadow rect here since WR does it for us
|
||||
// Now translate everything to device pixels.
|
||||
|
@ -4627,11 +4637,10 @@ void nsDisplayBoxShadowOuter::ComputeInvalidationRegion(
|
|||
nsDisplayListBuilder* aBuilder, const nsDisplayItemGeometry* aGeometry,
|
||||
nsRegion* aInvalidRegion) const {
|
||||
const auto* geometry =
|
||||
static_cast<const nsDisplayBoxShadowOuterGeometry*>(aGeometry);
|
||||
static_cast<const nsDisplayItemGenericGeometry*>(aGeometry);
|
||||
bool snap;
|
||||
if (!geometry->mBounds.IsEqualInterior(GetBounds(aBuilder, &snap)) ||
|
||||
!geometry->mBorderRect.IsEqualInterior(GetBorderRect()) ||
|
||||
mOpacity != geometry->mOpacity) {
|
||||
!geometry->mBorderRect.IsEqualInterior(GetBorderRect())) {
|
||||
nsRegion oldShadow, newShadow;
|
||||
nscoord dontCare[8];
|
||||
bool hasBorderRadius = mFrame->GetBorderRadii(dontCare);
|
||||
|
@ -4970,7 +4979,6 @@ nsDisplayOpacity::nsDisplayOpacity(
|
|||
mNeedsActiveLayer(aNeedsActiveLayer),
|
||||
mChildOpacityState(ChildOpacityState::Unknown) {
|
||||
MOZ_COUNT_CTOR(nsDisplayOpacity);
|
||||
mState.mOpacity = mOpacity;
|
||||
}
|
||||
|
||||
void nsDisplayOpacity::HitTest(nsDisplayListBuilder* aBuilder,
|
||||
|
@ -5041,15 +5049,8 @@ bool nsDisplayOpacity::NeedsActiveLayer(nsDisplayListBuilder* aBuilder,
|
|||
!(aEnforceMinimumSize && IsItemTooSmallForActiveLayer(aFrame)));
|
||||
}
|
||||
|
||||
void nsDisplayOpacity::ApplyOpacity(nsDisplayListBuilder* aBuilder,
|
||||
float aOpacity,
|
||||
const DisplayItemClipChain* aClip) {
|
||||
NS_ASSERTION(CanApplyOpacity(), "ApplyOpacity should be allowed");
|
||||
mOpacity = mOpacity * aOpacity;
|
||||
IntersectClip(aBuilder, aClip, false);
|
||||
}
|
||||
|
||||
bool nsDisplayOpacity::CanApplyOpacity() const {
|
||||
bool nsDisplayOpacity::CanApplyOpacity(WebRenderLayerManager* aManager,
|
||||
nsDisplayListBuilder* aBuilder) const {
|
||||
return !EffectCompositor::HasAnimationsForCompositor(
|
||||
mFrame, DisplayItemType::TYPE_OPACITY);
|
||||
}
|
||||
|
@ -5076,7 +5077,9 @@ static const size_t kOpacityMaxListSize = kOpacityMaxChildCount * 2;
|
|||
* item that returns false for CanApplyOpacity() is encountered.
|
||||
* Otherwise returns true.
|
||||
*/
|
||||
static bool CollectItemsWithOpacity(nsDisplayList* aList,
|
||||
static bool CollectItemsWithOpacity(WebRenderLayerManager* aManager,
|
||||
nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayList* aList,
|
||||
nsTArray<nsPaintedDisplayItem*>& aArray) {
|
||||
if (aList->Count() > kOpacityMaxListSize) {
|
||||
// Exit early, since |aList| will likely contain more than
|
||||
|
@ -5095,7 +5098,8 @@ static bool CollectItemsWithOpacity(nsDisplayList* aList,
|
|||
if (type == DisplayItemType::TYPE_WRAP_LIST ||
|
||||
type == DisplayItemType::TYPE_CONTAINER) {
|
||||
// The current display item has children, process them first.
|
||||
if (!CollectItemsWithOpacity(i->GetChildren(), aArray)) {
|
||||
if (!CollectItemsWithOpacity(aManager, aBuilder, i->GetChildren(),
|
||||
aArray)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -5107,7 +5111,7 @@ static bool CollectItemsWithOpacity(nsDisplayList* aList,
|
|||
}
|
||||
|
||||
auto* item = i->AsPaintedDisplayItem();
|
||||
if (!item || !item->CanApplyOpacity()) {
|
||||
if (!item || !item->CanApplyOpacity(aManager, aBuilder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -5117,7 +5121,8 @@ static bool CollectItemsWithOpacity(nsDisplayList* aList,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool nsDisplayOpacity::ApplyToChildren(nsDisplayListBuilder* aBuilder) {
|
||||
bool nsDisplayOpacity::CanApplyToChildren(WebRenderLayerManager* aManager,
|
||||
nsDisplayListBuilder* aBuilder) {
|
||||
if (mChildOpacityState == ChildOpacityState::Deferred) {
|
||||
return false;
|
||||
}
|
||||
|
@ -5125,7 +5130,7 @@ bool nsDisplayOpacity::ApplyToChildren(nsDisplayListBuilder* aBuilder) {
|
|||
// Iterate through the child display list and copy at most
|
||||
// |kOpacityMaxChildCount| child display item pointers to a temporary list.
|
||||
AutoTArray<nsPaintedDisplayItem*, kOpacityMaxChildCount> items;
|
||||
if (!CollectItemsWithOpacity(&mList, items)) {
|
||||
if (!CollectItemsWithOpacity(aManager, aBuilder, &mList, items)) {
|
||||
mChildOpacityState = ChildOpacityState::Deferred;
|
||||
return false;
|
||||
}
|
||||
|
@ -5152,10 +5157,6 @@ bool nsDisplayOpacity::ApplyToChildren(nsDisplayListBuilder* aBuilder) {
|
|||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < childCount; i++) {
|
||||
children[i].item->ApplyOpacity(aBuilder, mOpacity, mClipChain);
|
||||
}
|
||||
|
||||
mChildOpacityState = ChildOpacityState::Applied;
|
||||
return true;
|
||||
}
|
||||
|
@ -5165,7 +5166,7 @@ bool nsDisplayOpacity::ApplyToChildren(nsDisplayListBuilder* aBuilder) {
|
|||
* that has the same frame as the opacity item, and that supports painting with
|
||||
* opacity. In this case the opacity item can be optimized away.
|
||||
*/
|
||||
bool nsDisplayOpacity::ApplyToFilterOrMask(const bool aUsingLayers) {
|
||||
bool nsDisplayOpacity::ApplyToMask() {
|
||||
if (mList.Count() != 1) {
|
||||
return false;
|
||||
}
|
||||
|
@ -5177,17 +5178,16 @@ bool nsDisplayOpacity::ApplyToFilterOrMask(const bool aUsingLayers) {
|
|||
}
|
||||
|
||||
const DisplayItemType type = item->GetType();
|
||||
if (type == DisplayItemType::TYPE_MASK ||
|
||||
type == DisplayItemType::TYPE_FILTER) {
|
||||
auto* filterOrMaskItem = static_cast<nsDisplayEffectsBase*>(item);
|
||||
filterOrMaskItem->SelectOpacityOptimization(aUsingLayers);
|
||||
if (type == DisplayItemType::TYPE_MASK) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool nsDisplayOpacity::ShouldFlattenAway(nsDisplayListBuilder* aBuilder) {
|
||||
bool nsDisplayOpacity::CanApplyOpacityToChildren(
|
||||
WebRenderLayerManager* aManager, nsDisplayListBuilder* aBuilder,
|
||||
float aInheritedOpacity) {
|
||||
if (mFrame->GetPrevContinuation() || mFrame->GetNextContinuation() ||
|
||||
mFrame->HasAnyStateBits(NS_FRAME_PART_OF_IBSPLIT)) {
|
||||
// If we've been split, then we might need to merge, so
|
||||
|
@ -5207,16 +5207,17 @@ bool nsDisplayOpacity::ShouldFlattenAway(nsDisplayListBuilder* aBuilder) {
|
|||
return false;
|
||||
}
|
||||
|
||||
const bool usingLayers = !aBuilder->IsPaintingForWebRender();
|
||||
|
||||
if (ApplyToFilterOrMask(usingLayers)) {
|
||||
// We can only flatten opacity items into a mask if we haven't
|
||||
// already flattened an earlier ancestor, since the SVG code pulls the opacity
|
||||
// from style directly, and won't know about the outer opacity value.
|
||||
if (aInheritedOpacity == 1.0f && ApplyToMask()) {
|
||||
MOZ_ASSERT(SVGIntegrationUtils::UsingEffectsForFrame(mFrame));
|
||||
mChildOpacityState = ChildOpacityState::Applied;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Return true if we successfully applied opacity to child items.
|
||||
return ApplyToChildren(aBuilder);
|
||||
return CanApplyToChildren(aManager, aBuilder);
|
||||
}
|
||||
|
||||
void nsDisplayOpacity::ComputeInvalidationRegion(
|
||||
|
@ -5254,8 +5255,35 @@ bool nsDisplayOpacity::CreateWebRenderCommands(
|
|||
wr::DisplayListBuilder& aBuilder, wr::IpcResourceUpdateQueue& aResources,
|
||||
const StackingContextHelper& aSc, RenderRootStateManager* aManager,
|
||||
nsDisplayListBuilder* aDisplayListBuilder) {
|
||||
// If this is a new (not retained/reused) item, then we need to disable
|
||||
// the display item cache for descendants, since it's possible that some of
|
||||
// them got cached with a flattened opacity values., which may no longer be
|
||||
// applied.
|
||||
Maybe<AutoDisplayItemCacheSuppressor> cacheSuppressor;
|
||||
if (!IsReused()) {
|
||||
cacheSuppressor.emplace(aBuilder.GetDisplayItemCache());
|
||||
}
|
||||
|
||||
if (CanApplyOpacityToChildren(aManager->LayerManager(), aDisplayListBuilder,
|
||||
aBuilder.GetInheritedOpacity())) {
|
||||
// If all our children support handling the opacity directly, then push
|
||||
// the opacity and clip onto the builder and skip creating a stacking
|
||||
// context.
|
||||
float oldOpacity = aBuilder.GetInheritedOpacity();
|
||||
aBuilder.SetInheritedOpacity(oldOpacity * mOpacity);
|
||||
|
||||
aManager->CommandBuilder().CreateWebRenderCommandsFromDisplayList(
|
||||
&mList, this, aDisplayListBuilder, aSc, aBuilder, aResources);
|
||||
|
||||
aBuilder.SetInheritedOpacity(oldOpacity);
|
||||
return true;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mChildOpacityState != ChildOpacityState::Applied);
|
||||
float* opacityForSC = &mOpacity;
|
||||
float oldOpacity = aBuilder.GetInheritedOpacity();
|
||||
aBuilder.SetInheritedOpacity(1.0f);
|
||||
float opacity = mOpacity * oldOpacity;
|
||||
float* opacityForSC = &opacity;
|
||||
|
||||
uint64_t animationsId =
|
||||
AddAnimationsForWebRender(this, aManager, aDisplayListBuilder);
|
||||
|
@ -5274,6 +5302,7 @@ bool nsDisplayOpacity::CreateWebRenderCommands(
|
|||
|
||||
aManager->CommandBuilder().CreateWebRenderCommandsFromDisplayList(
|
||||
&mList, this, aDisplayListBuilder, sc, aBuilder, aResources);
|
||||
aBuilder.SetInheritedOpacity(oldOpacity);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -7760,7 +7789,6 @@ bool nsDisplayPerspective::CreateWebRenderCommands(
|
|||
nsDisplayText::nsDisplayText(nsDisplayListBuilder* aBuilder,
|
||||
nsTextFrame* aFrame)
|
||||
: nsPaintedDisplayItem(aBuilder, aFrame),
|
||||
mOpacity(1.0f),
|
||||
mVisIStartEdge(0),
|
||||
mVisIEndEdge(0) {
|
||||
MOZ_COUNT_CTOR(nsDisplayText);
|
||||
|
@ -7769,7 +7797,8 @@ nsDisplayText::nsDisplayText(nsDisplayListBuilder* aBuilder,
|
|||
mBounds.Inflate(mFrame->PresContext()->AppUnitsPerDevPixel());
|
||||
}
|
||||
|
||||
bool nsDisplayText::CanApplyOpacity() const {
|
||||
bool nsDisplayText::CanApplyOpacity(WebRenderLayerManager* aManager,
|
||||
nsDisplayListBuilder* aBuilder) const {
|
||||
auto* f = static_cast<nsTextFrame*>(mFrame);
|
||||
|
||||
if (f->IsSelected()) {
|
||||
|
@ -7852,7 +7881,8 @@ bool nsDisplayText::CreateWebRenderCommands(
|
|||
|
||||
aBuilder.StartGroup(this);
|
||||
|
||||
RenderToContext(textDrawer, aDisplayListBuilder, true);
|
||||
RenderToContext(textDrawer, aDisplayListBuilder,
|
||||
aBuilder.GetInheritedOpacity(), true);
|
||||
const bool result = textDrawer->GetTextDrawer()->Finish();
|
||||
|
||||
if (result) {
|
||||
|
@ -7866,7 +7896,7 @@ bool nsDisplayText::CreateWebRenderCommands(
|
|||
|
||||
void nsDisplayText::RenderToContext(gfxContext* aCtx,
|
||||
nsDisplayListBuilder* aBuilder,
|
||||
bool aIsRecording) {
|
||||
float aOpacity, bool aIsRecording) {
|
||||
nsTextFrame* f = static_cast<nsTextFrame*>(mFrame);
|
||||
|
||||
// Add 1 pixel of dirty area around mVisibleRect to allow us to paint
|
||||
|
@ -7927,7 +7957,7 @@ void nsDisplayText::RenderToContext(gfxContext* aCtx,
|
|||
}
|
||||
|
||||
f->PaintText(params, mVisIStartEdge, mVisIEndEdge, ToReferenceFrame(),
|
||||
f->IsSelected(), mOpacity);
|
||||
f->IsSelected(), aOpacity);
|
||||
|
||||
if (willClip) {
|
||||
aCtx->PopClip();
|
||||
|
@ -7941,7 +7971,6 @@ class nsDisplayTextGeometry : public nsDisplayItemGenericGeometry {
|
|||
public:
|
||||
nsDisplayTextGeometry(nsDisplayText* aItem, nsDisplayListBuilder* aBuilder)
|
||||
: nsDisplayItemGenericGeometry(aItem, aBuilder),
|
||||
mOpacity(aItem->Opacity()),
|
||||
mVisIStartEdge(aItem->VisIStartEdge()),
|
||||
mVisIEndEdge(aItem->VisIEndEdge()) {
|
||||
nsTextFrame* f = static_cast<nsTextFrame*>(aItem->Frame());
|
||||
|
@ -7955,7 +7984,6 @@ class nsDisplayTextGeometry : public nsDisplayItemGenericGeometry {
|
|||
* styles will only invalidate the parent frame and not this frame.
|
||||
*/
|
||||
nsTextFrame::TextDecorations mDecorations;
|
||||
float mOpacity;
|
||||
nscoord mVisIStartEdge;
|
||||
nscoord mVisIEndEdge;
|
||||
};
|
||||
|
@ -7983,8 +8011,7 @@ void nsDisplayText::ComputeInvalidationRegion(
|
|||
mVisIStartEdge != geometry->mVisIStartEdge ||
|
||||
mVisIEndEdge != geometry->mVisIEndEdge ||
|
||||
!oldRect.IsEqualInterior(newRect) ||
|
||||
!geometry->mBorderRect.IsEqualInterior(GetBorderRect()) ||
|
||||
mOpacity != geometry->mOpacity) {
|
||||
!geometry->mBorderRect.IsEqualInterior(GetBorderRect())) {
|
||||
aInvalidRegion->Or(oldRect, newRect);
|
||||
}
|
||||
}
|
||||
|
@ -8006,15 +8033,14 @@ nsDisplayEffectsBase::nsDisplayEffectsBase(
|
|||
nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsDisplayList* aList,
|
||||
const ActiveScrolledRoot* aActiveScrolledRoot, bool aClearClipChain)
|
||||
: nsDisplayWrapList(aBuilder, aFrame, aList, aActiveScrolledRoot,
|
||||
aClearClipChain),
|
||||
mHandleOpacity(false) {
|
||||
aClearClipChain) {
|
||||
MOZ_COUNT_CTOR(nsDisplayEffectsBase);
|
||||
}
|
||||
|
||||
nsDisplayEffectsBase::nsDisplayEffectsBase(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aFrame,
|
||||
nsDisplayList* aList)
|
||||
: nsDisplayWrapList(aBuilder, aFrame, aList), mHandleOpacity(false) {
|
||||
: nsDisplayWrapList(aBuilder, aFrame, aList) {
|
||||
MOZ_COUNT_CTOR(nsDisplayEffectsBase);
|
||||
}
|
||||
|
||||
|
@ -8051,9 +8077,7 @@ void nsDisplayEffectsBase::ComputeInvalidationRegion(
|
|||
nsRect bounds = GetBounds(aBuilder, &snap);
|
||||
if (geometry->mFrameOffsetToReferenceFrame != ToReferenceFrame() ||
|
||||
geometry->mUserSpaceOffset != UserSpaceOffset() ||
|
||||
!geometry->mBBox.IsEqualInterior(BBoxInUserSpace()) ||
|
||||
geometry->mOpacity != mFrame->StyleEffects()->mOpacity ||
|
||||
geometry->mHandleOpacity != ShouldHandleOpacity()) {
|
||||
!geometry->mBBox.IsEqualInterior(BBoxInUserSpace())) {
|
||||
// Filter and mask output can depend on the location of the frame's user
|
||||
// space and on the frame's BBox. We need to invalidate if either of these
|
||||
// change relative to the reference frame.
|
||||
|
@ -8147,8 +8171,7 @@ static void ComputeMaskGeometry(PaintFramesParams& aParams) {
|
|||
nsDisplayMasksAndClipPaths::nsDisplayMasksAndClipPaths(
|
||||
nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsDisplayList* aList,
|
||||
const ActiveScrolledRoot* aActiveScrolledRoot)
|
||||
: nsDisplayEffectsBase(aBuilder, aFrame, aList, aActiveScrolledRoot, true),
|
||||
mApplyOpacityWithSimpleClipPath(false) {
|
||||
: nsDisplayEffectsBase(aBuilder, aFrame, aList, aActiveScrolledRoot, true) {
|
||||
MOZ_COUNT_CTOR(nsDisplayMasksAndClipPaths);
|
||||
|
||||
nsPresContext* presContext = mFrame->PresContext();
|
||||
|
@ -8205,10 +8228,6 @@ bool nsDisplayMasksAndClipPaths::IsValidMask() {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (mFrame->StyleEffects()->mOpacity == 0.0f && mHandleOpacity) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsIFrame* firstFrame =
|
||||
nsLayoutUtils::FirstContinuationOrIBSplitSibling(mFrame);
|
||||
|
||||
|
@ -8220,6 +8239,7 @@ bool nsDisplayMasksAndClipPaths::IsValidMask() {
|
|||
|
||||
bool nsDisplayMasksAndClipPaths::PaintMask(nsDisplayListBuilder* aBuilder,
|
||||
gfxContext* aMaskContext,
|
||||
bool aHandleOpacity,
|
||||
bool* aMaskPainted) {
|
||||
MOZ_ASSERT(aMaskContext->GetDrawTarget()->GetFormat() == SurfaceFormat::A8);
|
||||
|
||||
|
@ -8227,7 +8247,7 @@ bool nsDisplayMasksAndClipPaths::PaintMask(nsDisplayListBuilder* aBuilder,
|
|||
nsRect borderArea = nsRect(ToReferenceFrame(), mFrame->GetSize());
|
||||
SVGIntegrationUtils::PaintFramesParams params(*aMaskContext, mFrame, mBounds,
|
||||
borderArea, aBuilder, nullptr,
|
||||
mHandleOpacity, imgParams);
|
||||
aHandleOpacity, imgParams);
|
||||
ComputeMaskGeometry(params);
|
||||
bool maskIsComplete = false;
|
||||
bool painted = SVGIntegrationUtils::PaintMask(params, maskIsComplete);
|
||||
|
@ -8316,7 +8336,7 @@ void nsDisplayMasksAndClipPaths::PaintWithContentsPaintCallback(
|
|||
nsRect borderArea = nsRect(ToReferenceFrame(), mFrame->GetSize());
|
||||
SVGIntegrationUtils::PaintFramesParams params(*aCtx, mFrame, GetPaintRect(),
|
||||
borderArea, aBuilder, nullptr,
|
||||
mHandleOpacity, imgParams);
|
||||
false, imgParams);
|
||||
|
||||
ComputeMaskGeometry(params);
|
||||
|
||||
|
@ -8494,6 +8514,8 @@ bool nsDisplayMasksAndClipPaths::CreateWebRenderCommands(
|
|||
Maybe<wr::WrClipId> clip = CreateWRClipPathAndMasks(
|
||||
this, bounds, aResources, aBuilder, aSc, aManager, aDisplayListBuilder);
|
||||
|
||||
float oldOpacity = aBuilder.GetInheritedOpacity();
|
||||
|
||||
Maybe<StackingContextHelper> layer;
|
||||
const StackingContextHelper* sc = &aSc;
|
||||
if (clip) {
|
||||
|
@ -8503,9 +8525,11 @@ bool nsDisplayMasksAndClipPaths::CreateWebRenderCommands(
|
|||
// The stacking context shouldn't have any offset.
|
||||
bounds.MoveTo(0, 0);
|
||||
|
||||
Maybe<float> opacity = mApplyOpacityWithSimpleClipPath
|
||||
? Some(mFrame->StyleEffects()->mOpacity)
|
||||
: Nothing();
|
||||
Maybe<float> opacity =
|
||||
(SVGIntegrationUtils::UsingSimpleClipPathForFrame(mFrame) &&
|
||||
aBuilder.GetInheritedOpacity() != 1.0f)
|
||||
? Some(aBuilder.GetInheritedOpacity())
|
||||
: Nothing();
|
||||
|
||||
wr::StackingContextParams params;
|
||||
params.clip = wr::WrStackingContextClip::ClipId(*clip);
|
||||
|
@ -8515,25 +8539,14 @@ bool nsDisplayMasksAndClipPaths::CreateWebRenderCommands(
|
|||
sc = layer.ptr();
|
||||
}
|
||||
|
||||
aBuilder.SetInheritedOpacity(1.0f);
|
||||
nsDisplayEffectsBase::CreateWebRenderCommands(aBuilder, aResources, *sc,
|
||||
aManager, aDisplayListBuilder);
|
||||
aBuilder.SetInheritedOpacity(oldOpacity);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void nsDisplayMasksAndClipPaths::SelectOpacityOptimization(
|
||||
const bool aUsingLayers) {
|
||||
if (aUsingLayers ||
|
||||
!SVGIntegrationUtils::UsingSimpleClipPathForFrame(mFrame)) {
|
||||
// Handle opacity in mask and clip-path drawing code.
|
||||
SetHandleOpacity();
|
||||
MOZ_ASSERT(!mApplyOpacityWithSimpleClipPath);
|
||||
} else {
|
||||
// Allow WebRender simple clip paths to also handle opacity.
|
||||
mApplyOpacityWithSimpleClipPath = true;
|
||||
}
|
||||
}
|
||||
|
||||
Maybe<nsRect> nsDisplayMasksAndClipPaths::GetClipWithRespectToASR(
|
||||
nsDisplayListBuilder* aBuilder, const ActiveScrolledRoot* aASR) const {
|
||||
if (const DisplayItemClip* clip =
|
||||
|
@ -8559,10 +8572,6 @@ void nsDisplayMasksAndClipPaths::PrintEffects(nsACString& aTo) {
|
|||
nsLayoutUtils::FirstContinuationOrIBSplitSibling(mFrame);
|
||||
bool first = true;
|
||||
aTo += " effects=(";
|
||||
if (mHandleOpacity) {
|
||||
first = false;
|
||||
aTo += nsPrintfCString("opacity(%f)", mFrame->StyleEffects()->mOpacity);
|
||||
}
|
||||
SVGClipPathFrame* clipPathFrame;
|
||||
// XXX Check return value?
|
||||
SVGObserverUtils::GetAndObserveClipPath(firstFrame, &clipPathFrame);
|
||||
|
@ -8712,7 +8721,7 @@ void nsDisplayFilters::PaintWithContentsPaintCallback(
|
|||
nsRect borderArea = nsRect(ToReferenceFrame(), mFrame->GetSize());
|
||||
SVGIntegrationUtils::PaintFramesParams params(*aCtx, mFrame, GetPaintRect(),
|
||||
borderArea, aBuilder, nullptr,
|
||||
mHandleOpacity, imgParams);
|
||||
false, imgParams);
|
||||
|
||||
gfxPoint userSpaceToFrameSpaceOffset =
|
||||
SVGIntegrationUtils::GetOffsetToUserSpaceInDevPx(mFrame, params);
|
||||
|
@ -8729,7 +8738,7 @@ void nsDisplayFilters::PaintWithContentsPaintCallback(
|
|||
nsDisplayFiltersGeometry::UpdateDrawResult(this, imgParams.result);
|
||||
}
|
||||
|
||||
bool nsDisplayFilters::CanCreateWebRenderCommands() {
|
||||
bool nsDisplayFilters::CanCreateWebRenderCommands() const {
|
||||
return SVGIntegrationUtils::CanCreateWebRenderFiltersForFrame(mFrame);
|
||||
}
|
||||
|
||||
|
@ -8760,17 +8769,19 @@ bool nsDisplayFilters::CreateWebRenderCommands(
|
|||
clip = wr::WrStackingContextClip::ClipChain(aBuilder.CurrentClipChainId());
|
||||
}
|
||||
|
||||
float opacity = mFrame->StyleEffects()->mOpacity;
|
||||
float opacity = aBuilder.GetInheritedOpacity();
|
||||
aBuilder.SetInheritedOpacity(1.0f);
|
||||
wr::StackingContextParams params;
|
||||
params.mFilters = std::move(wrFilters.filters);
|
||||
params.mFilterDatas = std::move(wrFilters.filter_datas);
|
||||
params.opacity = opacity != 1.0f && mHandleOpacity ? &opacity : nullptr;
|
||||
params.opacity = opacity != 1.0f ? &opacity : nullptr;
|
||||
params.clip = clip;
|
||||
StackingContextHelper sc(aSc, GetActiveScrolledRoot(), mFrame, this, aBuilder,
|
||||
params);
|
||||
|
||||
nsDisplayEffectsBase::CreateWebRenderCommands(aBuilder, aResources, sc,
|
||||
aManager, aDisplayListBuilder);
|
||||
aBuilder.SetInheritedOpacity(opacity);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -8781,10 +8792,6 @@ void nsDisplayFilters::PrintEffects(nsACString& aTo) {
|
|||
nsLayoutUtils::FirstContinuationOrIBSplitSibling(mFrame);
|
||||
bool first = true;
|
||||
aTo += " effects=(";
|
||||
if (mHandleOpacity) {
|
||||
first = false;
|
||||
aTo += nsPrintfCString("opacity(%f)", mFrame->StyleEffects()->mOpacity);
|
||||
}
|
||||
// We may exist for a mix of CSS filter functions and/or references to SVG
|
||||
// filters. If we have invalid references to SVG filters then we paint
|
||||
// nothing, but otherwise we will apply one or more filters.
|
||||
|
|
|
@ -1031,6 +1031,13 @@ class nsDisplayListBuilder {
|
|||
const DisplayItemClipChain* aAncestor,
|
||||
const DisplayItemClipChain* aLeafClip1,
|
||||
const DisplayItemClipChain* aLeafClip2);
|
||||
/**
|
||||
* Same as above, except aAncestor is computed as the nearest common
|
||||
* ancestor of the two provided clips.
|
||||
*/
|
||||
const DisplayItemClipChain* CreateClipChainIntersection(
|
||||
const DisplayItemClipChain* aLeafClip1,
|
||||
const DisplayItemClipChain* aLeafClip2);
|
||||
|
||||
/**
|
||||
* Clone the supplied clip chain's chain items into this builder's arena.
|
||||
|
@ -2182,6 +2189,7 @@ class nsDisplayItem : public nsDisplayItemLink {
|
|||
public:
|
||||
using Layer = layers::Layer;
|
||||
using LayerManager = layers::LayerManager;
|
||||
using WebRenderLayerManager = layers::WebRenderLayerManager;
|
||||
using StackingContextHelper = layers::StackingContextHelper;
|
||||
using ViewID = layers::ScrollableLayerGuid::ViewID;
|
||||
|
||||
|
@ -3035,20 +3043,14 @@ class nsPaintedDisplayItem : public nsDisplayItem {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the given opacity value to be applied when drawing. It is an error
|
||||
* to call this if CanApplyOpacity returned false.
|
||||
*/
|
||||
virtual void ApplyOpacity(nsDisplayListBuilder* aBuilder, float aOpacity,
|
||||
const DisplayItemClipChain* aClip) {
|
||||
MOZ_ASSERT(CanApplyOpacity(), "ApplyOpacity is not supported on this type");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this display item would return true from ApplyOpacity
|
||||
* without actually applying the opacity. Otherwise returns false.
|
||||
*/
|
||||
virtual bool CanApplyOpacity() const { return false; }
|
||||
virtual bool CanApplyOpacity(WebRenderLayerManager* aManager,
|
||||
nsDisplayListBuilder* aBuilder) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this item supports PaintWithClip, where the clipping
|
||||
|
@ -4234,13 +4236,6 @@ class nsDisplayBackgroundImage : public nsPaintedDisplayItem {
|
|||
nsIFrame* aFrameForBounds = nullptr);
|
||||
~nsDisplayBackgroundImage() override;
|
||||
|
||||
bool RestoreState() override {
|
||||
bool superChanged = nsPaintedDisplayItem::RestoreState();
|
||||
bool opacityChanged = (mOpacity != 1.0f);
|
||||
mOpacity = 1.0f;
|
||||
return (superChanged || opacityChanged);
|
||||
}
|
||||
|
||||
NS_DISPLAY_DECL_NAME("Background", TYPE_BACKGROUND)
|
||||
|
||||
/**
|
||||
|
@ -4271,11 +4266,9 @@ class nsDisplayBackgroundImage : public nsPaintedDisplayItem {
|
|||
bool* aSnap) const override;
|
||||
Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) const override;
|
||||
|
||||
bool CanApplyOpacity() const override { return true; }
|
||||
|
||||
void ApplyOpacity(nsDisplayListBuilder* aBuilder, float aOpacity,
|
||||
const DisplayItemClipChain* aClip) override {
|
||||
mOpacity = aOpacity;
|
||||
bool CanApplyOpacity(WebRenderLayerManager* aManager,
|
||||
nsDisplayListBuilder* aBuilder) const override {
|
||||
return CanBuildWebRenderDisplayItems(aManager, aBuilder);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4344,7 +4337,7 @@ class nsDisplayBackgroundImage : public nsPaintedDisplayItem {
|
|||
|
||||
protected:
|
||||
bool CanBuildWebRenderDisplayItems(layers::WebRenderLayerManager* aManager,
|
||||
nsDisplayListBuilder* aBuilder);
|
||||
nsDisplayListBuilder* aBuilder) const;
|
||||
nsRect GetBoundsInternal(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aFrameForBounds = nullptr);
|
||||
|
||||
|
@ -4365,8 +4358,6 @@ class nsDisplayBackgroundImage : public nsPaintedDisplayItem {
|
|||
bool mIsRasterImage;
|
||||
/* Whether the image should be treated as fixed to the viewport. */
|
||||
bool mShouldFixToViewport;
|
||||
uint32_t mImageFlags;
|
||||
float mOpacity;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -4531,8 +4522,6 @@ class nsDisplayBackgroundColor : public nsPaintedDisplayItem {
|
|||
mHasStyle(aBackgroundStyle),
|
||||
mDependentFrame(nullptr),
|
||||
mColor(gfx::sRGBColor::FromABGR(aColor)) {
|
||||
mState.mColor = mColor;
|
||||
|
||||
if (mHasStyle) {
|
||||
mBottomLayerClip =
|
||||
aBackgroundStyle->StyleBackground()->BottomLayer().mClip;
|
||||
|
@ -4549,15 +4538,6 @@ class nsDisplayBackgroundColor : public nsPaintedDisplayItem {
|
|||
|
||||
NS_DISPLAY_DECL_NAME("BackgroundColor", TYPE_BACKGROUND_COLOR)
|
||||
|
||||
bool RestoreState() override {
|
||||
if (!nsPaintedDisplayItem::RestoreState() && mColor == mState.mColor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mColor = mState.mColor;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HasBackgroundClipText() const {
|
||||
MOZ_ASSERT(mHasStyle);
|
||||
return mBottomLayerClip == StyleGeometryBox::Text;
|
||||
|
@ -4576,10 +4556,8 @@ class nsDisplayBackgroundColor : public nsPaintedDisplayItem {
|
|||
Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) const override;
|
||||
void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
HitTestState* aState, nsTArray<nsIFrame*>* aOutFrames) override;
|
||||
void ApplyOpacity(nsDisplayListBuilder* aBuilder, float aOpacity,
|
||||
const DisplayItemClipChain* aClip) override;
|
||||
|
||||
bool CanApplyOpacity() const override;
|
||||
bool CanApplyOpacity(WebRenderLayerManager* aManager,
|
||||
nsDisplayListBuilder* aBuilder) const override;
|
||||
|
||||
float GetOpacity() const { return mColor.a; }
|
||||
|
||||
|
@ -4649,10 +4627,6 @@ class nsDisplayBackgroundColor : public nsPaintedDisplayItem {
|
|||
StyleGeometryBox mBottomLayerClip;
|
||||
nsIFrame* mDependentFrame;
|
||||
gfx::sRGBColor mColor;
|
||||
|
||||
struct {
|
||||
gfx::sRGBColor mColor;
|
||||
} mState;
|
||||
};
|
||||
|
||||
class nsDisplayTableBackgroundColor : public nsDisplayBackgroundColor {
|
||||
|
@ -4701,7 +4675,7 @@ class nsDisplayTableBackgroundColor : public nsDisplayBackgroundColor {
|
|||
class nsDisplayBoxShadowOuter final : public nsPaintedDisplayItem {
|
||||
public:
|
||||
nsDisplayBoxShadowOuter(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
|
||||
: nsPaintedDisplayItem(aBuilder, aFrame), mOpacity(1.0f) {
|
||||
: nsPaintedDisplayItem(aBuilder, aFrame) {
|
||||
MOZ_COUNT_CTOR(nsDisplayBoxShadowOuter);
|
||||
mBounds = GetBoundsInternal();
|
||||
}
|
||||
|
@ -4710,15 +4684,6 @@ class nsDisplayBoxShadowOuter final : public nsPaintedDisplayItem {
|
|||
|
||||
NS_DISPLAY_DECL_NAME("BoxShadowOuter", TYPE_BOX_SHADOW_OUTER)
|
||||
|
||||
bool RestoreState() override {
|
||||
if (!nsPaintedDisplayItem::RestoreState() && mOpacity == 1.0f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mOpacity = 1.0f;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override;
|
||||
nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const override;
|
||||
bool IsInvisibleInRect(const nsRect& aRect) const override;
|
||||
|
@ -4726,21 +4691,12 @@ class nsDisplayBoxShadowOuter final : public nsPaintedDisplayItem {
|
|||
const nsDisplayItemGeometry* aGeometry,
|
||||
nsRegion* aInvalidRegion) const override;
|
||||
|
||||
void ApplyOpacity(nsDisplayListBuilder* aBuilder, float aOpacity,
|
||||
const DisplayItemClipChain* aClip) override {
|
||||
NS_ASSERTION(CanApplyOpacity(), "ApplyOpacity should be allowed");
|
||||
mOpacity = aOpacity;
|
||||
IntersectClip(aBuilder, aClip, false);
|
||||
bool CanApplyOpacity(WebRenderLayerManager* aManager,
|
||||
nsDisplayListBuilder* aBuilder) const override {
|
||||
return CanBuildWebRenderDisplayItems();
|
||||
}
|
||||
|
||||
bool CanApplyOpacity() const override { return true; }
|
||||
|
||||
nsDisplayItemGeometry* AllocateGeometry(
|
||||
nsDisplayListBuilder* aBuilder) override {
|
||||
return new nsDisplayBoxShadowOuterGeometry(this, aBuilder, mOpacity);
|
||||
}
|
||||
|
||||
bool CanBuildWebRenderDisplayItems();
|
||||
bool CanBuildWebRenderDisplayItems() const;
|
||||
bool CreateWebRenderCommands(
|
||||
wr::DisplayListBuilder& aBuilder, wr::IpcResourceUpdateQueue& aResources,
|
||||
const StackingContextHelper& aSc,
|
||||
|
@ -4750,7 +4706,6 @@ class nsDisplayBoxShadowOuter final : public nsPaintedDisplayItem {
|
|||
|
||||
private:
|
||||
nsRect mBounds;
|
||||
float mOpacity;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -5222,15 +5177,6 @@ class nsDisplayOpacity : public nsDisplayWrapList {
|
|||
|
||||
NS_DISPLAY_DECL_NAME("Opacity", TYPE_OPACITY)
|
||||
|
||||
bool RestoreState() override {
|
||||
if (!nsDisplayWrapList::RestoreState() && mOpacity == mState.mOpacity) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mOpacity = mState.mOpacity;
|
||||
return true;
|
||||
}
|
||||
|
||||
void InvalidateCachedChildInfo(nsDisplayListBuilder* aBuilder) override {
|
||||
mChildOpacityState = ChildOpacityState::Unknown;
|
||||
}
|
||||
|
@ -5263,10 +5209,15 @@ class nsDisplayOpacity : public nsDisplayWrapList {
|
|||
}
|
||||
return nsDisplayWrapList::IsInvalid(aRect);
|
||||
}
|
||||
void ApplyOpacity(nsDisplayListBuilder* aBuilder, float aOpacity,
|
||||
const DisplayItemClipChain* aClip) override;
|
||||
bool CanApplyOpacity() const override;
|
||||
bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override;
|
||||
bool CanApplyOpacity(WebRenderLayerManager* aManager,
|
||||
nsDisplayListBuilder* aBuilder) const override;
|
||||
bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CanApplyOpacityToChildren(WebRenderLayerManager* aManager,
|
||||
nsDisplayListBuilder* aBuilder,
|
||||
float aInheritedOpacity);
|
||||
|
||||
bool NeedsGeometryUpdates() const override {
|
||||
// For flattened nsDisplayOpacity items, ComputeInvalidationRegion() only
|
||||
|
@ -5301,8 +5252,9 @@ class nsDisplayOpacity : public nsDisplayWrapList {
|
|||
private:
|
||||
NS_DISPLAY_ALLOW_CLONING()
|
||||
|
||||
bool ApplyToChildren(nsDisplayListBuilder* aBuilder);
|
||||
bool ApplyToFilterOrMask(const bool aUsingLayers);
|
||||
bool CanApplyToChildren(WebRenderLayerManager* aManager,
|
||||
nsDisplayListBuilder* aBuilder);
|
||||
bool ApplyToMask();
|
||||
|
||||
float mOpacity;
|
||||
bool mForEventsOnly : 1;
|
||||
|
@ -5321,10 +5273,6 @@ class nsDisplayOpacity : public nsDisplayWrapList {
|
|||
#else
|
||||
ChildOpacityState mChildOpacityState;
|
||||
#endif
|
||||
|
||||
struct {
|
||||
float mOpacity;
|
||||
} mState{};
|
||||
};
|
||||
|
||||
class nsDisplayBlendMode : public nsDisplayWrapList {
|
||||
|
@ -5985,8 +5933,7 @@ class nsDisplayEffectsBase : public nsDisplayWrapList {
|
|||
nsDisplayEffectsBase(nsDisplayListBuilder* aBuilder,
|
||||
const nsDisplayEffectsBase& aOther)
|
||||
: nsDisplayWrapList(aBuilder, aOther),
|
||||
mEffectsBounds(aOther.mEffectsBounds),
|
||||
mHandleOpacity(aOther.mHandleOpacity) {
|
||||
mEffectsBounds(aOther.mEffectsBounds) {
|
||||
MOZ_COUNT_CTOR(nsDisplayEffectsBase);
|
||||
}
|
||||
|
||||
|
@ -5997,25 +5944,10 @@ class nsDisplayEffectsBase : public nsDisplayWrapList {
|
|||
void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
HitTestState* aState, nsTArray<nsIFrame*>* aOutFrames) override;
|
||||
|
||||
bool RestoreState() override {
|
||||
if (!nsDisplayWrapList::RestoreState() && !mHandleOpacity) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mHandleOpacity = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override {
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void SelectOpacityOptimization(const bool /* aUsingLayers */) {
|
||||
SetHandleOpacity();
|
||||
}
|
||||
|
||||
bool ShouldHandleOpacity() const { return mHandleOpacity; }
|
||||
|
||||
gfxRect BBoxInUserSpace() const;
|
||||
gfxPoint UserSpaceOffset() const;
|
||||
|
||||
|
@ -6024,13 +5956,10 @@ class nsDisplayEffectsBase : public nsDisplayWrapList {
|
|||
nsRegion* aInvalidRegion) const override;
|
||||
|
||||
protected:
|
||||
void SetHandleOpacity() { mHandleOpacity = true; }
|
||||
bool ValidateSVGFrame();
|
||||
|
||||
// relative to mFrame
|
||||
nsRect mEffectsBounds;
|
||||
// True if we need to handle css opacity in this display item.
|
||||
bool mHandleOpacity;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -6096,12 +6025,10 @@ class nsDisplayMasksAndClipPaths : public nsDisplayEffectsBase {
|
|||
* return whether the mask layer was painted successfully.
|
||||
*/
|
||||
bool PaintMask(nsDisplayListBuilder* aBuilder, gfxContext* aMaskContext,
|
||||
bool* aMaskPainted = nullptr);
|
||||
bool aHandleOpacity, bool* aMaskPainted = nullptr);
|
||||
|
||||
const nsTArray<nsRect>& GetDestRects() { return mDestRects; }
|
||||
|
||||
void SelectOpacityOptimization(const bool aUsingLayers) override;
|
||||
|
||||
bool CreateWebRenderCommands(
|
||||
wr::DisplayListBuilder& aBuilder, wr::IpcResourceUpdateQueue& aResources,
|
||||
const StackingContextHelper& aSc,
|
||||
|
@ -6122,7 +6049,6 @@ class nsDisplayMasksAndClipPaths : public nsDisplayEffectsBase {
|
|||
bool CanPaintOnMaskLayer(LayerManager* aManager);
|
||||
|
||||
nsTArray<nsRect> mDestRects;
|
||||
bool mApplyOpacityWithSimpleClipPath;
|
||||
};
|
||||
|
||||
class nsDisplayBackdropRootContainer : public nsDisplayWrapList {
|
||||
|
@ -6253,7 +6179,12 @@ class nsDisplayFilters : public nsDisplayEffectsBase {
|
|||
const StackingContextHelper& aSc,
|
||||
layers::RenderRootStateManager* aManager,
|
||||
nsDisplayListBuilder* aDisplayListBuilder) override;
|
||||
bool CanCreateWebRenderCommands();
|
||||
bool CanCreateWebRenderCommands() const;
|
||||
|
||||
bool CanApplyOpacity(WebRenderLayerManager* aManager,
|
||||
nsDisplayListBuilder* aBuilder) const override {
|
||||
return CanCreateWebRenderCommands();
|
||||
}
|
||||
|
||||
bool CreatesStackingContextHelper() override { return true; }
|
||||
|
||||
|
@ -6746,15 +6677,6 @@ class nsDisplayText final : public nsPaintedDisplayItem {
|
|||
|
||||
NS_DISPLAY_DECL_NAME("Text", TYPE_TEXT)
|
||||
|
||||
bool RestoreState() final {
|
||||
if (!nsPaintedDisplayItem::RestoreState() && mOpacity == 1.0f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mOpacity = 1.0f;
|
||||
return true;
|
||||
}
|
||||
|
||||
nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) const final {
|
||||
*aSnap = false;
|
||||
return mBounds;
|
||||
|
@ -6794,16 +6716,10 @@ class nsDisplayText final : public nsPaintedDisplayItem {
|
|||
nsRegion* aInvalidRegion) const final;
|
||||
|
||||
void RenderToContext(gfxContext* aCtx, nsDisplayListBuilder* aBuilder,
|
||||
bool aIsRecording = false);
|
||||
float aOpacity = 1.0f, bool aIsRecording = false);
|
||||
|
||||
bool CanApplyOpacity() const final;
|
||||
|
||||
void ApplyOpacity(nsDisplayListBuilder* aBuilder, float aOpacity,
|
||||
const DisplayItemClipChain* aClip) final {
|
||||
NS_ASSERTION(CanApplyOpacity(), "ApplyOpacity should be allowed");
|
||||
mOpacity = aOpacity;
|
||||
IntersectClip(aBuilder, aClip, false);
|
||||
}
|
||||
bool CanApplyOpacity(WebRenderLayerManager* aManager,
|
||||
nsDisplayListBuilder* aBuilder) const final;
|
||||
|
||||
void WriteDebugInfo(std::stringstream& aStream) final;
|
||||
|
||||
|
@ -6842,11 +6758,9 @@ class nsDisplayText final : public nsPaintedDisplayItem {
|
|||
|
||||
nscoord& VisIStartEdge() { return mVisIStartEdge; }
|
||||
nscoord& VisIEndEdge() { return mVisIEndEdge; }
|
||||
float Opacity() const { return mOpacity; }
|
||||
|
||||
private:
|
||||
nsRect mBounds;
|
||||
float mOpacity;
|
||||
|
||||
// Lengths measured from the visual inline start and end sides
|
||||
// (i.e. left and right respectively in horizontal writing modes,
|
||||
|
|
|
@ -91,10 +91,6 @@ void nsDisplayBoxShadowInnerGeometry::MoveBy(const nsPoint& aOffset) {
|
|||
mPaddingRect.MoveBy(aOffset);
|
||||
}
|
||||
|
||||
nsDisplayBoxShadowOuterGeometry::nsDisplayBoxShadowOuterGeometry(
|
||||
nsDisplayItem* aItem, nsDisplayListBuilder* aBuilder, float aOpacity)
|
||||
: nsDisplayItemGenericGeometry(aItem, aBuilder), mOpacity(aOpacity) {}
|
||||
|
||||
void nsDisplaySolidColorRegionGeometry::MoveBy(const nsPoint& aOffset) {
|
||||
nsDisplayItemGeometry::MoveBy(aOffset);
|
||||
mRegion.MoveBy(aOffset);
|
||||
|
@ -105,9 +101,7 @@ nsDisplaySVGEffectGeometry::nsDisplaySVGEffectGeometry(
|
|||
: nsDisplayItemGeometry(aItem, aBuilder),
|
||||
mBBox(aItem->BBoxInUserSpace()),
|
||||
mUserSpaceOffset(aItem->UserSpaceOffset()),
|
||||
mFrameOffsetToReferenceFrame(aItem->ToReferenceFrame()),
|
||||
mOpacity(aItem->Frame()->StyleEffects()->mOpacity),
|
||||
mHandleOpacity(aItem->ShouldHandleOpacity()) {}
|
||||
mFrameOffsetToReferenceFrame(aItem->ToReferenceFrame()) {}
|
||||
|
||||
void nsDisplaySVGEffectGeometry::MoveBy(const nsPoint& aOffset) {
|
||||
mBounds.MoveBy(aOffset);
|
||||
|
|
|
@ -245,15 +245,6 @@ class nsDisplayBoxShadowInnerGeometry : public nsDisplayItemGeometry {
|
|||
nsRect mPaddingRect;
|
||||
};
|
||||
|
||||
class nsDisplayBoxShadowOuterGeometry : public nsDisplayItemGenericGeometry {
|
||||
public:
|
||||
nsDisplayBoxShadowOuterGeometry(nsDisplayItem* aItem,
|
||||
nsDisplayListBuilder* aBuilder,
|
||||
float aOpacity);
|
||||
|
||||
float mOpacity;
|
||||
};
|
||||
|
||||
class nsDisplaySolidColorGeometry : public nsDisplayItemBoundsGeometry {
|
||||
public:
|
||||
nsDisplaySolidColorGeometry(nsDisplayItem* aItem,
|
||||
|
@ -289,7 +280,6 @@ class nsDisplaySVGEffectGeometry : public nsDisplayItemGeometry {
|
|||
gfxRect mBBox;
|
||||
gfxPoint mUserSpaceOffset;
|
||||
nsPoint mFrameOffsetToReferenceFrame;
|
||||
float mOpacity;
|
||||
bool mHandleOpacity;
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче