Bug 1360246 - Remove the RelativeToParent functions by propagating StackingContextHelper chains. r=nical
authorKartikaya Gupta <kgupta@mozilla.com>
Wed, 03 May 2017 08:48:08 -0400
changeset 357033 0f0a5f78c75c6f3be940f20c710b65103401bf20
parent 357032 2e29ab7dc180e0e30423ced43632a9d0a80a3208
child 357034 7cb3c4963a3fda3a9ed8fc4ef3e08296c693a53d
push id31780
push userkwierso@gmail.com
push dateMon, 08 May 2017 20:34:47 +0000
treeherdermozilla-central@bab7046ee2d8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs1360246
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1360246 - Remove the RelativeToParent functions by propagating StackingContextHelper chains. r=nical The only remaining callers of RelativeToParent() are in StackingContextHelper itself, which we can remove now by having the SCH take a parent SCH and use it instead of RelativeToParent(). This patch implements this change. This makes a failing test pass, because of how preserve-3d container layers work. Specifically, preserve-3d container layers render their descendants in z-order, not in tree order. If those children were assuming that their parent had already pushed a stacking context, that assumption may have been false because the parent might have not yet been rendered because of z-ordering. By using the StackingContextHelper chain instead of the layer tree ancestry, we fix the stacking-context-relative coordinates being used in the descendant subtree of preserve-3d container layers. MozReview-Commit-ID: HzZvBuAlMdB
gfx/layers/wr/StackingContextHelper.cpp
gfx/layers/wr/StackingContextHelper.h
gfx/layers/wr/WebRenderCanvasLayer.cpp
gfx/layers/wr/WebRenderColorLayer.cpp
gfx/layers/wr/WebRenderContainerLayer.cpp
gfx/layers/wr/WebRenderImageLayer.cpp
gfx/layers/wr/WebRenderLayer.cpp
gfx/layers/wr/WebRenderLayer.h
gfx/layers/wr/WebRenderPaintedLayer.cpp
gfx/layers/wr/WebRenderPaintedLayer.h
gfx/layers/wr/WebRenderPaintedLayerBlob.cpp
gfx/layers/wr/WebRenderPaintedLayerBlob.h
layout/reftests/transform-3d/reftest.list
--- a/gfx/layers/wr/StackingContextHelper.cpp
+++ b/gfx/layers/wr/StackingContextHelper.cpp
@@ -12,40 +12,42 @@ namespace mozilla {
 namespace layers {
 
 StackingContextHelper::StackingContextHelper()
   : mBuilder(nullptr)
 {
   // mOrigin remains at 0,0
 }
 
-StackingContextHelper::StackingContextHelper(wr::DisplayListBuilder& aBuilder,
+StackingContextHelper::StackingContextHelper(const StackingContextHelper& aParentSC,
+                                             wr::DisplayListBuilder& aBuilder,
                                              WebRenderLayer* aLayer,
                                              const Maybe<gfx::Matrix4x4>& aTransform)
   : mBuilder(&aBuilder)
 {
-  LayerRect scBounds = aLayer->RelativeToParent(aLayer->BoundsForStackingContext());
+  LayerRect scBounds = aLayer->BoundsForStackingContext();
   Layer* layer = aLayer->GetLayer();
   gfx::Matrix4x4 transform = aTransform.valueOr(layer->GetTransform());
-  mBuilder->PushStackingContext(wr::ToWrRect(scBounds),
+  mBuilder->PushStackingContext(aParentSC.ToRelativeWrRect(scBounds),
                                 1.0f,
                                 transform,
                                 wr::ToWrMixBlendMode(layer->GetMixBlendMode()));
   mOrigin = aLayer->Bounds().TopLeft();
 }
 
-StackingContextHelper::StackingContextHelper(wr::DisplayListBuilder& aBuilder,
+StackingContextHelper::StackingContextHelper(const StackingContextHelper& aParentSC,
+                                             wr::DisplayListBuilder& aBuilder,
                                              WebRenderLayer* aLayer,
                                              uint64_t aAnimationsId,
                                              float* aOpacityPtr,
                                              gfx::Matrix4x4* aTransformPtr)
   : mBuilder(&aBuilder)
 {
-  LayerRect scBounds = aLayer->RelativeToParent(aLayer->BoundsForStackingContext());
-  mBuilder->PushStackingContext(wr::ToWrRect(scBounds),
+  LayerRect scBounds = aLayer->BoundsForStackingContext();
+  mBuilder->PushStackingContext(aParentSC.ToRelativeWrRect(scBounds),
                                 aAnimationsId,
                                 aOpacityPtr,
                                 aTransformPtr,
                                 wr::ToWrMixBlendMode(aLayer->GetLayer()->GetMixBlendMode()));
   mOrigin = aLayer->Bounds().TopLeft();
 }
 
 StackingContextHelper::~StackingContextHelper()
--- a/gfx/layers/wr/StackingContextHelper.h
+++ b/gfx/layers/wr/StackingContextHelper.h
@@ -23,22 +23,24 @@ class WebRenderLayer;
  */
 class MOZ_RAII StackingContextHelper
 {
 public:
   // Pushes a stacking context onto the provided DisplayListBuilder. It uses
   // the transform if provided, otherwise takes the transform from the layer.
   // It also takes the mix-blend-mode and bounds from the layer, and uses 1.0
   // for the opacity.
-  StackingContextHelper(wr::DisplayListBuilder& aBuilder,
+  StackingContextHelper(const StackingContextHelper& aParentSC,
+                        wr::DisplayListBuilder& aBuilder,
                         WebRenderLayer* aLayer,
                         const Maybe<gfx::Matrix4x4>& aTransform = Nothing());
   // Alternate constructor which invokes the version of PushStackingContext
   // for animations.
-  StackingContextHelper(wr::DisplayListBuilder& aBuilder,
+  StackingContextHelper(const StackingContextHelper& aParentSC,
+                        wr::DisplayListBuilder& aBuilder,
                         WebRenderLayer* aLayer,
                         uint64_t aAnimationsId,
                         float* aOpacityPtr,
                         gfx::Matrix4x4* aTransformPtr);
   // 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.
--- a/gfx/layers/wr/WebRenderCanvasLayer.cpp
+++ b/gfx/layers/wr/WebRenderCanvasLayer.cpp
@@ -57,17 +57,17 @@ WebRenderCanvasLayer::RenderLayer(wr::Di
   }
 
   Maybe<gfx::Matrix4x4> transform;
   const bool needsYFlip = (mOriginPos == gl::OriginPos::BottomLeft);
   if (needsYFlip) {
     transform = Some(GetTransform().PreTranslate(0, mBounds.height, 0).PreScale(1, -1, 1));
   }
 
-  StackingContextHelper sc(aBuilder, this, transform);
+  StackingContextHelper sc(aSc, aBuilder, this, transform);
 
   LayerRect rect(0, 0, mBounds.width, mBounds.height);
   DumpLayerInfo("CanvasLayer", rect);
 
   LayerRect clipRect = ClipRect().valueOr(rect);
   Maybe<WrImageMask> mask = BuildWrMaskLayer(true);
   WrClipRegion clip = aBuilder.BuildClipRegion(
       sc.ToRelativeWrRect(clipRect),
--- a/gfx/layers/wr/WebRenderColorLayer.cpp
+++ b/gfx/layers/wr/WebRenderColorLayer.cpp
@@ -16,17 +16,17 @@ namespace mozilla {
 namespace layers {
 
 using namespace mozilla::gfx;
 
 void
 WebRenderColorLayer::RenderLayer(wr::DisplayListBuilder& aBuilder,
                                  const StackingContextHelper& aSc)
 {
-  StackingContextHelper sc(aBuilder, this);
+  StackingContextHelper sc(aSc, aBuilder, this);
 
   LayerRect rect = Bounds();
   DumpLayerInfo("ColorLayer", rect);
 
   LayerRect clipRect = ClipRect().valueOr(rect);
   Maybe<WrImageMask> mask = BuildWrMaskLayer(true);
   WrClipRegion clip = aBuilder.BuildClipRegion(
       sc.ToRelativeWrRect(clipRect),
--- a/gfx/layers/wr/WebRenderContainerLayer.cpp
+++ b/gfx/layers/wr/WebRenderContainerLayer.cpp
@@ -83,17 +83,17 @@ WebRenderContainerLayer::RenderLayer(wr:
 
     animationsId = GetCompositorAnimationsId();
     OpAddCompositorAnimations
       anim(CompositorAnimations(GetAnimations(), animationsId),
            transformForCompositor, opacityForCompositor);
     WrBridge()->AddWebRenderParentCommand(anim);
   }
 
-  StackingContextHelper sc(aBuilder, this, animationsId, opacityForSC, transformForSC);
+  StackingContextHelper sc(aSc, aBuilder, this, animationsId, opacityForSC, transformForSC);
 
   LayerRect rect = Bounds();
   DumpLayerInfo("ContainerLayer", rect);
 
   Maybe<WrImageMask> mask = BuildWrMaskLayer(true);
   aBuilder.PushClip(sc.ToRelativeWrRect(rect), mask.ptrOr(nullptr));
 
   for (LayerPolygon& child : children) {
--- a/gfx/layers/wr/WebRenderImageLayer.cpp
+++ b/gfx/layers/wr/WebRenderImageLayer.cpp
@@ -160,17 +160,17 @@ WebRenderImageLayer::RenderLayer(wr::Dis
                           mKey,
                           mExternalImageId.ref());
   }
 
   if (mKey.isNothing()) {
     return;
   }
 
-  StackingContextHelper sc(aBuilder, this);
+  StackingContextHelper sc(aSc, aBuilder, this);
 
   LayerRect rect(0, 0, size.width, size.height);
   if (mScaleMode != ScaleMode::SCALE_NONE) {
     NS_ASSERTION(mScaleMode == ScaleMode::STRETCH,
                  "No other scalemodes than stretch and none supported yet.");
     rect = LayerRect(0, 0, mScaleToSize.width, mScaleToSize.height);
   }
 
--- a/gfx/layers/wr/WebRenderLayer.cpp
+++ b/gfx/layers/wr/WebRenderLayer.cpp
@@ -46,29 +46,16 @@ WebRenderLayer::ParentBounds()
   // Walk up to find the parent stacking context. This will be created by the
   // parent layer which must be a ContainerLayer if it exists.
   if (Layer* parent = GetLayer()->GetParent()) {
     return ToWebRenderLayer(parent)->Bounds();
   }
   return LayerRect();
 }
 
-LayerRect
-WebRenderLayer::RelativeToParent(const LayerRect& aRect)
-{
-  return aRect - ParentBounds().TopLeft();
-}
-
-LayerRect
-WebRenderLayer::RelativeToParent(const LayoutDeviceRect& aRect)
-{
-  return RelativeToParent(ViewAs<LayerPixel>(
-      aRect, PixelCastJustification::WebRenderHasUnitResolution));
-}
-
 gfx::Rect
 WebRenderLayer::TransformedVisibleBoundsRelativeToParent()
 {
   IntRect bounds = GetLayer()->GetVisibleRegion().GetBounds().ToUnknownRect();
   Rect transformed = GetLayer()->GetTransform().TransformBounds(IntRectToRect(bounds));
   return transformed - ParentBounds().ToUnknownRect().TopLeft();
 }
 
--- a/gfx/layers/wr/WebRenderLayer.h
+++ b/gfx/layers/wr/WebRenderLayer.h
@@ -43,19 +43,16 @@ public:
                                      ImageContainer* aContainer,
                                      Maybe<wr::ImageKey>& aOldKey,
                                      wr::ExternalImageId& aExternalImageId);
 
   WebRenderLayerManager* WrManager();
   WebRenderBridgeChild* WrBridge();
   WrImageKey GetImageKey();
 
-  LayerRect RelativeToParent(const LayerRect& aRect);
-  LayerRect RelativeToParent(const LayoutDeviceRect& aRect);
-
   LayerRect Bounds();
   LayerRect BoundsForStackingContext();
 protected:
   BoundsTransformMatrix BoundsTransform();
   LayerRect ParentBounds();
   Maybe<LayerRect> ClipRect();
 
   gfx::Rect TransformedVisibleBoundsRelativeToParent();
--- a/gfx/layers/wr/WebRenderPaintedLayer.cpp
+++ b/gfx/layers/wr/WebRenderPaintedLayer.cpp
@@ -84,19 +84,20 @@ WebRenderPaintedLayer::UpdateImageClient
   if (!helper.UpdateImage()) {
     return false;
   }
 
   return true;
 }
 
 void
-WebRenderPaintedLayer::CreateWebRenderDisplayList(wr::DisplayListBuilder& aBuilder)
+WebRenderPaintedLayer::CreateWebRenderDisplayList(wr::DisplayListBuilder& aBuilder,
+                                                  const StackingContextHelper& aSc)
 {
-  StackingContextHelper sc(aBuilder, this);
+  StackingContextHelper sc(aSc, aBuilder, this);
 
   LayerRect rect = Bounds();
   DumpLayerInfo("PaintedLayer", rect);
 
   LayerRect clipRect = ClipRect().valueOr(rect);
   Maybe<WrImageMask> mask = BuildWrMaskLayer(true);
   WrClipRegion clip = aBuilder.BuildClipRegion(
       sc.ToRelativeWrRect(clipRect),
@@ -140,13 +141,13 @@ WebRenderPaintedLayer::RenderLayer(wr::D
     }
   } else {
     // We have an empty transaction, just reuse the old image we had before.
     MOZ_ASSERT(mExternalImageId);
     MOZ_ASSERT(mImageContainer->HasCurrentImage());
     MOZ_ASSERT(GetInvalidRegion().IsEmpty());
   }
 
-  CreateWebRenderDisplayList(aBuilder);
+  CreateWebRenderDisplayList(aBuilder, aSc);
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/wr/WebRenderPaintedLayer.h
+++ b/gfx/layers/wr/WebRenderPaintedLayer.h
@@ -50,15 +50,16 @@ public:
   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);
+  void CreateWebRenderDisplayList(wr::DisplayListBuilder& aBuilder,
+                                  const StackingContextHelper& aSc);
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif // GFX_WEBRENDERPAINTEDLAYER_H
--- a/gfx/layers/wr/WebRenderPaintedLayerBlob.cpp
+++ b/gfx/layers/wr/WebRenderPaintedLayerBlob.cpp
@@ -17,17 +17,17 @@
 
 namespace mozilla {
 namespace layers {
 
 using namespace mozilla::gfx;
 
 void
 WebRenderPaintedLayerBlob::RenderLayer(wr::DisplayListBuilder& aBuilder,
-                                       const StackingContextHelper& aHelper)
+                                       const StackingContextHelper& aSc)
 {
   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());
@@ -73,17 +73,17 @@ WebRenderPaintedLayerBlob::RenderLayer(w
     MOZ_ASSERT(GetInvalidRegion().IsEmpty());
   }
 
   wr::ByteBuffer bytes;
   bytes.Allocate(recorder->RecordingSize());
   DebugOnly<bool> ok = recorder->CopyRecording((char*)bytes.AsSlice().begin().get(), bytes.AsSlice().length());
   MOZ_ASSERT(ok);
 
-  StackingContextHelper sc(aBuilder, this);
+  StackingContextHelper sc(aSc, aBuilder, this);
   LayerRect rect = Bounds();
   DumpLayerInfo("PaintedLayer", rect);
 
   LayerRect clipRect = ClipRect().valueOr(rect);
   Maybe<WrImageMask> mask = BuildWrMaskLayer(true);
   WrClipRegion clip = aBuilder.BuildClipRegion(
       sc.ToRelativeWrRect(clipRect),
       mask.ptrOr(nullptr));
--- a/gfx/layers/wr/WebRenderPaintedLayerBlob.h
+++ b/gfx/layers/wr/WebRenderPaintedLayerBlob.h
@@ -43,17 +43,17 @@ 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,
-                   const StackingContextHelper& aHelper) override;
+                   const StackingContextHelper& aSc) override;
 private:
   RefPtr<ImageContainer> mImageContainer;
   RefPtr<ImageClient> mImageClient;
 
 };
 
 } // namespace layers
 } // namespace mozilla
--- a/layout/reftests/transform-3d/reftest.list
+++ b/layout/reftests/transform-3d/reftest.list
@@ -41,17 +41,17 @@ fails-if(webrender) == backface-visibili
 == perspective-clipping-1.html perspective-clipping-1-ref.html
 != perspective-origin-1a.html rotatex-perspective-1a.html
 == perspective-origin-1b.html perspective-origin-1a.html
 fuzzy(3,99) random-if(Android&&!browserIsRemote) == perspective-origin-2a.html perspective-origin-2-ref.html # subpixel AA, bug 732568
 fuzzy-if(winWidget&&!layersGPUAccelerated,1,61) == perspective-origin-3a.html perspective-origin-3-ref.html
 == perspective-origin-4a.html perspective-origin-4-ref.html
 fails-if(webrender) == perspective-zindex.html green-rect.html
 fails-if(webrender) == perspective-zindex-2.html green-rect.html
-fails-if(webrender) fails-if(stylo) != sorting-1a.html sorting-1-ref.html
+fails-if(stylo) != sorting-1a.html sorting-1-ref.html
 # Parallel planes, different z depth
 fails-if(webrender) == sorting-2a.html sorting-2-ref.html
 # Parallel planes, same z depth (shouldn't be sorted!)
 fails-if(webrender) == sorting-2b.html sorting-2-ref.html
 fails-if(webrender) == sorting-3a.html green-rect.html
 # Different, but equivalent (for the given transform) transform origins
 == rotatex-transformorigin-1a.html rotatex-transformorigin-1-ref.html
 fuzzy-if((gtkWidget&&layersOMTC)||(winWidget&&!layersGPUAccelerated),1,86) == overflow-hidden-1a.html overflow-hidden-1-ref.html