Bug 1360246 - Propagate a StackingContextHelper all the way through the RenderLayer traversal. r=nical
This is needed in part 3 to update WebRenderTextLayer::RenderLayer, so
that it no longer assumes the parent container layer has pushed a
stacking context, and instead explicitly uses the StackingContextHelper.
MozReview-Commit-ID: 9twUmDgUipX
--- a/gfx/layers/wr/StackingContextHelper.cpp
+++ b/gfx/layers/wr/StackingContextHelper.cpp
@@ -5,16 +5,22 @@
#include "mozilla/layers/StackingContextHelper.h"
#include "mozilla/layers/WebRenderLayer.h"
namespace mozilla {
namespace layers {
+StackingContextHelper::StackingContextHelper()
+ : mBuilder(nullptr)
+{
+ // mOrigin remains at 0,0
+}
+
StackingContextHelper::StackingContextHelper(wr::DisplayListBuilder& aBuilder,
WebRenderLayer* aLayer,
const Maybe<gfx::Matrix4x4>& aTransform)
: mBuilder(&aBuilder)
{
LayerRect scBounds = aLayer->RelativeToParent(aLayer->BoundsForStackingContext());
Layer* layer = aLayer->GetLayer();
gfx::Matrix4x4 transform = aTransform.valueOr(layer->GetTransform());
@@ -38,19 +44,21 @@ StackingContextHelper::StackingContextHe
aOpacityPtr,
aTransformPtr,
wr::ToWrMixBlendMode(aLayer->GetLayer()->GetMixBlendMode()));
mOrigin = aLayer->Bounds().TopLeft();
}
StackingContextHelper::~StackingContextHelper()
{
- mBuilder->PopStackingContext();
+ if (mBuilder) {
+ mBuilder->PopStackingContext();
+ }
}
WrRect
-StackingContextHelper::ToRelativeWrRect(const LayerRect& aRect)
+StackingContextHelper::ToRelativeWrRect(const LayerRect& aRect) const
{
return wr::ToWrRect(aRect - mOrigin);
}
} // namespace layers
} // namespace mozilla
--- a/gfx/layers/wr/StackingContextHelper.h
+++ b/gfx/layers/wr/StackingContextHelper.h
@@ -33,25 +33,31 @@ public:
const Maybe<gfx::Matrix4x4>& aTransform = Nothing());
// Alternate constructor which invokes the version of PushStackingContext
// for animations.
StackingContextHelper(wr::DisplayListBuilder& aBuilder,
WebRenderLayer* aLayer,
uint64_t aAnimationsId,
float* aOpacityPtr,
gfx::Matrix4x4* aTransformPtr);
- // Pops the stacking context
+ // This version of the constructor should only be used at the root level
+ // of the tree, so that we have a StackingContextHelper to pass down into
+ // the RenderLayer traversal, but don't actually want it to push a stacking
+ // context on the display list builder.
+ StackingContextHelper();
+
+ // Pops the stacking context, if one was pushed during the constructor.
~StackingContextHelper();
// When this StackingContextHelper is in scope, this function can be used
// to convert a rect from the layer system's coordinate space to a WrRect
// that is relative to the stacking context. This is useful because most
// things that are pushed inside the stacking context need to be relative
// to the stacking context.
- WrRect ToRelativeWrRect(const LayerRect& aRect);
+ WrRect ToRelativeWrRect(const LayerRect& aRect) const;
private:
wr::DisplayListBuilder* mBuilder;
LayerPoint mOrigin;
};
} // namespace layers
} // namespace mozilla
--- a/gfx/layers/wr/WebRenderCanvasLayer.cpp
+++ b/gfx/layers/wr/WebRenderCanvasLayer.cpp
@@ -42,17 +42,18 @@ WebRenderCanvasLayer::Initialize(const D
return;
gl::GLScreenBuffer* screen = mGLContext->Screen();
auto factory = MakeUnique<gl::SurfaceFactory_Basic>(mGLContext, screen->mCaps, mFlags);
screen->Morph(Move(factory));
}
void
-WebRenderCanvasLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
+WebRenderCanvasLayer::RenderLayer(wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc)
{
UpdateCompositableClient();
if (mExternalImageId.isNothing()) {
mExternalImageId = Some(WrBridge()->AllocExternalImageIdForCompositable(mCanvasClient));
}
Maybe<gfx::Matrix4x4> transform;
--- a/gfx/layers/wr/WebRenderCanvasLayer.h
+++ b/gfx/layers/wr/WebRenderCanvasLayer.h
@@ -33,17 +33,18 @@ public:
virtual void AttachCompositable() override;
protected:
virtual ~WebRenderCanvasLayer();
public:
Layer* GetLayer() override { return this; }
- void RenderLayer(wr::DisplayListBuilder& aBuilder) override;
+ void RenderLayer(wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc) override;
protected:
wr::MaybeExternalImageId mExternalImageId;
};
} // namespace layers
} // namespace mozilla
--- a/gfx/layers/wr/WebRenderColorLayer.cpp
+++ b/gfx/layers/wr/WebRenderColorLayer.cpp
@@ -13,17 +13,18 @@
#include "mozilla/layers/WebRenderBridgeChild.h"
namespace mozilla {
namespace layers {
using namespace mozilla::gfx;
void
-WebRenderColorLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
+WebRenderColorLayer::RenderLayer(wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc)
{
StackingContextHelper sc(aBuilder, this);
LayerRect rect = Bounds();
DumpLayerInfo("ColorLayer", rect);
LayerRect clipRect = ClipRect().valueOr(rect);
Maybe<WrImageMask> mask = BuildWrMaskLayer(true);
--- a/gfx/layers/wr/WebRenderColorLayer.h
+++ b/gfx/layers/wr/WebRenderColorLayer.h
@@ -25,15 +25,16 @@ public:
protected:
virtual ~WebRenderColorLayer()
{
MOZ_COUNT_DTOR(WebRenderColorLayer);
}
public:
Layer* GetLayer() override { return this; }
- void RenderLayer(wr::DisplayListBuilder& aBuilder) override;
+ void RenderLayer(wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc) override;
};
} // namespace layers
} // namespace mozilla
#endif // GFX_WEBRENDERCOLORLAYER_H
--- a/gfx/layers/wr/WebRenderContainerLayer.cpp
+++ b/gfx/layers/wr/WebRenderContainerLayer.cpp
@@ -37,17 +37,18 @@ WebRenderContainerLayer::UpdateTransform
transformData.inheritedYScale() = GetInheritedYScale();
transformData.hasPerspectiveParent() =
GetParent() && GetParent()->GetTransformIsPerspective();
}
}
}
void
-WebRenderContainerLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
+WebRenderContainerLayer::RenderLayer(wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc)
{
nsTArray<LayerPolygon> children = SortChildrenBy3DZOrder(SortMode::WITHOUT_GEOMETRY);
gfx::Matrix4x4 transform = GetTransform();
gfx::Matrix4x4* transformForSC = &transform;
float opacity = GetLocalOpacity();
float* opacityForSC = &opacity;
uint64_t animationsId = 0;
@@ -94,23 +95,24 @@ WebRenderContainerLayer::RenderLayer(wr:
Maybe<WrImageMask> mask = BuildWrMaskLayer(true);
aBuilder.PushClip(sc.ToRelativeWrRect(rect), mask.ptrOr(nullptr));
for (LayerPolygon& child : children) {
if (child.layer->IsBackfaceHidden()) {
continue;
}
- ToWebRenderLayer(child.layer)->RenderLayer(aBuilder);
+ ToWebRenderLayer(child.layer)->RenderLayer(aBuilder, sc);
}
aBuilder.PopClip();
}
void
-WebRenderRefLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
+WebRenderRefLayer::RenderLayer(wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc)
{
gfx::Matrix4x4 transform;// = GetTransform();
gfx::Rect relBounds = TransformedVisibleBoundsRelativeToParent();
WrClipRegion clipRegion = aBuilder.BuildClipRegion(wr::ToWrRect(relBounds));
if (gfxPrefs::LayersDump()) {
printf_stderr("RefLayer %p (%" PRIu64 ") using bounds/overflow=%s, transform=%s\n",
--- a/gfx/layers/wr/WebRenderContainerLayer.h
+++ b/gfx/layers/wr/WebRenderContainerLayer.h
@@ -37,17 +37,18 @@ protected:
ContainerLayer::RemoveAllChildren();
MOZ_COUNT_DTOR(WebRenderContainerLayer);
}
void UpdateTransformDataForAnimation();
public:
Layer* GetLayer() override { return this; }
- void RenderLayer(wr::DisplayListBuilder& aBuilder) override;
+ void RenderLayer(wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc) override;
void ClearAnimations() override;
virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) override
{
DefaultComputeEffectiveTransforms(aTransformToSurface);
}
};
@@ -63,17 +64,18 @@ public:
protected:
virtual ~WebRenderRefLayer()
{
MOZ_COUNT_DTOR(WebRenderRefLayer);
}
public:
Layer* GetLayer() override { return this; }
- void RenderLayer(wr::DisplayListBuilder& aBuilder) override;
+ void RenderLayer(wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc) override;
virtual void ComputeEffectiveTransforms(const gfx::Matrix4x4& aTransformToSurface) override
{
DefaultComputeEffectiveTransforms(aTransformToSurface);
}
};
} // namespace layers
--- a/gfx/layers/wr/WebRenderDisplayItemLayer.cpp
+++ b/gfx/layers/wr/WebRenderDisplayItemLayer.cpp
@@ -24,17 +24,18 @@ WebRenderDisplayItemLayer::~WebRenderDis
WrManager()->AddImageKeyForDiscard(mKey.value());
}
if (mExternalImageId.isSome()) {
WrBridge()->DeallocExternalImageId(mExternalImageId.ref());
}
}
void
-WebRenderDisplayItemLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
+WebRenderDisplayItemLayer::RenderLayer(wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc)
{
if (mVisibleRegion.IsEmpty()) {
return;
}
Maybe<WrImageMask> mask = BuildWrMaskLayer(false);
WrImageMask* imageMask = mask.ptrOr(nullptr);
if (imageMask) {
--- a/gfx/layers/wr/WebRenderDisplayItemLayer.h
+++ b/gfx/layers/wr/WebRenderDisplayItemLayer.h
@@ -31,17 +31,18 @@ public:
bool PushItemAsImage(wr::DisplayListBuilder& aBuilder,
nsTArray<layers::WebRenderParentCommand>& aParentCommands);
protected:
virtual ~WebRenderDisplayItemLayer();
public:
Layer* GetLayer() override { return this; }
- void RenderLayer(wr::DisplayListBuilder& aBuilder) override;
+ void RenderLayer(wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aHelper) override;
private:
wr::BuiltDisplayList mBuiltDisplayList;
nsTArray<WebRenderParentCommand> mParentCommands;
RefPtr<ImageClient> mImageClient;
RefPtr<ImageContainer> mImageContainer;
wr::MaybeExternalImageId mExternalImageId;
Maybe<wr::ImageKey> mKey;
--- a/gfx/layers/wr/WebRenderImageLayer.cpp
+++ b/gfx/layers/wr/WebRenderImageLayer.cpp
@@ -79,17 +79,18 @@ void
WebRenderImageLayer::ClearCachedResources()
{
if (mImageClient) {
mImageClient->ClearCachedResources();
}
}
void
-WebRenderImageLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
+WebRenderImageLayer::RenderLayer(wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc)
{
if (!mContainer) {
return;
}
CompositableType type = GetImageClientType();
if (type == CompositableType::UNKNOWN) {
return;
--- a/gfx/layers/wr/WebRenderImageLayer.h
+++ b/gfx/layers/wr/WebRenderImageLayer.h
@@ -24,17 +24,18 @@ public:
virtual void ClearCachedResources() override;
protected:
virtual ~WebRenderImageLayer();
public:
Layer* GetLayer() override { return this; }
- void RenderLayer(wr::DisplayListBuilder& aBuilder) override;
+ void RenderLayer(wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc) override;
Maybe<WrImageMask> RenderMaskLayer(const gfx::Matrix4x4& aTransform) override;
protected:
CompositableType GetImageClientType();
class Holder {
public:
explicit Holder(WebRenderImageLayer* aLayer)
--- a/gfx/layers/wr/WebRenderLayer.h
+++ b/gfx/layers/wr/WebRenderLayer.h
@@ -9,26 +9,28 @@
#include "Layers.h"
#include "mozilla/webrender/WebRenderTypes.h"
#include "mozilla/webrender/WebRenderAPI.h"
namespace mozilla {
namespace layers {
class ImageClientSingle;
+class StackingContextHelper;
class WebRenderBridgeChild;
class WebRenderLayerManager;
typedef gfx::Matrix4x4Typed<LayerPixel, LayerPixel> BoundsTransformMatrix;
class WebRenderLayer
{
public:
virtual Layer* GetLayer() = 0;
- virtual void RenderLayer(wr::DisplayListBuilder& aBuilder) = 0;
+ virtual void RenderLayer(wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc) = 0;
virtual Maybe<WrImageMask> RenderMaskLayer(const gfx::Matrix4x4& aTransform)
{
MOZ_ASSERT(false);
return Nothing();
}
virtual already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() { return nullptr; }
static inline WebRenderLayer*
--- a/gfx/layers/wr/WebRenderLayerManager.cpp
+++ b/gfx/layers/wr/WebRenderLayerManager.cpp
@@ -5,16 +5,17 @@
#include "WebRenderLayerManager.h"
#include "gfxPrefs.h"
#include "LayersLogging.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/gfx/GPUProcessManager.h"
#include "mozilla/layers/CompositorBridgeChild.h"
+#include "mozilla/layers/StackingContextHelper.h"
#include "mozilla/layers/TextureClient.h"
#include "mozilla/layers/WebRenderBridgeChild.h"
#include "WebRenderCanvasLayer.h"
#include "WebRenderColorLayer.h"
#include "WebRenderContainerLayer.h"
#include "WebRenderImageLayer.h"
#include "WebRenderPaintedLayer.h"
#include "WebRenderPaintedLayerBlob.h"
@@ -185,18 +186,19 @@ WebRenderLayerManager::EndTransactionInt
LayoutDeviceIntSize size = mWidget->GetClientSize();
if (!WrBridge()->DPBegin(size.ToUnknownSize())) {
return false;
}
DiscardCompositorAnimations();
mRoot->StartPendingAnimations(mAnimationReadyTime);
+ StackingContextHelper sc;
wr::DisplayListBuilder builder(WrBridge()->GetPipeline());
- WebRenderLayer::ToWebRenderLayer(mRoot)->RenderLayer(builder);
+ WebRenderLayer::ToWebRenderLayer(mRoot)->RenderLayer(builder, sc);
WrBridge()->ClearReadLocks();
// We can't finish this transaction so return. This usually
// happens in an empty transaction where we can't repaint a painted layer.
// In this case, leave the transaction open and let a full transaction happen.
if (mTransactionIncomplete) {
DiscardLocalImages();
return false;
--- a/gfx/layers/wr/WebRenderPaintedLayer.cpp
+++ b/gfx/layers/wr/WebRenderPaintedLayer.cpp
@@ -105,17 +105,18 @@ WebRenderPaintedLayer::CreateWebRenderDi
WrImageKey key = GetImageKey();
WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(mExternalImageId.value(), key));
WrManager()->AddImageKeyForDiscard(key);
aBuilder.PushImage(sc.ToRelativeWrRect(rect), clip, wr::ImageRendering::Auto, key);
}
void
-WebRenderPaintedLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
+WebRenderPaintedLayer::RenderLayer(wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc)
{
if (!SetupExternalImages()) {
return;
}
if (GetVisibleRegion().IsEmpty()) {
if (gfxPrefs::LayersDump()) {
printf_stderr("PaintedLayer %p skipping\n", this->GetLayer());
--- a/gfx/layers/wr/WebRenderPaintedLayer.h
+++ b/gfx/layers/wr/WebRenderPaintedLayer.h
@@ -42,17 +42,18 @@ protected:
public:
virtual void InvalidateRegion(const nsIntRegion& aRegion) override
{
mInvalidRegion.Add(aRegion);
mValidRegion.Sub(mValidRegion, mInvalidRegion.GetRegion());
}
Layer* GetLayer() override { return this; }
- void RenderLayer(wr::DisplayListBuilder& aBuilder) override;
+ void RenderLayer(wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc) override;
RefPtr<ImageContainer> mImageContainer;
RefPtr<ImageClient> mImageClient;
private:
bool SetupExternalImages();
bool UpdateImageClient();
void CreateWebRenderDisplayList(wr::DisplayListBuilder& aBuilder);
};
--- a/gfx/layers/wr/WebRenderPaintedLayerBlob.cpp
+++ b/gfx/layers/wr/WebRenderPaintedLayerBlob.cpp
@@ -16,17 +16,18 @@
#include "mozilla/webrender/WebRenderTypes.h"
namespace mozilla {
namespace layers {
using namespace mozilla::gfx;
void
-WebRenderPaintedLayerBlob::RenderLayer(wr::DisplayListBuilder& aBuilder)
+WebRenderPaintedLayerBlob::RenderLayer(wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aHelper)
{
LayerIntRegion visibleRegion = GetVisibleRegion();
LayerIntRect bounds = visibleRegion.GetBounds();
LayerIntSize size = bounds.Size();
if (visibleRegion.IsEmpty()) {
if (gfxPrefs::LayersDump()) {
printf_stderr("PaintedLayer %p skipping\n", this->GetLayer());
--- a/gfx/layers/wr/WebRenderPaintedLayerBlob.h
+++ b/gfx/layers/wr/WebRenderPaintedLayerBlob.h
@@ -42,17 +42,18 @@ protected:
public:
virtual void InvalidateRegion(const nsIntRegion& aRegion) override
{
mInvalidRegion.Add(aRegion);
mValidRegion.Sub(mValidRegion, mInvalidRegion.GetRegion());
}
Layer* GetLayer() override { return this; }
- void RenderLayer(wr::DisplayListBuilder& aBuilder) override;
+ void RenderLayer(wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aHelper) override;
private:
RefPtr<ImageContainer> mImageContainer;
RefPtr<ImageClient> mImageClient;
};
} // namespace layers
} // namespace mozilla
--- a/gfx/layers/wr/WebRenderTextLayer.cpp
+++ b/gfx/layers/wr/WebRenderTextLayer.cpp
@@ -13,17 +13,18 @@
#include "mozilla/gfx/2D.h"
namespace mozilla {
namespace layers {
using namespace mozilla::gfx;
void
-WebRenderTextLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
+WebRenderTextLayer::RenderLayer(wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc)
{
if (mBounds.IsEmpty()) {
return;
}
gfx::Rect rect = GetTransform().TransformBounds(IntRectToRect(mBounds))
- ParentBounds().ToUnknownRect().TopLeft();
gfx::Rect clip;
--- a/gfx/layers/wr/WebRenderTextLayer.h
+++ b/gfx/layers/wr/WebRenderTextLayer.h
@@ -27,16 +27,17 @@ public:
protected:
virtual ~WebRenderTextLayer()
{
MOZ_COUNT_DTOR(WebRenderTextLayer);
}
public:
Layer* GetLayer() override { return this; }
- void RenderLayer(wr::DisplayListBuilder& aBuilder) override;
+ void RenderLayer(wr::DisplayListBuilder& aBuilder,
+ const StackingContextHelper& aSc) override;
};
} // namespace layers
} // namespace mozilla
#endif // GFX_WEBRENDERTEXTLAYER_H