From ea26418751cb80ca8a162a4a57c9476126bca396 Mon Sep 17 00:00:00 2001 From: Ethan Lin Date: Thu, 13 Apr 2017 15:13:51 +0800 Subject: [PATCH] Bug 1355012 - Add mask layer support for WebRenderDisplayItemLayer. r=kats --- gfx/layers/wr/WebRenderCanvasLayer.cpp | 2 +- gfx/layers/wr/WebRenderColorLayer.cpp | 2 +- gfx/layers/wr/WebRenderContainerLayer.cpp | 2 +- gfx/layers/wr/WebRenderDisplayItemLayer.cpp | 14 ++++++++++++++ gfx/layers/wr/WebRenderImageLayer.cpp | 2 +- gfx/layers/wr/WebRenderLayerManager.cpp | 11 +++++++---- gfx/layers/wr/WebRenderLayerManager.h | 2 +- gfx/layers/wr/WebRenderPaintedLayer.cpp | 2 +- 8 files changed, 27 insertions(+), 10 deletions(-) diff --git a/gfx/layers/wr/WebRenderCanvasLayer.cpp b/gfx/layers/wr/WebRenderCanvasLayer.cpp index f62d0b7a69c6..5b29445de42c 100644 --- a/gfx/layers/wr/WebRenderCanvasLayer.cpp +++ b/gfx/layers/wr/WebRenderCanvasLayer.cpp @@ -66,7 +66,7 @@ WebRenderCanvasLayer::RenderLayer(wr::DisplayListBuilder& aBuilder) gfx::Rect rect = RelativeToVisible(gfx::Rect(0, 0, mBounds.width, mBounds.height)); gfx::Rect clipRect = GetWrClipRect(rect); - Maybe mask = BuildWrMaskLayer(); + Maybe mask = BuildWrMaskLayer(true); WrClipRegion clip = aBuilder.BuildClipRegion(wr::ToWrRect(clipRect), mask.ptrOr(nullptr)); wr::ImageRendering filter = wr::ToImageRendering(mSamplingFilter); diff --git a/gfx/layers/wr/WebRenderColorLayer.cpp b/gfx/layers/wr/WebRenderColorLayer.cpp index da7a5e44fe45..f53de1e3b9c1 100644 --- a/gfx/layers/wr/WebRenderColorLayer.cpp +++ b/gfx/layers/wr/WebRenderColorLayer.cpp @@ -24,7 +24,7 @@ WebRenderColorLayer::RenderLayer(wr::DisplayListBuilder& aBuilder) gfx::Rect rect = GetWrBoundsRect(); gfx::Rect clipRect = GetWrClipRect(rect); - Maybe mask = BuildWrMaskLayer(); + Maybe mask = BuildWrMaskLayer(true); WrClipRegion clip = aBuilder.BuildClipRegion(wr::ToWrRect(clipRect), mask.ptrOr(nullptr)); wr::MixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode()); diff --git a/gfx/layers/wr/WebRenderContainerLayer.cpp b/gfx/layers/wr/WebRenderContainerLayer.cpp index 3bf746b23257..e5919a3b0e9c 100644 --- a/gfx/layers/wr/WebRenderContainerLayer.cpp +++ b/gfx/layers/wr/WebRenderContainerLayer.cpp @@ -23,7 +23,7 @@ WebRenderContainerLayer::RenderLayer(wr::DisplayListBuilder& aBuilder) gfx::Rect relBounds = GetWrRelBounds(); gfx::Rect overflow(0, 0, relBounds.width, relBounds.height); - Maybe mask = BuildWrMaskLayer(); + Maybe mask = BuildWrMaskLayer(true); wr::MixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode()); diff --git a/gfx/layers/wr/WebRenderDisplayItemLayer.cpp b/gfx/layers/wr/WebRenderDisplayItemLayer.cpp index 0ccf0b94b545..a24b6b9258fe 100644 --- a/gfx/layers/wr/WebRenderDisplayItemLayer.cpp +++ b/gfx/layers/wr/WebRenderDisplayItemLayer.cpp @@ -22,6 +22,16 @@ WebRenderDisplayItemLayer::RenderLayer(wr::DisplayListBuilder& aBuilder) return; } + Maybe mask = BuildWrMaskLayer(false); + WrImageMask* imageMask = mask.ptrOr(nullptr); + if (imageMask) { + gfx::Rect rect = TransformedVisibleBoundsRelativeToParent(); + gfx::Rect overflow(0.0, 0.0, rect.width, rect.height); + aBuilder.PushScrollLayer(wr::ToWrRect(rect), + wr::ToWrRect(overflow), + imageMask); + } + if (mItem) { wr::DisplayListBuilder builder(WrBridge()->GetPipeline()); // We might have recycled this layer. Throw away the old commands. @@ -34,6 +44,10 @@ WebRenderDisplayItemLayer::RenderLayer(wr::DisplayListBuilder& aBuilder) aBuilder.PushBuiltDisplayList(Move(mBuiltDisplayList)); WrBridge()->AddWebRenderParentCommands(mParentCommands); + + if (imageMask) { + aBuilder.PopScrollLayer(); + } } uint64_t diff --git a/gfx/layers/wr/WebRenderImageLayer.cpp b/gfx/layers/wr/WebRenderImageLayer.cpp index bdbdc85700e1..307fdb9ce541 100644 --- a/gfx/layers/wr/WebRenderImageLayer.cpp +++ b/gfx/layers/wr/WebRenderImageLayer.cpp @@ -139,7 +139,7 @@ WebRenderImageLayer::RenderLayer(wr::DisplayListBuilder& aBuilder) rect = RelativeToVisible(rect); gfx::Rect clipRect = GetWrClipRect(rect); - Maybe mask = BuildWrMaskLayer(); + Maybe mask = BuildWrMaskLayer(true); WrClipRegion clip = aBuilder.BuildClipRegion(wr::ToWrRect(clipRect), mask.ptrOr(nullptr)); wr::ImageRendering filter = wr::ToImageRendering(mSamplingFilter); diff --git a/gfx/layers/wr/WebRenderLayerManager.cpp b/gfx/layers/wr/WebRenderLayerManager.cpp index d5429146c21d..61763a9d8f19 100644 --- a/gfx/layers/wr/WebRenderLayerManager.cpp +++ b/gfx/layers/wr/WebRenderLayerManager.cpp @@ -103,14 +103,17 @@ WebRenderLayer::TransformedVisibleBoundsRelativeToParent() } Maybe -WebRenderLayer::BuildWrMaskLayer() +WebRenderLayer::BuildWrMaskLayer(bool aUnapplyLayerTransform) { if (GetLayer()->GetMaskLayer()) { WebRenderLayer* maskLayer = ToWebRenderLayer(GetLayer()->GetMaskLayer()); - // The size of mask layer is transformed, and we also push the layer transform to wr stacking context. + // The size of mask layer is transformed, and we may set the layer transform to wr stacking context. // So we should apply inverse transform for mask layer. - gfx::Matrix4x4 transform = GetWrBoundTransform(); - return maskLayer->RenderMaskLayer(transform.Inverse()); + gfx::Matrix4x4 transform; + if (aUnapplyLayerTransform) { + transform = GetWrBoundTransform().Inverse(); + } + return maskLayer->RenderMaskLayer(transform); } return Nothing(); diff --git a/gfx/layers/wr/WebRenderLayerManager.h b/gfx/layers/wr/WebRenderLayerManager.h index 5253fc8c3394..aad131bae8eb 100644 --- a/gfx/layers/wr/WebRenderLayerManager.h +++ b/gfx/layers/wr/WebRenderLayerManager.h @@ -59,7 +59,7 @@ protected: gfx::Rect GetWrClipRect(gfx::Rect& aRect); gfx::Matrix4x4 GetWrBoundTransform(); void DumpLayerInfo(const char* aLayerType, gfx::Rect& aRect); - Maybe BuildWrMaskLayer(); + Maybe BuildWrMaskLayer(bool aUnapplyLayerTransform); }; class WebRenderLayerManager final : public LayerManager diff --git a/gfx/layers/wr/WebRenderPaintedLayer.cpp b/gfx/layers/wr/WebRenderPaintedLayer.cpp index bf81b407b3f9..de440dcd95c4 100644 --- a/gfx/layers/wr/WebRenderPaintedLayer.cpp +++ b/gfx/layers/wr/WebRenderPaintedLayer.cpp @@ -189,7 +189,7 @@ WebRenderPaintedLayer::RenderLayer(wr::DisplayListBuilder& aBuilder) gfx::Rect rect(0, 0, size.width, size.height); gfx::Rect clipRect = GetWrClipRect(rect); - Maybe mask = BuildWrMaskLayer(); + Maybe mask = BuildWrMaskLayer(true); WrClipRegion clip = aBuilder.BuildClipRegion(wr::ToWrRect(clipRect), mask.ptrOr(nullptr)); wr::MixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());