Bug 1359842 - Convert RelativeToParent to deal with typed units. r=nical draft
authorKartikaya Gupta <kgupta@mozilla.com>
Wed, 26 Apr 2017 16:37:16 -0400
changeset 568970 4c710669b8e25b6739ec6f9bb0438c46c20cc973
parent 568969 8f4b90e09b2eeffdede770c868bd2fd1f8c050be
child 568971 5151e0e158035590f841ee12a48ab93eb2128c9c
push id56034
push userkgupta@mozilla.com
push dateWed, 26 Apr 2017 20:37:45 +0000
reviewersnical
bugs1359842
milestone55.0a1
Bug 1359842 - Convert RelativeToParent to deal with typed units. r=nical As we are often converting from LayoutDevicePixel to LayerPixel types in WebRenderDisplayItem code, I added a convenience overload of RelativeToParent that takes a LayoutDeviceRect and returns a LayerRect, even though this is a potential footgun if abused. MozReview-Commit-ID: DABAWdOBsbV
gfx/layers/wr/WebRenderBridgeChild.cpp
gfx/layers/wr/WebRenderBridgeChild.h
gfx/layers/wr/WebRenderCanvasLayer.cpp
gfx/layers/wr/WebRenderColorLayer.cpp
gfx/layers/wr/WebRenderContainerLayer.cpp
gfx/layers/wr/WebRenderDisplayItemLayer.cpp
gfx/layers/wr/WebRenderImageLayer.cpp
gfx/layers/wr/WebRenderLayer.cpp
gfx/layers/wr/WebRenderLayer.h
gfx/layers/wr/WebRenderPaintedLayer.cpp
gfx/layers/wr/WebRenderTextLayer.cpp
layout/generic/nsBulletFrame.cpp
layout/generic/nsCanvasFrame.cpp
layout/painting/nsCSSRenderingBorders.cpp
layout/painting/nsCSSRenderingGradients.cpp
layout/painting/nsDisplayList.cpp
layout/painting/nsImageRenderer.cpp
--- a/gfx/layers/wr/WebRenderBridgeChild.cpp
+++ b/gfx/layers/wr/WebRenderBridgeChild.cpp
@@ -173,17 +173,17 @@ WriteFontFileData(const uint8_t* aData, 
   }
   memcpy(data->mFontBuffer.mData, aData, aLength);
 
   data->mFontIndex = aIndex;
 }
 
 void
 WebRenderBridgeChild::PushGlyphs(wr::DisplayListBuilder& aBuilder, const nsTArray<GlyphArray>& aGlyphs,
-                                 gfx::ScaledFont* aFont, const gfx::Point& aOffset, const gfx::Rect& aBounds,
+                                 gfx::ScaledFont* aFont, const LayerPoint& aOffset, const gfx::Rect& aBounds,
                                  const gfx::Rect& aClip)
 {
   MOZ_ASSERT(aFont);
   MOZ_ASSERT(!aGlyphs.IsEmpty());
 
   WrFontKey key = GetFontKeyForScaledFont(aFont);
   MOZ_ASSERT(key.mNamespace && key.mHandle);
 
--- a/gfx/layers/wr/WebRenderBridgeChild.h
+++ b/gfx/layers/wr/WebRenderBridgeChild.h
@@ -87,17 +87,17 @@ public:
   uint32_t GetNextResourceId() { return ++mResourceId; }
   uint32_t GetNamespace() { return mIdNamespace; }
   void SetNamespace(uint32_t aIdNamespace)
   {
     mIdNamespace = aIdNamespace;
   }
 
   void PushGlyphs(wr::DisplayListBuilder& aBuilder, const nsTArray<GlyphArray>& aGlyphs,
-                  gfx::ScaledFont* aFont, const gfx::Point& aOffset, const gfx::Rect& aBounds,
+                  gfx::ScaledFont* aFont, const LayerPoint& aOffset, const gfx::Rect& aBounds,
                   const gfx::Rect& aClip);
 
   wr::FontKey GetFontKeyForScaledFont(gfx::ScaledFont* aScaledFont);
 
   void RemoveExpiredFontKeys();
   void ClearReadLocks();
 
 private:
--- a/gfx/layers/wr/WebRenderCanvasLayer.cpp
+++ b/gfx/layers/wr/WebRenderCanvasLayer.cpp
@@ -55,17 +55,17 @@ WebRenderCanvasLayer::RenderLayer(wr::Di
   }
 
   gfx::Matrix4x4 transform = GetTransform();
   const bool needsYFlip = (mOriginPos == gl::OriginPos::BottomLeft);
   if (needsYFlip) {
     transform.PreTranslate(0, mBounds.height, 0).PreScale(1, -1, 1);
   }
 
-  gfx::Rect relBounds = GetWrRelBounds();
+  LayerRect relBounds = GetWrRelBounds();
   LayerRect rect = RelativeToVisible(LayerRect(0, 0, mBounds.width, mBounds.height));
 
   LayerRect clipRect = GetWrClipRect(rect);
   Maybe<WrImageMask> mask = BuildWrMaskLayer(true);
   WrClipRegion clip = aBuilder.BuildClipRegion(wr::ToWrRect(clipRect), mask.ptrOr(nullptr));
 
   wr::ImageRendering filter = wr::ToImageRendering(mSamplingFilter);
   wr::MixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
--- a/gfx/layers/wr/WebRenderColorLayer.cpp
+++ b/gfx/layers/wr/WebRenderColorLayer.cpp
@@ -15,17 +15,17 @@ namespace mozilla {
 namespace layers {
 
 using namespace mozilla::gfx;
 
 void
 WebRenderColorLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
 {
   gfx::Matrix4x4 transform = GetTransform();
-  gfx::Rect relBounds = GetWrRelBounds();
+  LayerRect relBounds = GetWrRelBounds();
   LayerRect rect = GetWrBoundsRect();
 
   LayerRect clipRect = GetWrClipRect(rect);
   Maybe<WrImageMask> mask = BuildWrMaskLayer(true);
   WrClipRegion clip = aBuilder.BuildClipRegion(wr::ToWrRect(clipRect), mask.ptrOr(nullptr));
 
   wr::MixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
 
--- a/gfx/layers/wr/WebRenderContainerLayer.cpp
+++ b/gfx/layers/wr/WebRenderContainerLayer.cpp
@@ -16,17 +16,17 @@ namespace layers {
 
 void
 WebRenderContainerLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
 {
   nsTArray<LayerPolygon> children = SortChildrenBy3DZOrder(SortMode::WITHOUT_GEOMETRY);
 
   gfx::Matrix4x4 transform = GetTransform();
   float opacity = GetLocalOpacity();
-  gfx::Rect relBounds = GetWrRelBounds();
+  LayerRect relBounds = GetWrRelBounds();
   gfx::Rect clip(0, 0, relBounds.width, relBounds.height);
 
   Maybe<WrImageMask> mask = BuildWrMaskLayer(true);
 
   wr::MixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
 
   if (gfxPrefs::LayersDump()) {
     printf_stderr("ContainerLayer %p using bounds=%s, clip=%s, transform=%s, mix-blend-mode=%s\n",
--- a/gfx/layers/wr/WebRenderDisplayItemLayer.cpp
+++ b/gfx/layers/wr/WebRenderDisplayItemLayer.cpp
@@ -163,17 +163,17 @@ WebRenderDisplayItemLayer::PushItemAsIma
     nsRenderingContext ctx(context);
     mItem->Paint(mBuilder, &ctx);
   }
 
   if (!helper.UpdateImage()) {
     return false;
   }
 
-  gfx::Rect dest = RelativeToParent(imageRect.ToUnknownRect()) + offset.ToUnknownPoint();
+  LayerRect dest = RelativeToParent(imageRect) + offset;
   WrClipRegion clipRegion = aBuilder.BuildClipRegion(wr::ToWrRect(dest));
   WrImageKey key = GetImageKey();
   aParentCommands.AppendElement(layers::OpAddExternalImage(
                                 mExternalImageId.value(),
                                 key));
   aBuilder.PushImage(wr::ToWrRect(dest),
                      clipRegion,
                      WrImageRendering::Auto,
--- a/gfx/layers/wr/WebRenderImageLayer.cpp
+++ b/gfx/layers/wr/WebRenderImageLayer.cpp
@@ -140,17 +140,17 @@ WebRenderImageLayer::RenderLayer(wr::Dis
                           mExternalImageId.ref());
   }
 
   if (mKey.isNothing()) {
     return;
   }
 
   gfx::Matrix4x4 transform = GetTransform();
-  gfx::Rect relBounds = GetWrRelBounds();
+  LayerRect relBounds = GetWrRelBounds();
 
   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);
   }
   rect = RelativeToVisible(rect);
--- a/gfx/layers/wr/WebRenderLayer.cpp
+++ b/gfx/layers/wr/WebRenderLayer.cpp
@@ -50,56 +50,59 @@ Rect
 WebRenderLayer::RelativeToTransformedVisible(Rect aRect)
 {
   IntRect bounds = GetLayer()->GetVisibleRegion().GetBounds().ToUnknownRect();
   Rect transformed = GetLayer()->GetTransform().TransformBounds(IntRectToRect(bounds));
   aRect.MoveBy(-transformed.x, -transformed.y);
   return aRect;
 }
 
-Rect
+LayerRect
 WebRenderLayer::ParentStackingContextBounds()
 {
   // Walk up to find the parent stacking context. This will be created either
   // by the nearest scrollable metrics, or by the parent layer which must be a
   // ContainerLayer.
-  Layer* layer = GetLayer();
-  if (layer->GetParent()) {
-    return IntRectToRect(layer->GetParent()->GetVisibleRegion().GetBounds().ToUnknownRect());
+  if (Layer* parent = GetLayer()->GetParent()) {
+    return ToWebRenderLayer(parent)->Bounds();
   }
-  return Rect();
+  return LayerRect();
 }
 
-Rect
-WebRenderLayer::RelativeToParent(Rect aRect)
+LayerRect
+WebRenderLayer::RelativeToParent(const LayerRect& aRect)
 {
-  Rect parentBounds = ParentStackingContextBounds();
-  aRect.MoveBy(-parentBounds.x, -parentBounds.y);
-  return aRect;
+  return aRect - ParentStackingContextBounds().TopLeft();
 }
 
-Point
-WebRenderLayer::GetOffsetToParent()
+LayerRect
+WebRenderLayer::RelativeToParent(const LayoutDeviceRect& aRect)
 {
-  Rect parentBounds = ParentStackingContextBounds();
-  return parentBounds.TopLeft();
+  return RelativeToParent(ViewAs<LayerPixel>(
+      aRect, PixelCastJustification::WebRenderHasUnitResolution));
 }
 
-Rect
+LayerPoint
+WebRenderLayer::GetOffsetToParent()
+{
+  return ParentStackingContextBounds().TopLeft();
+}
+
+LayerRect
 WebRenderLayer::VisibleBoundsRelativeToParent()
 {
-  return RelativeToParent(IntRectToRect(GetLayer()->GetVisibleRegion().GetBounds().ToUnknownRect()));
+  return RelativeToParent(Bounds());
 }
 
-Rect
+gfx::Rect
 WebRenderLayer::TransformedVisibleBoundsRelativeToParent()
 {
   IntRect bounds = GetLayer()->GetVisibleRegion().GetBounds().ToUnknownRect();
   Rect transformed = GetLayer()->GetTransform().TransformBounds(IntRectToRect(bounds));
-  return RelativeToParent(transformed);
+  return transformed - ParentStackingContextBounds().ToUnknownRect().TopLeft();
 }
 
 Maybe<WrImageMask>
 WebRenderLayer::BuildWrMaskLayer(bool aUnapplyLayerTransform)
 {
   if (GetLayer()->GetMaskLayer()) {
     WebRenderLayer* maskLayer = ToWebRenderLayer(GetLayer()->GetMaskLayer());
 
@@ -173,20 +176,20 @@ WebRenderLayer::ClipRect()
   if (!layer->GetClipRect()) {
     return Nothing();
   }
   ParentLayerRect clip(layer->GetClipRect().ref());
   LayerToParentLayerMatrix4x4 transform = layer->GetLocalTransformTyped();
   return Some(transform.Inverse().TransformBounds(clip));
 }
 
-gfx::Rect
+LayerRect
 WebRenderLayer::GetWrRelBounds()
 {
-  return RelativeToParent(BoundsForStackingContext().ToUnknownRect());
+  return RelativeToParent(BoundsForStackingContext());
 }
 
 Maybe<wr::ImageKey>
 WebRenderLayer::UpdateImageKey(ImageClientSingle* aImageClient,
                                ImageContainer* aContainer,
                                Maybe<wr::ImageKey>& aOldKey,
                                wr::ExternalImageId& aExternalImageId)
 {
@@ -223,17 +226,17 @@ void
 WebRenderLayer::DumpLayerInfo(const char* aLayerType, const LayerRect& aRect)
 {
   if (!gfxPrefs::LayersDump()) {
     return;
   }
 
   Matrix4x4 transform = GetLayer()->GetTransform();
   LayerRect clip = GetWrClipRect(aRect);
-  Rect relBounds = GetWrRelBounds();
+  LayerRect relBounds = GetWrRelBounds();
   Rect overflow(0, 0, relBounds.width, relBounds.height);
   WrMixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetLayer()->GetMixBlendMode());
 
   printf_stderr("%s %p using bounds=%s, overflow=%s, transform=%s, rect=%s, clip=%s, mix-blend-mode=%s\n",
                 aLayerType,
                 GetLayer(),
                 Stringify(relBounds).c_str(),
                 Stringify(overflow).c_str(),
--- a/gfx/layers/wr/WebRenderLayer.h
+++ b/gfx/layers/wr/WebRenderLayer.h
@@ -43,29 +43,30 @@ public:
                                      wr::ExternalImageId& aExternalImageId);
 
   WebRenderLayerManager* WrManager();
   WebRenderBridgeChild* WrBridge();
   WrImageKey GetImageKey();
 
   LayerRect RelativeToVisible(const LayerRect& aRect);
   gfx::Rect RelativeToTransformedVisible(gfx::Rect aRect);
-  gfx::Rect ParentStackingContextBounds();
-  gfx::Rect RelativeToParent(gfx::Rect aRect);
-  gfx::Rect VisibleBoundsRelativeToParent();
-  gfx::Point GetOffsetToParent();
+  LayerRect ParentStackingContextBounds();
+  LayerRect RelativeToParent(const LayerRect& aRect);
+  LayerRect RelativeToParent(const LayoutDeviceRect& aRect);
+  LayerRect VisibleBoundsRelativeToParent();
+  LayerPoint GetOffsetToParent();
   gfx::Rect TransformedVisibleBoundsRelativeToParent();
 protected:
   LayerRect Bounds();
   BoundsTransformMatrix BoundsTransform();
   LayerRect BoundsForStackingContext();
   Maybe<LayerRect> ClipRect();
 
   LayerRect GetWrBoundsRect();
-  gfx::Rect GetWrRelBounds();
+  LayerRect GetWrRelBounds();
   LayerRect GetWrClipRect(const LayerRect& aRect);
   void DumpLayerInfo(const char* aLayerType, const LayerRect& aRect);
   Maybe<WrImageMask> BuildWrMaskLayer(bool aUnapplyLayerTransform);
 };
 
 } // namespace layers
 } // namespace mozilla
 
--- a/gfx/layers/wr/WebRenderPaintedLayer.cpp
+++ b/gfx/layers/wr/WebRenderPaintedLayer.cpp
@@ -90,17 +90,17 @@ WebRenderPaintedLayer::UpdateImageClient
 void
 WebRenderPaintedLayer::CreateWebRenderDisplayList(wr::DisplayListBuilder& aBuilder)
 {
   LayerIntRegion visibleRegion = GetVisibleRegion();
   LayerIntRect bounds = visibleRegion.GetBounds();
   LayerIntSize size = bounds.Size();
 
   gfx::Matrix4x4 transform = GetTransform();
-  gfx::Rect relBounds = GetWrRelBounds();
+  LayerRect relBounds = GetWrRelBounds();
   LayerRect rect(0, 0, size.width, size.height);
 
   LayerRect clipRect = GetWrClipRect(rect);
   Maybe<WrImageMask> mask = BuildWrMaskLayer(true);
   WrClipRegion clip = aBuilder.BuildClipRegion(wr::ToWrRect(clipRect), mask.ptrOr(nullptr));
 
   wr::MixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
 
--- a/gfx/layers/wr/WebRenderTextLayer.cpp
+++ b/gfx/layers/wr/WebRenderTextLayer.cpp
@@ -19,20 +19,22 @@ using namespace mozilla::gfx;
 
 void
 WebRenderTextLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
 {
     if (mBounds.IsEmpty()) {
         return;
     }
 
-    gfx::Rect rect = RelativeToParent(GetTransform().TransformBounds(IntRectToRect(mBounds)));
+    gfx::Rect rect = GetTransform().TransformBounds(IntRectToRect(mBounds))
+        - ParentStackingContextBounds().ToUnknownRect().TopLeft();
     gfx::Rect clip;
     if (GetClipRect().isSome()) {
-      clip = RelativeToParent(IntRectToRect(GetClipRect().ref().ToUnknownRect()));
+      clip = IntRectToRect(GetClipRect().ref().ToUnknownRect())
+          - ParentStackingContextBounds().ToUnknownRect().TopLeft();
     } else {
       clip = rect;
     }
 
     if (gfxPrefs::LayersDump()) {
         printf_stderr("TextLayer %p using rect=%s, clip=%s\n",
                       this->GetLayer(),
                       Stringify(rect).c_str(),
--- a/layout/generic/nsBulletFrame.cpp
+++ b/layout/generic/nsBulletFrame.cpp
@@ -458,19 +458,19 @@ BulletRenderer::CreateWebRenderCommandsF
   }
 
   Maybe<wr::ImageKey> key = layer->SendImageContainer(container, aParentCommands);
   if (key.isNothing()) {
     return;
   }
 
   const int32_t appUnitsPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
-  Rect destRect = LayoutDeviceRect::FromAppUnits(mDest, appUnitsPerDevPixel).ToUnknownRect();
-  Rect destRectTransformed = aLayer->RelativeToParent(destRect);
-  IntRect dest = RoundedToInt(destRectTransformed);
+  LayoutDeviceRect destRect = LayoutDeviceRect::FromAppUnits(mDest, appUnitsPerDevPixel);
+  LayerRect destRectTransformed = aLayer->RelativeToParent(destRect);
+  LayerIntRect dest = RoundedToInt(destRectTransformed);
 
   WrClipRegion clipRegion = aBuilder.BuildClipRegion(wr::ToWrRect(dest));
 
   aBuilder.PushImage(wr::ToWrRect(dest),
                      clipRegion,
                      WrImageRendering::Auto,
                      key.value());
 }
@@ -497,19 +497,19 @@ BulletRenderer::CreateWebRenderCommandsF
   MOZ_ASSERT(IsTextType());
   MOZ_ASSERT(mFont);
   MOZ_ASSERT(!mGlyphs.IsEmpty());
 
   layers::WebRenderDisplayItemLayer* layer = static_cast<layers::WebRenderDisplayItemLayer*>(aLayer);
   nsDisplayListBuilder* builder = layer->GetDisplayListBuilder();
   const int32_t appUnitsPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
   bool dummy;
-  Rect destRect = LayoutDeviceRect::FromAppUnits(
-      aItem->GetBounds(builder, &dummy), appUnitsPerDevPixel).ToUnknownRect();
-  Rect destRectTransformed = aLayer->RelativeToParent(destRect);
+  LayoutDeviceRect destRect = LayoutDeviceRect::FromAppUnits(
+      aItem->GetBounds(builder, &dummy), appUnitsPerDevPixel);
+  gfx::Rect destRectTransformed = aLayer->RelativeToParent(destRect).ToUnknownRect();
 
   layer->WrBridge()->PushGlyphs(aBuilder, mGlyphs, mFont, aLayer->GetOffsetToParent(),
                                 destRectTransformed, destRectTransformed);
 }
 
 class nsDisplayBullet final : public nsDisplayItem {
 public:
   nsDisplayBullet(nsDisplayListBuilder* aBuilder, nsBulletFrame* aFrame)
--- a/layout/generic/nsCanvasFrame.cpp
+++ b/layout/generic/nsCanvasFrame.cpp
@@ -307,22 +307,20 @@ nsDisplayCanvasBackgroundColor::CreateWe
                                                         nsTArray<WebRenderParentCommand>& aParentCommands,
                                                         WebRenderDisplayItemLayer* aLayer)
 {
   nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame);
   nsPoint offset = ToReferenceFrame();
   nsRect bgClipRect = frame->CanvasArea() + offset;
   int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
 
-  Rect devPxRect(Float(bgClipRect.x / appUnitsPerDevPixel),
-                 Float(bgClipRect.y / appUnitsPerDevPixel),
-                 Float(bgClipRect.width / appUnitsPerDevPixel),
-                 Float(bgClipRect.height / appUnitsPerDevPixel));
+  LayoutDeviceRect rect = LayoutDeviceRect::FromAppUnits(
+          bgClipRect, appUnitsPerDevPixel);
 
-  Rect transformedRect = aLayer->RelativeToParent(devPxRect);
+  LayerRect transformedRect = aLayer->RelativeToParent(rect);
   aBuilder.PushRect(wr::ToWrRect(transformedRect),
                     aBuilder.BuildClipRegion(wr::ToWrRect(transformedRect)),
                     wr::ToWrColor(ToDeviceColor(mColor)));
 }
 
 #ifdef MOZ_DUMP_PAINTING
 void
 nsDisplayCanvasBackgroundColor::WriteDebugInfo(std::stringstream& aStream)
--- a/layout/painting/nsCSSRenderingBorders.cpp
+++ b/layout/painting/nsCSSRenderingBorders.cpp
@@ -3549,17 +3549,18 @@ nsCSSBorderRenderer::CanCreateWebRenderC
   return true;
 }
 
 void
 nsCSSBorderRenderer::CreateWebRenderCommands(wr::DisplayListBuilder& aBuilder,
                                              layers::WebRenderDisplayItemLayer* aLayer,
                                              gfx::Rect aClipRect)
 {
-  Rect transformedRect = aLayer->RelativeToParent(mOuterRect);
+  LayoutDeviceRect outerRect = LayoutDeviceRect::FromUnknownRect(mOuterRect);
+  LayerRect transformedRect = aLayer->RelativeToParent(outerRect);
   WrBorderSide side[4];
   NS_FOR_CSS_SIDES(i) {
     side[i] = wr::ToWrBorderSide(ToDeviceColor(mBorderColors[i]), mBorderStyles[i]);
   }
 
   WrClipRegion clipRegion = aBuilder.BuildClipRegion(wr::ToWrRect(transformedRect));
   if (!aClipRect.IsEmpty()) {
     clipRegion = aBuilder.BuildClipRegion(wr::ToWrRect(aClipRect));
--- a/layout/painting/nsCSSRenderingGradients.cpp
+++ b/layout/painting/nsCSSRenderingGradients.cpp
@@ -1057,51 +1057,51 @@ nsCSSGradientRenderer::BuildWebRenderDis
   LayoutDevicePoint tileToClip = clipBounds.BottomRight() - firstTileBounds.TopLeft();
   LayoutDeviceRect gradientBounds = LayoutDeviceRect(firstTileBounds.TopLeft(),
                                                      LayoutDeviceSize(tileToClip.x, tileToClip.y));
 
   // Calculate the tile spacing, which is the repeat size minus the tile size
   LayoutDeviceSize tileSpacing = tileRepeat - firstTileBounds.Size();
 
   // Make the rects relative to the parent stacking context
-  clipBounds = LayoutDeviceRect::FromUnknownRect(aLayer->RelativeToParent(clipBounds.ToUnknownRect()));
-  firstTileBounds = LayoutDeviceRect::FromUnknownRect(aLayer->RelativeToParent(firstTileBounds.ToUnknownRect()));
-  gradientBounds = LayoutDeviceRect::FromUnknownRect(aLayer->RelativeToParent(gradientBounds.ToUnknownRect()));
+  LayerRect layerClipBounds = aLayer->RelativeToParent(clipBounds);
+  LayerRect layerFirstTileBounds = aLayer->RelativeToParent(firstTileBounds);
+  LayerRect layerGradientBounds = aLayer->RelativeToParent(gradientBounds);
 
   // srcTransform is used for scaling the gradient to match aSrc
   LayoutDeviceRect srcTransform = LayoutDeviceRect(mPresContext->CSSPixelsToAppUnits(aSrc.x),
                                                    mPresContext->CSSPixelsToAppUnits(aSrc.y),
                                                    aDest.width / ((float)mPresContext->CSSPixelsToAppUnits(aSrc.width)),
                                                    aDest.height / ((float)mPresContext->CSSPixelsToAppUnits(aSrc.height)));
 
   lineStart.x = (lineStart.x - srcTransform.x) * srcTransform.width;
   lineStart.y = (lineStart.y - srcTransform.y) * srcTransform.height;
 
   if (mGradient->mShape == NS_STYLE_GRADIENT_SHAPE_LINEAR) {
     lineEnd.x = (lineEnd.x - srcTransform.x) * srcTransform.width;
     lineEnd.y = (lineEnd.y - srcTransform.y) * srcTransform.height;
 
     aBuilder.PushLinearGradient(
-      mozilla::wr::ToWrRect(gradientBounds),
-      aBuilder.BuildClipRegion(mozilla::wr::ToWrRect(clipBounds)),
+      mozilla::wr::ToWrRect(layerGradientBounds),
+      aBuilder.BuildClipRegion(mozilla::wr::ToWrRect(layerClipBounds)),
       mozilla::wr::ToWrPoint(lineStart),
       mozilla::wr::ToWrPoint(lineEnd),
       stops,
       extendMode,
-      mozilla::wr::ToWrSize(firstTileBounds.Size()),
+      mozilla::wr::ToWrSize(layerFirstTileBounds.Size()),
       mozilla::wr::ToWrSize(tileSpacing));
   } else {
     gradientRadius.width *= srcTransform.width;
     gradientRadius.height *= srcTransform.height;
 
     aBuilder.PushRadialGradient(
-      mozilla::wr::ToWrRect(gradientBounds),
-      aBuilder.BuildClipRegion(mozilla::wr::ToWrRect(clipBounds)),
+      mozilla::wr::ToWrRect(layerGradientBounds),
+      aBuilder.BuildClipRegion(mozilla::wr::ToWrRect(layerClipBounds)),
       mozilla::wr::ToWrPoint(lineStart),
       mozilla::wr::ToWrSize(gradientRadius),
       stops,
       extendMode,
-      mozilla::wr::ToWrSize(firstTileBounds.Size()),
+      mozilla::wr::ToWrSize(layerFirstTileBounds.Size()),
       mozilla::wr::ToWrSize(tileSpacing));
   }
 }
 
 } // namespace mozilla
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -4506,26 +4506,26 @@ nsDisplayCaret::CreateWebRenderCommands(
 
   int32_t appUnitsPerDevPixel = frame->PresContext()->AppUnitsPerDevPixel();
 
   nsRect caretRect;
   nsRect hookRect;
   mCaret->ComputeCaretRects(frame, contentOffset, &caretRect, &hookRect);
 
   gfx::Color color = ToDeviceColor(frame->GetCaretColorAt(contentOffset));
-  Rect devCaretRect = LayoutDeviceRect::FromAppUnits(
-    caretRect + ToReferenceFrame(), appUnitsPerDevPixel).ToUnknownRect();
-  Rect devHookRect = LayoutDeviceRect::FromAppUnits(
-    hookRect + ToReferenceFrame(), appUnitsPerDevPixel).ToUnknownRect();
-
-  Rect caretTransformedRect = aLayer->RelativeToParent(devCaretRect);
-  Rect hookTransformedRect = aLayer->RelativeToParent(devHookRect);
-
-  IntRect caret = RoundedToInt(caretTransformedRect);
-  IntRect hook = RoundedToInt(hookTransformedRect);
+  LayoutDeviceRect devCaretRect = LayoutDeviceRect::FromAppUnits(
+    caretRect + ToReferenceFrame(), appUnitsPerDevPixel);
+  LayoutDeviceRect devHookRect = LayoutDeviceRect::FromAppUnits(
+    hookRect + ToReferenceFrame(), appUnitsPerDevPixel);
+
+  LayerRect caretTransformedRect = aLayer->RelativeToParent(devCaretRect);
+  LayerRect hookTransformedRect = aLayer->RelativeToParent(devHookRect);
+
+  LayerIntRect caret = RoundedToInt(caretTransformedRect);
+  LayerIntRect hook = RoundedToInt(hookTransformedRect);
 
   // Note, WR will pixel snap anything that is layout aligned.
   aBuilder.PushRect(wr::ToWrRect(caret),
                     aBuilder.BuildClipRegion(wr::ToWrRect(caret)),
                     wr::ToWrColor(color));
 
   if (!devHookRect.IsEmpty()) {
     aBuilder.PushRect(wr::ToWrRect(hook),
@@ -4764,26 +4764,26 @@ nsDisplayBorder::CreateBorderImageWebRen
   float outset[4];
   const int32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
   NS_FOR_CSS_SIDES(i) {
     slice[i] = (float)(mBorderImageRenderer->mSlice.Side(i)) / appUnitsPerDevPixel;
     widths[i] = (float)(mBorderImageRenderer->mWidths.Side(i)) / appUnitsPerDevPixel;
     outset[i] = (float)(mBorderImageRenderer->mImageOutset.Side(i)) / appUnitsPerDevPixel;
   }
 
-  Rect destRect = LayoutDeviceRect::FromAppUnits(
-    mBorderImageRenderer->mArea, appUnitsPerDevPixel).ToUnknownRect();
-  Rect destRectTransformed = aLayer->RelativeToParent(destRect);
-  IntRect dest = RoundedToInt(destRectTransformed);
-
-  IntRect clip = dest;
+  LayoutDeviceRect destRect = LayoutDeviceRect::FromAppUnits(
+    mBorderImageRenderer->mArea, appUnitsPerDevPixel);
+  LayerRect destRectTransformed = aLayer->RelativeToParent(destRect);
+  LayerIntRect dest = RoundedToInt(destRectTransformed);
+
+  LayerIntRect clip = dest;
   if (!mBorderImageRenderer->mClip.IsEmpty()) {
-    Rect clipRect = LayoutDeviceRect::FromAppUnits(
-      mBorderImageRenderer->mClip, appUnitsPerDevPixel).ToUnknownRect();
-    Rect clipRectTransformed = aLayer->RelativeToParent(clipRect);
+    LayoutDeviceRect clipRect = LayoutDeviceRect::FromAppUnits(
+      mBorderImageRenderer->mClip, appUnitsPerDevPixel);
+    LayerRect clipRectTransformed = aLayer->RelativeToParent(clipRect);
     clip = RoundedToInt(clipRectTransformed);
   }
 
   switch (mBorderImageRenderer->mImageRenderer.GetType()) {
     case eStyleImageType_Image:
     {
       nsDisplayListBuilder* builder = aLayer->GetDisplayListBuilder();
       uint32_t flags = builder->ShouldSyncDecodeImages() ?
@@ -4824,20 +4824,20 @@ nsDisplayBorder::CreateBorderImageWebRen
       WrGradientExtendMode extendMode;
       nsTArray<WrGradientStop> stops;
       LayoutDevicePoint lineStart;
       LayoutDevicePoint lineEnd;
       LayoutDeviceSize gradientRadius;
       renderer.BuildWebRenderParameters(1.0, extendMode, stops, lineStart, lineEnd, gradientRadius);
 
       if (gradientData->mShape == NS_STYLE_GRADIENT_SHAPE_LINEAR) {
-        Point startPoint = dest.TopLeft();
-        startPoint = startPoint + Point(lineStart.x, lineStart.y);
-        Point endPoint = dest.TopLeft();
-        endPoint = endPoint + Point(lineEnd.x, lineEnd.y);
+        LayerPoint startPoint = dest.TopLeft();
+        startPoint = startPoint + ViewAs<LayerPixel>(lineStart, PixelCastJustification::WebRenderHasUnitResolution);
+        LayerPoint endPoint = dest.TopLeft();
+        endPoint = endPoint + ViewAs<LayerPixel>(lineEnd, PixelCastJustification::WebRenderHasUnitResolution);
 
         aBuilder.PushBorderGradient(wr::ToWrRect(dest),
                                     aBuilder.BuildClipRegion(wr::ToWrRect(clip)),
                                     wr::ToWrBorderWidths(widths[0], widths[1], widths[2], widths[3]),
                                     wr::ToWrPoint(startPoint),
                                     wr::ToWrPoint(endPoint),
                                     stops,
                                     extendMode,
@@ -5150,18 +5150,18 @@ nsDisplayBoxShadowOuter::CreateWebRender
                                                      borderRect,
                                                      mFrame,
                                                      borderRadii);
     MOZ_ASSERT(borderRadii.AreRadiiSame());
   }
 
   // Everything here is in app units, change to device units.
   for (uint32_t i = 0; i < rects.Length(); ++i) {
-    Rect clipRect = LayoutDeviceRect::FromAppUnits(
-        rects[i], appUnitsPerDevPixel).ToUnknownRect();
+    LayoutDeviceRect clipRect = LayoutDeviceRect::FromAppUnits(
+        rects[i], appUnitsPerDevPixel);
     nsCSSShadowArray* shadows = mFrame->StyleEffects()->mBoxShadow;
     MOZ_ASSERT(shadows);
 
     for (uint32_t j = shadows->Length(); j  > 0; j--) {
       nsCSSShadowItem* shadow = shadows->ShadowAt(j - 1);
       float blurRadius = float(shadow->mRadius) / float(appUnitsPerDevPixel);
       gfx::Color shadowColor = nsCSSRendering::GetShadowColor(shadow,
                                                               mFrame,
@@ -5169,21 +5169,21 @@ nsDisplayBoxShadowOuter::CreateWebRender
 
       // We don't move the shadow rect here since WR does it for us
       // Now translate everything to device pixels.
       nsRect shadowRect = frameRect;
       Point shadowOffset;
       shadowOffset.x = (shadow->mXOffset / appUnitsPerDevPixel);
       shadowOffset.y = (shadow->mYOffset / appUnitsPerDevPixel);
 
-      Rect deviceBoxRect = LayoutDeviceRect::FromAppUnits(
-          shadowRect, appUnitsPerDevPixel).ToUnknownRect();
-      deviceBoxRect = aLayer->RelativeToParent(deviceBoxRect);
+      LayoutDeviceRect deviceBox = LayoutDeviceRect::FromAppUnits(
+          shadowRect, appUnitsPerDevPixel);
+      LayerRect deviceBoxRect = aLayer->RelativeToParent(deviceBox);
       deviceBoxRect.Round();
-      Rect deviceClipRect = aLayer->RelativeToParent(clipRect);
+      LayerRect deviceClipRect = aLayer->RelativeToParent(clipRect);
 
       // TODO: support non-uniform border radius.
       float borderRadius = hasBorderRadius ? borderRadii.TopLeft().width
                                            : 0.0;
       float spreadRadius = float(shadow->mSpread) / float(appUnitsPerDevPixel);
 
       if (blurRadius <= 0) {
         MOZ_ASSERT(false, "WR needs clip out first");
@@ -5342,34 +5342,34 @@ nsDisplayBoxShadowInner::CreateInsetBoxS
 
   AutoTArray<nsRect,10> rects;
   nsRegion visible = aLayer->GetVisibleRegion().ToAppUnits(appUnitsPerDevPixel);
   ComputeDisjointRectangles(visible, &rects);
 
   nsCSSShadowArray* shadows = aFrame->StyleEffects()->mBoxShadow;
 
   for (uint32_t i = 0; i < rects.Length(); ++i) {
-    Rect clipRect = LayoutDeviceRect::FromAppUnits(
-        rects[i], appUnitsPerDevPixel).ToUnknownRect();
+    LayoutDeviceRect clipRect = LayoutDeviceRect::FromAppUnits(
+        rects[i], appUnitsPerDevPixel);
 
     for (uint32_t i = shadows->Length(); i > 0; --i) {
       nsCSSShadowItem* shadowItem = shadows->ShadowAt(i - 1);
       if (!shadowItem->mInset) {
         continue;
       }
 
       nsRect shadowRect =
         nsCSSRendering::GetBoxShadowInnerPaddingRect(aFrame, aBorderRect);
       RectCornerRadii innerRadii;
       nsCSSRendering::GetShadowInnerRadii(aFrame, aBorderRect, innerRadii);
 
       // Now translate everything to device pixels.
       Rect deviceBoxRect = LayoutDeviceRect::FromAppUnits(
           shadowRect, appUnitsPerDevPixel).ToUnknownRect();
-      Rect deviceClipRect = aLayer->RelativeToParent(clipRect);
+      LayerRect deviceClipRect = aLayer->RelativeToParent(clipRect);
       Color shadowColor = nsCSSRendering::GetShadowColor(shadowItem, aFrame, 1.0);
 
       Point shadowOffset;
       shadowOffset.x = (shadowItem->mXOffset / appUnitsPerDevPixel);
       shadowOffset.y = (shadowItem->mYOffset / appUnitsPerDevPixel);
 
       float blurRadius = float(shadowItem->mRadius) / float(appUnitsPerDevPixel);
       // TODO: WR doesn't support non-uniform border radii
--- a/layout/painting/nsImageRenderer.cpp
+++ b/layout/painting/nsImageRenderer.cpp
@@ -617,25 +617,25 @@ nsImageRenderer::BuildWebRenderDisplayIt
         return DrawResult::BAD_IMAGE;
       }
       Maybe<wr::ImageKey> key = aLayer->SendImageContainer(container, aParentCommands);
       if (key.isNothing()) {
         return DrawResult::BAD_IMAGE;
       }
 
       const int32_t appUnitsPerDevPixel = mForFrame->PresContext()->AppUnitsPerDevPixel();
-      Rect destRect = LayoutDeviceRect::FromAppUnits(
-          aDest, appUnitsPerDevPixel).ToUnknownRect();
-      Rect dest = aLayer->RelativeToParent(destRect);
+      LayoutDeviceRect destRect = LayoutDeviceRect::FromAppUnits(
+          aDest, appUnitsPerDevPixel);
+      LayerRect dest = aLayer->RelativeToParent(destRect);
 
-      Rect fillRect = LayoutDeviceRect::FromAppUnits(
-          aFill, appUnitsPerDevPixel).ToUnknownRect();
-      Rect fill = aLayer->RelativeToParent(fillRect);
+      LayoutDeviceRect fillRect = LayoutDeviceRect::FromAppUnits(
+          aFill, appUnitsPerDevPixel);
+      LayerRect fill = aLayer->RelativeToParent(fillRect);
 
-      Rect clip = fill;
+      LayerRect clip = fill;
       Size gapSize((aRepeatSize.width - aDest.width) / appUnitsPerDevPixel,
                    (aRepeatSize.height - aDest.height) / appUnitsPerDevPixel);
       aBuilder.PushImage(wr::ToWrRect(fill), aBuilder.BuildClipRegion(wr::ToWrRect(clip)),
                          wr::ToWrSize(dest.Size()), wr::ToWrSize(gapSize),
                          wr::ImageRendering::Auto, key.value());
       break;
     }
     default: