Cherry-pick "Fix spurious 1px scrolling."

> In the case when the temporary_impl_bounds_ variable is set to
> ComputeInnerViewportContainerSize() (which is device_viewport_size_ /
> device_scale_factor()) the value should be rounded up, to match
> ContentViewCoreImpl::GetViewportSizeDip(). The incorrect rounding
> is causing the layer to be scrollable when the physical width
> is not cleanly divisible by the dpi scale.
>
> BUG=405580
> Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=291035

BUG: 14810760
Change-Id: I4f1f0d97f3de8f07b404526cd398c99514caad10
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc
index fa68275..1c945f6 100644
--- a/cc/layers/layer_impl.cc
+++ b/cc/layers/layer_impl.cc
@@ -760,7 +760,7 @@
 
 // TODO(wjmaclean) Convert so that bounds returns SizeF.
 gfx::Size LayerImpl::bounds() const {
-  return ToFlooredSize(temporary_impl_bounds_);
+  return ToCeiledSize(temporary_impl_bounds_);
 }
 
 void LayerImpl::SetBounds(const gfx::Size& bounds) {
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index fd4261b..0832cef 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -3019,6 +3019,21 @@
                  wheel_scroll_delta);
 }
 
+TEST_F(LayerTreeHostImplTest, ScrollViewportRounding) {
+  int width = 332;
+  int height = 20;
+  int scale = 3;
+  SetupScrollAndContentsLayers(gfx::Size(width, height));
+  host_impl_->SetViewportSize(gfx::Size(width * scale - 1, height * scale));
+  host_impl_->SetDeviceScaleFactor(scale);
+  host_impl_->active_tree()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f);
+
+  LayerImpl* inner_viewport_scroll_layer =
+      host_impl_->active_tree()->InnerViewportScrollLayer();
+  EXPECT_EQ(gfx::Vector2d(0, 0),
+            inner_viewport_scroll_layer->MaxScrollOffset());
+}
+
 class TestScrollOffsetDelegate : public LayerScrollOffsetDelegate {
  public:
   TestScrollOffsetDelegate()