Bug 1284837 - Disallow implicit conversions from float to integer when creating IntPoint and IntSize objects. r=botond
authorNicolas Silva <nsilva@mozilla.com>
Tue, 26 Jul 2016 16:48:30 +0200
changeset 306729 550c31d39ecc648f4ca31e651ada238fd27b91e8
parent 306728 5f38091eaca223909b979aaad5c1171cf4447883
child 306730 1ea1e25c73fcd5e04734f94e2b88c66168a409de
push id20120
push userkwierso@gmail.com
push dateTue, 26 Jul 2016 23:55:13 +0000
treeherderfx-team@d9290a592a0d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbotond
bugs1284837
milestone50.0a1
Bug 1284837 - Disallow implicit conversions from float to integer when creating IntPoint and IntSize objects. r=botond
dom/base/Element.cpp
dom/base/nsDOMWindowUtils.cpp
dom/base/nsGlobalWindow.cpp
dom/canvas/CanvasRenderingContext2D.cpp
dom/media/raw/RawReader.cpp
dom/plugins/base/nsPluginInstanceOwner.cpp
dom/svg/SVGFETurbulenceElement.cpp
gfx/2d/DrawTargetD2D1.cpp
gfx/2d/Point.h
gfx/gl/SharedSurfaceIO.cpp
gfx/layers/MacIOSurfaceHelpers.cpp
gfx/layers/MacIOSurfaceImage.h
gfx/layers/apz/util/APZCCallbackHelper.cpp
gfx/layers/basic/BasicCompositor.cpp
gfx/layers/basic/BasicLayerManager.cpp
gfx/layers/composite/ContainerLayerComposite.cpp
gfx/thebes/PrintTargetWindows.cpp
image/ClippedImage.cpp
image/RasterImage.cpp
image/VectorImage.cpp
layout/base/FrameLayerBuilder.cpp
layout/base/nsLayoutUtils.cpp
layout/generic/nsCanvasFrame.cpp
layout/svg/nsSVGImageFrame.cpp
widget/InputData.cpp
widget/android/AndroidJavaWrappers.cpp
widget/android/nsWindow.cpp
widget/cocoa/nsChildView.mm
widget/cocoa/nsCocoaUtils.mm
widget/cocoa/nsDeviceContextSpecX.mm
widget/gtk/nsDeviceContextSpecG.cpp
widget/gtk/nsDragService.cpp
widget/gtk/nsWindow.cpp
widget/nsDeviceContextSpecProxy.cpp
widget/windows/nsDeviceContextSpecWin.cpp
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -696,18 +696,18 @@ Element::Scroll(const CSSIntPoint& aScro
     sf->ScrollToCSSPixels(aScroll, scrollMode);
   }
 }
 
 void
 Element::Scroll(double aXScroll, double aYScroll)
 {
   // Convert -Inf, Inf, and NaN to 0; otherwise, convert by C-style cast.
-  CSSIntPoint scrollPos(mozilla::ToZeroIfNonfinite(aXScroll),
-                        mozilla::ToZeroIfNonfinite(aYScroll));
+  auto scrollPos = CSSIntPoint::Truncate(mozilla::ToZeroIfNonfinite(aXScroll),
+                                         mozilla::ToZeroIfNonfinite(aYScroll));
 
   Scroll(scrollPos, ScrollOptions());
 }
 
 void
 Element::Scroll(const ScrollToOptions& aOptions)
 {
   nsIScrollableFrame *sf = GetScrollFrame();
@@ -736,18 +736,18 @@ Element::ScrollTo(const ScrollToOptions&
 }
 
 void
 Element::ScrollBy(double aXScrollDif, double aYScrollDif)
 {
   nsIScrollableFrame *sf = GetScrollFrame();
   if (sf) {
     CSSIntPoint scrollPos = sf->GetScrollPositionCSSPixels();
-    scrollPos += CSSIntPoint(mozilla::ToZeroIfNonfinite(aXScrollDif),
-                             mozilla::ToZeroIfNonfinite(aYScrollDif));
+    scrollPos += CSSIntPoint::Truncate(mozilla::ToZeroIfNonfinite(aXScrollDif),
+                                       mozilla::ToZeroIfNonfinite(aYScrollDif));
     Scroll(scrollPos, ScrollOptions());
   }
 }
 
 void
 Element::ScrollBy(const ScrollToOptions& aOptions)
 {
   nsIScrollableFrame *sf = GetScrollFrame();
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -2803,17 +2803,17 @@ nsDOMWindowUtils::WrapDOMFile(nsIFile *a
 static bool
 CheckLeafLayers(Layer* aLayer, const nsIntPoint& aOffset, nsIntRegion* aCoveredRegion)
 {
   gfx::Matrix transform;
   if (!aLayer->GetTransform().Is2D(&transform) ||
       transform.HasNonIntegerTranslation())
     return false;
   transform.NudgeToIntegers();
-  nsIntPoint offset = aOffset + nsIntPoint(transform._31, transform._32);
+  IntPoint offset = aOffset + IntPoint::Truncate(transform._31, transform._32);
 
   Layer* child = aLayer->GetFirstChild();
   if (child) {
     while (child) {
       if (!CheckLeafLayers(child, offset, aCoveredRegion))
         return false;
       child = child->GetNextSibling();
     }
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -7719,27 +7719,27 @@ nsGlobalWindow::GetTopWindowRoot()
   nsCOMPtr<nsPIWindowRoot> window = do_QueryInterface(piWin->GetChromeEventHandler());
   return window.forget();
 }
 
 void
 nsGlobalWindow::Scroll(double aXScroll, double aYScroll)
 {
   // Convert -Inf, Inf, and NaN to 0; otherwise, convert by C-style cast.
-  CSSIntPoint scrollPos(mozilla::ToZeroIfNonfinite(aXScroll),
-                        mozilla::ToZeroIfNonfinite(aYScroll));
+  auto scrollPos = CSSIntPoint::Truncate(mozilla::ToZeroIfNonfinite(aXScroll),
+                                         mozilla::ToZeroIfNonfinite(aYScroll));
   ScrollTo(scrollPos, ScrollOptions());
 }
 
 void
 nsGlobalWindow::ScrollTo(double aXScroll, double aYScroll)
 {
   // Convert -Inf, Inf, and NaN to 0; otherwise, convert by C-style cast.
-  CSSIntPoint scrollPos(mozilla::ToZeroIfNonfinite(aXScroll),
-                        mozilla::ToZeroIfNonfinite(aYScroll));
+  auto scrollPos = CSSIntPoint::Truncate(mozilla::ToZeroIfNonfinite(aXScroll),
+                                         mozilla::ToZeroIfNonfinite(aYScroll));
   ScrollTo(scrollPos, ScrollOptions());
 }
 
 void
 nsGlobalWindow::ScrollTo(const ScrollToOptions& aOptions)
 {
   FlushPendingNotifications(Flush_Layout);
   nsIScrollableFrame *sf = GetScrollFrame();
@@ -7798,18 +7798,18 @@ nsGlobalWindow::ScrollTo(const CSSIntPoi
 void
 nsGlobalWindow::ScrollBy(double aXScrollDif, double aYScrollDif)
 {
   FlushPendingNotifications(Flush_Layout);
   nsIScrollableFrame *sf = GetScrollFrame();
 
   if (sf) {
     // Convert -Inf, Inf, and NaN to 0; otherwise, convert by C-style cast.
-    CSSIntPoint scrollDif(mozilla::ToZeroIfNonfinite(aXScrollDif),
-                          mozilla::ToZeroIfNonfinite(aYScrollDif));
+    auto scrollDif = CSSIntPoint::Truncate(mozilla::ToZeroIfNonfinite(aXScrollDif),
+                                           mozilla::ToZeroIfNonfinite(aYScrollDif));
     // It seems like it would make more sense for ScrollBy to use
     // SMOOTH mode, but tests seem to depend on the synchronous behaviour.
     // Perhaps Web content does too.
     ScrollTo(sf->GetScrollPositionCSSPixels() + scrollDif, ScrollOptions());
   }
 }
 
 void
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -4815,18 +4815,18 @@ CanvasRenderingContext2D::DrawDirectlyTo
   }
   gfxSize contextScale(contextMatrix.ScaleFactors(true));
 
   // Scale the dest rect to include the context scale.
   aDest.Scale(contextScale.width, contextScale.height);
 
   // Scale the image size to the dest rect, and adjust the source rect to match.
   gfxSize scale(aDest.width / aSrc.width, aDest.height / aSrc.height);
-  nsIntSize scaledImageSize(std::ceil(aImgSize.width * scale.width),
-                            std::ceil(aImgSize.height * scale.height));
+  IntSize scaledImageSize = IntSize::Ceil(aImgSize.width * scale.width,
+                                          aImgSize.height * scale.height);
   aSrc.Scale(scale.width, scale.height);
 
   // We're wrapping tempTarget's (our) DrawTarget here, so we need to restore
   // the matrix even though this is a temp gfxContext.
   AutoRestoreTransform autoRestoreTransform(mTarget);
 
   RefPtr<gfxContext> context = gfxContext::CreateOrNull(tempTarget);
   if (!context) {
@@ -5040,17 +5040,17 @@ CanvasRenderingContext2D::DrawWindow(nsG
   {
     thebes = gfxContext::CreateOrNull(mTarget);
     MOZ_ASSERT(thebes); // already checked the draw target above
                         // (in SupportsAzureContentForDrawTarget)
     thebes->SetMatrix(gfxMatrix(matrix._11, matrix._12, matrix._21,
                                 matrix._22, matrix._31, matrix._32));
   } else {
     drawDT =
-      gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(IntSize(ceil(sw), ceil(sh)),
+      gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(IntSize::Ceil(sw, sh),
                                                                    SurfaceFormat::B8G8R8A8);
     if (!drawDT || !drawDT->IsValid()) {
       aError.Throw(NS_ERROR_FAILURE);
       return;
     }
 
     thebes = gfxContext::CreateOrNull(drawDT);
     MOZ_ASSERT(thebes); // alrady checked the draw target above
--- a/dom/media/raw/RawReader.cpp
+++ b/dom/media/raw/RawReader.cpp
@@ -55,20 +55,20 @@ nsresult RawReader::ReadMetadata(MediaIn
 
   if (mMetadata.aspectDenominator == 0 ||
       mMetadata.framerateDenominator == 0)
     return NS_ERROR_FAILURE; // Invalid data
 
   // Determine and verify frame display size.
   float pixelAspectRatio = static_cast<float>(mMetadata.aspectNumerator) /
                             mMetadata.aspectDenominator;
-  nsIntSize display(mMetadata.frameWidth, mMetadata.frameHeight);
+  nsIntSize display(uint32_t(mMetadata.frameWidth), uint32_t(mMetadata.frameHeight));
   ScaleDisplayByAspectRatio(display, pixelAspectRatio);
   mPicture = nsIntRect(0, 0, mMetadata.frameWidth, mMetadata.frameHeight);
-  nsIntSize frameSize(mMetadata.frameWidth, mMetadata.frameHeight);
+  nsIntSize frameSize(uint32_t(mMetadata.frameWidth), uint32_t(mMetadata.frameHeight));
   if (!IsValidVideoRegion(frameSize, mPicture, display)) {
     // Video track's frame sizes will overflow. Fail.
     return NS_ERROR_FAILURE;
   }
 
   mInfo.mVideo.mDisplay = display;
 
   mFrameRate = static_cast<float>(mMetadata.framerateNumerator) /
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -176,17 +176,17 @@ AttachToContainerAsSurfaceTexture(ImageC
 
   mozilla::gl::AndroidSurfaceTexture* surfTex = instance->AsSurfaceTexture();
   if (!surfTex) {
     return;
   }
 
   RefPtr<Image> img = new SurfaceTextureImage(
     surfTex,
-    gfx::IntSize(rect.width, rect.height),
+    gfx::IntSize::Truncate(rect.width, rect.height),
     instance->OriginPos());
   *out_image = img;
 }
 #endif
 
 bool
 nsPluginInstanceOwner::NeedsScrollImageLayer()
 {
@@ -217,17 +217,17 @@ nsPluginInstanceOwner::GetImageContainer
     return nullptr;
 
   LayoutDeviceRect r = GetPluginRect();
 
   // NotifySize() causes Flash to do a bunch of stuff like ask for surfaces to render
   // into, set y-flip flags, etc, so we do this at the beginning.
   float resolution = mPluginFrame->PresContext()->PresShell()->GetCumulativeResolution();
   ScreenSize screenSize = (r * LayoutDeviceToScreenScale(resolution)).Size();
-  mInstance->NotifySize(nsIntSize(screenSize.width, screenSize.height));
+  mInstance->NotifySize(nsIntSize::Truncate(screenSize.width, screenSize.height));
 
   container = LayerManager::CreateImageContainer();
 
   // Try to get it as an EGLImage first.
   RefPtr<Image> img;
   AttachToContainerAsSurfaceTexture(container, mInstance, r, &img);
 
   if (img) {
@@ -1579,17 +1579,17 @@ nsPluginInstanceOwner::GetVideos(nsTArra
 
 already_AddRefed<ImageContainer>
 nsPluginInstanceOwner::GetImageContainerForVideo(nsNPAPIPluginInstance::VideoInfo* aVideoInfo)
 {
   RefPtr<ImageContainer> container = LayerManager::CreateImageContainer();
 
   RefPtr<Image> img = new SurfaceTextureImage(
     aVideoInfo->mSurfaceTexture,
-    gfx::IntSize(aVideoInfo->mDimensions.width, aVideoInfo->mDimensions.height),
+    gfx::IntSize::Truncate(aVideoInfo->mDimensions.width, aVideoInfo->mDimensions.height),
     gl::OriginPos::BottomLeft);
   container->SetCurrentImageInTransaction(img);
 
   return container.forget();
 }
 
 void nsPluginInstanceOwner::Invalidate() {
   NPRect rect;
--- a/dom/svg/SVGFETurbulenceElement.cpp
+++ b/dom/svg/SVGFETurbulenceElement.cpp
@@ -142,17 +142,17 @@ SVGFETurbulenceElement::GetPrimitiveDesc
   // depending on the filter primitive region.
   gfxRect firstPeriodInUserSpace(0, 0, 1 / fX, 1 / fY);
   gfxRect firstPeriodInFilterSpace = aInstance->UserSpaceToFilterSpace(firstPeriodInUserSpace);
   Size frequencyInFilterSpace(1 / firstPeriodInFilterSpace.width,
                               1 / firstPeriodInFilterSpace.height);
   gfxPoint offset = firstPeriodInFilterSpace.TopLeft();
 
   FilterPrimitiveDescription descr(PrimitiveType::Turbulence);
-  descr.Attributes().Set(eTurbulenceOffset, IntPoint(offset.x, offset.y));
+  descr.Attributes().Set(eTurbulenceOffset, IntPoint::Truncate(offset.x, offset.y));
   descr.Attributes().Set(eTurbulenceBaseFrequency, frequencyInFilterSpace);
   descr.Attributes().Set(eTurbulenceSeed, seed);
   descr.Attributes().Set(eTurbulenceNumOctaves, octaves);
   descr.Attributes().Set(eTurbulenceStitchable, stitch == SVG_STITCHTYPE_STITCH);
   descr.Attributes().Set(eTurbulenceType, type);
   return descr;
 }
 
--- a/gfx/2d/DrawTargetD2D1.cpp
+++ b/gfx/2d/DrawTargetD2D1.cpp
@@ -334,17 +334,17 @@ DrawTargetD2D1::MaskSurface(const Patter
   mDC->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
 
   image->QueryInterface((ID2D1Bitmap**)getter_AddRefs(bitmap));
   if (!bitmap) {
     gfxWarning() << "FillOpacityMask only works with Bitmap source surfaces.";
     return;
   }
 
-  IntSize size = IntSize(bitmap->GetSize().width, bitmap->GetSize().height);
+  IntSize size = IntSize::Truncate(bitmap->GetSize().width, bitmap->GetSize().height);
 
   Rect maskRect = Rect(0.f, 0.f, Float(size.width), Float(size.height));
 
   Rect dest = Rect(aOffset.x, aOffset.y, Float(size.width), Float(size.height));
   RefPtr<ID2D1Brush> brush = CreateBrushForPattern(aSource, aOptions.mAlpha);
   mDC->FillOpacityMask(bitmap, brush, D2D1_OPACITY_MASK_CONTENT_GRAPHICS, D2DRect(dest), D2DRect(maskRect));
 
   mDC->SetAntialiasMode(D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
--- a/gfx/2d/Point.h
+++ b/gfx/2d/Point.h
@@ -28,33 +28,72 @@ namespace gfx {
 struct UnknownUnits {};
 
 } // namespace gfx
 
 template<> struct IsPixel<gfx::UnknownUnits> : TrueType {};
 
 namespace gfx {
 
+/// Use this for parameters of functions to allow implicit conversions to
+/// integer types but not floating point types.
+/// We use this wrapper to prevent IntSize and IntPoint's constructors to
+/// take foating point values as parameters, and not require their constructors
+/// to have implementations for each permutation of integer types.
+template<typename T>
+struct IntParam {
+  constexpr MOZ_IMPLICIT IntParam(char val) : value(val) {}
+  constexpr MOZ_IMPLICIT IntParam(unsigned char val) : value(val) {}
+  constexpr MOZ_IMPLICIT IntParam(short val) : value(val) {}
+  constexpr MOZ_IMPLICIT IntParam(unsigned short val) : value(val) {}
+  constexpr MOZ_IMPLICIT IntParam(int val) : value(val) {}
+  constexpr MOZ_IMPLICIT IntParam(unsigned int val) : value(val) {}
+  constexpr MOZ_IMPLICIT IntParam(long val) : value(val) {}
+  constexpr MOZ_IMPLICIT IntParam(unsigned long val) : value(val) {}
+  constexpr MOZ_IMPLICIT IntParam(long long val) : value(val) {}
+  constexpr MOZ_IMPLICIT IntParam(unsigned long long val) : value(val) {}
+  template<typename Unit>
+  constexpr MOZ_IMPLICIT IntParam(IntCoordTyped<Unit> val) : value(val) {}
+
+  // Disable the evil ones!
+  MOZ_IMPLICIT IntParam(float val) = delete;
+  MOZ_IMPLICIT IntParam(double val) = delete;
+
+  T value;
+};
+
 template<class units>
 struct IntPointTyped :
   public BasePoint< int32_t, IntPointTyped<units>, IntCoordTyped<units> >,
   public units {
   static_assert(IsPixel<units>::value,
                 "'units' must be a coordinate system tag");
 
+  typedef IntParam<int32_t> ToInt;
   typedef IntCoordTyped<units> Coord;
   typedef BasePoint< int32_t, IntPointTyped<units>, IntCoordTyped<units> > Super;
 
   constexpr IntPointTyped() : Super() {}
-  constexpr IntPointTyped(int32_t aX, int32_t aY) : Super(Coord(aX), Coord(aY)) {}
-  // The mixed-type constructors (int, Coord) and (Coord, int) are needed to
-  // avoid ambiguities because Coord is implicitly convertible to int.
-  constexpr IntPointTyped(int32_t aX, Coord aY) : Super(Coord(aX), aY) {}
-  constexpr IntPointTyped(Coord aX, int32_t aY) : Super(aX, Coord(aY)) {}
-  constexpr IntPointTyped(Coord aX, Coord aY) : Super(aX, aY) {}
+  constexpr IntPointTyped(ToInt aX, ToInt aY) : Super(Coord(aX.value), Coord(aY.value)) {}
+
+  static IntPointTyped<units> Round(float aX, float aY) {
+    return IntPointTyped(int32_t(floorf(aX + 0.5)), int32_t(floorf(aY + 0.5)));
+  }
+
+  static IntPointTyped<units> Ceil(float aX, float aY) {
+    return IntPointTyped(int32_t(ceil(aX)), int32_t(ceil(aY)));
+  }
+
+  static IntPointTyped<units> Floor(float aX, float aY) {
+    return IntPointTyped(int32_t(floorf(aX)), int32_t(floorf(aY)));
+  }
+
+  static IntPointTyped<units> Truncate(float aX, float aY) {
+    return IntPointTyped(int32_t(aX), int32_t(aY));
+  }
 
   // XXX When all of the code is ported, the following functions to convert to and from
   // unknown types should be removed.
 
   static IntPointTyped<units> FromUnknownPoint(const IntPointTyped<UnknownUnits>& aPoint) {
     return IntPointTyped<units>(aPoint.x, aPoint.y);
   }
 
@@ -94,24 +133,22 @@ struct PointTyped :
     return PointTyped<UnknownUnits, F>(this->x, this->y);
   }
 };
 typedef PointTyped<UnknownUnits> Point;
 typedef PointTyped<UnknownUnits, double> PointDouble;
 
 template<class units>
 IntPointTyped<units> RoundedToInt(const PointTyped<units>& aPoint) {
-  return IntPointTyped<units>(int32_t(floorf(aPoint.x + 0.5f)),
-                              int32_t(floorf(aPoint.y + 0.5f)));
+  return IntPointTyped<units>::Round(aPoint.x, aPoint.y);
 }
-
+  
 template<class units>
 IntPointTyped<units> TruncatedToInt(const PointTyped<units>& aPoint) {
-  return IntPointTyped<units>(int32_t(aPoint.x),
-                              int32_t(aPoint.y));
+  return IntPointTyped<units>::Truncate(aPoint.x, aPoint.y);
 }
 
 template<class units, class F = Float>
 struct Point3DTyped :
   public BasePoint3D< F, Point3DTyped<units, F> > {
   static_assert(IsPixel<units>::value,
                 "'units' must be a coordinate system tag");
 
@@ -165,20 +202,37 @@ typedef Point4DTyped<UnknownUnits, doubl
 
 template<class units>
 struct IntSizeTyped :
   public BaseSize< int32_t, IntSizeTyped<units> >,
   public units {
   static_assert(IsPixel<units>::value,
                 "'units' must be a coordinate system tag");
 
+  typedef IntParam<int32_t> ToInt;
   typedef BaseSize< int32_t, IntSizeTyped<units> > Super;
 
   constexpr IntSizeTyped() : Super() {}
-  constexpr IntSizeTyped(int32_t aWidth, int32_t aHeight) : Super(aWidth, aHeight) {}
+  constexpr IntSizeTyped(ToInt aWidth, ToInt aHeight) : Super(aWidth.value, aHeight.value) {}
+
+  static IntSizeTyped<units> Round(float aWidth, float aHeight) {
+    return IntSizeTyped(int32_t(floorf(aWidth + 0.5)), int32_t(floorf(aHeight + 0.5)));
+  }
+
+  static IntSizeTyped<units> Truncate(float aWidth, float aHeight) {
+    return IntSizeTyped(int32_t(aWidth), int32_t(aHeight));
+  }
+
+  static IntSizeTyped<units> Ceil(float aWidth, float aHeight) {
+    return IntSizeTyped(int32_t(ceil(aWidth)), int32_t(ceil(aHeight)));
+  }
+
+  static IntSizeTyped<units> Floor(float aWidth, float aHeight) {
+    return IntSizeTyped(int32_t(floorf(aWidth)), int32_t(floorf(aHeight)));
+  }
 
   // XXX When all of the code is ported, the following functions to convert to and from
   // unknown types should be removed.
 
   static IntSizeTyped<units> FromUnknownSize(const IntSizeTyped<UnknownUnits>& aSize) {
     return IntSizeTyped<units>(aSize.width, aSize.height);
   }
 
--- a/gfx/gl/SharedSurfaceIO.cpp
+++ b/gfx/gl/SharedSurfaceIO.cpp
@@ -17,17 +17,17 @@ namespace gl {
 /*static*/ UniquePtr<SharedSurface_IOSurface>
 SharedSurface_IOSurface::Create(const RefPtr<MacIOSurface>& ioSurf,
                                 GLContext* gl,
                                 bool hasAlpha)
 {
     MOZ_ASSERT(ioSurf);
     MOZ_ASSERT(gl);
 
-    gfx::IntSize size(ioSurf->GetWidth(), ioSurf->GetHeight());
+    auto size = gfx::IntSize::Truncate(ioSurf->GetWidth(), ioSurf->GetHeight());
 
     typedef SharedSurface_IOSurface ptrT;
     UniquePtr<ptrT> ret( new ptrT(ioSurf, gl, size, hasAlpha) );
     return Move(ret);
 }
 
 void
 SharedSurface_IOSurface::ProducerReleaseImpl()
@@ -209,18 +209,18 @@ SharedSurface_IOSurface::ReadbackByShare
 ////////////////////////////////////////////////////////////////////////
 // SurfaceFactory_IOSurface
 
 /*static*/ UniquePtr<SurfaceFactory_IOSurface>
 SurfaceFactory_IOSurface::Create(GLContext* gl, const SurfaceCaps& caps,
                                  const RefPtr<layers::ClientIPCAllocator>& allocator,
                                  const layers::TextureFlags& flags)
 {
-    gfx::IntSize maxDims(MacIOSurface::GetMaxWidth(),
-                         MacIOSurface::GetMaxHeight());
+    auto maxDims = gfx::IntSize::Truncate(MacIOSurface::GetMaxWidth(),
+                                          MacIOSurface::GetMaxHeight());
 
     typedef SurfaceFactory_IOSurface ptrT;
     UniquePtr<ptrT> ret( new ptrT(gl, caps, allocator, flags, maxDims) );
     return Move(ret);
 }
 
 UniquePtr<SharedSurface>
 SurfaceFactory_IOSurface::CreateShared(const gfx::IntSize& size)
--- a/gfx/layers/MacIOSurfaceHelpers.cpp
+++ b/gfx/layers/MacIOSurfaceHelpers.cpp
@@ -31,17 +31,17 @@ CreateSourceSurfaceFromLockedMacIOSurfac
   }
 
   SurfaceFormat format =
     (ioFormat == SurfaceFormat::NV12 || ioFormat == SurfaceFormat::YUV422)
       ? SurfaceFormat::B8G8R8X8
       : SurfaceFormat::B8G8R8A8;
 
   RefPtr<DataSourceSurface> dataSurface =
-    Factory::CreateDataSourceSurface(IntSize(ioWidth, ioHeight), format);
+    Factory::CreateDataSourceSurface(IntSize::Truncate(ioWidth, ioHeight), format);
   if (NS_WARN_IF(!dataSurface)) {
     return nullptr;
   }
 
   DataSourceSurface::MappedSurface mappedSurface;
   if (!dataSurface->Map(DataSourceSurface::WRITE, &mappedSurface)) {
     return nullptr;
   }
@@ -70,24 +70,24 @@ CreateSourceSurfaceFromLockedMacIOSurfac
         rowSrc++;
       }
     }
 
     /* Convert to RGB */
     PlanarYCbCrData data;
     data.mYChannel = (uint8_t*)aSurface->GetBaseAddressOfPlane(0);
     data.mYStride = aSurface->GetBytesPerRow(0);
-    data.mYSize = IntSize(ioWidth, ioHeight);
+    data.mYSize = IntSize::Truncate(ioWidth, ioHeight);
     data.mCbChannel = cbPlane.get();
     data.mCrChannel = crPlane.get();
     data.mCbCrStride = cbCrWidth;
-    data.mCbCrSize = IntSize(cbCrWidth, cbCrHeight);
+    data.mCbCrSize = IntSize::Truncate(cbCrWidth, cbCrHeight);
     data.mPicSize = data.mYSize;
 
-    ConvertYCbCrToRGB(data, SurfaceFormat::B8G8R8X8, IntSize(ioWidth, ioHeight), mappedSurface.mData, mappedSurface.mStride);
+    ConvertYCbCrToRGB(data, SurfaceFormat::B8G8R8X8, IntSize::Truncate(ioWidth, ioHeight), mappedSurface.mData, mappedSurface.mStride);
   } else if (ioFormat == SurfaceFormat::YUV422) {
     /* Convert to YV16 */
     size_t cbCrWidth = (ioWidth+1)>>1;
     size_t cbCrHeight = ioHeight;
     // Ensure our stride is a multiple of 32 to allow for memory aligned rows.
     size_t cbCrStride = ALIGNED_32(cbCrWidth);
     size_t strideDelta = cbCrStride - cbCrWidth;
     MOZ_ASSERT(strideDelta <= 31);
@@ -123,24 +123,24 @@ CreateSourceSurfaceFromLockedMacIOSurfac
         yDest  += strideDelta << 1;
       }
     }
 
     /* Convert to RGB */
     PlanarYCbCrData data;
     data.mYChannel = ALIGNEDPTR_32(yPlane.get());
     data.mYStride = cbCrStride * 2;
-    data.mYSize = IntSize(ioWidth, ioHeight);
+    data.mYSize = IntSize::Truncate(ioWidth, ioHeight);
     data.mCbChannel = ALIGNEDPTR_32(cbPlane.get());
     data.mCrChannel = ALIGNEDPTR_32(crPlane.get());
     data.mCbCrStride = cbCrStride;
-    data.mCbCrSize = IntSize(cbCrWidth, cbCrHeight);
+    data.mCbCrSize = IntSize::Truncate(cbCrWidth, cbCrHeight);
     data.mPicSize = data.mYSize;
 
-    ConvertYCbCrToRGB(data, SurfaceFormat::B8G8R8X8, IntSize(ioWidth, ioHeight), mappedSurface.mData, mappedSurface.mStride);
+    ConvertYCbCrToRGB(data, SurfaceFormat::B8G8R8X8, IntSize::Truncate(ioWidth, ioHeight), mappedSurface.mData, mappedSurface.mStride);
   } else {
     unsigned char* ioData = (unsigned char*)aSurface->GetBaseAddress();
 
     for (size_t i = 0; i < ioHeight; ++i) {
       memcpy(mappedSurface.mData + i * mappedSurface.mStride,
              ioData + i * bytesPerRow,
              ioWidth * 4);
     }
--- a/gfx/layers/MacIOSurfaceImage.h
+++ b/gfx/layers/MacIOSurfaceImage.h
@@ -20,17 +20,18 @@ public:
   explicit MacIOSurfaceImage(MacIOSurface* aSurface)
    : Image(nullptr, ImageFormat::MAC_IOSURFACE),
      mSurface(aSurface)
   {}
 
   MacIOSurface* GetSurface() { return mSurface; }
 
   gfx::IntSize GetSize() override {
-    return gfx::IntSize(mSurface->GetDevicePixelWidth(), mSurface->GetDevicePixelHeight());
+    return gfx::IntSize::Truncate(mSurface->GetDevicePixelWidth(),
+                                  mSurface->GetDevicePixelHeight());
   }
 
   virtual already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() override;
 
   virtual TextureClient* GetTextureClient(CompositableClient* aClient) override;
 
   virtual MacIOSurfaceImage* AsMacIOSurfaceImage() override {
     return this;
--- a/gfx/layers/apz/util/APZCCallbackHelper.cpp
+++ b/gfx/layers/apz/util/APZCCallbackHelper.cpp
@@ -466,17 +466,17 @@ APZCCallbackHelper::DispatchSynthesizedM
                                                   Modifiers aModifiers,
                                                   nsIWidget* aWidget)
 {
   MOZ_ASSERT(aMsg == eMouseMove || aMsg == eMouseDown ||
              aMsg == eMouseUp || aMsg == eMouseLongTap);
 
   WidgetMouseEvent event(true, aMsg, aWidget,
                          WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal);
-  event.mRefPoint = LayoutDeviceIntPoint(aRefPoint.x, aRefPoint.y);
+  event.mRefPoint = LayoutDeviceIntPoint::Truncate(aRefPoint.x, aRefPoint.y);
   event.mTime = aTime;
   event.button = WidgetMouseEvent::eLeftButton;
   event.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH;
   event.mIgnoreRootScrollFrame = true;
   if (aMsg != eMouseMove) {
     event.mClickCount = 1;
   }
   event.mModifiers = aModifiers;
--- a/gfx/layers/basic/BasicCompositor.cpp
+++ b/gfx/layers/basic/BasicCompositor.cpp
@@ -355,19 +355,19 @@ DrawSurfaceWithTextureCoords(DrawTarget 
 
   // Floating point error can accumulate above and we know our visible region
   // is integer-aligned, so round it out.
   sourceRect.Round();
 
   // Compute a transform that maps sourceRect to aDestRect.
   Matrix matrix =
     gfxUtils::TransformRectToRect(sourceRect,
-                                  gfx::IntPoint(aDestRect.x, aDestRect.y),
-                                  gfx::IntPoint(aDestRect.XMost(), aDestRect.y),
-                                  gfx::IntPoint(aDestRect.XMost(), aDestRect.YMost()));
+                                  gfx::IntPoint::Truncate(aDestRect.x, aDestRect.y),
+                                  gfx::IntPoint::Truncate(aDestRect.XMost(), aDestRect.y),
+                                  gfx::IntPoint::Truncate(aDestRect.XMost(), aDestRect.YMost()));
 
   // Only use REPEAT if aTextureCoords is outside (0, 0, 1, 1).
   gfx::Rect unitRect(0, 0, 1, 1);
   ExtendMode mode = unitRect.Contains(aTextureCoords) ? ExtendMode::CLAMP : ExtendMode::REPEAT;
 
   FillRectWithMask(aDest, aDestRect, aSource, aSamplingFilter, aOptions,
                    mode, aMask, aMaskTransform, &matrix);
 }
@@ -621,17 +621,17 @@ BasicCompositor::DrawQuad(const gfx::Rec
     dest->Flush();
 
     RefPtr<SourceSurface> destSnapshot = dest->Snapshot();
 
     SetupMask(aEffectChain, buffer, offset, sourceMask, maskTransform);
 
     if (sourceMask) {
       RefPtr<DrawTarget> transformDT =
-        dest->CreateSimilarDrawTarget(IntSize(transformBounds.width, transformBounds.height),
+        dest->CreateSimilarDrawTarget(IntSize::Truncate(transformBounds.width, transformBounds.height),
                                       SurfaceFormat::B8G8R8A8);
       new3DTransform.PostTranslate(-transformBounds.x, -transformBounds.y, 0);
       if (transformDT &&
           transformDT->Draw3DTransformedSurface(destSnapshot, new3DTransform)) {
         RefPtr<SourceSurface> transformSnapshot = transformDT->Snapshot();
 
         // Transform the source by it's normal transform, and then the inverse
         // of the mask transform so that it's in the mask's untransformed
--- a/gfx/layers/basic/BasicLayerManager.cpp
+++ b/gfx/layers/basic/BasicLayerManager.cpp
@@ -931,17 +931,17 @@ BasicLayerManager::PaintLayer(gfxContext
       effectiveTransform.TransformAndClipBounds(Rect(bounds),
                                                 ToRect(aTarget->GetClipExtents()));
     xformBounds.RoundOut();
     effectiveTransform.PostTranslate(-xformBounds.x, -xformBounds.y, 0);
     effectiveTransform.PreTranslate(bounds.x, bounds.y, 0);
 
     RefPtr<SourceSurface> untransformedSurf = untransformedDT->Snapshot();
     RefPtr<DrawTarget> xformDT =
-      untransformedDT->CreateSimilarDrawTarget(IntSize(xformBounds.width, xformBounds.height),
+      untransformedDT->CreateSimilarDrawTarget(IntSize::Truncate(xformBounds.width, xformBounds.height),
                                                SurfaceFormat::B8G8R8A8);
     RefPtr<SourceSurface> xformSurf;
     if(xformDT && untransformedSurf &&
        xformDT->Draw3DTransformedSurface(untransformedSurf, effectiveTransform)) {
       xformSurf = xformDT->Snapshot();
     }
 
     if (xformSurf) {
--- a/gfx/layers/composite/ContainerLayerComposite.cpp
+++ b/gfx/layers/composite/ContainerLayerComposite.cpp
@@ -721,17 +721,17 @@ CreateTemporaryTargetAndCopyFromBackgrou
   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;
   MOZ_ASSERT(transform.Is2D(&transform2d) && !gfx::ThebesMatrix(transform2d).HasNonIntegerTranslation());
-  sourcePoint += gfx::IntPoint(transform._41, transform._42);
+  sourcePoint += gfx::IntPoint::Truncate(transform._41, transform._42);
 
   sourcePoint -= compositor->GetCurrentRenderTarget()->GetOrigin();
 
   return compositor->CreateRenderTargetFromSource(surfaceRect, previousTarget, sourcePoint);
 }
 
 template<class ContainerT> void
 RenderIntermediate(ContainerT* aContainer,
--- a/gfx/thebes/PrintTargetWindows.cpp
+++ b/gfx/thebes/PrintTargetWindows.cpp
@@ -29,17 +29,17 @@ PrintTargetWindows::CreateOrNull(HDC aDC
   // Figure out the cairo surface size - Windows we need to use the printable
   // area of the page.  Note: we only scale the printing using the LOGPIXELSY,
   // so we use that when calculating the surface width as well as the height.
   int32_t heightDPI = ::GetDeviceCaps(aDC, LOGPIXELSY);
   float width =
     (::GetDeviceCaps(aDC, HORZRES) * POINTS_PER_INCH_FLOAT) / heightDPI;
   float height =
     (::GetDeviceCaps(aDC, VERTRES) * POINTS_PER_INCH_FLOAT) / heightDPI;
-  IntSize size(width, height);
+  IntSize size = IntSize::Truncate(width, height);
 
   if (!Factory::CheckSurfaceSize(size)) {
     return nullptr;
   }
 
   cairo_surface_t* surface = cairo_win32_printing_surface_create(aDC);
 
   if (cairo_surface_status(surface)) {
--- a/image/ClippedImage.cpp
+++ b/image/ClippedImage.cpp
@@ -515,35 +515,35 @@ ClippedImage::OptimalImageSizeForDest(co
   }
 
   if (needScale) {
     // To avoid ugly sampling artifacts, ClippedImage needs the image size to
     // be chosen such that the clipping region lies on pixel boundaries.
 
     // First, we select a scale that's good for ClippedImage. An integer
     // multiple of the size of the clipping region is always fine.
-    nsIntSize scale(ceil(aDest.width / mClip.width),
-                    ceil(aDest.height / mClip.height));
+    IntSize scale = IntSize::Ceil(aDest.width / mClip.width,
+                                  aDest.height / mClip.height);
 
     if (forceUniformScaling) {
       scale.width = scale.height = max(scale.height, scale.width);
     }
 
     // Determine the size we'd prefer to render the inner image at, and ask the
     // inner image what size we should actually use.
     gfxSize desiredSize(imgWidth * scale.width, imgHeight * scale.height);
     nsIntSize innerDesiredSize =
       InnerImage()->OptimalImageSizeForDest(desiredSize, aWhichFrame,
                                             aSamplingFilter, aFlags);
 
     // To get our final result, we take the inner image's desired size and
     // determine how large the clipped region would be at that scale. (Again, we
     // ensure an integer multiple of the size of the clipping region.)
-    nsIntSize finalScale(ceil(double(innerDesiredSize.width) / imgWidth),
-                         ceil(double(innerDesiredSize.height) / imgHeight));
+    IntSize finalScale = IntSize::Ceil(double(innerDesiredSize.width) / imgWidth,
+                                       double(innerDesiredSize.height) / imgHeight);
     return mClip.Size() * finalScale;
   }
 
   MOZ_ASSERT(false,
              "If ShouldClip() led us to draw then we should never get here");
   return InnerImage()->OptimalImageSizeForDest(aDest, aWhichFrame,
                                                aSamplingFilter, aFlags);
 }
--- a/image/RasterImage.cpp
+++ b/image/RasterImage.cpp
@@ -1818,17 +1818,17 @@ RasterImage::OptimalImageSizeForDest(con
   MOZ_ASSERT(aDest.width >= 0 || ceil(aDest.width) <= INT32_MAX ||
              aDest.height >= 0 || ceil(aDest.height) <= INT32_MAX,
              "Unexpected destination size");
 
   if (mSize.IsEmpty() || aDest.IsEmpty()) {
     return IntSize(0, 0);
   }
 
-  IntSize destSize(ceil(aDest.width), ceil(aDest.height));
+  IntSize destSize = IntSize::Ceil(aDest.width, aDest.height);
 
   if (aSamplingFilter == SamplingFilter::GOOD &&
       CanDownscaleDuringDecode(destSize, aFlags)) {
     return destSize;
   }
 
   // We can't scale to this size. Use our intrinsic size for now.
   return mSize;
--- a/image/VectorImage.cpp
+++ b/image/VectorImage.cpp
@@ -1297,17 +1297,17 @@ VectorImage::OptimalImageSizeForDest(con
                                      SamplingFilter aSamplingFilter,
                                      uint32_t aFlags)
 {
   MOZ_ASSERT(aDest.width >= 0 || ceil(aDest.width) <= INT32_MAX ||
              aDest.height >= 0 || ceil(aDest.height) <= INT32_MAX,
              "Unexpected destination size");
 
   // We can rescale SVGs freely, so just return the provided destination size.
-  return nsIntSize(ceil(aDest.width), ceil(aDest.height));
+  return nsIntSize::Ceil(aDest.width, aDest.height);
 }
 
 already_AddRefed<imgIContainer>
 VectorImage::Unwrap()
 {
   nsCOMPtr<imgIContainer> self(this);
   return self.forget();
 }
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -5549,17 +5549,17 @@ static void DebugPaintItem(DrawTarget& a
                            nsDisplayItem *aItem,
                            nsDisplayListBuilder* aBuilder)
 {
   bool snap;
   Rect bounds = NSRectToRect(aItem->GetBounds(aBuilder, &snap),
                              aPresContext->AppUnitsPerDevPixel());
 
   RefPtr<DrawTarget> tempDT =
-    aDrawTarget.CreateSimilarDrawTarget(IntSize(bounds.width, bounds.height),
+    aDrawTarget.CreateSimilarDrawTarget(IntSize::Truncate(bounds.width, bounds.height),
                                         SurfaceFormat::B8G8R8A8);
   RefPtr<gfxContext> context = gfxContext::CreateOrNull(tempDT);
   if (!context) {
     // Leave this as crash, it's in the debugging code, we want to know
     gfxDevCrash(LogReason::InvalidContext) << "DebugPaintItem context problem " << gfx::hexa(tempDT);
     return;
   }
   context->SetMatrix(gfxMatrix::Translation(-bounds.x, -bounds.y));
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -6536,17 +6536,17 @@ ComputeSnappedImageDrawingParameters(gfx
     aImage->OptimalImageSizeForDest(snappedDestSize,
                                     imgIContainer::FRAME_CURRENT,
                                     aSamplingFilter, aImageFlags);
   gfxSize imageSize(intImageSize.width, intImageSize.height);
 
   // XXX(seth): May be buggy; see bug 1151016.
   CSSIntSize svgViewportSize = currentMatrix.IsIdentity()
     ? CSSIntSize(intImageSize.width, intImageSize.height)
-    : CSSIntSize(devPixelDest.width, devPixelDest.height);
+    : CSSIntSize::Truncate(devPixelDest.width, devPixelDest.height);
 
   // Compute the set of pixels that would be sampled by an ideal rendering
   gfxPoint subimageTopLeft =
     MapToFloatImagePixels(imageSize, devPixelDest, devPixelFill.TopLeft());
   gfxPoint subimageBottomRight =
     MapToFloatImagePixels(imageSize, devPixelDest, devPixelFill.BottomRight());
   gfxRect subimage;
   subimage.MoveTo(NSToIntFloor(subimageTopLeft.x),
--- a/layout/generic/nsCanvasFrame.cpp
+++ b/layout/generic/nsCanvasFrame.cpp
@@ -302,18 +302,18 @@ nsDisplayCanvasBackgroundImage::Paint(ns
     RefPtr<DrawTarget> dt = 
       Frame()->Properties().Get(nsIFrame::CachedBackgroundImageDT());
     DrawTarget* destDT = dest->GetDrawTarget();
     if (dt) {
       BlitSurface(destDT, destRect, dt);
       return;
     }
 
-    dt = destDT->CreateSimilarDrawTarget(IntSize(ceil(destRect.width),
-                                                 ceil(destRect.height)),
+    dt = destDT->CreateSimilarDrawTarget(IntSize::Ceil(destRect.width,
+                                                       destRect.height),
                                          SurfaceFormat::B8G8R8A8);
     if (dt && dt->IsValid()) {
       RefPtr<gfxContext> ctx = gfxContext::CreateOrNull(dt);
       MOZ_ASSERT(ctx); // already checked draw target above
       ctx->SetMatrix(ctx->CurrentMatrix().Translate(-destRect.x, -destRect.y));
       nsRenderingContext context(ctx);
       PaintInternal(aBuilder, &context, bgClipRect, &bgClipRect);
       BlitSurface(dest->GetDrawTarget(), destRect, dt);
--- a/layout/svg/nsSVGImageFrame.cpp
+++ b/layout/svg/nsSVGImageFrame.cpp
@@ -398,17 +398,17 @@ nsSVGImageFrame::PaintSVG(gfxContext& aC
 
     if (mImageContainer->GetType() == imgIContainer::TYPE_VECTOR) {
       // Package up the attributes of this image element which can override the
       // attributes of mImageContainer's internal SVG document.  The 'width' &
       // 'height' values we're passing in here are in CSS units (though they
       // come from width/height *attributes* in SVG). They influence the region
       // of the SVG image's internal document that is visible, in combination
       // with preserveAspectRatio and viewBox.
-      SVGImageContext context(CSSIntSize(width, height),
+      SVGImageContext context(CSSIntSize::Truncate(width, height),
                               Some(imgElem->mPreserveAspectRatio.GetAnimValue()),
                               1.0, true);
 
       // For the actual draw operation to draw crisply (and at the right size),
       // our destination rect needs to be |width|x|height|, *in dev pixels*.
       LayoutDeviceSize devPxSize(width, height);
       nsRect destRect(nsPoint(),
                       LayoutDevicePixel::ToAppUnits(devPxSize,
--- a/widget/InputData.cpp
+++ b/widget/InputData.cpp
@@ -16,18 +16,18 @@ namespace mozilla {
 
 using namespace dom;
 
 already_AddRefed<Touch> SingleTouchData::ToNewDOMTouch() const
 {
   MOZ_ASSERT(NS_IsMainThread(),
              "Can only create dom::Touch instances on main thread");
   RefPtr<Touch> touch = new Touch(mIdentifier,
-                                  LayoutDeviceIntPoint(mScreenPoint.x, mScreenPoint.y),
-                                  LayoutDeviceIntPoint(mRadius.width, mRadius.height),
+                                  LayoutDeviceIntPoint::Truncate(mScreenPoint.x, mScreenPoint.y),
+                                  LayoutDeviceIntPoint::Truncate(mRadius.width, mRadius.height),
                                   mRotationAngle,
                                   mForce);
   return touch.forget();
 }
 
 MouseInput::MouseInput(const WidgetMouseEventBase& aMouseEvent)
   : InputData(MOUSE_INPUT, aMouseEvent.mTime, aMouseEvent.mTimeStamp,
               aMouseEvent.mModifiers)
--- a/widget/android/AndroidJavaWrappers.cpp
+++ b/widget/android/AndroidJavaWrappers.cpp
@@ -502,20 +502,20 @@ AndroidGeckoEvent::MakeTouchEvent(nsIWid
     const LayoutDeviceIntPoint& offset = widget->WidgetToScreenOffset();
     event.mTouches.SetCapacity(endIndex - startIndex);
     for (int i = startIndex; i < endIndex; i++) {
         // In this code branch, we are dispatching this event directly
         // into Gecko (as opposed to going through the AsyncPanZoomController),
         // and the Points() array has points in CSS pixels, which we need
         // to convert.
         CSSToLayoutDeviceScale scale = widget->GetDefaultScale();
-        LayoutDeviceIntPoint pt(
+        auto pt = LayoutDeviceIntPoint::Truncate(
             (Points()[i].x * scale.scale) - offset.x,
             (Points()[i].y * scale.scale) - offset.y);
-        LayoutDeviceIntPoint radius(
+        auto radius = LayoutDeviceIntPoint::Truncate(
             PointRadii()[i].x * scale.scale,
             PointRadii()[i].y * scale.scale);
         RefPtr<Touch> t = new Touch(PointIndicies()[i],
                                     pt,
                                     radius,
                                     Orientations()[i],
                                     Pressures()[i]);
         event.mTouches.AppendElement(t);
@@ -620,18 +620,18 @@ AndroidGeckoEvent::MakeMouseEvent(nsIWid
     event.mTime = Time();
 
     // We are dispatching this event directly into Gecko (as opposed to going
     // through the AsyncPanZoomController), and the Points() array has points
     // in CSS pixels, which we need to convert to LayoutDevice pixels.
     const LayoutDeviceIntPoint& offset = widget->WidgetToScreenOffset();
     CSSToLayoutDeviceScale scale = widget->GetDefaultScale();
     event.mRefPoint =
-        LayoutDeviceIntPoint((Points()[0].x * scale.scale) - offset.x,
-                             (Points()[0].y * scale.scale) - offset.y);
+        LayoutDeviceIntPoint::Truncate((Points()[0].x * scale.scale) - offset.x,
+                                       (Points()[0].y * scale.scale) - offset.y);
     return event;
 }
 
 Modifiers
 AndroidGeckoEvent::DOMModifiers() const
 {
     Modifiers result = 0;
     if (mMetaState & AMETA_ALT_MASK) {
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -1615,18 +1615,19 @@ nsWindow::Resize(double aX,
 
     bool needSizeDispatch = aWidth != mBounds.width || aHeight != mBounds.height;
 
     mBounds.x = NSToIntRound(aX);
     mBounds.y = NSToIntRound(aY);
     mBounds.width = NSToIntRound(aWidth);
     mBounds.height = NSToIntRound(aHeight);
 
-    if (needSizeDispatch)
-        OnSizeChanged(gfx::IntSize(aWidth, aHeight));
+    if (needSizeDispatch) {
+        OnSizeChanged(gfx::IntSize::Truncate(aWidth, aHeight));
+    }
 
     // Should we skip honoring aRepaint here?
     if (aRepaint && FindTopLevel() == nsWindow::TopWindow())
         RedrawAll();
 
     nsIWidgetListener* listener = GetWidgetListener();
     if (mAwaitingFullScreen && listener) {
       listener->FullscreenChanged(mIsFullScreen);
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -3741,17 +3741,17 @@ NSEvent* gLastDragMouseDownEvent = nil;
   // scales one user space unit to one Cocoa point, which can consist of
   // multiple dev pixels. But Gecko expects its supplied context to be scaled
   // to device pixels, so we need to reverse the scaling.
   double scale = mGeckoChild->BackingScaleFactor();
   CGContextSaveGState(aContext);
   CGContextScaleCTM(aContext, 1.0 / scale, 1.0 / scale);
 
   NSSize viewSize = [self bounds].size;
-  nsIntSize backingSize(viewSize.width * scale, viewSize.height * scale);
+  gfx::IntSize backingSize = gfx::IntSize::Truncate(viewSize.width * scale, viewSize.height * scale);
   LayoutDeviceIntRegion region = [self nativeDirtyRegionWithBoundingRect:aRect];
 
   bool painted = mGeckoChild->PaintWindowInContext(aContext, region, backingSize);
 
   // Undo the scale transform so that from now on the context is in
   // CocoaPoints again.
   CGContextRestoreGState(aContext);
 
@@ -4121,17 +4121,17 @@ NSEvent* gLastDragMouseDownEvent = nil;
           break;
         }
       }
 
       if (shouldRollup) {
         if ([theEvent type] == NSLeftMouseDown) {
           NSPoint point = [NSEvent mouseLocation];
           FlipCocoaScreenCoordinate(point);
-          nsIntPoint pos(point.x, point.y);
+          gfx::IntPoint pos = gfx::IntPoint::Truncate(point.x, point.y);
           consumeEvent = (BOOL)rollupListener->Rollup(popupsToRollup, true, &pos, nullptr);
         }
         else {
           consumeEvent = (BOOL)rollupListener->Rollup(popupsToRollup, true, nullptr, nullptr);
         }
       }
     }
   }
@@ -5765,17 +5765,17 @@ PanGestureTypeForEvent(NSEvent* aEvent)
     NS_ASSERTION(mDragService, "Couldn't get a drag service - big problem!");
   }
 
   if (mDragService) {
     // set the dragend point from the current mouse location
     nsDragService* dragService = static_cast<nsDragService *>(mDragService);
     NSPoint pnt = [NSEvent mouseLocation];
     FlipCocoaScreenCoordinate(pnt);
-    dragService->SetDragEndPoint(nsIntPoint(NSToIntRound(pnt.x), NSToIntRound(pnt.y)));
+    dragService->SetDragEndPoint(gfx::IntPoint::Round(pnt.x, pnt.y));
 
     // XXX: dropEffect should be updated per |operation|.
     // As things stand though, |operation| isn't well handled within "our"
     // events, that is, when the drop happens within the window: it is set
     // either to NSDragOperationGeneric or to NSDragOperationNone.
     // For that reason, it's not yet possible to override dropEffect per the
     // given OS value, and it's also unclear what's the correct dropEffect
     // value for NSDragOperationGeneric that is passed by other applications.
--- a/widget/cocoa/nsCocoaUtils.mm
+++ b/widget/cocoa/nsCocoaUtils.mm
@@ -472,17 +472,17 @@ nsresult nsCocoaUtils::CreateNSImageFrom
 {
   RefPtr<SourceSurface> surface;
   int32_t width = 0, height = 0;
   aImage->GetWidth(&width);
   aImage->GetHeight(&height);
 
   // Render a vector image at the correct resolution on a retina display
   if (aImage->GetType() == imgIContainer::TYPE_VECTOR && scaleFactor != 1.0f) {
-    IntSize scaledSize(ceil(width * scaleFactor), ceil(height * scaleFactor));
+    IntSize scaledSize = IntSize::Ceil(width * scaleFactor, height * scaleFactor);
 
     RefPtr<DrawTarget> drawTarget = gfxPlatform::GetPlatform()->
       CreateOffscreenContentDrawTarget(scaledSize, SurfaceFormat::B8G8R8A8);
     if (!drawTarget || !drawTarget->IsValid()) {
       NS_ERROR("Failed to create valid DrawTarget");
       return NS_ERROR_FAILURE;
     }
 
--- a/widget/cocoa/nsDeviceContextSpecX.mm
+++ b/widget/cocoa/nsDeviceContextSpecX.mm
@@ -141,17 +141,17 @@ void nsDeviceContextSpecX::GetPaperRect(
 already_AddRefed<PrintTarget> nsDeviceContextSpecX::MakePrintTarget()
 {
     NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
     double top, left, bottom, right;
     GetPaperRect(&top, &left, &bottom, &right);
     const double width = right - left;
     const double height = bottom - top;
-    IntSize size(floor(width), floor(height));
+    IntSize size = IntSize::Floor(width, height);
 
     CGContextRef context;
     ::PMSessionGetCGGraphicsContext(mPrintSession, &context);
 
     if (context) {
         // Initially, origin is at bottom-left corner of the paper.
         // Here, we translate it to top-left corner of the paper.
         CGContextTranslateCTM(context, 0, height);
--- a/widget/gtk/nsDeviceContextSpecG.cpp
+++ b/widget/gtk/nsDeviceContextSpecG.cpp
@@ -156,17 +156,17 @@ already_AddRefed<PrintTarget> nsDeviceCo
     if (mIsPPreview) {
       // There is nothing to detect on Print Preview, use PS.
       format = nsIPrintSettings::kOutputFormatPS;
     } else {
       return nullptr;
     }
   }
 
-  IntSize size(width, height);
+  IntSize size = IntSize::Truncate(width, height);
 
   if (format == nsIPrintSettings::kOutputFormatPDF) {
     return PrintTargetPDF::CreateOrNull(stream, size);
   }
 
   int32_t orientation;
   mPrintSettings->GetOrientation(&orientation);
   return PrintTargetPS::CreateOrNull(stream,
--- a/widget/gtk/nsDragService.cpp
+++ b/widget/gtk/nsDragService.cpp
@@ -232,18 +232,18 @@ OnSourceGrabEventAfter(GtkWidget *widget
             gdk_event_free(sMotionEvent);
         }
         sMotionEvent = gdk_event_copy(event);
 
         // Update the cursor position.  The last of these recorded gets used for
         // the eDragEnd event.
         nsDragService *dragService = static_cast<nsDragService*>(user_data);
         gint scale = nsScreenGtk::GetGtkMonitorScaleFactor();
-        LayoutDeviceIntPoint p(floor(event->motion.x_root * scale + 0.5),
-                               floor(event->motion.y_root * scale + 0.5));
+        auto p = LayoutDeviceIntPoint::Round(event->motion.x_root * scale,
+                                             event->motion.y_root * scale);
         dragService->SetDragEndPoint(p);
     } else if (sMotionEvent && (event->type == GDK_KEY_PRESS ||
                                 event->type == GDK_KEY_RELEASE)) {
         // Update modifier state from key events.
         sMotionEvent->motion.state = event->key.state;
     } else {
         return;
     }
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -5205,17 +5205,17 @@ nsWindow::CheckForRollup(gdouble aMouseX
                   }
                   break;
                 }
             } // foreach parent menu widget
         } // if rollup listener knows about menus
 
         // if we've determined that we should still rollup, do it.
         bool usePoint = !aIsWheel && !aAlwaysRollup;
-        nsIntPoint point(aMouseX, aMouseY);
+        IntPoint point = IntPoint::Truncate(aMouseX, aMouseY);
         if (rollup && rollupListener->Rollup(popupsToRollup, true, usePoint ? &point : nullptr, nullptr)) {
             retVal = true;
         }
     }
     return retVal;
 }
 
 /* static */
@@ -6806,17 +6806,17 @@ int
 nsWindow::GdkCoordToDevicePixels(gint coord) {
     return coord * GdkScaleFactor();
 }
 
 LayoutDeviceIntPoint
 nsWindow::GdkEventCoordsToDevicePixels(gdouble x, gdouble y)
 {
     gint scale = GdkScaleFactor();
-    return LayoutDeviceIntPoint(floor(x * scale + 0.5), floor(y * scale + 0.5));
+    return LayoutDeviceIntPoint::Round(x * scale, y * scale);
 }
 
 LayoutDeviceIntPoint
 nsWindow::GdkPointToDevicePixels(GdkPoint point) {
     gint scale = GdkScaleFactor();
     return LayoutDeviceIntPoint(point.x * scale,
                                 point.y * scale);
 }
--- a/widget/nsDeviceContextSpecProxy.cpp
+++ b/widget/nsDeviceContextSpecProxy.cpp
@@ -76,17 +76,17 @@ nsDeviceContextSpecProxy::MakePrintTarge
     return nullptr;
   }
 
   // convert twips to points
   width /= TWIPS_PER_POINT_FLOAT;
   height /= TWIPS_PER_POINT_FLOAT;
 
   RefPtr<gfxASurface> surface = gfxPlatform::GetPlatform()->
-    CreateOffscreenSurface(mozilla::gfx::IntSize(width, height),
+    CreateOffscreenSurface(mozilla::gfx::IntSize::Truncate(width, height),
                            mozilla::gfx::SurfaceFormat::A8R8G8B8_UINT32);
   if (!surface) {
     return nullptr;
   }
 
   // The type of PrintTarget that we return here shouldn't really matter since
   // our implementation of GetDrawEventRecorder returns an object, which means
   // the DrawTarget returned by the PrintTarget will be a DrawTargetRecording.
--- a/widget/windows/nsDeviceContextSpecWin.cpp
+++ b/widget/windows/nsDeviceContextSpecWin.cpp
@@ -247,17 +247,17 @@ already_AddRefed<PrintTarget> nsDeviceCo
     }
 
     nsCOMPtr<nsIFileOutputStream> stream = do_CreateInstance("@mozilla.org/network/file-output-stream;1");
     rv = stream->Init(file, -1, -1, 0);
     if (NS_FAILED(rv)) {
       return nullptr;
     }
 
-    return PrintTargetPDF::CreateOrNull(stream, IntSize(width, height));
+    return PrintTargetPDF::CreateOrNull(stream, IntSize::Truncate(width, height));
   }
 
   if (mDevMode) {
     NS_WARN_IF_FALSE(mDriverName, "No driver!");
     HDC dc = ::CreateDCW(mDriverName, mDeviceName, nullptr, mDevMode);
     if (!dc) {
       gfxCriticalError(gfxCriticalError::DefaultOptions(false))
         << "Failed to create device context in GetSurfaceForPrinter";