Bug 1354464 - Fix the size of webrender mask layer. r=mchang
authorEthan Lin <ethlin@mozilla.com>
Mon, 10 Apr 2017 17:10:37 +0800
changeset 400878 09534c0cda7cab07bcdd1a08b097b468cbce9059
parent 400877 c2d11e5e96d664e9c88384fe3c3dfbb600f225e8
child 400879 350d77ec1b74f2c1bbd39aab6f9e7de33f0ce2d0
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmchang
bugs1354464
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 1354464 - Fix the size of webrender mask layer. r=mchang
gfx/layers/wr/WebRenderImageLayer.cpp
gfx/layers/wr/WebRenderImageLayer.h
gfx/layers/wr/WebRenderLayerManager.cpp
gfx/layers/wr/WebRenderLayerManager.h
--- a/gfx/layers/wr/WebRenderImageLayer.cpp
+++ b/gfx/layers/wr/WebRenderImageLayer.cpp
@@ -167,17 +167,17 @@ WebRenderImageLayer::RenderLayer(wr::Dis
                             mixBlendMode);
   aBuilder.PushImage(wr::ToWrRect(rect), clip, filter, key);
   aBuilder.PopStackingContext();
 
   //mContainer->SetImageFactory(originalIF);
 }
 
 Maybe<WrImageMask>
-WebRenderImageLayer::RenderMaskLayer()
+WebRenderImageLayer::RenderMaskLayer(const gfx::Matrix4x4& aTransform)
 {
   if (!mContainer) {
      return Nothing();
   }
 
   CompositableType type = GetImageClientType();
   if (type == CompositableType::UNKNOWN) {
     return Nothing();
@@ -220,15 +220,16 @@ WebRenderImageLayer::RenderMaskLayer()
   WrImageKey key;
   key.mNamespace = WrBridge()->GetNamespace();
   key.mHandle = WrBridge()->GetNextResourceId();
   WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(mExternalImageId, key));
 
   gfx::IntSize size = image->GetSize();
   WrImageMask imageMask;
   imageMask.image = key;
-  imageMask.rect = wr::ToWrRect(Rect(0, 0, size.width, size.height));
+  Rect maskRect = aTransform.TransformBounds(Rect(0, 0, size.width, size.height));
+  imageMask.rect = wr::ToWrRect(maskRect);
   imageMask.repeat = false;
   return Some(imageMask);
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/wr/WebRenderImageLayer.h
+++ b/gfx/layers/wr/WebRenderImageLayer.h
@@ -28,17 +28,17 @@ protected:
   WebRenderLayerManager* Manager()
   {
     return static_cast<WebRenderLayerManager*>(mManager);
   }
 
 public:
   Layer* GetLayer() override { return this; }
   void RenderLayer(wr::DisplayListBuilder& aBuilder) override;
-  Maybe<WrImageMask> RenderMaskLayer() override;
+  Maybe<WrImageMask> RenderMaskLayer(const gfx::Matrix4x4& aTransform) override;
 
 protected:
   CompositableType GetImageClientType();
 
   uint64_t mExternalImageId;
   RefPtr<ImageClient> mImageClient;
   CompositableType mImageClientTypeContainer;
 };
--- a/gfx/layers/wr/WebRenderLayerManager.cpp
+++ b/gfx/layers/wr/WebRenderLayerManager.cpp
@@ -107,17 +107,20 @@ WebRenderLayer::TransformedVisibleBounds
   return RelativeToParent(transformed);
 }
 
 Maybe<WrImageMask>
 WebRenderLayer::BuildWrMaskLayer()
 {
   if (GetLayer()->GetMaskLayer()) {
     WebRenderLayer* maskLayer = ToWebRenderLayer(GetLayer()->GetMaskLayer());
-    return maskLayer->RenderMaskLayer();
+    // The size of mask layer is transformed, and we also push 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());
   }
 
   return Nothing();
 }
 
 gfx::Rect
 WebRenderLayer::GetWrBoundsRect()
 {
@@ -137,28 +140,34 @@ WebRenderLayer::GetWrClipRect(gfx::Rect&
            );
   } else {
     clip = aRect;
   }
 
   return clip;
 }
 
+gfx::Matrix4x4
+WebRenderLayer::GetWrBoundTransform()
+{
+  gfx::Matrix4x4 transform = GetLayer()->GetTransform();
+  transform._41 = 0.0f;
+  transform._42 = 0.0f;
+  transform._43 = 0.0f;
+  return transform;
+}
+
 gfx::Rect
 WebRenderLayer::GetWrRelBounds()
 {
   gfx::Rect relBounds = VisibleBoundsRelativeToParent();
-  gfx::Matrix4x4 transform = GetLayer()->GetTransform();
+  gfx::Matrix4x4 transform = GetWrBoundTransform();
   if (!transform.IsIdentity()) {
     // WR will only apply the 'translate' of the transform, so we need to do the scale/rotation manually.
-    gfx::Matrix4x4 boundTransform = transform;
-    boundTransform._41 = 0.0f;
-    boundTransform._42 = 0.0f;
-    boundTransform._43 = 0.0f;
-    relBounds.MoveTo(boundTransform.TransformPoint(relBounds.TopLeft()));
+    relBounds.MoveTo(transform.TransformPoint(relBounds.TopLeft()));
   }
 
   return relBounds;
 }
 
 void
 WebRenderLayer::DumpLayerInfo(const char* aLayerType, gfx::Rect& aRect)
 {
--- a/gfx/layers/wr/WebRenderLayerManager.h
+++ b/gfx/layers/wr/WebRenderLayerManager.h
@@ -25,17 +25,17 @@ class WebRenderBridgeChild;
 class WebRenderLayerManager;
 class APZCTreeManager;
 
 class WebRenderLayer
 {
 public:
   virtual Layer* GetLayer() = 0;
   virtual void RenderLayer(wr::DisplayListBuilder& aBuilder) = 0;
-  virtual Maybe<WrImageMask> RenderMaskLayer()
+  virtual Maybe<WrImageMask> RenderMaskLayer(const gfx::Matrix4x4& aTransform)
   {
     MOZ_ASSERT(false);
     return Nothing();
   }
 
   virtual already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() { return nullptr; }
   static inline WebRenderLayer*
   ToWebRenderLayer(Layer* aLayer)
@@ -52,16 +52,17 @@ public:
   gfx::Rect RelativeToParent(gfx::Rect aRect);
   gfx::Rect VisibleBoundsRelativeToParent();
   gfx::Point GetOffsetToParent();
   gfx::Rect TransformedVisibleBoundsRelativeToParent();
 protected:
   gfx::Rect GetWrBoundsRect();
   gfx::Rect GetWrRelBounds();
   gfx::Rect GetWrClipRect(gfx::Rect& aRect);
+  gfx::Matrix4x4 GetWrBoundTransform();
   void DumpLayerInfo(const char* aLayerType, gfx::Rect& aRect);
   Maybe<WrImageMask> BuildWrMaskLayer();
 };
 
 class WebRenderLayerManager final : public LayerManager
 {
   typedef nsTArray<RefPtr<Layer> > LayerRefArray;