Bug 1220873 - Make Layer::mVisibleRegion a LayerIntRegion. r=botond
authorSunny Sidhu <sidhus11@uni.coventry.ac.uk>
Sun, 29 Nov 2015 02:07:55 -0500
changeset 274518 294b89a6fdae56d6eb3870081b5457238851e58c
parent 274517 673461c0b772b7a63fc9eb4115ae682c3a9c32e1
child 274519 4d7efb9a8026d7b36eac541f4606157ad073743a
push id68614
push userbballo@mozilla.com
push dateSun, 29 Nov 2015 19:11:27 +0000
treeherdermozilla-inbound@294b89a6fdae [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbotond
bugs1220873
milestone45.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 1220873 - Make Layer::mVisibleRegion a LayerIntRegion. r=botond
dom/base/nsDOMWindowUtils.cpp
embedding/browser/nsWebBrowser.cpp
gfx/ipc/GfxMessageUtils.h
gfx/layers/LayerMetricsWrapper.h
gfx/layers/LayerSorter.cpp
gfx/layers/LayerTreeInvalidation.cpp
gfx/layers/Layers.cpp
gfx/layers/Layers.h
gfx/layers/ReadbackProcessor.cpp
gfx/layers/RotatedBuffer.cpp
gfx/layers/apz/test/gtest/TestAsyncPanZoomController.cpp
gfx/layers/basic/BasicCanvasLayer.h
gfx/layers/basic/BasicColorLayer.cpp
gfx/layers/basic/BasicContainerLayer.cpp
gfx/layers/basic/BasicContainerLayer.h
gfx/layers/basic/BasicImageLayer.cpp
gfx/layers/basic/BasicLayerManager.cpp
gfx/layers/basic/BasicLayersImpl.h
gfx/layers/basic/BasicPaintedLayer.cpp
gfx/layers/basic/BasicPaintedLayer.h
gfx/layers/client/ClientCanvasLayer.h
gfx/layers/client/ClientColorLayer.cpp
gfx/layers/client/ClientContainerLayer.h
gfx/layers/client/ClientImageLayer.cpp
gfx/layers/client/ClientPaintedLayer.cpp
gfx/layers/client/ClientPaintedLayer.h
gfx/layers/client/ClientTiledPaintedLayer.cpp
gfx/layers/composite/ContainerLayerComposite.cpp
gfx/layers/composite/LayerManagerComposite.cpp
gfx/layers/composite/LayerManagerComposite.h
gfx/layers/composite/PaintedLayerComposite.cpp
gfx/layers/ipc/CompositorParent.cpp
gfx/layers/ipc/LayersMessages.ipdlh
gfx/tests/gtest/TestCompositor.cpp
gfx/tests/gtest/TestLayers.cpp
layout/base/FrameLayerBuilder.cpp
layout/base/nsPresContext.cpp
layout/base/nsPresShell.cpp
widget/gonk/HwcComposer2D.cpp
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -2562,17 +2562,17 @@ CheckLeafLayers(Layer* aLayer, const nsI
   Layer* child = aLayer->GetFirstChild();
   if (child) {
     while (child) {
       if (!CheckLeafLayers(child, offset, aCoveredRegion))
         return false;
       child = child->GetNextSibling();
     }
   } else {
-    nsIntRegion rgn = aLayer->GetVisibleRegion();
+    nsIntRegion rgn = aLayer->GetVisibleRegion().ToUnknownRegion();
     rgn.MoveBy(offset);
     nsIntRegion tmp;
     tmp.And(rgn, *aCoveredRegion);
     if (!tmp.IsEmpty())
       return false;
     aCoveredRegion->Or(*aCoveredRegion, rgn);
   }
 
@@ -2598,17 +2598,17 @@ nsDOMWindowUtils::LeafLayersPartitionWin
   if (!root)
     return NS_ERROR_FAILURE;
 
   nsIntPoint offset(0, 0);
   nsIntRegion coveredRegion;
   if (!CheckLeafLayers(root, offset, &coveredRegion)) {
     *aResult = false;
   }
-  if (!coveredRegion.IsEqual(root->GetVisibleRegion())) {
+  if (!coveredRegion.IsEqual(root->GetVisibleRegion().ToUnknownRegion())) {
     *aResult = false;
   }
 #endif
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::CheckAndClearPaintedState(nsIDOMElement* aElement, bool* aResult)
--- a/embedding/browser/nsWebBrowser.cpp
+++ b/embedding/browser/nsWebBrowser.cpp
@@ -1732,17 +1732,17 @@ nsWebBrowser::PaintWindow(nsIWidget* aWi
 {
   LayerManager* layerManager = aWidget->GetLayerManager();
   NS_ASSERTION(layerManager, "Must be in paint event");
 
   layerManager->BeginTransaction();
   RefPtr<PaintedLayer> root = layerManager->CreatePaintedLayer();
   if (root) {
     nsIntRect dirtyRect = aRegion.GetBounds();
-    root->SetVisibleRegion(dirtyRect);
+    root->SetVisibleRegion(LayerIntRegion::FromUnknownRegion(dirtyRect));
     layerManager->SetRoot(root);
   }
 
   layerManager->EndTransaction(DrawPaintedLayer, &mBackgroundColor);
   return true;
 }
 
 NS_IMETHODIMP
--- a/gfx/ipc/GfxMessageUtils.h
+++ b/gfx/ipc/GfxMessageUtils.h
@@ -391,19 +391,21 @@ struct RegionParamTraits
       if (rect.IsEmpty())
         return true;
       result->Or(*result, rect);
     }
     return false;
   }
 };
 
-template<>
-struct ParamTraits<nsIntRegion>
-  : RegionParamTraits<nsIntRegion, mozilla::gfx::IntRect, nsIntRegionRectIterator>
+template<class Units>
+struct ParamTraits<mozilla::gfx::IntRegionTyped<Units>>
+  : RegionParamTraits<mozilla::gfx::IntRegionTyped<Units>,
+                      mozilla::gfx::IntRectTyped<Units>,
+                      typename mozilla::gfx::IntRegionTyped<Units>::RectIterator>
 {};
 
 template<>
 struct ParamTraits<mozilla::gfx::IntSize>
 {
   typedef mozilla::gfx::IntSize paramType;
 
   static void Write(Message* msg, const paramType& param)
--- a/gfx/layers/LayerMetricsWrapper.h
+++ b/gfx/layers/LayerMetricsWrapper.h
@@ -338,24 +338,24 @@ public:
     MOZ_ASSERT(IsValid());
 
     if (AtBottomLayer()) {
       return mLayer->AsRefLayer();
     }
     return nullptr;
   }
 
-  nsIntRegion GetVisibleRegion() const
+  LayerIntRegion GetVisibleRegion() const
   {
     MOZ_ASSERT(IsValid());
 
     if (AtBottomLayer()) {
       return mLayer->GetVisibleRegion();
     }
-    nsIntRegion region = mLayer->GetVisibleRegion();
+    LayerIntRegion region = mLayer->GetVisibleRegion();
     region.Transform(mLayer->GetTransform());
     return region;
   }
 
   const Maybe<ParentLayerIntRect>& GetClipRect() const
   {
     MOZ_ASSERT(IsValid());
 
--- a/gfx/layers/LayerSorter.cpp
+++ b/gfx/layers/LayerSorter.cpp
@@ -71,18 +71,18 @@ static gfxFloat RecoverZDepth(const Matr
  * depths and use this point to determine an ordering for the two layers.
  * For layers that are intersecting in 3d space, this essentially guesses an 
  * order. In a lot of cases we only intersect right at the edge point (3d cubes
  * in particular) and this generates the 'correct' looking ordering. For planes
  * that truely intersect, then there is no correct ordering and this remains
  * unsolved without changing our rendering code.
  */
 static LayerSortOrder CompareDepth(Layer* aOne, Layer* aTwo) {
-  gfxRect ourRect = ThebesRect(aOne->GetEffectiveVisibleRegion().GetBounds());
-  gfxRect otherRect = ThebesRect(aTwo->GetEffectiveVisibleRegion().GetBounds());
+  gfxRect ourRect = ThebesRect(aOne->GetEffectiveVisibleRegion().ToUnknownRegion().GetBounds());
+  gfxRect otherRect = ThebesRect(aTwo->GetEffectiveVisibleRegion().ToUnknownRegion().GetBounds());
 
   MOZ_ASSERT(aOne->GetParent() && aOne->GetParent()->Extend3DContext() &&
              aTwo->GetParent() && aTwo->GetParent()->Extend3DContext());
   // Effective transform of leaves may had been projected to 2D.
   Matrix4x4 ourTransform =
     aOne->GetLocalTransform() * aOne->GetParent()->GetEffectiveTransform();
   Matrix4x4 otherTransform =
     aTwo->GetLocalTransform() * aTwo->GetParent()->GetEffectiveTransform();
--- a/gfx/layers/LayerTreeInvalidation.cpp
+++ b/gfx/layers/LayerTreeInvalidation.cpp
@@ -120,25 +120,25 @@ NotifySubdocumentInvalidationRecursive(L
   if (!container) {
     return;
   }
 
   for (Layer* child = container->GetFirstChild(); child; child = child->GetNextSibling()) {
     NotifySubdocumentInvalidationRecursive(child, aCallback);
   }
 
-  aCallback(container, container->GetVisibleRegion());
+  aCallback(container, container->GetVisibleRegion().ToUnknownRegion());
 }
 
 struct LayerPropertiesBase : public LayerProperties
 {
   explicit LayerPropertiesBase(Layer* aLayer)
     : mLayer(aLayer)
     , mMaskLayer(nullptr)
-    , mVisibleRegion(aLayer->GetVisibleRegion())
+    , mVisibleRegion(aLayer->GetVisibleRegion().ToUnknownRegion())
     , mInvalidRegion(aLayer->GetInvalidRegion())
     , mPostXScale(aLayer->GetPostXScale())
     , mPostYScale(aLayer->GetPostYScale())
     , mOpacity(aLayer->GetLocalOpacity())
     , mUseClipRect(!!aLayer->GetEffectiveClipRect())
   {
     MOZ_COUNT_CTOR(LayerPropertiesBase);
     if (aLayer->GetMaskLayer()) {
@@ -230,23 +230,23 @@ struct LayerPropertiesBase : public Laye
     }
 
     mLayer->ClearInvalidRect();
     return result;
   }
 
   IntRect NewTransformedBounds()
   {
-    return TransformRect(mLayer->GetVisibleRegion().GetBounds(),
+    return TransformRect(mLayer->GetVisibleRegion().ToUnknownRegion().GetBounds(),
                          GetTransformForInvalidation(mLayer));
   }
 
   IntRect OldTransformedBounds()
   {
-    return TransformRect(mVisibleRegion.GetBounds(), mTransform);
+    return TransformRect(mVisibleRegion.ToUnknownRegion().GetBounds(), mTransform);
   }
 
   virtual nsIntRegion ComputeChangeInternal(NotifySubDocInvalidationFunc aCallback,
                                             bool& aGeometryChanged)
   {
     return IntRect();
   }
 
@@ -342,17 +342,17 @@ struct ContainerLayerProperties : public
           invalidateChildsCurrentArea = true;
         }
       } else {
         // |child| is new, or was reordered to a higher index
         invalidateChildsCurrentArea = true;
       }
       if (invalidateChildsCurrentArea) {
         aGeometryChanged = true;
-        AddTransformedRegion(result, child->GetVisibleRegion(),
+        AddTransformedRegion(result, child->GetVisibleRegion().ToUnknownRegion(),
                              GetTransformForInvalidation(child));
         if (aCallback) {
           NotifySubdocumentInvalidationRecursive(child, aCallback);
         } else {
           ClearInvalidations(child);
         }
       }
       childrenChanged |= invalidateChildsCurrentArea;
@@ -449,17 +449,17 @@ struct ImageLayerProperties : public Lay
     }
   }
 
   virtual nsIntRegion ComputeChangeInternal(NotifySubDocInvalidationFunc aCallback,
                                             bool& aGeometryChanged)
   {
     ImageLayer* imageLayer = static_cast<ImageLayer*>(mLayer.get());
     
-    if (!imageLayer->GetVisibleRegion().IsEqual(mVisibleRegion)) {
+    if (!imageLayer->GetVisibleRegion().ToUnknownRegion().IsEqual(mVisibleRegion)) {
       aGeometryChanged = true;
       IntRect result = NewTransformedBounds();
       result = result.Union(OldTransformedBounds());
       return result;
     }
 
     ImageContainer* container = imageLayer->GetContainer();
     ImageHost* host = GetImageHost(imageLayer);
@@ -591,17 +591,17 @@ LayerPropertiesBase::ComputeDifferences(
 {
   NS_ASSERTION(aRoot, "Must have a layer tree to compare against!");
   if (mLayer != aRoot) {
     if (aCallback) {
       NotifySubdocumentInvalidationRecursive(aRoot, aCallback);
     } else {
       ClearInvalidations(aRoot);
     }
-    IntRect result = TransformRect(aRoot->GetVisibleRegion().GetBounds(),
+    IntRect result = TransformRect(aRoot->GetVisibleRegion().ToUnknownRegion().GetBounds(),
                                      aRoot->GetLocalTransform());
     result = result.Union(OldTransformedBounds());
     if (aGeometryChanged != nullptr) {
       *aGeometryChanged = true;
     }
     return result;
   } else {
     bool geometryChanged = (aGeometryChanged != nullptr) ? *aGeometryChanged : false;
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -614,17 +614,17 @@ const Maybe<ParentLayerIntRect>&
 Layer::GetEffectiveClipRect()
 {
   if (LayerComposite* shadow = AsLayerComposite()) {
     return shadow->GetShadowClipRect();
   }
   return GetClipRect();
 }
 
-const nsIntRegion&
+const LayerIntRegion&
 Layer::GetEffectiveVisibleRegion()
 {
   if (LayerComposite* shadow = AsLayerComposite()) {
     return shadow->GetShadowVisibleRegion();
   }
   return GetVisibleRegion();
 }
 
@@ -1018,17 +1018,17 @@ Layer::GetVisibleRegionRelativeToRootLay
 {
   MOZ_ASSERT(aLayerOffset, "invalid offset pointer");
 
   if (!GetParent()) {
     return false;
   }
 
   IntPoint offset;
-  aResult = GetEffectiveVisibleRegion();
+  aResult = GetEffectiveVisibleRegion().ToUnknownRegion();
   for (Layer* layer = this; layer; layer = layer->GetParent()) {
     gfx::Matrix matrix;
     if (!layer->GetLocalTransform().Is2D(&matrix) ||
         !matrix.IsTranslation()) {
       return false;
     }
 
     // The offset of |layer| to its parent.
@@ -1055,17 +1055,17 @@ Layer::GetVisibleRegionRelativeToRootLay
       if (!sibling->GetLocalTransform().Is2D(&siblingMatrix) ||
           !siblingMatrix.IsTranslation()) {
         return false;
       }
 
       // Retreive the translation from sibling to |layer|. The accumulated
       // visible region is currently oriented with |layer|.
       IntPoint siblingOffset = RoundedToInt(siblingMatrix.GetTranslation());
-      nsIntRegion siblingVisibleRegion(sibling->GetEffectiveVisibleRegion());
+      nsIntRegion siblingVisibleRegion(sibling->GetEffectiveVisibleRegion().ToUnknownRegion());
       // Translate the siblings region to |layer|'s origin.
       siblingVisibleRegion.MoveBy(-siblingOffset.x, -siblingOffset.y);
       // Apply the sibling's clip.
       // Layer clip rects are not affected by the layer's transform.
       Maybe<ParentLayerIntRect> clipRect = sibling->GetEffectiveClipRect();
       if (clipRect) {
         siblingVisibleRegion.AndWith(clipRect->ToUnknownRect());
       }
@@ -1889,17 +1889,17 @@ Layer::PrintInfo(std::stringstream& aStr
   }
   if (mTransformIsPerspective) {
     aStream << " [perspective]";
   }
   if (!mLayerBounds.IsEmpty()) {
     AppendToString(aStream, mLayerBounds, " [bounds=", "]");
   }
   if (!mVisibleRegion.IsEmpty()) {
-    AppendToString(aStream, mVisibleRegion, " [visible=", "]");
+    AppendToString(aStream, mVisibleRegion.ToUnknownRegion(), " [visible=", "]");
   } else {
     aStream << " [not visible]";
   }
   if (!mEventRegions.IsEmpty()) {
     AppendToString(aStream, mEventRegions, " ", "");
   }
   if (1.0 != mOpacity) {
     aStream << nsPrintfCString(" [opacity=%g]", mOpacity).get();
@@ -2008,30 +2008,30 @@ Layer::DumpPacket(layerscope::LayersPack
     LayersPacket::Layer::Shadow* s = layer->mutable_shadow();
     if (const Maybe<ParentLayerIntRect>& clipRect = lc->GetShadowClipRect()) {
       DumpRect(s->mutable_clip(), *clipRect);
     }
     if (!lc->GetShadowTransform().IsIdentity()) {
       DumpTransform(s->mutable_transform(), lc->GetShadowTransform());
     }
     if (!lc->GetShadowVisibleRegion().IsEmpty()) {
-      DumpRegion(s->mutable_vregion(), lc->GetShadowVisibleRegion());
+      DumpRegion(s->mutable_vregion(), lc->GetShadowVisibleRegion().ToUnknownRegion());
     }
   }
   // Clip
   if (mClipRect) {
     DumpRect(layer->mutable_clip(), *mClipRect);
   }
   // Transform
   if (!mTransform.IsIdentity()) {
     DumpTransform(layer->mutable_transform(), mTransform);
   }
   // Visible region
-  if (!mVisibleRegion.IsEmpty()) {
-    DumpRegion(layer->mutable_vregion(), mVisibleRegion);
+  if (!mVisibleRegion.ToUnknownRegion().IsEmpty()) {
+    DumpRegion(layer->mutable_vregion(), mVisibleRegion.ToUnknownRegion());
   }
   // EventRegions
   if (!mEventRegions.IsEmpty()) {
     const EventRegions &e = mEventRegions;
     if (!e.mHitRegion.IsEmpty()) {
       DumpRegion(layer->mutable_hitregion(), e.mHitRegion);
     }
     if (!e.mDispatchToContentHitRegion.IsEmpty()) {
@@ -2417,30 +2417,30 @@ PrintInfo(std::stringstream& aStream, La
   }
   if (const Maybe<ParentLayerIntRect>& clipRect = aLayerComposite->GetShadowClipRect()) {
     AppendToString(aStream, *clipRect, " [shadow-clip=", "]");
   }
   if (!aLayerComposite->GetShadowTransform().IsIdentity()) {
     AppendToString(aStream, aLayerComposite->GetShadowTransform(), " [shadow-transform=", "]");
   }
   if (!aLayerComposite->GetShadowVisibleRegion().IsEmpty()) {
-    AppendToString(aStream, aLayerComposite->GetShadowVisibleRegion(), " [shadow-visible=", "]");
+    AppendToString(aStream, aLayerComposite->GetShadowVisibleRegion().ToUnknownRegion(), " [shadow-visible=", "]");
   }
 }
 
 void
 SetAntialiasingFlags(Layer* aLayer, DrawTarget* aTarget)
 {
   bool permitSubpixelAA = !(aLayer->GetContentFlags() & Layer::CONTENT_DISABLE_SUBPIXEL_AA);
   if (aTarget->GetFormat() != SurfaceFormat::B8G8R8A8) {
     aTarget->SetPermitSubpixelAA(permitSubpixelAA);
     return;
   }
 
-  const IntRect& bounds = aLayer->GetVisibleRegion().GetBounds();
+  const IntRect& bounds = aLayer->GetVisibleRegion().ToUnknownRegion().GetBounds();
   gfx::Rect transformedBounds = aTarget->GetTransform().TransformBounds(gfx::Rect(Float(bounds.x), Float(bounds.y),
                                                                                   Float(bounds.width), Float(bounds.height)));
   transformedBounds.RoundOut();
   IntRect intTransformedBounds;
   transformedBounds.ToIntRect(&intTransformedBounds);
   permitSubpixelAA &= !(aLayer->GetContentFlags() & Layer::CONTENT_COMPONENT_ALPHA) ||
                       aTarget->GetOpaqueRect().Contains(intTransformedBounds);
   aTarget->SetPermitSubpixelAA(permitSubpixelAA);
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -840,17 +840,17 @@ public:
    * that are covered by opaque contents of other layers, and it can
    * exclude areas where this layer simply contains no content at all.
    * (This can be an overapproximation to the "true" visible region.)
    *
    * There is no general guarantee that drawing outside the bounds of the
    * visible region will be ignored. So if a layer draws outside the bounds
    * of its visible region, it needs to ensure that what it draws is valid.
    */
-  virtual void SetVisibleRegion(const nsIntRegion& aRegion)
+  virtual void SetVisibleRegion(const LayerIntRegion& aRegion)
   {
     if (!mVisibleRegion.IsEqual(aRegion)) {
       MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) VisibleRegion was %s is %s", this,
         mVisibleRegion.ToString().get(), aRegion.ToString().get()));
       mVisibleRegion = aRegion;
       Mutated();
     }
   }
@@ -1256,17 +1256,17 @@ public:
   }
 
   // These getters can be used anytime.
   float GetOpacity() { return mOpacity; }
   gfx::CompositionOp GetMixBlendMode() const { return mMixBlendMode; }
   const Maybe<ParentLayerIntRect>& GetClipRect() const { return mClipRect; }
   uint32_t GetContentFlags() { return mContentFlags; }
   const gfx::IntRect& GetLayerBounds() const { return mLayerBounds; }
-  const nsIntRegion& GetVisibleRegion() const { return mVisibleRegion; }
+  const LayerIntRegion& GetVisibleRegion() const { return mVisibleRegion; }
   const FrameMetrics& GetFrameMetrics(uint32_t aIndex) const;
   uint32_t GetFrameMetricsCount() const { return mFrameMetrics.Length(); }
   const nsTArray<FrameMetrics>& GetAllFrameMetrics() { return mFrameMetrics; }
   bool HasScrollableFrameMetrics() const;
   bool IsScrollInfoLayer() const;
   const EventRegions& GetEventRegions() const { return mEventRegions; }
   ContainerLayer* GetParent() { return mParent; }
   Layer* GetNextSibling() { return mNextSibling; }
@@ -1468,17 +1468,17 @@ public:
    * ShadowableLayer.  Can be used anytime.
    */
   virtual ShadowableLayer* AsShadowableLayer() { return nullptr; }
 
   // These getters can be used anytime.  They return the effective
   // values that should be used when drawing this layer to screen,
   // accounting for this layer possibly being a shadow.
   const Maybe<ParentLayerIntRect>& GetEffectiveClipRect();
-  const nsIntRegion& GetEffectiveVisibleRegion();
+  const LayerIntRegion& GetEffectiveVisibleRegion();
 
   bool Extend3DContext() {
     return GetContentFlags() & CONTENT_EXTEND_3D_CONTEXT;
   }
   bool Combines3DTransformWithAncestors() {
     return GetParent() &&
       reinterpret_cast<Layer*>(GetParent())->Extend3DContext();
   }
@@ -1639,17 +1639,17 @@ public:
   const nsIntRegion& GetInvalidRegion() { return mInvalidRegion; }
   const void AddInvalidRegion(const nsIntRegion& aRegion) {
     mInvalidRegion.Or(mInvalidRegion, aRegion);
   }
 
   /**
    * Mark the entirety of the layer's visible region as being invalid.
    */
-  void SetInvalidRectToVisibleRegion() { mInvalidRegion = GetVisibleRegion(); }
+  void SetInvalidRectToVisibleRegion() { mInvalidRegion = GetVisibleRegion().ToUnknownRegion(); }
 
   /**
    * Adds to the current invalid rect.
    */
   void AddInvalidRect(const gfx::IntRect& aRect) { mInvalidRegion.Or(mInvalidRegion, aRect); }
 
   /**
    * Clear the invalid rect, marking the layer as being identical to what is currently
@@ -1782,17 +1782,17 @@ protected:
   ContainerLayer* mParent;
   Layer* mNextSibling;
   Layer* mPrevSibling;
   void* mImplData;
   RefPtr<Layer> mMaskLayer;
   nsTArray<RefPtr<Layer>> mAncestorMaskLayers;
   gfx::UserData mUserData;
   gfx::IntRect mLayerBounds;
-  nsIntRegion mVisibleRegion;
+  LayerIntRegion mVisibleRegion;
   nsTArray<FrameMetrics> mFrameMetrics;
   EventRegions mEventRegions;
   gfx::Matrix4x4 mTransform;
   // A mutation of |mTransform| that we've queued to be applied at the
   // end of the next transaction (if nothing else overrides it in the
   // meantime).
   nsAutoPtr<gfx::Matrix4x4> mPendingTransform;
   float mPostXScale;
@@ -2083,17 +2083,17 @@ public:
    * in this layer's coordinate system.
    *
    * NOTE: Since this layer has an intermediate surface it follows
    *       that LayerPixel == RenderTargetPixel
    */
   RenderTargetIntRect GetIntermediateSurfaceRect()
   {
     NS_ASSERTION(mUseIntermediateSurface, "Must have intermediate surface");
-    return RenderTargetIntRect::FromUnknownRect(GetEffectiveVisibleRegion().GetBounds());
+    return RenderTargetIntRect::FromUnknownRect(GetEffectiveVisibleRegion().ToUnknownRegion().GetBounds());
   }
 
   /**
    * Returns true if this container has more than one non-empty child
    */
   bool HasMultipleChildren();
 
   /**
--- a/gfx/layers/ReadbackProcessor.cpp
+++ b/gfx/layers/ReadbackProcessor.cpp
@@ -58,17 +58,17 @@ FindBackgroundLayer(ReadbackLayer* aLaye
   for (Layer* l = aLayer->GetPrevSibling(); l; l = l->GetPrevSibling()) {
     gfx::Matrix backgroundTransform;
     if (!l->GetTransform().Is2D(&backgroundTransform) ||
         gfx::ThebesMatrix(backgroundTransform).HasNonIntegerTranslation())
       return nullptr;
 
     nsIntPoint backgroundOffset(int32_t(backgroundTransform._31), int32_t(backgroundTransform._32));
     IntRect rectInBackground(transformOffset - backgroundOffset, aLayer->GetSize());
-    const nsIntRegion& visibleRegion = l->GetEffectiveVisibleRegion();
+    const nsIntRegion visibleRegion = l->GetEffectiveVisibleRegion().ToUnknownRegion();
     if (!visibleRegion.Intersects(rectInBackground))
       continue;
     // Since l is present in the background, from here on we either choose l
     // or nothing.
     if (!visibleRegion.Contains(rectInBackground))
       return nullptr;
 
     if (l->GetEffectiveOpacity() != 1.0 ||
--- a/gfx/layers/RotatedBuffer.cpp
+++ b/gfx/layers/RotatedBuffer.cpp
@@ -216,24 +216,24 @@ RotatedContentBuffer::DrawTo(PaintedLaye
   bool clipped = false;
 
   // If the entire buffer is valid, we can just draw the whole thing,
   // no need to clip. But we'll still clip if clipping is cheap ---
   // that might let us copy a smaller region of the buffer.
   // Also clip to the visible region if we're told to.
   if (!aLayer->GetValidRegion().Contains(BufferRect()) ||
       (ToData(aLayer)->GetClipToVisibleRegion() &&
-       !aLayer->GetVisibleRegion().Contains(BufferRect())) ||
-      IsClippingCheap(aTarget, aLayer->GetEffectiveVisibleRegion())) {
+       !aLayer->GetVisibleRegion().ToUnknownRegion().Contains(BufferRect())) ||
+      IsClippingCheap(aTarget, aLayer->GetEffectiveVisibleRegion().ToUnknownRegion())) {
     // We don't want to draw invalid stuff, so we need to clip. Might as
     // well clip to the smallest area possible --- the visible region.
     // Bug 599189 if there is a non-integer-translation transform in aTarget,
     // we might sample pixels outside GetEffectiveVisibleRegion(), which is wrong
     // and may cause gray lines.
-    gfxUtils::ClipToRegion(aTarget, aLayer->GetEffectiveVisibleRegion());
+    gfxUtils::ClipToRegion(aTarget, aLayer->GetEffectiveVisibleRegion().ToUnknownRegion());
     clipped = true;
   }
 
   DrawBufferWithRotation(aTarget, BUFFER_BLACK, aOpacity, aOp, aMask, aMaskTransform);
   if (clipped) {
     aTarget->PopClip();
   }
 }
@@ -449,17 +449,17 @@ RotatedContentBuffer::BeginPaint(Painted
   SurfaceMode mode;
   nsIntRegion neededRegion;
   IntRect destBufferRect;
 
   bool canReuseBuffer = HaveBuffer();
 
   while (true) {
     mode = aLayer->GetSurfaceMode();
-    neededRegion = aLayer->GetVisibleRegion();
+    neededRegion = aLayer->GetVisibleRegion().ToUnknownRegion();
     canReuseBuffer &= BufferSizeOkFor(neededRegion.GetBounds().Size());
     result.mContentType = layerContentType;
 
     if (canReuseBuffer) {
       if (mBufferRect.Contains(neededRegion.GetBounds())) {
         // We don't need to adjust mBufferRect.
         destBufferRect = mBufferRect;
       } else if (neededRegion.GetBounds().Size() <= mBufferRect.Size()) {
--- a/gfx/layers/apz/test/gtest/TestAsyncPanZoomController.cpp
+++ b/gfx/layers/apz/test/gtest/TestAsyncPanZoomController.cpp
@@ -2075,17 +2075,17 @@ protected:
   static void SetScrollableFrameMetrics(Layer* aLayer, FrameMetrics::ViewID aScrollId,
                                         CSSRect aScrollableRect = CSSRect(-1, -1, -1, -1)) {
     FrameMetrics metrics;
     metrics.SetScrollId(aScrollId);
     // By convention in this test file, START_SCROLL_ID is the root, so mark it as such.
     if (aScrollId == FrameMetrics::START_SCROLL_ID) {
       metrics.SetIsLayersIdRoot(true);
     }
-    IntRect layerBound = aLayer->GetVisibleRegion().GetBounds();
+    IntRect layerBound = aLayer->GetVisibleRegion().ToUnknownRegion().GetBounds();
     metrics.SetCompositionBounds(ParentLayerRect(layerBound.x, layerBound.y,
                                                  layerBound.width, layerBound.height));
     metrics.SetScrollableRect(aScrollableRect);
     metrics.SetScrollOffset(CSSPoint(0, 0));
     metrics.SetPageScrollAmount(LayoutDeviceIntSize(50, 100));
     metrics.SetAllowVerticalScrollWithWheel();
     aLayer->SetFrameMetrics(metrics);
     aLayer->SetClipRect(Some(ViewAs<ParentLayerPixel>(layerBound)));
@@ -2750,17 +2750,17 @@ TEST_F(APZHitTestingTester, Bug1148350) 
 
   uint64_t blockId;
   TouchDown(manager, 100, 100, mcc->Time(), &blockId);
   if (gfxPrefs::TouchActionEnabled()) {
     SetDefaultAllowedTouchBehavior(manager, blockId);
   }
   mcc->AdvanceByMillis(100);
 
-  layers[0]->SetVisibleRegion(nsIntRegion(IntRect(0,50,200,150)));
+  layers[0]->SetVisibleRegion(LayerIntRegion(LayerIntRect(0,50,200,150)));
   layers[0]->SetBaseTransform(Matrix4x4::Translation(0, 50, 0));
   manager->UpdateHitTestingTree(nullptr, root, false, 0, 0);
 
   TouchUp(manager, 100, 100, mcc->Time());
   mcc->RunThroughDelayedTasks();
   check.Call("Tapped with interleaved transform");
 }
 
--- a/gfx/layers/basic/BasicCanvasLayer.h
+++ b/gfx/layers/basic/BasicCanvasLayer.h
@@ -19,17 +19,17 @@ namespace layers {
 class BasicCanvasLayer : public CopyableCanvasLayer,
                          public BasicImplData
 {
 public:
   explicit BasicCanvasLayer(BasicLayerManager* aLayerManager) :
     CopyableCanvasLayer(aLayerManager, static_cast<BasicImplData*>(this))
   { }
 
-  virtual void SetVisibleRegion(const nsIntRegion& aRegion) override
+  virtual void SetVisibleRegion(const LayerIntRegion& aRegion) override
   {
     NS_ASSERTION(BasicManager()->InConstruction(),
                  "Can only set properties in construction phase");
     CanvasLayer::SetVisibleRegion(aRegion);
   }
 
   virtual void Paint(gfx::DrawTarget* aDT,
                      const gfx::Point& aDeviceOffset,
--- a/gfx/layers/basic/BasicColorLayer.cpp
+++ b/gfx/layers/basic/BasicColorLayer.cpp
@@ -34,17 +34,17 @@ public:
 
 protected:
   virtual ~BasicColorLayer()
   {
     MOZ_COUNT_DTOR(BasicColorLayer);
   }
 
 public:
-  virtual void SetVisibleRegion(const nsIntRegion& aRegion) override
+  virtual void SetVisibleRegion(const LayerIntRegion& aRegion) override
   {
     NS_ASSERTION(BasicManager()->InConstruction(),
                  "Can only set properties in construction phase");
     ColorLayer::SetVisibleRegion(aRegion);
   }
 
   virtual void Paint(DrawTarget* aDT,
                      const gfx::Point& aDeviceOffset,
--- a/gfx/layers/basic/BasicContainerLayer.cpp
+++ b/gfx/layers/basic/BasicContainerLayer.cpp
@@ -104,29 +104,29 @@ bool
 BasicContainerLayer::ChildrenPartitionVisibleRegion(const gfx::IntRect& aInRect)
 {
   Matrix transform;
   if (!GetEffectiveTransform().CanDraw2D(&transform) ||
       ThebesMatrix(transform).HasNonIntegerTranslation())
     return false;
 
   nsIntPoint offset(int32_t(transform._31), int32_t(transform._32));
-  gfx::IntRect rect = aInRect.Intersect(GetEffectiveVisibleRegion().GetBounds() + offset);
+  gfx::IntRect rect = aInRect.Intersect(GetEffectiveVisibleRegion().ToUnknownRegion().GetBounds() + offset);
   nsIntRegion covered;
 
   for (Layer* l = mFirstChild; l; l = l->GetNextSibling()) {
     if (ToData(l)->IsHidden())
       continue;
 
     Matrix childTransform;
     if (!l->GetEffectiveTransform().CanDraw2D(&childTransform) ||
         ThebesMatrix(childTransform).HasNonIntegerTranslation() ||
         l->GetEffectiveOpacity() != 1.0)
       return false;
-    nsIntRegion childRegion = l->GetEffectiveVisibleRegion();
+    nsIntRegion childRegion = l->GetEffectiveVisibleRegion().ToUnknownRegion();
     childRegion.MoveBy(int32_t(childTransform._31), int32_t(childTransform._32));
     childRegion.And(childRegion, rect);
     if (l->GetClipRect()) {
       childRegion.And(childRegion, l->GetClipRect()->ToUnknownRect() + offset);
     }
     nsIntRegion intersection;
     intersection.And(covered, childRegion);
     if (!intersection.IsEmpty())
--- a/gfx/layers/basic/BasicContainerLayer.h
+++ b/gfx/layers/basic/BasicContainerLayer.h
@@ -24,17 +24,17 @@ public:
   {
     MOZ_COUNT_CTOR(BasicContainerLayer);
     mSupportsComponentAlphaChildren = true;
   }
 protected:
   virtual ~BasicContainerLayer();
 
 public:
-  virtual void SetVisibleRegion(const nsIntRegion& aRegion) override
+  virtual void SetVisibleRegion(const LayerIntRegion& aRegion) override
   {
     NS_ASSERTION(BasicManager()->InConstruction(),
                  "Can only set properties in construction phase");
     ContainerLayer::SetVisibleRegion(aRegion);
   }
   virtual bool InsertAfter(Layer* aChild, Layer* aAfter) override
   {
     if (!BasicManager()->InConstruction()) {
--- a/gfx/layers/basic/BasicImageLayer.cpp
+++ b/gfx/layers/basic/BasicImageLayer.cpp
@@ -33,17 +33,17 @@ public:
   }
 protected:
   virtual ~BasicImageLayer()
   {
     MOZ_COUNT_DTOR(BasicImageLayer);
   }
 
 public:
-  virtual void SetVisibleRegion(const nsIntRegion& aRegion) override
+  virtual void SetVisibleRegion(const LayerIntRegion& aRegion) override
   {
     NS_ASSERTION(BasicManager()->InConstruction(),
                  "Can only set properties in construction phase");
     ImageLayer::SetVisibleRegion(aRegion);
   }
 
   virtual void Paint(DrawTarget* aDT,
                      const gfx::Point& aDeviceOffset,
--- a/gfx/layers/basic/BasicLayerManager.cpp
+++ b/gfx/layers/basic/BasicLayerManager.cpp
@@ -240,17 +240,17 @@ public:
   void Apply2DTransform()
   {
     mTarget->SetMatrix(ThebesMatrix(mTransform));
   }
 
   // Set the opaque rect to match the bounds of the visible region.
   void AnnotateOpaqueRect()
   {
-    const nsIntRegion& visibleRegion = mLayer->GetEffectiveVisibleRegion();
+    const nsIntRegion visibleRegion = mLayer->GetEffectiveVisibleRegion().ToUnknownRegion();
     const IntRect& bounds = visibleRegion.GetBounds();
 
     DrawTarget *dt = mTarget->GetDrawTarget();
     const IntRect& targetOpaqueRect = dt->GetOpaqueRect();
 
     // Try to annotate currentSurface with a region of pixels that have been
     // (or will be) painted opaque, if no such region is currently set.
     if (targetOpaqueRect.IsEmpty() && visibleRegion.GetNumRects() == 1 &&
@@ -427,17 +427,17 @@ MarkLayersHidden(Layer* aLayer, const In
 
   if (!aLayer->AsContainerLayer()) {
     Matrix transform;
     if (!aLayer->GetEffectiveTransform().CanDraw2D(&transform)) {
       data->SetHidden(false);
       return;
     }
 
-    nsIntRegion region = aLayer->GetEffectiveVisibleRegion();
+    nsIntRegion region = aLayer->GetEffectiveVisibleRegion().ToUnknownRegion();
     IntRect r = region.GetBounds();
     TransformIntRect(r, transform, ToOutsideIntRect);
     r.IntersectRect(r, aDirtyRect);
     data->SetHidden(aOpaqueRegion.Contains(r));
 
     // Allow aLayer to cover underlying layers only if aLayer's
     // content is opaque
     if ((aLayer->GetContentFlags() & Layer::CONTENT_OPAQUE) &&
@@ -915,17 +915,17 @@ BasicLayerManager::FlushGroup(PaintLayer
   // those temporary surfaces from being composited to aTarget.
   // ApplyDoubleBuffering guarantees that this container layer can't
   // intersect any other leaf layers, so if the transaction is not yet marked
   // incomplete, the contents of this container layer are the final contents
   // for the window.
   if (!mTransactionIncomplete) {
     if (aNeedsClipToVisibleRegion) {
       gfxUtils::ClipToRegion(aPaintContext.mTarget,
-                             aPaintContext.mLayer->GetEffectiveVisibleRegion());
+                             aPaintContext.mLayer->GetEffectiveVisibleRegion().ToUnknownRegion());
     }
 
     CompositionOp op = GetEffectiveOperator(aPaintContext.mLayer);
     AutoSetOperator setOperator(aPaintContext.mTarget, op);
 
     PaintWithMask(aPaintContext.mTarget, aPaintContext.mLayer->GetEffectiveOpacity(),
                   aPaintContext.mLayer->GetMaskLayer());
   }
@@ -1027,17 +1027,17 @@ BasicLayerManager::PaintLayer(gfxContext
     InstallLayerClipPreserves3D(aTarget, aLayer);
     for (Layer* l = parent; l && l->Extend3DContext(); l = l->GetParent()) {
       InstallLayerClipPreserves3D(aTarget, l);
     }
   }
 
   paintLayerContext.Apply2DTransform();
 
-  const nsIntRegion& visibleRegion = aLayer->GetEffectiveVisibleRegion();
+  const nsIntRegion visibleRegion = aLayer->GetEffectiveVisibleRegion().ToUnknownRegion();
   // If needsGroup is true, we'll clip to the visible region after we've popped the group
   if (needsClipToVisibleRegion && !needsGroup) {
     gfxUtils::ClipToRegion(aTarget, visibleRegion);
     // Don't need to clip to visible region again
     needsClipToVisibleRegion = false;
   }
   
   if (is2D) {
@@ -1048,17 +1048,17 @@ BasicLayerManager::PaintLayer(gfxContext
   if (clipIsEmpty) {
     PaintSelfOrChildren(paintLayerContext, aTarget);
     return;
   }
 
   if (is2D) {
     if (needsGroup) {
       PushedGroup pushedGroup =
-        PushGroupForLayer(aTarget, aLayer, aLayer->GetEffectiveVisibleRegion());
+        PushGroupForLayer(aTarget, aLayer, aLayer->GetEffectiveVisibleRegion().ToUnknownRegion());
       PaintSelfOrChildren(paintLayerContext, pushedGroup.mGroupTarget);
       PopGroupForLayer(pushedGroup);
     } else {
       PaintSelfOrChildren(paintLayerContext, aTarget);
     }
   } else {
     if (!needsGroup && container) {
       PaintSelfOrChildren(paintLayerContext, aTarget);
--- a/gfx/layers/basic/BasicLayersImpl.h
+++ b/gfx/layers/basic/BasicLayersImpl.h
@@ -57,17 +57,17 @@ public:
 
 protected:
   virtual ~BasicReadbackLayer()
   {
     MOZ_COUNT_DTOR(BasicReadbackLayer);
   }
 
 public:
-  virtual void SetVisibleRegion(const nsIntRegion& aRegion)
+  virtual void SetVisibleRegion(const LayerIntRegion& aRegion)
   {
     NS_ASSERTION(BasicManager()->InConstruction(),
                  "Can only set properties in construction phase");
     ReadbackLayer::SetVisibleRegion(aRegion);
   }
 
 protected:
   BasicLayerManager* BasicManager()
--- a/gfx/layers/basic/BasicPaintedLayer.cpp
+++ b/gfx/layers/basic/BasicPaintedLayer.cpp
@@ -58,17 +58,17 @@ BasicPaintedLayer::PaintThebes(gfxContex
 
   float opacity = GetEffectiveOpacity();
   CompositionOp effectiveOperator = GetEffectiveOperator(this);
 
   if (!BasicManager()->IsRetained()) {
     mValidRegion.SetEmpty();
     mContentClient->Clear();
 
-    nsIntRegion toDraw = IntersectWithClip(GetEffectiveVisibleRegion(), aContext);
+    nsIntRegion toDraw = IntersectWithClip(GetEffectiveVisibleRegion().ToUnknownRegion(), aContext);
 
     RenderTraceInvalidateStart(this, "FFFF00", toDraw.GetBounds());
 
     if (!toDraw.IsEmpty() && !IsHidden()) {
       if (!aCallback) {
         BasicManager()->SetTransactionIncomplete();
         return;
       }
@@ -163,17 +163,17 @@ BasicPaintedLayer::Validate(LayerManager
   mValidRegion.Sub(mValidRegion, state.mRegionToInvalidate);
 
   if (DrawTarget* target = mContentClient->BorrowDrawTargetForPainting(state)) {
     // The area that became invalid and is visible needs to be repainted
     // (this could be the whole visible area if our buffer switched
     // from RGB to RGBA, because we might need to repaint with
     // subpixel AA)
     state.mRegionToInvalidate.And(state.mRegionToInvalidate,
-                                  GetEffectiveVisibleRegion());
+                                  GetEffectiveVisibleRegion().ToUnknownRegion());
     SetAntialiasingFlags(this, target);
 
     RenderTraceInvalidateStart(this, "FFFF00", state.mRegionToDraw.GetBounds());
 
     RefPtr<gfxContext> ctx = gfxContext::ContextForDrawTarget(target);
     PaintBuffer(ctx,
                 state.mRegionToDraw, state.mRegionToDraw, state.mRegionToInvalidate,
                 state.mDidSelfCopy,
--- a/gfx/layers/basic/BasicPaintedLayer.h
+++ b/gfx/layers/basic/BasicPaintedLayer.h
@@ -39,17 +39,17 @@ public:
 
 protected:
   virtual ~BasicPaintedLayer()
   {
     MOZ_COUNT_DTOR(BasicPaintedLayer);
   }
 
 public:
-  virtual void SetVisibleRegion(const nsIntRegion& aRegion) override
+  virtual void SetVisibleRegion(const LayerIntRegion& aRegion) override
   {
     NS_ASSERTION(BasicManager()->InConstruction(),
                  "Can only set properties in construction phase");
     PaintedLayer::SetVisibleRegion(aRegion);
   }
   virtual void InvalidateRegion(const nsIntRegion& aRegion) override
   {
     NS_ASSERTION(BasicManager()->InConstruction(),
@@ -114,17 +114,17 @@ protected:
     }
     aCallback(this, aContext, aExtendedRegionToDraw, aExtendedRegionToDraw,
               aClip, aRegionToInvalidate, aCallbackData);
     // Everything that's visible has been validated. Do this instead of just
     // OR-ing with aRegionToDraw, since that can lead to a very complex region
     // here (OR doesn't automatically simplify to the simplest possible
     // representation of a region.)
     nsIntRegion tmp;
-    tmp.Or(mVisibleRegion, aExtendedRegionToDraw);
+    tmp.Or(mVisibleRegion.ToUnknownRegion(), aExtendedRegionToDraw);
     mValidRegion.Or(mValidRegion, tmp);
   }
 
   RefPtr<ContentClientBasic> mContentClient;
 };
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/client/ClientCanvasLayer.h
+++ b/gfx/layers/client/ClientCanvasLayer.h
@@ -39,17 +39,17 @@ public:
   {
     MOZ_COUNT_CTOR(ClientCanvasLayer);
   }
 
 protected:
   virtual ~ClientCanvasLayer();
 
 public:
-  virtual void SetVisibleRegion(const nsIntRegion& aRegion) override
+  virtual void SetVisibleRegion(const LayerIntRegion& aRegion) override
   {
     NS_ASSERTION(ClientManager()->InConstruction(),
                  "Can only set properties in construction phase");
     CanvasLayer::SetVisibleRegion(aRegion);
   }
 
   virtual void Initialize(const Data& aData) override;
 
--- a/gfx/layers/client/ClientColorLayer.cpp
+++ b/gfx/layers/client/ClientColorLayer.cpp
@@ -29,17 +29,17 @@ public:
 
 protected:
   virtual ~ClientColorLayer()
   {
     MOZ_COUNT_DTOR(ClientColorLayer);
   }
 
 public:
-  virtual void SetVisibleRegion(const nsIntRegion& aRegion)
+  virtual void SetVisibleRegion(const LayerIntRegion& aRegion)
   {
     NS_ASSERTION(ClientManager()->InConstruction(),
                  "Can only set properties in construction phase");
     ColorLayer::SetVisibleRegion(aRegion);
   }
 
   virtual void RenderLayer()
   {
--- a/gfx/layers/client/ClientContainerLayer.h
+++ b/gfx/layers/client/ClientContainerLayer.h
@@ -66,17 +66,17 @@ public:
 
       if (!ClientManager()->GetRepeatTransaction() &&
           !child->GetInvalidRegion().IsEmpty()) {
         child->Mutated();
       }
     }
   }
 
-  virtual void SetVisibleRegion(const nsIntRegion& aRegion) override
+  virtual void SetVisibleRegion(const LayerIntRegion& aRegion) override
   {
     NS_ASSERTION(ClientManager()->InConstruction(),
                  "Can only set properties in construction phase");
     ContainerLayer::SetVisibleRegion(aRegion);
   }
   virtual bool InsertAfter(Layer* aChild, Layer* aAfter) override
   {
     if(!ClientManager()->InConstruction()) {
--- a/gfx/layers/client/ClientImageLayer.cpp
+++ b/gfx/layers/client/ClientImageLayer.cpp
@@ -41,17 +41,17 @@ protected:
   }
 
   virtual void SetContainer(ImageContainer* aContainer) override
   {
     ImageLayer::SetContainer(aContainer);
     mImageClientTypeContainer = CompositableType::UNKNOWN;
   }
 
-  virtual void SetVisibleRegion(const nsIntRegion& aRegion) override
+  virtual void SetVisibleRegion(const LayerIntRegion& aRegion) override
   {
     NS_ASSERTION(ClientManager()->InConstruction(),
                  "Can only set properties in construction phase");
     ImageLayer::SetVisibleRegion(aRegion);
   }
 
   virtual void RenderLayer() override;
   
--- a/gfx/layers/client/ClientPaintedLayer.cpp
+++ b/gfx/layers/client/ClientPaintedLayer.cpp
@@ -70,17 +70,17 @@ ClientPaintedLayer::PaintThebes()
     return;
   }
 
   // The area that became invalid and is visible needs to be repainted
   // (this could be the whole visible area if our buffer switched
   // from RGB to RGBA, because we might need to repaint with
   // subpixel AA)
   state.mRegionToInvalidate.And(state.mRegionToInvalidate,
-                                GetEffectiveVisibleRegion());
+                                GetEffectiveVisibleRegion().ToUnknownRegion());
 
   bool didUpdate = false;
   RotatedContentBuffer::DrawIterator iter;
   while (DrawTarget* target = mContentClient->BorrowDrawTargetForPainting(state, &iter)) {
     SetAntialiasingFlags(this, target);
 
     RefPtr<gfxContext> ctx = gfxContext::ContextForDrawTarget(target);
 
@@ -105,17 +105,17 @@ ClientPaintedLayer::PaintThebes()
     ContentClientRemote* contentClientRemote = static_cast<ContentClientRemote*>(mContentClient.get());
     MOZ_ASSERT(contentClientRemote->GetIPDLActor());
 
     // Hold(this) ensures this layer is kept alive through the current transaction
     // The ContentClient assumes this layer is kept alive (e.g., in CreateBuffer),
     // so deleting this Hold for whatever reason will break things.
     ClientManager()->Hold(this);
     contentClientRemote->Updated(state.mRegionToDraw,
-                                 mVisibleRegion,
+                                 mVisibleRegion.ToUnknownRegion(),
                                  state.mDidSelfCopy);
   }
 }
 
 void
 ClientPaintedLayer::RenderLayerWithReadback(ReadbackProcessor *aReadback)
 {
   RenderMaskLayers(this);
--- a/gfx/layers/client/ClientPaintedLayer.h
+++ b/gfx/layers/client/ClientPaintedLayer.h
@@ -45,17 +45,17 @@ protected:
     if (mContentClient) {
       mContentClient->OnDetach();
       mContentClient = nullptr;
     }
     MOZ_COUNT_DTOR(ClientPaintedLayer);
   }
 
 public:
-  virtual void SetVisibleRegion(const nsIntRegion& aRegion) override
+  virtual void SetVisibleRegion(const LayerIntRegion& aRegion) override
   {
     NS_ASSERTION(ClientManager()->InConstruction(),
                  "Can only set properties in construction phase");
     PaintedLayer::SetVisibleRegion(aRegion);
   }
   virtual void InvalidateRegion(const nsIntRegion& aRegion) override
   {
     NS_ASSERTION(ClientManager()->InConstruction(),
--- a/gfx/layers/client/ClientTiledPaintedLayer.cpp
+++ b/gfx/layers/client/ClientTiledPaintedLayer.cpp
@@ -405,17 +405,17 @@ ClientTiledPaintedLayer::EndPaint()
 
 void
 ClientTiledPaintedLayer::RenderLayer()
 {
   LayerManager::DrawPaintedLayerCallback callback =
     ClientManager()->GetPaintedLayerCallback();
   void *data = ClientManager()->GetPaintedLayerCallbackData();
 
-  IntSize layerSize = mVisibleRegion.GetBounds().Size();
+  IntSize layerSize = mVisibleRegion.ToUnknownRegion().GetBounds().Size();
   if (mContentClient && !mContentClient->SupportsLayerSize(layerSize, ClientManager())) {
     ClearCachedResources();
     MOZ_ASSERT(!mContentClient);
   }
 
   if (!mContentClient) {
     if (mCreationHint == LayerManager::NONE &&
         SingleTiledContentClient::ClientSupportsLayerSize(layerSize, ClientManager()) &&
@@ -434,17 +434,17 @@ ClientTiledPaintedLayer::RenderLayer()
     mValidRegion = nsIntRegion();
     mContentClient->GetTiledBuffer()->ResetPaintedAndValidState();
   }
 
   TILING_LOG("TILING %p: Initial visible region %s\n", this, Stringify(mVisibleRegion).c_str());
   TILING_LOG("TILING %p: Initial valid region %s\n", this, Stringify(mValidRegion).c_str());
   TILING_LOG("TILING %p: Initial low-precision valid region %s\n", this, Stringify(mLowPrecisionValidRegion).c_str());
 
-  nsIntRegion neededRegion = mVisibleRegion;
+  nsIntRegion neededRegion = mVisibleRegion.ToUnknownRegion();
 #ifndef MOZ_IGNORE_PAINT_WILL_RESAMPLE
   // This is handled by PadDrawTargetOutFromRegion in TiledContentClient for mobile
   if (MayResample()) {
     // If we're resampling then bilinear filtering can read up to 1 pixel
     // outside of our texture coords. Make the visible region a single rect,
     // and pad it out by 1 pixel (restricted to tile boundaries) so that
     // we always have valid content or transparent pixels to sample from.
     IntRect bounds = neededRegion.GetBounds();
--- a/gfx/layers/composite/ContainerLayerComposite.cpp
+++ b/gfx/layers/composite/ContainerLayerComposite.cpp
@@ -78,30 +78,30 @@ static void DrawLayerInfo(const RenderTa
     // is hard to do, since it will often get superimposed over the first
     // child of the layer, which is bad.
     return;
   }
 
   std::stringstream ss;
   aLayer->PrintInfo(ss, "");
 
-  nsIntRegion visibleRegion = aLayer->GetVisibleRegion();
+  LayerIntRegion visibleRegion = aLayer->GetVisibleRegion();
 
   uint32_t maxWidth = std::min<uint32_t>(visibleRegion.GetBounds().width, 500);
 
-  IntPoint topLeft = visibleRegion.GetBounds().TopLeft();
+  IntPoint topLeft = visibleRegion.ToUnknownRegion().GetBounds().TopLeft();
   aManager->GetTextRenderer()->RenderText(ss.str().c_str(), topLeft,
                                           aLayer->GetEffectiveTransform(), 16,
                                           maxWidth);
 }
 
 template<class ContainerT>
 static gfx::IntRect ContainerVisibleRect(ContainerT* aContainer)
 {
-  gfx::IntRect surfaceRect = aContainer->GetEffectiveVisibleRegion().GetBounds();
+  gfx::IntRect surfaceRect = aContainer->GetEffectiveVisibleRegion().ToUnknownRegion().GetBounds();
   return surfaceRect;
 }
 
 static void PrintUniformityInfo(Layer* aLayer)
 {
 #ifdef MOZ_ENABLE_PROFILER_SPS
   if (!profiler_is_active()) {
     return;
@@ -228,17 +228,17 @@ ContainerRenderVR(ContainerT* aContainer
       // XXX this is a hack! Canvas layers aren't reporting the
       // proper bounds here (visible region bounds are 0,0,0,0)
       // and I'm not sure if this is the bounds we want anyway.
       if (layer->GetType() == Layer::TYPE_CANVAS) {
         layerBounds =
           IntRectToRect(static_cast<CanvasLayer*>(layer)->GetBounds());
       } else {
         layerBounds =
-          IntRectToRect(layer->GetEffectiveVisibleRegion().GetBounds());
+          IntRectToRect(layer->GetEffectiveVisibleRegion().ToUnknownRegion().GetBounds());
       }
       const gfx::Matrix4x4 childTransform = layer->GetEffectiveTransform();
       layerBounds = childTransform.TransformBounds(layerBounds);
 
       DUMP("  layer %p [type %d] bounds [%f %f %f %f] surfaceRect [%d %d %d %d]\n", layer, (int) layer->GetType(),
            XYWH(layerBounds), XYWH(surfaceRect));
 
       bool restoreTransform = false;
@@ -637,17 +637,17 @@ CreateOrRecycleTarget(ContainerT* aConta
   }
 }
 
 template<class ContainerT> RefPtr<CompositingRenderTarget>
 CreateTemporaryTargetAndCopyFromBackground(ContainerT* aContainer,
                                            LayerManagerComposite* aManager)
 {
   Compositor* compositor = aManager->GetCompositor();
-  gfx::IntRect visibleRect = aContainer->GetEffectiveVisibleRegion().GetBounds();
+  gfx::IntRect visibleRect = aContainer->GetEffectiveVisibleRegion().ToUnknownRegion().GetBounds();
   RefPtr<CompositingRenderTarget> previousTarget = compositor->GetCurrentRenderTarget();
   gfx::IntRect surfaceRect = gfx::IntRect(visibleRect.x, visibleRect.y,
                                           visibleRect.width, visibleRect.height);
 
   gfx::IntPoint sourcePoint = gfx::IntPoint(visibleRect.x, visibleRect.y);
 
   gfx::Matrix4x4 transform = aContainer->GetEffectiveTransform();
   DebugOnly<gfx::Matrix> transform2d;
@@ -705,17 +705,17 @@ ContainerRender(ContainerT* aContainer,
       surface = aContainer->mPrepared->mTmpTarget;
     }
 
     if (!surface) {
       aContainer->mPrepared = nullptr;
       return;
     }
 
-    gfx::Rect visibleRect(aContainer->GetEffectiveVisibleRegion().GetBounds());
+    gfx::Rect visibleRect(aContainer->GetEffectiveVisibleRegion().ToUnknownRegion().GetBounds());
     RefPtr<Compositor> compositor = aManager->GetCompositor();
 #ifdef MOZ_DUMP_PAINTING
     if (gfxEnv::DumpCompositorTextures()) {
       RefPtr<gfx::DataSourceSurface> surf = surface->Dump(compositor);
       if (surf) {
         WriteSnapshotToDumpFile(aContainer, surf);
       }
     }
--- a/gfx/layers/composite/LayerManagerComposite.cpp
+++ b/gfx/layers/composite/LayerManagerComposite.cpp
@@ -233,30 +233,30 @@ LayerManagerComposite::PostProcessLayers
   //    descendantsVisibleRegion.
   LayerIntRegion descendantsVisibleRegion;
   for (Layer* child = aLayer->GetLastChild(); child; child = child->GetPrevSibling()) {
     PostProcessLayers(child, localOpaque, descendantsVisibleRegion);
   }
 
   // Recalculate our visible region.
   LayerComposite* composite = aLayer->AsLayerComposite();
-  LayerIntRegion visible = LayerIntRegion::FromUnknownRegion(composite->GetShadowVisibleRegion());
+  LayerIntRegion visible = composite->GetShadowVisibleRegion();
 
   // If we have descendants, throw away the visible region stored on this
   // layer, and use the region accumulated by our descendants instead.
   if (aLayer->GetFirstChild()) {
     visible = descendantsVisibleRegion;
   }
 
   // Subtract any areas that we know to be opaque.
   if (!obscured.IsEmpty()) {
     visible.SubOut(LayerIntRegion::FromUnknownRegion(obscured));
   }
 
-  composite->SetShadowVisibleRegion(visible.ToUnknownRegion());
+  composite->SetShadowVisibleRegion(visible);
 
   // Transform the newly calculated visible region into our parent's space,
   // apply our clip to it (if any), and accumulate it into |aVisibleRegion|
   // for the caller to use.
   ParentLayerIntRegion visibleParentSpace = TransformTo<ParentLayerPixel>(
       aLayer->GetLocalTransform(), visible);
   if (const Maybe<ParentLayerIntRect>& clipRect = composite->GetShadowClipRect()) {
     visibleParentSpace.AndWith(*clipRect);
@@ -1135,17 +1135,17 @@ LayerManagerComposite::ComputeRenderInte
 
   // Only painted layers can be incomplete
   PaintedLayer* paintedLayer = aLayer->AsPaintedLayer();
   if (!paintedLayer) {
     return;
   }
 
   // See if there's any incomplete rendering
-  nsIntRegion incompleteRegion = aLayer->GetEffectiveVisibleRegion();
+  nsIntRegion incompleteRegion = aLayer->GetEffectiveVisibleRegion().ToUnknownRegion();
   incompleteRegion.Sub(incompleteRegion, paintedLayer->GetValidRegion());
 
   if (!incompleteRegion.IsEmpty()) {
     // Calculate the transform to get between screen and layer space
     Matrix4x4 transformToScreen = aLayer->GetEffectiveTransform();
     transformToScreen = aTransform * transformToScreen;
 
     SubtractTransformedRegion(aScreenRegion, incompleteRegion, transformToScreen);
@@ -1470,24 +1470,24 @@ LayerManagerComposite::AsyncPanZoomEnabl
 {
   return mCompositor->GetWidget()->AsyncPanZoomEnabled();
 }
 
 nsIntRegion
 LayerComposite::GetFullyRenderedRegion() {
   if (TiledContentHost* tiled = GetCompositableHost() ? GetCompositableHost()->AsTiledContentHost()
                                                         : nullptr) {
-    nsIntRegion shadowVisibleRegion = GetShadowVisibleRegion();
+    nsIntRegion shadowVisibleRegion = GetShadowVisibleRegion().ToUnknownRegion();
     // Discard the region which hasn't been drawn yet when doing
     // progressive drawing. Note that if the shadow visible region
     // shrunk the tiled valig region may not have discarded this yet.
     shadowVisibleRegion.And(shadowVisibleRegion, tiled->GetValidRegion());
     return shadowVisibleRegion;
   } else {
-    return GetShadowVisibleRegion();
+    return GetShadowVisibleRegion().ToUnknownRegion();
   }
 }
 
 #ifndef MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS
 
 /*static*/ bool
 LayerManagerComposite::SupportsDirectTexturing()
 {
--- a/gfx/layers/composite/LayerManagerComposite.h
+++ b/gfx/layers/composite/LayerManagerComposite.h
@@ -444,17 +444,17 @@ public:
 
   /**
    * The following methods are
    *
    * CONSTRUCTION PHASE ONLY
    *
    * They are analogous to the Layer interface.
    */
-  void SetShadowVisibleRegion(const nsIntRegion& aRegion)
+  void SetShadowVisibleRegion(const LayerIntRegion& aRegion)
   {
     mShadowVisibleRegion = aRegion;
   }
 
   void SetShadowOpacity(float aOpacity)
   {
     mShadowOpacity = aOpacity;
   }
@@ -481,32 +481,32 @@ public:
   void SetClearRect(const gfx::IntRect& aRect)
   {
     mClearRect = aRect;
   }
 
   // These getters can be used anytime.
   float GetShadowOpacity() { return mShadowOpacity; }
   const Maybe<ParentLayerIntRect>& GetShadowClipRect() { return mShadowClipRect; }
-  const nsIntRegion& GetShadowVisibleRegion() { return mShadowVisibleRegion; }
+  const LayerIntRegion& GetShadowVisibleRegion() { return mShadowVisibleRegion; }
   const gfx::Matrix4x4& GetShadowTransform() { return mShadowTransform; }
   bool GetShadowTransformSetByAnimation() { return mShadowTransformSetByAnimation; }
   bool HasLayerBeenComposited() { return mLayerComposited; }
   gfx::IntRect GetClearRect() { return mClearRect; }
 
   /**
    * Return the part of the visible region that has been fully rendered.
    * While progressive drawing is in progress this region will be
    * a subset of the shadow visible region.
    */
   nsIntRegion GetFullyRenderedRegion();
 
 protected:
   gfx::Matrix4x4 mShadowTransform;
-  nsIntRegion mShadowVisibleRegion;
+  LayerIntRegion mShadowVisibleRegion;
   Maybe<ParentLayerIntRect> mShadowClipRect;
   LayerManagerComposite* mCompositeManager;
   RefPtr<Compositor> mCompositor;
   float mShadowOpacity;
   bool mShadowTransformSetByAnimation;
   bool mDestroyed;
   bool mLayerComposited;
   gfx::IntRect mClearRect;
@@ -571,17 +571,17 @@ RenderWithAllMasks(Layer* aLayer, Compos
   //  (1) The first mask
   //  (2) The list of intermediate masks (every mask except first and last)
   //  (3) The final mask.
   // Part (2) can be empty.
   // For parts (1) and (2) we need to allocate intermediate surfaces to render
   // into. The final mask gets rendered into the original render target.
 
   // Calculate the size of the intermediate surfaces.
-  gfx::Rect visibleRect(aLayer->GetEffectiveVisibleRegion().GetBounds());
+  gfx::Rect visibleRect(aLayer->GetEffectiveVisibleRegion().ToUnknownRegion().GetBounds());
   gfx::Matrix4x4 transform = aLayer->GetEffectiveTransform();
   // TODO: Use RenderTargetIntRect and TransformTo<...> here
   gfx::IntRect surfaceRect =
     RoundedOut(transform.TransformAndClipBounds(visibleRect, gfx::Rect(aClipRect)));
   if (surfaceRect.IsEmpty()) {
     return;
   }
 
--- a/gfx/layers/composite/PaintedLayerComposite.cpp
+++ b/gfx/layers/composite/PaintedLayerComposite.cpp
@@ -107,17 +107,17 @@ PaintedLayerComposite::RenderLayer(const
     js::ProfileEntry::Category::GRAPHICS);
 
   Compositor* compositor = mCompositeManager->GetCompositor();
 
   MOZ_ASSERT(mBuffer->GetCompositor() == compositor &&
              mBuffer->GetLayer() == this,
              "buffer is corrupted");
 
-  const nsIntRegion& visibleRegion = GetEffectiveVisibleRegion();
+  const nsIntRegion visibleRegion = GetEffectiveVisibleRegion().ToUnknownRegion();
 
 #ifdef MOZ_DUMP_PAINTING
   if (gfxEnv::DumpCompositorTextures()) {
     RefPtr<gfx::DataSourceSurface> surf = mBuffer->GetAsSurface();
     if (surf) {
       WriteSnapshotToDumpFile(this, surf);
     }
   }
--- a/gfx/layers/ipc/CompositorParent.cpp
+++ b/gfx/layers/ipc/CompositorParent.cpp
@@ -768,17 +768,17 @@ CompositorParent::RecvNotifyRegionInvali
   return true;
 }
 
 void
 CompositorParent::Invalidate()
 {
   if (mLayerManager && mLayerManager->GetRoot()) {
     mLayerManager->AddInvalidRegion(
-        mLayerManager->GetRoot()->GetVisibleRegion().GetBounds());
+                                    mLayerManager->GetRoot()->GetVisibleRegion().ToUnknownRegion().GetBounds());
   }
 }
 
 bool
 CompositorParent::RecvStartFrameTimeRecording(const int32_t& aBufferSize, uint32_t* aOutStartIndex)
 {
   if (mLayerManager) {
     *aOutStartIndex = mLayerManager->StartFrameTimeRecording(aBufferSize);
--- a/gfx/layers/ipc/LayersMessages.ipdlh
+++ b/gfx/layers/ipc/LayersMessages.ipdlh
@@ -29,16 +29,17 @@ using class mozilla::TimeDuration from "
 using class mozilla::TimeStamp from "mozilla/TimeStamp.h";
 using mozilla::ScreenRotation from "mozilla/WidgetUtils.h";
 using nsCSSProperty from "nsCSSProperty.h";
 using mozilla::dom::ScreenOrientationInternal from "mozilla/dom/ScreenOrientation.h";
 using struct mozilla::layers::TextureInfo from "mozilla/layers/CompositorTypes.h";
 using mozilla::LayerMargin from "Units.h";
 using mozilla::LayerPoint from "Units.h";
 using mozilla::LayerRect from "Units.h";
+using mozilla::LayerIntRegion from "Units.h";
 using mozilla::ParentLayerIntRect from "Units.h";
 using mozilla::layers::ScaleMode from "mozilla/layers/LayersTypes.h";
 using mozilla::layers::EventRegions from "mozilla/layers/LayersTypes.h";
 using mozilla::layers::EventRegionsOverride from "mozilla/layers/LayersTypes.h";
 using mozilla::layers::DiagnosticTypes from "mozilla/layers/CompositorTypes.h";
 using struct mozilla::layers::FrameMetrics from "FrameMetrics.h";
 using mozilla::layers::FrameMetrics::ViewID from "FrameMetrics.h";
 using struct mozilla::layers::FenceHandle from "mozilla/layers/FenceUtils.h";
@@ -197,17 +198,17 @@ struct Animation {
   nsCSSProperty property;
   AnimationData data;
   float playbackRate;
 };
 
 // Change a layer's attributes
 struct CommonLayerAttributes {
   IntRect layerBounds;
-  nsIntRegion visibleRegion;
+  LayerIntRegion visibleRegion;
   EventRegions eventRegions;
   TransformMatrix transform;
   bool transformIsPerspective;
   float postXScale;
   float postYScale;
   uint32_t contentFlags;
   float opacity;
   bool useClipRect;
--- a/gfx/tests/gtest/TestCompositor.cpp
+++ b/gfx/tests/gtest/TestCompositor.cpp
@@ -238,29 +238,29 @@ TEST(Gfx, CompositorSimpleTree)
       nsIntRegion(IntRect(0, 0, 100, 100)),
       nsIntRegion(IntRect(0, 50, 100, 100)),
     };
     RefPtr<Layer> root = CreateLayerTree("c(ooo)", layerVisibleRegion, nullptr, lmBase, layers);
 
     { // background
       ColorLayer* colorLayer = layers[1]->AsColorLayer();
       colorLayer->SetColor(Color(1.f, 0.f, 1.f, 1.f));
-      colorLayer->SetBounds(colorLayer->GetVisibleRegion().GetBounds());
+      colorLayer->SetBounds(colorLayer->GetVisibleRegion().ToUnknownRegion().GetBounds());
     }
 
     {
       ColorLayer* colorLayer = layers[2]->AsColorLayer();
       colorLayer->SetColor(Color(1.f, 0.f, 0.f, 1.f));
-      colorLayer->SetBounds(colorLayer->GetVisibleRegion().GetBounds());
+      colorLayer->SetBounds(colorLayer->GetVisibleRegion().ToUnknownRegion().GetBounds());
     }
 
     {
       ColorLayer* colorLayer = layers[3]->AsColorLayer();
       colorLayer->SetColor(Color(0.f, 0.f, 1.f, 1.f));
-      colorLayer->SetBounds(colorLayer->GetVisibleRegion().GetBounds());
+      colorLayer->SetBounds(colorLayer->GetVisibleRegion().ToUnknownRegion().GetBounds());
     }
 
     RefPtr<DrawTarget> refDT = CreateDT();
     refDT->FillRect(Rect(0, 0, gCompWidth, gCompHeight), ColorPattern(Color(1.f, 0.f, 1.f, 1.f)));
     refDT->FillRect(Rect(0, 0, 100, 100), ColorPattern(Color(1.f, 0.f, 0.f, 1.f)));
     refDT->FillRect(Rect(0, 50, 100, 100), ColorPattern(Color(0.f, 0.f, 1.f, 1.f)));
     EXPECT_TRUE(CompositeAndCompare(layerManager, refDT));
   }
--- a/gfx/tests/gtest/TestLayers.cpp
+++ b/gfx/tests/gtest/TestLayers.cpp
@@ -209,17 +209,17 @@ already_AddRefed<Layer> CreateLayerTree(
         MOZ_CRASH();
       }
     } else if (aLayerTreeDescription[i] == ')') {
       parentContainerLayer = parentContainerLayer->GetParent();
       lastLayer = nullptr;
     } else {
       RefPtr<Layer> layer = CreateLayer(aLayerTreeDescription[i], manager.get());
       if (aVisibleRegions) {
-        layer->SetVisibleRegion(aVisibleRegions[layerNumber]);
+        layer->SetVisibleRegion(LayerIntRegion::FromUnknownRegion(aVisibleRegions[layerNumber]));
         layer->SetEventRegions(EventRegions(aVisibleRegions[layerNumber]));
       }
       if (aTransforms) {
         layer->SetBaseTransform(aTransforms[layerNumber]);
       }
       aLayersOut.AppendElement(layer);
       layerNumber++;
       if (rootLayer && !parentContainerLayer) {
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -2279,17 +2279,17 @@ ComputeAndSetIgnoreInvalidationRect(Pain
   // parentFrame is a scrollable frame, and aLayer contains the scrolled
   // contents of that frame.
 
   // maxNewVisibleBounds is a conservative approximation of the new visible
   // region of aLayer.
   nsIntRect maxNewVisibleBounds =
     dirtyRect.ScaleToOutsidePixels(aData->mXScale, aData->mYScale,
                                    aData->mAppUnitsPerDevPixel) - aLayerTranslation;
-  aData->mOldVisibleBounds = aLayer->GetVisibleRegion().GetBounds();
+  aData->mOldVisibleBounds = aLayer->GetVisibleRegion().ToUnknownRegion().GetBounds();
 
   // When the visible region of aLayer changes (e.g. due to scrolling),
   // three distinct types of invalidations need to be triggered:
   //  (1) Items (or parts of items) that have left the visible region need
   //      to be invalidated so that the pixels they painted are no longer
   //      part of the layer's valid region.
   //  (2) Items (or parts of items) that weren't in the old visible region
   //      but are in the new visible region need to be invalidated. This
@@ -2457,17 +2457,17 @@ SetOuterVisibleRegion(Layer* aLayer, nsI
     nsIntRect visRect;
     if (gfxUtils::GfxRectToIntRect(layerVisible, &visRect)) {
       *aOuterVisibleRegion = visRect;
     } else  {
       aOuterVisibleRegion->SetEmpty();
     }
   }
 
-  aLayer->SetVisibleRegion(*aOuterVisibleRegion);
+  aLayer->SetVisibleRegion(LayerIntRegion::FromUnknownRegion(*aOuterVisibleRegion));
 }
 
 void
 ContainerState::SetOuterVisibleRegionForLayer(Layer* aLayer,
                                               const nsIntRegion& aOuterVisibleRegion,
                                               const nsIntRect* aLayerContentsVisibleRect,
                                               bool aOuterUntransformed) const
 {
@@ -3176,17 +3176,17 @@ void ContainerState::FinishPaintedLayerD
       newLayerEntry->mAnimatedGeometryRootForScrollMetadata = data->mAnimatedGeometryRootForScrollMetadata;
       newLayerEntry->mFixedPosFrameForLayerData = data->mFixedPosFrameForLayerData;
       newLayerEntry->mIsCaret = data->mIsCaret;
 
       // Hide the PaintedLayer. We leave it in the layer tree so that we
       // can find and recycle it later.
       ParentLayerIntRect emptyRect;
       data->mLayer->SetClipRect(Some(emptyRect));
-      data->mLayer->SetVisibleRegion(nsIntRegion());
+      data->mLayer->SetVisibleRegion(LayerIntRegion());
       data->mLayer->InvalidateRegion(data->mLayer->GetValidRegion().GetBounds());
       data->mLayer->SetEventRegions(EventRegions());
     }
   }
 
   if (!layer) {
     // We couldn't optimize to an image layer or a color layer above.
     layer = data->mLayer;
@@ -4803,17 +4803,17 @@ InvalidateVisibleBoundsChangesForScrolle
     // during DLBI. Now is the right time to do that, because at this point aLayer
     // knows its new visible region.
     // We use the visible regions' bounds here (as opposed to the true region)
     // in order to limit rgn's complexity. The only possible disadvantage of
     // this is that it might cause us to unnecessarily recomposite parts of the
     // window that are in the visible region's bounds but not in the visible
     // region itself, but that is acceptable for scrolled layers.
     nsIntRegion rgn;
-    rgn.Or(data->mOldVisibleBounds, aLayer->GetVisibleRegion().GetBounds());
+    rgn.Or(data->mOldVisibleBounds, aLayer->GetVisibleRegion().ToUnknownRegion().GetBounds());
     rgn.Sub(rgn, *data->mIgnoreInvalidationsOutsideRect);
     if (!rgn.IsEmpty()) {
       aLayer->InvalidateRegion(rgn);
 #ifdef MOZ_DUMP_PAINTING
       if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
         printf_stderr("Invalidating changes of the visible region bounds of the scrolled contents\n");
         nsAutoCString str;
         AppendToString(str, rgn);
@@ -5403,17 +5403,17 @@ FrameLayerBuilder::BuildContainerLayerFo
       flags &= ~Layer::CONTENT_COMPONENT_ALPHA;
       flags |= Layer::CONTENT_OPAQUE;
     }
   }
   containerLayer->SetContentFlags(flags);
   // If aContainerItem is non-null some BuildContainerLayer further up the
   // call stack is responsible for setting containerLayer's visible region.
   if (!aContainerItem) {
-    containerLayer->SetVisibleRegion(pixBounds);
+    containerLayer->SetVisibleRegion(LayerIntRegion::FromUnknownRegion(pixBounds));
   }
   if (aParameters.mLayerContentsVisibleRect) {
     *aParameters.mLayerContentsVisibleRect = pixBounds + scaleParameters.mOffset;
   }
 
   mContainerLayerGeneration = oldGeneration;
   nsPresContext::ClearNotifySubDocInvalidationData(containerLayer);
 
@@ -5738,17 +5738,17 @@ static bool ShouldDrawRectsSeparately(gf
   return !dt->SupportsRegionClipping();
 }
 
 static void DrawForcedBackgroundColor(DrawTarget& aDrawTarget,
                                       Layer* aLayer, nscolor
                                       aBackgroundColor)
 {
   if (NS_GET_A(aBackgroundColor) > 0) {
-    nsIntRect r = aLayer->GetVisibleRegion().GetBounds();
+    LayerIntRect r = aLayer->GetVisibleRegion().GetBounds();
     ColorPattern color(ToDeviceColor(aBackgroundColor));
     aDrawTarget.FillRect(Rect(r.x, r.y, r.width, r.height), color);
   }
 }
 
 /*
  * A note on residual transforms:
  *
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -2538,17 +2538,17 @@ nsPresContext::NotifySubDocInvalidation(
 {
   ContainerLayerPresContext *data =
     static_cast<ContainerLayerPresContext*>(
       aContainer->GetUserData(&gNotifySubDocInvalidationData));
   if (!data) {
     return;
   }
 
-  nsIntPoint topLeft = aContainer->GetVisibleRegion().GetBounds().TopLeft();
+  nsIntPoint topLeft = aContainer->GetVisibleRegion().ToUnknownRegion().GetBounds().TopLeft();
 
   nsIntRegionRectIterator iter(aRegion);
   while (const nsIntRect* r = iter.Next()) {
     nsIntRect rect = *r;
     //PresContext coordinate space is relative to the start of our visible
     // region. Is this really true? This feels like the wrong way to get the right
     // answer.
     rect.MoveBy(-topLeft);
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -6125,17 +6125,17 @@ PresShell::Paint(nsView*        aViewToP
 
   RefPtr<ColorLayer> root = layerManager->CreateColorLayer();
   if (root) {
     nsPresContext* pc = GetPresContext();
     nsIntRect bounds =
       pc->GetVisibleArea().ToOutsidePixels(pc->AppUnitsPerDevPixel());
     bgcolor = NS_ComposeColors(bgcolor, mCanvasBackgroundColor);
     root->SetColor(Color::FromABGR(bgcolor));
-    root->SetVisibleRegion(bounds);
+    root->SetVisibleRegion(LayerIntRegion::FromUnknownRegion(bounds));
     layerManager->SetRoot(root);
   }
   MaybeSetupTransactionIdAllocator(layerManager, aViewToPaint);
   layerManager->EndTransaction(nullptr, nullptr, (aFlags & PAINT_COMPOSITE) ?
     LayerManager::END_DEFAULT : LayerManager::END_NO_COMPOSITE);
 }
 
 // static
--- a/widget/gonk/HwcComposer2D.cpp
+++ b/widget/gonk/HwcComposer2D.cpp
@@ -273,17 +273,17 @@ HwcComposer2D::PrepareLayerList(Layer* a
                                 const Matrix& aParentTransform)
 {
     // NB: we fall off this path whenever there are container layers
     // that require intermediate surfaces.  That means all the
     // GetEffective*() coordinates are relative to the framebuffer.
 
     bool fillColor = false;
 
-    const nsIntRegion& visibleRegion = aLayer->GetEffectiveVisibleRegion();
+    const nsIntRegion visibleRegion = aLayer->GetEffectiveVisibleRegion().ToUnknownRegion();
     if (visibleRegion.IsEmpty()) {
         return true;
     }
 
     uint8_t opacity = std::min(0xFF, (int)(aLayer->GetEffectiveOpacity() * 256.0));
     if (opacity == 0) {
         LOGD("%s Layer has zero opacity; skipping", aLayer->Name());
         return true;