зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset dfb973b3e25c (bug 1619367) for reftest failures at mask-opacity-invalidation-1.html. CLOSED TREE
This commit is contained in:
Родитель
6a17ceea10
Коммит
c6bf1adfa6
|
@ -2381,8 +2381,7 @@ class WebRenderMaskData : public WebRenderUserData {
|
|||
explicit WebRenderMaskData(RenderRootStateManager* aManager,
|
||||
nsDisplayItem* aItem)
|
||||
: WebRenderUserData(aManager, aItem),
|
||||
mMaskStyle(nsStyleImageLayers::LayerType::Mask),
|
||||
mShouldHandleOpacity(false) {
|
||||
mMaskStyle(nsStyleImageLayers::LayerType::Mask) {
|
||||
MOZ_COUNT_CTOR(WebRenderMaskData);
|
||||
}
|
||||
virtual ~WebRenderMaskData() {
|
||||
|
@ -2407,7 +2406,6 @@ class WebRenderMaskData : public WebRenderUserData {
|
|||
nsPoint mMaskOffset;
|
||||
nsStyleImageLayers mMaskStyle;
|
||||
gfx::Size mScale;
|
||||
bool mShouldHandleOpacity;
|
||||
};
|
||||
|
||||
Maybe<wr::ImageMask> WebRenderCommandBuilder::BuildWrMaskImage(
|
||||
|
@ -2452,13 +2450,10 @@ Maybe<wr::ImageMask> WebRenderCommandBuilder::BuildWrMaskImage(
|
|||
nsPoint maskOffset = aMaskItem->ToReferenceFrame() - bounds.TopLeft();
|
||||
|
||||
nsRect dirtyRect;
|
||||
// If this mask item is being painted for the first time, some members of
|
||||
// WebRenderMaskData are still default initialized. This is intentional.
|
||||
if (aMaskItem->IsInvalid(dirtyRect) ||
|
||||
!itemRect.IsEqualInterior(maskData->mItemRect) ||
|
||||
!(aMaskItem->Frame()->StyleSVGReset()->mMask == maskData->mMaskStyle) ||
|
||||
maskOffset != maskData->mMaskOffset || !sameScale ||
|
||||
aMaskItem->ShouldHandleOpacity() != maskData->mShouldHandleOpacity) {
|
||||
maskOffset != maskData->mMaskOffset || !sameScale) {
|
||||
IntSize size = itemRect.Size().ToUnknownSize();
|
||||
|
||||
std::vector<RefPtr<ScaledFont>> fonts;
|
||||
|
@ -2552,7 +2547,6 @@ Maybe<wr::ImageMask> WebRenderCommandBuilder::BuildWrMaskImage(
|
|||
maskData->mMaskOffset = maskOffset;
|
||||
maskData->mScale = scale;
|
||||
maskData->mMaskStyle = aMaskItem->Frame()->StyleSVGReset()->mMask;
|
||||
maskData->mShouldHandleOpacity = aMaskItem->ShouldHandleOpacity();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6316,8 +6316,6 @@ nsRegion nsDisplayOpacity::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
|
|||
already_AddRefed<Layer> nsDisplayOpacity::BuildLayer(
|
||||
nsDisplayListBuilder* aBuilder, LayerManager* aManager,
|
||||
const ContainerLayerParameters& aContainerParameters) {
|
||||
MOZ_ASSERT(mChildOpacityState != ChildOpacityState::Applied);
|
||||
|
||||
ContainerLayerParameters params = aContainerParameters;
|
||||
RefPtr<Layer> container = aManager->GetLayerBuilder()->BuildContainerLayerFor(
|
||||
aBuilder, aManager, mFrame, this, &mList, params, nullptr,
|
||||
|
@ -6436,7 +6434,7 @@ static bool CollectItemsWithOpacity(nsDisplayList* aList,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool nsDisplayOpacity::ApplyToChildren(nsDisplayListBuilder* aBuilder) {
|
||||
bool nsDisplayOpacity::ApplyOpacityToChildren(nsDisplayListBuilder* aBuilder) {
|
||||
if (mChildOpacityState == ChildOpacityState::Deferred) {
|
||||
return false;
|
||||
}
|
||||
|
@ -6481,29 +6479,24 @@ bool nsDisplayOpacity::ApplyToChildren(nsDisplayListBuilder* aBuilder) {
|
|||
|
||||
/**
|
||||
* Returns true if this nsDisplayOpacity contains only a filter or a mask item
|
||||
* 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.
|
||||
* that has the same frame as the opacity item. In this case the opacity item
|
||||
* can be optimized away.
|
||||
*/
|
||||
bool nsDisplayOpacity::ApplyToFilterOrMask(const bool aUsingLayers) {
|
||||
bool nsDisplayOpacity::IsEffectsWrapper() const {
|
||||
if (mList.Count() != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsDisplayItem* item = mList.GetBottom();
|
||||
const nsDisplayItem* item = mList.GetBottom();
|
||||
|
||||
if (item->Frame() != mFrame) {
|
||||
// The effect item needs to have the same frame as the opacity item.
|
||||
return false;
|
||||
}
|
||||
|
||||
const DisplayItemType type = item->GetType();
|
||||
if (type == DisplayItemType::TYPE_MASK ||
|
||||
type == DisplayItemType::TYPE_FILTER) {
|
||||
auto* filterOrMaskItem = static_cast<nsDisplayEffectsBase*>(item);
|
||||
filterOrMaskItem->SelectOpacityOptimization(aUsingLayers);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return type == DisplayItemType::TYPE_MASK ||
|
||||
type == DisplayItemType::TYPE_FILTER;
|
||||
}
|
||||
|
||||
bool nsDisplayOpacity::ShouldFlattenAway(nsDisplayListBuilder* aBuilder) {
|
||||
|
@ -6526,10 +6519,9 @@ bool nsDisplayOpacity::ShouldFlattenAway(nsDisplayListBuilder* aBuilder) {
|
|||
return false;
|
||||
}
|
||||
|
||||
const bool usingLayers = !aBuilder->IsPaintingForWebRender();
|
||||
|
||||
if (ApplyToFilterOrMask(usingLayers)) {
|
||||
if (IsEffectsWrapper()) {
|
||||
MOZ_ASSERT(nsSVGIntegrationUtils::UsingEffectsForFrame(mFrame));
|
||||
static_cast<nsDisplayEffectsBase*>(mList.GetBottom())->SetHandleOpacity();
|
||||
mChildOpacityState = ChildOpacityState::Applied;
|
||||
return true;
|
||||
}
|
||||
|
@ -6537,7 +6529,7 @@ bool nsDisplayOpacity::ShouldFlattenAway(nsDisplayListBuilder* aBuilder) {
|
|||
// Return true if we successfully applied opacity to child items, or if
|
||||
// WebRender is not in use. In the latter case, the opacity gets flattened and
|
||||
// applied during layer building.
|
||||
return ApplyToChildren(aBuilder) || usingLayers;
|
||||
return ApplyOpacityToChildren(aBuilder) || !gfxVars::UseWebRender();
|
||||
}
|
||||
|
||||
nsDisplayItem::LayerState nsDisplayOpacity::GetLayerState(
|
||||
|
@ -6586,22 +6578,7 @@ void nsDisplayOpacity::ComputeInvalidationRegion(
|
|||
}
|
||||
|
||||
void nsDisplayOpacity::WriteDebugInfo(std::stringstream& aStream) {
|
||||
aStream << " (opacity " << mOpacity << ", mChildOpacityState: ";
|
||||
switch (mChildOpacityState) {
|
||||
case ChildOpacityState::Unknown:
|
||||
aStream << "Unknown";
|
||||
break;
|
||||
case ChildOpacityState::Applied:
|
||||
aStream << "Applied";
|
||||
break;
|
||||
case ChildOpacityState::Deferred:
|
||||
aStream << "Deferred";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
aStream << ")";
|
||||
aStream << " (opacity " << mOpacity << ")";
|
||||
}
|
||||
|
||||
bool nsDisplayOpacity::CreateWebRenderCommands(
|
||||
|
@ -6610,7 +6587,6 @@ bool nsDisplayOpacity::CreateWebRenderCommands(
|
|||
const StackingContextHelper& aSc,
|
||||
mozilla::layers::RenderRootStateManager* aManager,
|
||||
nsDisplayListBuilder* aDisplayListBuilder) {
|
||||
MOZ_ASSERT(mChildOpacityState != ChildOpacityState::Applied);
|
||||
float* opacityForSC = &mOpacity;
|
||||
|
||||
uint64_t animationsId = AddAnimationsForWebRender(
|
||||
|
@ -9772,8 +9748,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();
|
||||
|
@ -10102,13 +10077,18 @@ static Maybe<wr::WrClipId> CreateSimpleClipRegion(
|
|||
return Some(clipId);
|
||||
}
|
||||
|
||||
static Maybe<wr::WrClipId> CreateWRClipPathAndMasks(
|
||||
enum class HandleOpacity {
|
||||
No,
|
||||
Yes,
|
||||
};
|
||||
|
||||
static Maybe<std::pair<wr::WrClipId, HandleOpacity>> CreateWRClipPathAndMasks(
|
||||
nsDisplayMasksAndClipPaths* aDisplayItem, const LayoutDeviceRect& aBounds,
|
||||
wr::IpcResourceUpdateQueue& aResources, wr::DisplayListBuilder& aBuilder,
|
||||
const StackingContextHelper& aSc, layers::RenderRootStateManager* aManager,
|
||||
nsDisplayListBuilder* aDisplayListBuilder) {
|
||||
if (auto clip = CreateSimpleClipRegion(*aDisplayItem, aBuilder)) {
|
||||
return clip;
|
||||
return Some(std::make_pair(*clip, HandleOpacity::Yes));
|
||||
}
|
||||
|
||||
Maybe<wr::ImageMask> mask = aManager->CommandBuilder().BuildWrMaskImage(
|
||||
|
@ -10120,7 +10100,7 @@ static Maybe<wr::WrClipId> CreateWRClipPathAndMasks(
|
|||
wr::WrClipId clipId = aBuilder.DefineClip(
|
||||
Nothing(), wr::ToLayoutRect(aBounds), nullptr, mask.ptr());
|
||||
|
||||
return Some(clipId);
|
||||
return Some(std::make_pair(clipId, HandleOpacity::No));
|
||||
}
|
||||
|
||||
bool nsDisplayMasksAndClipPaths::CreateWebRenderCommands(
|
||||
|
@ -10135,7 +10115,7 @@ bool nsDisplayMasksAndClipPaths::CreateWebRenderCommands(
|
|||
LayoutDeviceRect bounds =
|
||||
LayoutDeviceRect::FromAppUnits(displayBounds, appUnitsPerDevPixel);
|
||||
|
||||
Maybe<wr::WrClipId> clip = CreateWRClipPathAndMasks(
|
||||
Maybe<std::pair<wr::WrClipId, HandleOpacity>> clip = CreateWRClipPathAndMasks(
|
||||
this, bounds, aResources, aBuilder, aSc, aManager, aDisplayListBuilder);
|
||||
|
||||
Maybe<StackingContextHelper> layer;
|
||||
|
@ -10147,12 +10127,14 @@ bool nsDisplayMasksAndClipPaths::CreateWebRenderCommands(
|
|||
// The stacking context shouldn't have any offset.
|
||||
bounds.MoveTo(0, 0);
|
||||
|
||||
Maybe<float> opacity = mApplyOpacityWithSimpleClipPath
|
||||
wr::WrClipId clipId = clip->first;
|
||||
|
||||
Maybe<float> opacity = clip->second == HandleOpacity::Yes
|
||||
? Some(mFrame->StyleEffects()->mOpacity)
|
||||
: Nothing();
|
||||
|
||||
wr::StackingContextParams params;
|
||||
params.clip = wr::WrStackingContextClip::ClipId(*clip);
|
||||
params.clip = wr::WrStackingContextClip::ClipId(clipId);
|
||||
params.opacity = opacity.ptrOr(nullptr);
|
||||
layer.emplace(aSc, GetActiveScrolledRoot(), mFrame, this, aBuilder, params,
|
||||
bounds);
|
||||
|
@ -10165,19 +10147,6 @@ bool nsDisplayMasksAndClipPaths::CreateWebRenderCommands(
|
|||
return true;
|
||||
}
|
||||
|
||||
void nsDisplayMasksAndClipPaths::SelectOpacityOptimization(
|
||||
const bool aUsingLayers) {
|
||||
if (aUsingLayers ||
|
||||
!nsSVGIntegrationUtils::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 =
|
||||
|
|
|
@ -5730,13 +5730,13 @@ class nsDisplayOpacity : public nsDisplayWrapList {
|
|||
private:
|
||||
NS_DISPLAY_ALLOW_CLONING()
|
||||
|
||||
bool ApplyToChildren(nsDisplayListBuilder* aBuilder);
|
||||
bool ApplyToFilterOrMask(const bool aUsingLayers);
|
||||
bool ApplyOpacityToChildren(nsDisplayListBuilder* aBuilder);
|
||||
bool IsEffectsWrapper() const;
|
||||
|
||||
float mOpacity;
|
||||
bool mForEventsAndPluginsOnly : 1;
|
||||
enum class ChildOpacityState : uint8_t {
|
||||
// Our child list has changed since the last time ApplyToChildren was
|
||||
// Our child list has changed since the last time ApplyOpacityToChildren was
|
||||
// called.
|
||||
Unknown,
|
||||
// Our children defer opacity handling to us.
|
||||
|
@ -6560,10 +6560,7 @@ class nsDisplayEffectsBase : public nsDisplayWrapList {
|
|||
return false;
|
||||
}
|
||||
|
||||
virtual void SelectOpacityOptimization(const bool /* aUsingLayers */) {
|
||||
SetHandleOpacity();
|
||||
}
|
||||
|
||||
void SetHandleOpacity() { mHandleOpacity = true; }
|
||||
bool ShouldHandleOpacity() const { return mHandleOpacity; }
|
||||
|
||||
gfxRect BBoxInUserSpace() const;
|
||||
|
@ -6574,7 +6571,6 @@ class nsDisplayEffectsBase : public nsDisplayWrapList {
|
|||
nsRegion* aInvalidRegion) const override;
|
||||
|
||||
protected:
|
||||
void SetHandleOpacity() { mHandleOpacity = true; }
|
||||
bool ValidateSVGFrame();
|
||||
|
||||
// relative to mFrame
|
||||
|
@ -6661,8 +6657,6 @@ class nsDisplayMasksAndClipPaths : public nsDisplayEffectsBase {
|
|||
|
||||
const nsTArray<nsRect>& GetDestRects() { return mDestRects; }
|
||||
|
||||
void SelectOpacityOptimization(const bool aUsingLayers) override;
|
||||
|
||||
bool CreateWebRenderCommands(
|
||||
mozilla::wr::DisplayListBuilder& aBuilder,
|
||||
mozilla::wr::IpcResourceUpdateQueue& aResources,
|
||||
|
@ -6682,7 +6676,6 @@ class nsDisplayMasksAndClipPaths : public nsDisplayEffectsBase {
|
|||
bool CanPaintOnMaskLayer(LayerManager* aManager);
|
||||
|
||||
nsTArray<nsRect> mDestRects;
|
||||
bool mApplyOpacityWithSimpleClipPath;
|
||||
};
|
||||
|
||||
class nsDisplayBackdropRootContainer : public nsDisplayWrapList {
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<title></title>
|
||||
<style>
|
||||
#mask {
|
||||
clip-path: circle(50%);
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
#content {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: green;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="mask">
|
||||
<div id="content"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,41 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en" class="reftest-wait">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<title></title>
|
||||
<style>
|
||||
#mask {
|
||||
clip-path: circle(50%);
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
#content {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: green;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="mask">
|
||||
<div id="content"></div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
function step1() {
|
||||
document.querySelector("#mask").style.opacity = 0.1;
|
||||
window.requestAnimationFrame(() => window.requestAnimationFrame(step2));
|
||||
};
|
||||
|
||||
function step2() {
|
||||
document.querySelector("#mask").style.opacity = 0.5;
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
|
||||
window.addEventListener("MozReftestInvalidate", step1);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -596,5 +596,3 @@ fails-if(Android) != mask-resource.html about:blank # The image the test uses is
|
|||
|
||||
!= bug-1562091.html bug-1562091-ref.html
|
||||
== 1570363-1.html 1570363-1-ref.html
|
||||
|
||||
fuzzy-if(webrender,1-1,80-92) fuzzy-if(!webrender,0-2,0-7882) == mask-opacity-invalidation-1.html mask-opacity-invalidation-1-ref.html # clip-path mask/opacity optimization
|
||||
|
|
Загрузка…
Ссылка в новой задаче