Remove gfx::ScrollOffset in favor of gfx::Vector2dF

See https://groups.google.com/u/2/a/chromium.org/g/graphics-dev/c/9cbhVRAPWnk
for the discussion.

Bug: 738465
Change-Id: I0d5887feb17027d35b08bf7c655f8c8313ab7093
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3202335
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Reviewed-by: danakj <danakj@chromium.org>
Reviewed-by: Steve Kobes <skobes@chromium.org>
Owners-Override: danakj <danakj@chromium.org>
Cr-Commit-Position: refs/heads/main@{#928841}
diff --git a/android_webview/browser/gfx/browser_view_renderer.cc b/android_webview/browser/gfx/browser_view_renderer.cc
index 400465a..ffd532d 100644
--- a/android_webview/browser/gfx/browser_view_renderer.cc
+++ b/android_webview/browser/gfx/browser_view_renderer.cc
@@ -35,8 +35,8 @@
 #include "third_party/skia/include/core/SkPicture.h"
 #include "third_party/skia/include/core/SkPictureRecorder.h"
 #include "ui/gfx/geometry/point.h"
-#include "ui/gfx/geometry/scroll_offset.h"
 #include "ui/gfx/geometry/vector2d_conversions.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 
 namespace android_webview {
 
@@ -434,12 +434,10 @@
       // value when scroll_reset is out of scope.
       base::AutoReset<gfx::Vector2dF> scroll_reset(&scroll_offset_unscaled_,
                                                    gfx::Vector2dF());
-      compositor_->DidChangeRootLayerScrollOffset(
-          gfx::ScrollOffset(scroll_offset_unscaled_));
+      compositor_->DidChangeRootLayerScrollOffset(scroll_offset_unscaled_);
       CompositeSW(rec_canvas, /*software_canvas=*/false);
     }
-    compositor_->DidChangeRootLayerScrollOffset(
-        gfx::ScrollOffset(scroll_offset_unscaled_));
+    compositor_->DidChangeRootLayerScrollOffset(scroll_offset_unscaled_);
   }
   return recorder.finishRecordingAsPicture();
 }
@@ -697,8 +695,7 @@
                        scroll_offset_unscaled.y());
 
   if (compositor_)
-    compositor_->DidChangeRootLayerScrollOffset(
-        gfx::ScrollOffset(scroll_offset_unscaled));
+    compositor_->DidChangeRootLayerScrollOffset(scroll_offset_unscaled);
 }
 
 void BrowserViewRenderer::RestoreScrollAfterTransition(
diff --git a/android_webview/browser/gfx/browser_view_renderer.h b/android_webview/browser/gfx/browser_view_renderer.h
index 244aadb..bfbaf30 100644
--- a/android_webview/browser/gfx/browser_view_renderer.h
+++ b/android_webview/browser/gfx/browser_view_renderer.h
@@ -261,16 +261,12 @@
 
   // When zoom-for-dsf enabled |max_scroll_offset_unscaled_| and
   // |scroll_offset_unscaled_| is in physical pixel; otherwise, they are in dip
-  // TODO(miletus): Make scroll_offset_unscaled_ a gfx::ScrollOffset.
   gfx::Vector2dF scroll_offset_unscaled_;
-
-  // TODO(miletus): Make max_scroll_offset_unscaled_ a gfx::ScrollOffset.
   gfx::Vector2dF max_scroll_offset_unscaled_;
 
   // Used to prevent rounding errors from accumulating enough to generate
   // visible skew (especially noticeable when scrolling up and down in the same
   // spot over a period of time).
-  // TODO(miletus): Make overscroll_rounding_error_ a gfx::ScrollOffset.
   gfx::Vector2dF overscroll_rounding_error_;
 
   // The scroll to apply after the next scroll state update.
diff --git a/cc/animation/animation_host.cc b/cc/animation/animation_host.cc
index 091f17b4..e6f4a9d 100644
--- a/cc/animation/animation_host.cc
+++ b/cc/animation/animation_host.cc
@@ -28,7 +28,7 @@
 #include "cc/animation/worklet_animation.h"
 #include "ui/gfx/animation/keyframe/timing_function.h"
 #include "ui/gfx/geometry/box_f.h"
-#include "ui/gfx/geometry/scroll_offset.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 
 namespace cc {
 
@@ -691,8 +691,8 @@
 
 void AnimationHost::ImplOnlyAutoScrollAnimationCreate(
     ElementId element_id,
-    const gfx::ScrollOffset& target_offset,
-    const gfx::ScrollOffset& current_offset,
+    const gfx::Vector2dF& target_offset,
+    const gfx::Vector2dF& current_offset,
     float autoscroll_velocity,
     base::TimeDelta animation_start_offset) {
   DCHECK(scroll_offset_animations_impl_);
@@ -703,8 +703,8 @@
 
 void AnimationHost::ImplOnlyScrollAnimationCreate(
     ElementId element_id,
-    const gfx::ScrollOffset& target_offset,
-    const gfx::ScrollOffset& current_offset,
+    const gfx::Vector2dF& target_offset,
+    const gfx::Vector2dF& current_offset,
     base::TimeDelta delayed_by,
     base::TimeDelta animation_start_offset) {
   DCHECK(scroll_offset_animations_impl_);
@@ -715,7 +715,7 @@
 
 bool AnimationHost::ImplOnlyScrollAnimationUpdateTarget(
     const gfx::Vector2dF& scroll_delta,
-    const gfx::ScrollOffset& max_scroll_offset,
+    const gfx::Vector2dF& max_scroll_offset,
     base::TimeTicks frame_monotonic_time,
     base::TimeDelta delayed_by) {
   DCHECK(scroll_offset_animations_impl_);
diff --git a/cc/animation/animation_host.h b/cc/animation/animation_host.h
index 224d411..ea2c627 100644
--- a/cc/animation/animation_host.h
+++ b/cc/animation/animation_host.h
@@ -19,10 +19,6 @@
 #include "ui/gfx/geometry/box_f.h"
 #include "ui/gfx/geometry/vector2d_f.h"
 
-namespace gfx {
-class ScrollOffset;
-}
-
 namespace cc {
 
 class Animation;
@@ -163,20 +159,20 @@
 
   void ImplOnlyAutoScrollAnimationCreate(
       ElementId element_id,
-      const gfx::ScrollOffset& target_offset,
-      const gfx::ScrollOffset& current_offset,
+      const gfx::Vector2dF& target_offset,
+      const gfx::Vector2dF& current_offset,
       float autoscroll_velocity,
       base::TimeDelta animation_start_offset) override;
 
   void ImplOnlyScrollAnimationCreate(
       ElementId element_id,
-      const gfx::ScrollOffset& target_offset,
-      const gfx::ScrollOffset& current_offset,
+      const gfx::Vector2dF& target_offset,
+      const gfx::Vector2dF& current_offset,
       base::TimeDelta delayed_by,
       base::TimeDelta animation_start_offset) override;
   bool ImplOnlyScrollAnimationUpdateTarget(
       const gfx::Vector2dF& scroll_delta,
-      const gfx::ScrollOffset& max_scroll_offset,
+      const gfx::Vector2dF& max_scroll_offset,
       base::TimeTicks frame_monotonic_time,
       base::TimeDelta delayed_by) override;
 
diff --git a/cc/animation/animation_host_unittest.cc b/cc/animation/animation_host_unittest.cc
index c0a7bbe4..e9a9d85f 100644
--- a/cc/animation/animation_host_unittest.cc
+++ b/cc/animation/animation_host_unittest.cc
@@ -124,14 +124,14 @@
   client_.RegisterElementId(element_id_, ElementListType::ACTIVE);
   client_impl_.RegisterElementId(element_id_, ElementListType::PENDING);
 
-  gfx::ScrollOffset target_offset(0., 2.);
-  gfx::ScrollOffset current_offset(0., 1.);
+  gfx::Vector2dF target_offset(0., 2.);
+  gfx::Vector2dF current_offset(0., 1.);
   host_impl_->ImplOnlyScrollAnimationCreate(element_id_, target_offset,
                                             current_offset, base::TimeDelta(),
                                             base::TimeDelta());
 
   gfx::Vector2dF scroll_delta(0, 0.5);
-  gfx::ScrollOffset max_scroll_offset(0., 3.);
+  gfx::Vector2dF max_scroll_offset(0., 3.);
 
   base::TimeTicks time;
 
@@ -291,7 +291,7 @@
 
 void SetScrollOffset(PropertyTrees* property_trees,
                      ElementId element_id,
-                     gfx::ScrollOffset offset) {
+                     gfx::Vector2dF offset) {
   // Update both scroll and transform trees
   property_trees->scroll_tree.SetScrollOffset(element_id, offset);
   TransformNode* transform_node =
@@ -317,14 +317,14 @@
   CreateScrollingNodeForElement(element_id, &property_trees);
 
   // Set an initial scroll value.
-  SetScrollOffset(&property_trees, element_id, gfx::ScrollOffset(10, 10));
+  SetScrollOffset(&property_trees, element_id, gfx::Vector2dF(10, 10));
 
   scoped_refptr<MockAnimation> mock_scroll_animation(
       new MockAnimation(animation_id1));
   EXPECT_CALL(*mock_scroll_animation, Tick(_))
       .WillOnce(InvokeWithoutArgs([&]() {
         // Scroll to 20% of the max value.
-        SetScrollOffset(&property_trees, element_id, gfx::ScrollOffset(20, 20));
+        SetScrollOffset(&property_trees, element_id, gfx::Vector2dF(20, 20));
       }));
 
   // Ensure scroll animation is ticking.
@@ -398,7 +398,7 @@
             KeyframeModel::WAITING_FOR_TARGET_AVAILABILITY);
 
   auto& scroll_tree = property_trees.scroll_tree;
-  SetScrollOffset(&property_trees, element_id_, gfx::ScrollOffset(0, 20));
+  SetScrollOffset(&property_trees, element_id_, gfx::Vector2dF(0, 20));
   EXPECT_TRUE(host_impl_->TickAnimations(base::TimeTicks(),
                                          property_trees.scroll_tree, false));
 
@@ -447,7 +447,7 @@
   EXPECT_CALL(*mock_scroll_animation, Tick(_))
       .WillOnce(InvokeWithoutArgs([&]() {
         // Scroll to 20% of the max value.
-        SetScrollOffset(&property_trees, element_id_, gfx::ScrollOffset(0, 20));
+        SetScrollOffset(&property_trees, element_id_, gfx::Vector2dF(0, 20));
       }));
 
   // Ensure scroll animation is ticking.
diff --git a/cc/animation/element_animations.cc b/cc/animation/element_animations.cc
index ebe6c50fd..af9e206578 100644
--- a/cc/animation/element_animations.cc
+++ b/cc/animation/element_animations.cc
@@ -288,7 +288,7 @@
 }
 
 void ElementAnimations::OnScrollOffsetAnimated(
-    const gfx::ScrollOffset& scroll_offset,
+    const gfx::Vector2dF& scroll_offset,
     int target_property_id,
     gfx::KeyframeModel* keyframe_model) {
   if (KeyframeModelAffectsActiveElements(keyframe_model))
@@ -533,7 +533,7 @@
 
 void ElementAnimations::OnScrollOffsetAnimated(
     ElementListType list_type,
-    const gfx::ScrollOffset& scroll_offset,
+    const gfx::Vector2dF& scroll_offset,
     gfx::KeyframeModel* keyframe_model) {
   ElementId target_element_id = CalculateTargetElementId(this, keyframe_model);
   DCHECK(target_element_id);
@@ -543,14 +543,14 @@
       target_element_id, list_type, scroll_offset);
 }
 
-gfx::ScrollOffset ElementAnimations::ScrollOffsetForAnimation() const {
+gfx::Vector2dF ElementAnimations::ScrollOffsetForAnimation() const {
   if (animation_host_) {
     DCHECK(animation_host_->mutator_host_client());
     return animation_host_->mutator_host_client()->GetScrollOffsetForAnimation(
         element_id());
   }
 
-  return gfx::ScrollOffset();
+  return gfx::Vector2dF();
 }
 
 PropertyToElementIdMap ElementAnimations::GetPropertyToElementIdMap() const {
diff --git a/cc/animation/element_animations.h b/cc/animation/element_animations.h
index 8430489..575cc81a 100644
--- a/cc/animation/element_animations.h
+++ b/cc/animation/element_animations.h
@@ -16,7 +16,7 @@
 #include "cc/trees/target_property.h"
 #include "ui/gfx/animation/keyframe/animation_curve.h"
 #include "ui/gfx/animation/keyframe/target_property.h"
-#include "ui/gfx/geometry/scroll_offset.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 #include "ui/gfx/transform.h"
 
 namespace gfx {
@@ -151,11 +151,11 @@
   void OnTransformAnimated(const gfx::TransformOperations& operations,
                            int target_property_id,
                            gfx::KeyframeModel* keyframe_model) override;
-  void OnScrollOffsetAnimated(const gfx::ScrollOffset& scroll_offset,
+  void OnScrollOffsetAnimated(const gfx::Vector2dF& scroll_offset,
                               int target_property_id,
                               gfx::KeyframeModel* keyframe_model) override;
 
-  gfx::ScrollOffset ScrollOffsetForAnimation() const;
+  gfx::Vector2dF ScrollOffsetForAnimation() const;
 
   // Returns a map of target property to the ElementId for that property, for
   // KeyframeEffects associated with this ElementAnimations.
@@ -202,7 +202,7 @@
                            const gfx::Transform& transform,
                            gfx::KeyframeModel* keyframe_model);
   void OnScrollOffsetAnimated(ElementListType list_type,
-                              const gfx::ScrollOffset& scroll_offset,
+                              const gfx::Vector2dF& scroll_offset,
                               gfx::KeyframeModel* keyframe_model);
 
   static gfx::TargetProperties GetPropertiesMaskForAnimationState();
diff --git a/cc/animation/element_animations_unittest.cc b/cc/animation/element_animations_unittest.cc
index 583509cf..1a0c9c0 100644
--- a/cc/animation/element_animations_unittest.cc
+++ b/cc/animation/element_animations_unittest.cc
@@ -5,6 +5,7 @@
 #include "cc/animation/element_animations.h"
 
 #include <limits>
+#include <memory>
 #include <utility>
 
 #include "base/memory/ptr_util.h"
@@ -256,9 +257,9 @@
   EXPECT_FALSE(
       animation_impl_->GetKeyframeModel(TargetProperty::SCROLL_OFFSET));
 
-  gfx::ScrollOffset initial_value(100.f, 300.f);
-  gfx::ScrollOffset provider_initial_value(150.f, 300.f);
-  gfx::ScrollOffset target_value(300.f, 200.f);
+  gfx::Vector2dF initial_value(100.f, 300.f);
+  gfx::Vector2dF provider_initial_value(150.f, 300.f);
+  gfx::Vector2dF target_value(300.f, 200.f);
 
   client_impl_.SetScrollOffsetForAnimation(provider_initial_value);
 
@@ -887,8 +888,8 @@
 
   auto events = CreateEventsForTesting();
 
-  gfx::ScrollOffset initial_value(100.f, 300.f);
-  gfx::ScrollOffset target_value(300.f, 200.f);
+  gfx::Vector2dF initial_value(100.f, 300.f);
+  gfx::Vector2dF target_value(300.f, 200.f);
   std::unique_ptr<ScrollOffsetAnimationCurve> curve(
       ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
           target_value));
@@ -958,8 +959,8 @@
 
   auto events = CreateEventsForTesting();
 
-  gfx::ScrollOffset initial_value(100.f, 300.f);
-  gfx::ScrollOffset target_value(300.f, 200.f);
+  gfx::Vector2dF initial_value(100.f, 300.f);
+  gfx::Vector2dF target_value(300.f, 200.f);
   std::unique_ptr<ScrollOffsetAnimationCurve> curve(
       ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
           target_value));
@@ -1007,8 +1008,8 @@
 
   // Add first scroll offset animation.
   AddScrollOffsetAnimationToAnimation(animation_impl_.get(),
-                                      gfx::ScrollOffset(100.f, 300.f),
-                                      gfx::ScrollOffset(100.f, 200.f));
+                                      gfx::Vector2dF(100.f, 300.f),
+                                      gfx::Vector2dF(100.f, 200.f));
 
   // Calling UpdateState after Animate should promote the animation to running
   // state.
@@ -1025,8 +1026,8 @@
 
   // Add second scroll offset animation.
   AddScrollOffsetAnimationToAnimation(animation_impl_.get(),
-                                      gfx::ScrollOffset(100.f, 200.f),
-                                      gfx::ScrollOffset(100.f, 100.f));
+                                      gfx::Vector2dF(100.f, 200.f),
+                                      gfx::Vector2dF(100.f, 100.f));
 
   // Calling UpdateState without Animate should NOT promote the animation to
   // running state.
@@ -1042,7 +1043,7 @@
             animation_impl_->GetKeyframeModel(TargetProperty::SCROLL_OFFSET)
                 ->run_state());
   EXPECT_VECTOR2DF_EQ(
-      gfx::ScrollOffset(100.f, 200.f),
+      gfx::Vector2dF(100.f, 200.f),
       client_impl_.GetScrollOffset(element_id_, ElementListType::ACTIVE));
 }
 
@@ -1060,8 +1061,8 @@
 
   auto events = CreateEventsForTesting();
 
-  gfx::ScrollOffset initial_value(500.f, 100.f);
-  gfx::ScrollOffset target_value(300.f, 200.f);
+  gfx::Vector2dF initial_value(500.f, 100.f);
+  gfx::Vector2dF target_value(300.f, 200.f);
   std::unique_ptr<ScrollOffsetAnimationCurve> curve(
       ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
           target_value));
@@ -1091,8 +1092,8 @@
   EXPECT_TRUE(animation_->keyframe_effect()->HasTickingKeyframeModel());
   EXPECT_EQ(initial_value,
             client_.GetScrollOffset(element_id_, ElementListType::ACTIVE));
-  EXPECT_EQ(gfx::ScrollOffset(), client_impl_.GetScrollOffset(
-                                     element_id_, ElementListType::PENDING));
+  EXPECT_EQ(gfx::Vector2dF(), client_impl_.GetScrollOffset(
+                                  element_id_, ElementListType::PENDING));
 
   animation_impl_->Tick(kInitialTickTime);
 
@@ -1140,7 +1141,7 @@
   auto events = CreateEventsForTesting();
 
   // First test the 1-argument version of RemoveKeyframeModel.
-  gfx::ScrollOffset target_value(300.f, 200.f);
+  gfx::Vector2dF target_value(300.f, 200.f);
   std::unique_ptr<ScrollOffsetAnimationCurve> curve(
       ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
           target_value));
@@ -1263,8 +1264,8 @@
   TestAnimationDelegate delegate;
   animation_impl_->set_animation_delegate(&delegate);
 
-  gfx::ScrollOffset initial_value(100.f, 300.f);
-  gfx::ScrollOffset target_value(300.f, 200.f);
+  gfx::Vector2dF initial_value(100.f, 300.f);
+  gfx::Vector2dF target_value(300.f, 200.f);
   std::unique_ptr<ScrollOffsetAnimationCurve> curve(
       ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
           target_value));
@@ -2069,8 +2070,8 @@
 
   // Add impl-only scroll offset animation.
   const int keyframe_model_id = 1;
-  gfx::ScrollOffset initial_value(100.f, 300.f);
-  gfx::ScrollOffset target_value(300.f, 200.f);
+  gfx::Vector2dF initial_value(100.f, 300.f);
+  gfx::Vector2dF target_value(300.f, 200.f);
   std::unique_ptr<ScrollOffsetAnimationCurve> curve(
       ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
           target_value));
diff --git a/cc/animation/keyframe_effect.cc b/cc/animation/keyframe_effect.cc
index 99beca1..0fae2ac 100644
--- a/cc/animation/keyframe_effect.cc
+++ b/cc/animation/keyframe_effect.cc
@@ -585,7 +585,7 @@
         !ScrollOffsetAnimationCurve::ToScrollOffsetAnimationCurve(
              keyframe_model->curve())
              ->HasSetInitialValue()) {
-      gfx::ScrollOffset current_scroll_offset;
+      gfx::Vector2dF current_scroll_offset;
       if (keyframe_effect_impl->HasElementInActiveList()) {
         current_scroll_offset =
             keyframe_effect_impl->ScrollOffsetForAnimation();
@@ -1013,7 +1013,7 @@
   return element_animations_->has_element_in_active_list();
 }
 
-gfx::ScrollOffset KeyframeEffect::ScrollOffsetForAnimation() const {
+gfx::Vector2dF KeyframeEffect::ScrollOffsetForAnimation() const {
   DCHECK(has_bound_element_animations());
   return element_animations_->ScrollOffsetForAnimation();
 }
diff --git a/cc/animation/keyframe_effect.h b/cc/animation/keyframe_effect.h
index f0a26d7..d76b282 100644
--- a/cc/animation/keyframe_effect.h
+++ b/cc/animation/keyframe_effect.h
@@ -20,7 +20,7 @@
 #include "cc/trees/target_property.h"
 #include "ui/gfx/animation/keyframe/keyframe_effect.h"
 #include "ui/gfx/geometry/box_f.h"
-#include "ui/gfx/geometry/scroll_offset.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 
 namespace cc {
 
@@ -168,7 +168,7 @@
   void MarkFinishedKeyframeModels(base::TimeTicks monotonic_time);
 
   bool HasElementInActiveList() const;
-  gfx::ScrollOffset ScrollOffsetForAnimation() const;
+  gfx::Vector2dF ScrollOffsetForAnimation() const;
   void GenerateEvent(AnimationEvents* events,
                      const KeyframeModel& keyframe_model,
                      AnimationEvent::Type type,
diff --git a/cc/animation/scroll_offset_animation_curve.cc b/cc/animation/scroll_offset_animation_curve.cc
index 8eb523e..e86e3e6 100644
--- a/cc/animation/scroll_offset_animation_curve.cc
+++ b/cc/animation/scroll_offset_animation_curve.cc
@@ -81,11 +81,11 @@
   return CubicBezierTimingFunction::Create(x1, y1, x2, y2);
 }
 
-bool IsNewTargetInOppositeDirection(const gfx::ScrollOffset& current_position,
-                                    const gfx::ScrollOffset& old_target,
-                                    const gfx::ScrollOffset& new_target) {
-  gfx::Vector2dF old_delta = old_target.DeltaFrom(current_position);
-  gfx::Vector2dF new_delta = new_target.DeltaFrom(current_position);
+bool IsNewTargetInOppositeDirection(const gfx::Vector2dF& current_position,
+                                    const gfx::Vector2dF& old_target,
+                                    const gfx::Vector2dF& new_target) {
+  gfx::Vector2dF old_delta = old_target - current_position;
+  gfx::Vector2dF new_delta = new_target - current_position;
 
   // We only declare the new target to be in the "opposite" direction when
   // one of the dimensions doesn't change at all. This may sound a bit strange,
@@ -132,7 +132,7 @@
     ScrollOffsetAnimationCurve::animation_duration_for_testing_;
 
 ScrollOffsetAnimationCurve::ScrollOffsetAnimationCurve(
-    const gfx::ScrollOffset& target_value,
+    const gfx::Vector2dF& target_value,
     AnimationType animation_type,
     absl::optional<DurationBehavior> duration_behavior)
     : target_value_(target_value),
@@ -157,7 +157,7 @@
 }
 
 ScrollOffsetAnimationCurve::ScrollOffsetAnimationCurve(
-    const gfx::ScrollOffset& target_value,
+    const gfx::Vector2dF& target_value,
     std::unique_ptr<TimingFunction> timing_function,
     AnimationType animation_type,
     absl::optional<DurationBehavior> duration_behavior)
@@ -212,7 +212,7 @@
     const gfx::Vector2dF& new_delta,
     base::TimeDelta t,
     base::TimeDelta delayed_by) {
-  gfx::Vector2dF old_delta = target_value_.DeltaFrom(initial_value_);
+  gfx::Vector2dF old_delta = target_value_ - initial_value_;
   double velocity = CalculateVelocity(t);
 
   // Use the velocity-based duration bound when it is less than the constant
@@ -276,13 +276,13 @@
 }
 
 void ScrollOffsetAnimationCurve::SetInitialValue(
-    const gfx::ScrollOffset& initial_value,
+    const gfx::Vector2dF& initial_value,
     base::TimeDelta delayed_by,
     float velocity) {
   initial_value_ = initial_value;
   has_set_initial_value_ = true;
 
-  gfx::Vector2dF delta = target_value_.DeltaFrom(initial_value);
+  gfx::Vector2dF delta = target_value_ - initial_value;
   total_animation_duration_ = SegmentDuration(delta, delayed_by, velocity);
 }
 
@@ -292,12 +292,11 @@
 
 void ScrollOffsetAnimationCurve::ApplyAdjustment(
     const gfx::Vector2dF& adjustment) {
-  initial_value_ = ScrollOffsetWithDelta(initial_value_, adjustment);
-  target_value_ = ScrollOffsetWithDelta(target_value_, adjustment);
+  initial_value_ = initial_value_ + adjustment;
+  target_value_ = target_value_ + adjustment;
 }
 
-gfx::ScrollOffset ScrollOffsetAnimationCurve::GetValue(
-    base::TimeDelta t) const {
+gfx::Vector2dF ScrollOffsetAnimationCurve::GetValue(base::TimeDelta t) const {
   const base::TimeDelta duration = total_animation_duration_ - last_retarget_;
   t -= last_retarget_;
 
@@ -307,11 +306,10 @@
     return initial_value_;
 
   const double progress = timing_function_->GetValue(t / duration);
-  return gfx::ScrollOffset(
-      gfx::Tween::FloatValueBetween(progress, initial_value_.x(),
-                                    target_value_.x()),
-      gfx::Tween::FloatValueBetween(progress, initial_value_.y(),
-                                    target_value_.y()));
+  return gfx::Vector2dF(gfx::Tween::FloatValueBetween(
+                            progress, initial_value_.x(), target_value_.x()),
+                        gfx::Tween::FloatValueBetween(
+                            progress, initial_value_.y(), target_value_.y()));
 }
 
 base::TimeDelta ScrollOffsetAnimationCurve::Duration() const {
@@ -363,7 +361,7 @@
   const double slope =
       timing_function_->Velocity((t - last_retarget_) / duration);
 
-  gfx::Vector2dF delta = target_value_.DeltaFrom(initial_value_);
+  gfx::Vector2dF delta = target_value_ - initial_value_;
 
   // TimingFunction::Velocity just gives the slope of the curve. Convert it to
   // units of pixels per second.
@@ -372,7 +370,7 @@
 
 void ScrollOffsetAnimationCurve::UpdateTarget(
     base::TimeDelta t,
-    const gfx::ScrollOffset& new_target) {
+    const gfx::Vector2dF& new_target) {
   DCHECK_NE(animation_type_, AnimationType::kLinear)
       << "UpdateTarget is not supported on linear scroll animations.";
 
@@ -388,8 +386,7 @@
   t = std::max(t, last_retarget_);
 
   if (animation_type_ == AnimationType::kEaseInOut &&
-      std::abs(MaximumDimension(target_value_.DeltaFrom(new_target))) <
-          kEpsilon) {
+      std::abs(MaximumDimension(target_value_ - new_target)) < kEpsilon) {
     // Don't update the animation if the new target is the same as the old one.
     // This is done for EaseInOut-style animation curves, since the duration is
     // inversely proportional to the distance, and it may cause an animation
@@ -401,8 +398,8 @@
     return;
   }
 
-  gfx::ScrollOffset current_position = GetValue(t);
-  gfx::Vector2dF new_delta = new_target.DeltaFrom(current_position);
+  gfx::Vector2dF current_position = GetValue(t);
+  gfx::Vector2dF new_delta = new_target - current_position;
 
   // We are already at or very close to the new target. Stop animating.
   if (std::abs(MaximumDimension(new_delta)) < kEpsilon) {
diff --git a/cc/animation/scroll_offset_animation_curve.h b/cc/animation/scroll_offset_animation_curve.h
index 5bed80b..ec3448b5 100644
--- a/cc/animation/scroll_offset_animation_curve.h
+++ b/cc/animation/scroll_offset_animation_curve.h
@@ -12,7 +12,7 @@
 #include "cc/animation/animation_export.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/animation/keyframe/animation_curve.h"
-#include "ui/gfx/geometry/scroll_offset.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 
 namespace gfx {
 class TimingFunction;
@@ -34,7 +34,7 @@
    public:
     ~Target() = default;
 
-    virtual void OnScrollOffsetAnimated(const gfx::ScrollOffset& value,
+    virtual void OnScrollOffsetAnimated(const gfx::Vector2dF& value,
                                         int target_property_id,
                                         gfx::KeyframeModel* keyframe_model) = 0;
   };
@@ -83,18 +83,18 @@
       delete;
 
   // Sets the initial offset and velocity (in pixels per second).
-  void SetInitialValue(const gfx::ScrollOffset& initial_value,
+  void SetInitialValue(const gfx::Vector2dF& initial_value,
                        base::TimeDelta delayed_by = base::TimeDelta(),
                        float velocity = 0);
   bool HasSetInitialValue() const;
-  gfx::ScrollOffset GetValue(base::TimeDelta t) const;
-  gfx::ScrollOffset target_value() const { return target_value_; }
+  gfx::Vector2dF GetValue(base::TimeDelta t) const;
+  gfx::Vector2dF target_value() const { return target_value_; }
 
   // Updates the current curve to aim at a new target, starting at time t
   // relative to the start of the animation. The duration is recomputed based
   // on the animation type the curve was constructed with. The timing function
   // is modified to preserve velocity at t.
-  void UpdateTarget(base::TimeDelta t, const gfx::ScrollOffset& new_target);
+  void UpdateTarget(base::TimeDelta t, const gfx::Vector2dF& new_target);
 
   // Shifts the entire curve by a delta without affecting its shape or timing.
   // Used for scroll anchoring adjustments that happen during scroll animations
@@ -124,11 +124,11 @@
   // |duration_behavior| should be provided if (and only if) |animation_type| is
   // kEaseInOut.
   ScrollOffsetAnimationCurve(
-      const gfx::ScrollOffset& target_value,
+      const gfx::Vector2dF& target_value,
       AnimationType animation_type,
       absl::optional<DurationBehavior> duration_behavior = absl::nullopt);
   ScrollOffsetAnimationCurve(
-      const gfx::ScrollOffset& target_value,
+      const gfx::Vector2dF& target_value,
       std::unique_ptr<gfx::TimingFunction> timing_function,
       AnimationType animation_type,
       absl::optional<DurationBehavior> duration_behavior);
@@ -146,8 +146,8 @@
   // Returns the velocity at time t in units of pixels per second.
   double CalculateVelocity(base::TimeDelta t);
 
-  gfx::ScrollOffset initial_value_;
-  gfx::ScrollOffset target_value_;
+  gfx::Vector2dF initial_value_;
+  gfx::Vector2dF target_value_;
   base::TimeDelta total_animation_duration_;
 
   // Time from animation start to most recent UpdateTarget.
diff --git a/cc/animation/scroll_offset_animation_curve_factory.cc b/cc/animation/scroll_offset_animation_curve_factory.cc
index 469792b5..34c8912 100644
--- a/cc/animation/scroll_offset_animation_curve_factory.cc
+++ b/cc/animation/scroll_offset_animation_curve_factory.cc
@@ -32,7 +32,7 @@
 // static
 std::unique_ptr<ScrollOffsetAnimationCurve>
 ScrollOffsetAnimationCurveFactory::CreateAnimation(
-    const gfx::ScrollOffset& target_value,
+    const gfx::Vector2dF& target_value,
     ScrollType scroll_type) {
   if (scroll_type == ScrollType::kAutoScroll)
     return CreateLinearAnimation(target_value);
@@ -47,7 +47,7 @@
 // static
 std::unique_ptr<ScrollOffsetAnimationCurve>
 ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
-    const gfx::ScrollOffset& target_value,
+    const gfx::Vector2dF& target_value,
     ScrollOffsetAnimationCurve::DurationBehavior duration_behavior) {
   return CreateEaseInOutAnimation(target_value, duration_behavior);
 }
@@ -55,21 +55,21 @@
 // static
 std::unique_ptr<ScrollOffsetAnimationCurve>
 ScrollOffsetAnimationCurveFactory::CreateLinearAnimationForTesting(
-    const gfx::ScrollOffset& target_value) {
+    const gfx::Vector2dF& target_value) {
   return CreateLinearAnimation(target_value);
 }
 
 // static
 std::unique_ptr<ScrollOffsetAnimationCurve>
 ScrollOffsetAnimationCurveFactory::CreateImpulseAnimationForTesting(
-    const gfx::ScrollOffset& target_value) {
+    const gfx::Vector2dF& target_value) {
   return CreateImpulseAnimation(target_value);
 }
 
 // static
 std::unique_ptr<ScrollOffsetAnimationCurve>
 ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimation(
-    const gfx::ScrollOffset& target_value,
+    const gfx::Vector2dF& target_value,
     ScrollOffsetAnimationCurve::DurationBehavior duration_behavior) {
   return base::WrapUnique(new ScrollOffsetAnimationCurve(
       target_value, ScrollOffsetAnimationCurve::AnimationType::kEaseInOut,
@@ -79,7 +79,7 @@
 // static
 std::unique_ptr<ScrollOffsetAnimationCurve>
 ScrollOffsetAnimationCurveFactory::CreateLinearAnimation(
-    const gfx::ScrollOffset& target_value) {
+    const gfx::Vector2dF& target_value) {
   return base::WrapUnique(new ScrollOffsetAnimationCurve(
       target_value, ScrollOffsetAnimationCurve::AnimationType::kLinear));
 }
@@ -87,7 +87,7 @@
 // static
 std::unique_ptr<ScrollOffsetAnimationCurve>
 ScrollOffsetAnimationCurveFactory::CreateImpulseAnimation(
-    const gfx::ScrollOffset& target_value) {
+    const gfx::Vector2dF& target_value) {
   return base::WrapUnique(new ScrollOffsetAnimationCurve(
       target_value, ScrollOffsetAnimationCurve::AnimationType::kImpulse,
       ScrollOffsetAnimationCurve::DurationBehavior::INVERSE_DELTA));
diff --git a/cc/animation/scroll_offset_animation_curve_factory.h b/cc/animation/scroll_offset_animation_curve_factory.h
index 86cee47..4278133c 100644
--- a/cc/animation/scroll_offset_animation_curve_factory.h
+++ b/cc/animation/scroll_offset_animation_curve_factory.h
@@ -5,6 +5,8 @@
 #ifndef CC_ANIMATION_SCROLL_OFFSET_ANIMATION_CURVE_FACTORY_H_
 #define CC_ANIMATION_SCROLL_OFFSET_ANIMATION_CURVE_FACTORY_H_
 
+#include <memory>
+
 #include "cc/animation/scroll_offset_animation_curve.h"
 
 namespace cc {
@@ -13,31 +15,31 @@
   enum class ScrollType { kProgrammatic, kKeyboard, kMouseWheel, kAutoScroll };
 
   static std::unique_ptr<ScrollOffsetAnimationCurve> CreateAnimation(
-      const gfx::ScrollOffset& target_value,
+      const gfx::Vector2dF& target_value,
       ScrollType scroll_type);
 
   static std::unique_ptr<ScrollOffsetAnimationCurve>
   CreateEaseInOutAnimationForTesting(
-      const gfx::ScrollOffset& target_value,
+      const gfx::Vector2dF& target_value,
       ScrollOffsetAnimationCurve::DurationBehavior duration_behavior =
           ScrollOffsetAnimationCurve::DurationBehavior::DELTA_BASED);
 
   static std::unique_ptr<ScrollOffsetAnimationCurve>
-  CreateLinearAnimationForTesting(const gfx::ScrollOffset& target_value);
+  CreateLinearAnimationForTesting(const gfx::Vector2dF& target_value);
 
   static std::unique_ptr<ScrollOffsetAnimationCurve>
-  CreateImpulseAnimationForTesting(const gfx::ScrollOffset& target_value);
+  CreateImpulseAnimationForTesting(const gfx::Vector2dF& target_value);
 
  private:
   static std::unique_ptr<ScrollOffsetAnimationCurve> CreateEaseInOutAnimation(
-      const gfx::ScrollOffset& target_value,
+      const gfx::Vector2dF& target_value,
       ScrollOffsetAnimationCurve::DurationBehavior duration_hint);
 
   static std::unique_ptr<ScrollOffsetAnimationCurve> CreateLinearAnimation(
-      const gfx::ScrollOffset& target_value);
+      const gfx::Vector2dF& target_value);
 
   static std::unique_ptr<ScrollOffsetAnimationCurve> CreateImpulseAnimation(
-      const gfx::ScrollOffset& target_value);
+      const gfx::Vector2dF& target_value);
 };
 }  // namespace cc
 
diff --git a/cc/animation/scroll_offset_animation_curve_unittest.cc b/cc/animation/scroll_offset_animation_curve_unittest.cc
index c9b052d..3e25f0f 100644
--- a/cc/animation/scroll_offset_animation_curve_unittest.cc
+++ b/cc/animation/scroll_offset_animation_curve_unittest.cc
@@ -24,7 +24,7 @@
 }  // namespace
 
 TEST(ScrollOffsetAnimationCurveTest, DeltaBasedDuration) {
-  gfx::ScrollOffset target_value(100.f, 200.f);
+  gfx::Vector2dF target_value(100.f, 200.f);
   std::unique_ptr<ScrollOffsetAnimationCurve> curve(
       ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
           target_value));
@@ -33,41 +33,41 @@
   EXPECT_DOUBLE_EQ(0.0, curve->Duration().InSecondsF());
 
   // x decreases, y stays the same.
-  curve->SetInitialValue(gfx::ScrollOffset(136.f, 200.f));
+  curve->SetInitialValue(gfx::Vector2dF(136.f, 200.f));
   EXPECT_DOUBLE_EQ(0.1, curve->Duration().InSecondsF());
 
   // x increases, y stays the same.
-  curve->SetInitialValue(gfx::ScrollOffset(19.f, 200.f));
+  curve->SetInitialValue(gfx::Vector2dF(19.f, 200.f));
   EXPECT_DOUBLE_EQ(0.15, curve->Duration().InSecondsF());
 
   // x stays the same, y decreases.
-  curve->SetInitialValue(gfx::ScrollOffset(100.f, 344.f));
+  curve->SetInitialValue(gfx::Vector2dF(100.f, 344.f));
   EXPECT_DOUBLE_EQ(0.2, curve->Duration().InSecondsF());
 
   // x stays the same, y increases.
-  curve->SetInitialValue(gfx::ScrollOffset(100.f, 191.f));
+  curve->SetInitialValue(gfx::Vector2dF(100.f, 191.f));
   EXPECT_DOUBLE_EQ(0.05, curve->Duration().InSecondsF());
 
   // x decreases, y decreases.
-  curve->SetInitialValue(gfx::ScrollOffset(32500.f, 500.f));
+  curve->SetInitialValue(gfx::Vector2dF(32500.f, 500.f));
   EXPECT_DOUBLE_EQ(0.7, curve->Duration().InSecondsF());
 
   // x decreases, y increases.
-  curve->SetInitialValue(gfx::ScrollOffset(150.f, 119.f));
+  curve->SetInitialValue(gfx::Vector2dF(150.f, 119.f));
   EXPECT_DOUBLE_EQ(0.15, curve->Duration().InSecondsF());
 
   // x increases, y decreases.
-  curve->SetInitialValue(gfx::ScrollOffset(0.f, 14600.f));
+  curve->SetInitialValue(gfx::Vector2dF(0.f, 14600.f));
   EXPECT_DOUBLE_EQ(0.7, curve->Duration().InSecondsF());
 
   // x increases, y increases.
-  curve->SetInitialValue(gfx::ScrollOffset(95.f, 191.f));
+  curve->SetInitialValue(gfx::Vector2dF(95.f, 191.f));
   EXPECT_DOUBLE_EQ(0.05, curve->Duration().InSecondsF());
 }
 
 TEST(ScrollOffsetAnimationCurveTest, GetValue) {
-  gfx::ScrollOffset initial_value(2.f, 40.f);
-  gfx::ScrollOffset target_value(10.f, 20.f);
+  gfx::Vector2dF initial_value(2.f, 40.f);
+  gfx::Vector2dF target_value(10.f, 20.f);
   std::unique_ptr<ScrollOffsetAnimationCurve> curve(
       ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
           target_value));
@@ -81,22 +81,22 @@
 
   EXPECT_VECTOR2DF_EQ(initial_value, curve->GetValue(base::Seconds(-1.0)));
   EXPECT_VECTOR2DF_EQ(initial_value, curve->GetValue(base::TimeDelta()));
-  EXPECT_VECTOR2DF_NEAR(gfx::ScrollOffset(6.f, 30.f),
+  EXPECT_VECTOR2DF_NEAR(gfx::Vector2dF(6.f, 30.f),
                         curve->GetValue(duration * 0.5f), 0.00025);
   EXPECT_VECTOR2DF_EQ(target_value, curve->GetValue(duration));
   EXPECT_VECTOR2DF_EQ(target_value,
                       curve->GetValue(duration + base::Seconds(1.0)));
 
   // Verify that GetValue takes the timing function into account.
-  gfx::ScrollOffset value = curve->GetValue(duration * 0.25f);
+  gfx::Vector2dF value = curve->GetValue(duration * 0.25f);
   EXPECT_NEAR(3.0333f, value.x(), 0.0002f);
   EXPECT_NEAR(37.4168f, value.y(), 0.0002f);
 }
 
 // Verify that a clone behaves exactly like the original.
 TEST(ScrollOffsetAnimationCurveTest, Clone) {
-  gfx::ScrollOffset initial_value(2.f, 40.f);
-  gfx::ScrollOffset target_value(10.f, 20.f);
+  gfx::Vector2dF initial_value(2.f, 40.f);
+  gfx::Vector2dF target_value(10.f, 20.f);
   std::unique_ptr<ScrollOffsetAnimationCurve> curve(
       ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
           target_value));
@@ -113,21 +113,21 @@
   EXPECT_VECTOR2DF_EQ(initial_value,
                       cloned_curve->GetValue(base::Seconds(-1.0)));
   EXPECT_VECTOR2DF_EQ(initial_value, cloned_curve->GetValue(base::TimeDelta()));
-  EXPECT_VECTOR2DF_NEAR(gfx::ScrollOffset(6.f, 30.f),
+  EXPECT_VECTOR2DF_NEAR(gfx::Vector2dF(6.f, 30.f),
                         cloned_curve->GetValue(duration * 0.5f), 0.00025);
   EXPECT_VECTOR2DF_EQ(target_value, cloned_curve->GetValue(duration));
   EXPECT_VECTOR2DF_EQ(target_value,
                       cloned_curve->GetValue(duration + base::Seconds(1.f)));
 
   // Verify that the timing function was cloned correctly.
-  gfx::ScrollOffset value = cloned_curve->GetValue(duration * 0.25f);
+  gfx::Vector2dF value = cloned_curve->GetValue(duration * 0.25f);
   EXPECT_NEAR(3.0333f, value.x(), 0.0002f);
   EXPECT_NEAR(37.4168f, value.y(), 0.0002f);
 }
 
 TEST(ScrollOffsetAnimationCurveTest, EaseInOutUpdateTarget) {
-  gfx::ScrollOffset initial_value(0.f, 0.f);
-  gfx::ScrollOffset target_value(0.f, 3600.f);
+  gfx::Vector2dF initial_value(0.f, 0.f);
+  gfx::Vector2dF target_value(0.f, 3600.f);
   double duration = kConstantDuration / kDurationDivisor;
   std::unique_ptr<ScrollOffsetAnimationCurve> curve(
       ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
@@ -138,8 +138,7 @@
               0.0002f);
   EXPECT_NEAR(3600.0, curve->GetValue(base::Seconds(duration)).y(), 0.0002f);
 
-  curve->UpdateTarget(base::Seconds(duration / 2),
-                      gfx::ScrollOffset(0.0, 9900.0));
+  curve->UpdateTarget(base::Seconds(duration / 2), gfx::Vector2dF(0.0, 9900.0));
 
   EXPECT_NEAR(duration * 1.5, curve->Duration().InSecondsF(), 0.0002f);
   EXPECT_NEAR(1800.0, curve->GetValue(base::Seconds(duration / 2.0)).y(),
@@ -148,7 +147,7 @@
   EXPECT_NEAR(9900.0, curve->GetValue(base::Seconds(duration * 1.5)).y(),
               0.0002f);
 
-  curve->UpdateTarget(base::Seconds(duration), gfx::ScrollOffset(0.0, 7200.0));
+  curve->UpdateTarget(base::Seconds(duration), gfx::Vector2dF(0.0, 7200.0));
 
   // A closer target at high velocity reduces the duration.
   EXPECT_NEAR(duration * 1.0794, curve->Duration().InSecondsF(), 0.0002f);
@@ -158,9 +157,9 @@
 }
 
 TEST(ScrollOffsetAnimationCurveTest, ImpulseUpdateTarget) {
-  gfx::ScrollOffset initial_value(0.f, 0.f);
-  gfx::ScrollOffset initial_target_value(0.f, 3600.f);
-  gfx::Vector2dF initial_delta = initial_target_value.DeltaFrom(initial_value);
+  gfx::Vector2dF initial_value(0.f, 0.f);
+  gfx::Vector2dF initial_target_value(0.f, 3600.f);
+  gfx::Vector2dF initial_delta = initial_target_value - initial_value;
   std::unique_ptr<ScrollOffsetAnimationCurve> curve(
       ScrollOffsetAnimationCurveFactory::CreateImpulseAnimationForTesting(
           initial_target_value));
@@ -177,14 +176,14 @@
               0.0002f);
 
   base::TimeDelta time_of_update = initial_duration / 2;
-  gfx::ScrollOffset distance_halfway_through_initial_animation =
+  gfx::Vector2dF distance_halfway_through_initial_animation =
       curve->GetValue(time_of_update);
 
-  gfx::ScrollOffset new_target_value(0.f, 9900.f);
+  gfx::Vector2dF new_target_value(0.f, 9900.f);
   curve->UpdateTarget(time_of_update, new_target_value);
 
   gfx::Vector2dF new_delta =
-      new_target_value.DeltaFrom(distance_halfway_through_initial_animation);
+      new_target_value - distance_halfway_through_initial_animation;
   base::TimeDelta updated_segment_duration =
       curve->EaseInOutBoundedSegmentDuration(new_delta, base::TimeDelta(),
                                              base::TimeDelta());
@@ -208,13 +207,11 @@
 }
 
 TEST(ScrollOffsetAnimationCurveTest, ImpulseUpdateTargetSwitchDirections) {
-  gfx::ScrollOffset initial_value(0.f, 0.f);
-  gfx::ScrollOffset initial_target_value(0.f, 200.f);
-  double initial_duration =
-      ScrollOffsetAnimationCurve::ImpulseSegmentDuration(
-          gfx::Vector2dF(initial_target_value.x(), initial_target_value.y()),
-          base::TimeDelta())
-          .InSecondsF();
+  gfx::Vector2dF initial_value(0.f, 0.f);
+  gfx::Vector2dF initial_target_value(0.f, 200.f);
+  double initial_duration = ScrollOffsetAnimationCurve::ImpulseSegmentDuration(
+                                initial_target_value, base::TimeDelta())
+                                .InSecondsF();
 
   std::unique_ptr<ScrollOffsetAnimationCurve> curve(
       ScrollOffsetAnimationCurveFactory::CreateImpulseAnimationForTesting(
@@ -227,9 +224,9 @@
 
   // Animate back to 0. This should force the new curve's initial velocity to be
   // 0, so the default curve will be generated.
-  gfx::ScrollOffset updated_initial_value = gfx::ScrollOffset(
+  gfx::Vector2dF updated_initial_value = gfx::Vector2dF(
       0, initial_target_value.y() * halfway_through_default_impulse_curve);
-  gfx::ScrollOffset updated_target = gfx::ScrollOffset(0.f, 0.f);
+  gfx::Vector2dF updated_target(0.f, 0.f);
   curve->UpdateTarget(base::Seconds(initial_duration / 2), updated_target);
 
   EXPECT_NEAR(initial_target_value.y() * halfway_through_default_impulse_curve,
@@ -238,12 +235,11 @@
 
   // Once the impulse style curve is updated, it turns to an ease-in ease-out
   // type curve.
-  double updated_duration = curve
-                                ->EaseInOutBoundedSegmentDuration(
-                                    gfx::Vector2dF(updated_initial_value.x(),
-                                                   updated_initial_value.y()),
-                                    base::TimeDelta(), base::TimeDelta())
-                                .InSecondsF();
+  double updated_duration =
+      curve
+          ->EaseInOutBoundedSegmentDuration(
+              updated_initial_value, base::TimeDelta(), base::TimeDelta())
+          .InSecondsF();
   EXPECT_NEAR(updated_initial_value.y() * 0.5,
               curve
                   ->GetValue(base::Seconds(initial_duration / 2.0 +
@@ -260,28 +256,28 @@
 TEST(ScrollOffsetAnimationCurveTest, InverseDeltaDuration) {
   std::unique_ptr<ScrollOffsetAnimationCurve> curve(
       ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
-          gfx::ScrollOffset(0.f, 100.f), DurationBehavior::INVERSE_DELTA));
+          gfx::Vector2dF(0.f, 100.f), DurationBehavior::INVERSE_DELTA));
 
-  curve->SetInitialValue(gfx::ScrollOffset());
+  curve->SetInitialValue(gfx::Vector2dF());
   double smallDeltaDuration = curve->Duration().InSecondsF();
 
-  curve->UpdateTarget(base::Seconds(0.01f), gfx::ScrollOffset(0.f, 300.f));
+  curve->UpdateTarget(base::Seconds(0.01f), gfx::Vector2dF(0.f, 300.f));
   double mediumDeltaDuration = curve->Duration().InSecondsF();
 
-  curve->UpdateTarget(base::Seconds(0.01f), gfx::ScrollOffset(0.f, 500.f));
+  curve->UpdateTarget(base::Seconds(0.01f), gfx::Vector2dF(0.f, 500.f));
   double largeDeltaDuration = curve->Duration().InSecondsF();
 
   EXPECT_GT(smallDeltaDuration, mediumDeltaDuration);
   EXPECT_GT(mediumDeltaDuration, largeDeltaDuration);
 
-  curve->UpdateTarget(base::Seconds(0.01f), gfx::ScrollOffset(0.f, 5000.f));
+  curve->UpdateTarget(base::Seconds(0.01f), gfx::Vector2dF(0.f, 5000.f));
   EXPECT_EQ(largeDeltaDuration, curve->Duration().InSecondsF());
 }
 
 TEST(ScrollOffsetAnimationCurveTest, LinearAnimation) {
   // Testing autoscroll downwards for a scroller of length 1000px.
-  gfx::ScrollOffset current_offset(0.f, 0.f);
-  gfx::ScrollOffset target_offset(0.f, 1000.f);
+  gfx::Vector2dF current_offset(0.f, 0.f);
+  gfx::Vector2dF target_offset(0.f, 1000.f);
   std::unique_ptr<ScrollOffsetAnimationCurve> curve(
       ScrollOffsetAnimationCurveFactory::CreateLinearAnimationForTesting(
           target_offset));
@@ -292,13 +288,13 @@
   EXPECT_FLOAT_EQ(1.25f, curve->Duration().InSecondsF());
 
   // Test scrolling down from half way.
-  current_offset = gfx::ScrollOffset(0.f, 500.f);
+  current_offset = gfx::Vector2dF(0.f, 500.f);
   curve->SetInitialValue(current_offset, base::TimeDelta(),
                          autoscroll_velocity);
   EXPECT_FLOAT_EQ(0.625f, curve->Duration().InSecondsF());
 
   // Test scrolling down when max_offset is reached.
-  current_offset = gfx::ScrollOffset(0.f, 1000.f);
+  current_offset = gfx::Vector2dF(0.f, 1000.f);
   curve->SetInitialValue(current_offset, base::TimeDelta(),
                          autoscroll_velocity);
   EXPECT_FLOAT_EQ(0.f, curve->Duration().InSecondsF());
@@ -328,29 +324,29 @@
 TEST(ScrollOffsetAnimationCurveTest, CurveWithDelay) {
   std::unique_ptr<ScrollOffsetAnimationCurve> curve(
       ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
-          gfx::ScrollOffset(0.f, 100.f), DurationBehavior::INVERSE_DELTA));
+          gfx::Vector2dF(0.f, 100.f), DurationBehavior::INVERSE_DELTA));
   double duration_in_seconds = kInverseDeltaMaxDuration / kDurationDivisor;
   double delay_in_seconds = 0.02;
   double curve_duration = duration_in_seconds - delay_in_seconds;
 
-  curve->SetInitialValue(gfx::ScrollOffset(), base::Seconds(delay_in_seconds));
+  curve->SetInitialValue(gfx::Vector2dF(), base::Seconds(delay_in_seconds));
   EXPECT_NEAR(curve_duration, curve->Duration().InSecondsF(), 0.0002f);
 
-  curve->UpdateTarget(base::Seconds(0.01f), gfx::ScrollOffset(0.f, 500.f));
+  curve->UpdateTarget(base::Seconds(0.01f), gfx::Vector2dF(0.f, 500.f));
   EXPECT_GT(curve_duration, curve->Duration().InSecondsF());
-  EXPECT_EQ(gfx::ScrollOffset(0.f, 500.f), curve->target_value());
+  EXPECT_EQ(gfx::Vector2dF(0.f, 500.f), curve->target_value());
 }
 
 TEST(ScrollOffsetAnimationCurveTest, CurveWithLargeDelay) {
   DurationBehavior duration_hint = DurationBehavior::INVERSE_DELTA;
   std::unique_ptr<ScrollOffsetAnimationCurve> curve(
       ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
-          gfx::ScrollOffset(0.f, 100.f), duration_hint));
-  curve->SetInitialValue(gfx::ScrollOffset(), base::Seconds(0.2));
+          gfx::Vector2dF(0.f, 100.f), duration_hint));
+  curve->SetInitialValue(gfx::Vector2dF(), base::TimeDelta::FromSecondsD(0.2));
   EXPECT_EQ(0.f, curve->Duration().InSecondsF());
 
   // Re-targeting when animation duration is 0.
-  curve->UpdateTarget(base::Seconds(-0.01), gfx::ScrollOffset(0.f, 300.f));
+  curve->UpdateTarget(base::Seconds(-0.01), gfx::Vector2dF(0.f, 300.f));
   double duration =
       ScrollOffsetAnimationCurve::EaseInOutSegmentDuration(
           gfx::Vector2dF(0.f, 200.f), duration_hint, base::Seconds(0.01))
@@ -359,13 +355,13 @@
 
   // Re-targeting before last_retarget_, the  difference should be accounted for
   // in duration.
-  curve->UpdateTarget(base::Seconds(-0.01), gfx::ScrollOffset(0.f, 500.f));
+  curve->UpdateTarget(base::Seconds(-0.01), gfx::Vector2dF(0.f, 500.f));
   duration = ScrollOffsetAnimationCurve::EaseInOutSegmentDuration(
                  gfx::Vector2dF(0.f, 500.f), duration_hint, base::Seconds(0.01))
                  .InSecondsF();
   EXPECT_EQ(duration, curve->Duration().InSecondsF());
 
-  EXPECT_VECTOR2DF_EQ(gfx::ScrollOffset(0.f, 500.f),
+  EXPECT_VECTOR2DF_EQ(gfx::Vector2dF(0.f, 500.f),
                       curve->GetValue(base::Seconds(1.0)));
 }
 
@@ -375,40 +371,37 @@
   DurationBehavior duration_hint = DurationBehavior::INVERSE_DELTA;
   std::unique_ptr<ScrollOffsetAnimationCurve> curve(
       ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
-          gfx::ScrollOffset(0.f, 100.f), duration_hint));
+          gfx::Vector2dF(0.f, 100.f), duration_hint));
   double duration_in_seconds = kInverseDeltaMaxDuration / kDurationDivisor;
   double delay_in_seconds = 0.02;
   double curve_duration = duration_in_seconds - delay_in_seconds;
 
-  curve->SetInitialValue(gfx::ScrollOffset(), base::Seconds(delay_in_seconds));
+  curve->SetInitialValue(gfx::Vector2dF(), base::Seconds(delay_in_seconds));
   EXPECT_NEAR(curve_duration, curve->Duration().InSecondsF(), 0.0002f);
 
   // Re-target 1, this should set last_retarget_ to 0.05.
-  gfx::ScrollOffset new_delta =
-      gfx::ScrollOffset(0.f, 200.f) - curve->GetValue(base::Seconds(0.05));
+  gfx::Vector2dF new_delta =
+      gfx::Vector2dF(0.f, 200.f) - curve->GetValue(base::Seconds(0.05));
   double expected_duration =
       ScrollOffsetAnimationCurve::EaseInOutSegmentDuration(
-          gfx::Vector2dF(new_delta.x(), new_delta.y()), duration_hint,
-          base::TimeDelta())
+          new_delta, duration_hint, base::TimeDelta())
           .InSecondsF() +
       0.05;
-  curve->UpdateTarget(base::Seconds(0.05), gfx::ScrollOffset(0.f, 200.f));
+  curve->UpdateTarget(base::Seconds(0.05), gfx::Vector2dF(0.f, 200.f));
   EXPECT_NEAR(expected_duration, curve->Duration().InSecondsF(), 0.0002f);
 
   // Re-target 2, this should set total_animation_duration to t, which is
   // last_retarget_. This is what would cause the DCHECK failure in
   // crbug.com/645317.
-  curve->UpdateTarget(base::Seconds(-0.145), gfx::ScrollOffset(0.f, 300.f));
+  curve->UpdateTarget(base::Seconds(-0.145), gfx::Vector2dF(0.f, 300.f));
   EXPECT_NEAR(0.05, curve->Duration().InSecondsF(), 0.0002f);
 
   // Re-target 3, this should set total_animation_duration based on new_delta.
-  new_delta =
-      gfx::ScrollOffset(0.f, 500.f) - curve->GetValue(base::Seconds(0.05));
+  new_delta = gfx::Vector2dF(0.f, 500.f) - curve->GetValue(base::Seconds(0.05));
   expected_duration = ScrollOffsetAnimationCurve::EaseInOutSegmentDuration(
-                          gfx::Vector2dF(new_delta.x(), new_delta.y()),
-                          duration_hint, base::Seconds(0.15))
+                          new_delta, duration_hint, base::Seconds(0.15))
                           .InSecondsF();
-  curve->UpdateTarget(base::Seconds(-0.1), gfx::ScrollOffset(0.f, 500.f));
+  curve->UpdateTarget(base::Seconds(-0.1), gfx::Vector2dF(0.f, 500.f));
   EXPECT_NEAR(expected_duration, curve->Duration().InSecondsF(), 0.0002f);
 }
 
diff --git a/cc/animation/scroll_offset_animations_impl.cc b/cc/animation/scroll_offset_animations_impl.cc
index 73fc4ed..0926b73 100644
--- a/cc/animation/scroll_offset_animations_impl.cc
+++ b/cc/animation/scroll_offset_animations_impl.cc
@@ -39,8 +39,8 @@
 
 void ScrollOffsetAnimationsImpl::AutoScrollAnimationCreate(
     ElementId element_id,
-    const gfx::ScrollOffset& target_offset,
-    const gfx::ScrollOffset& current_offset,
+    const gfx::Vector2dF& target_offset,
+    const gfx::Vector2dF& current_offset,
     float autoscroll_velocity,
     base::TimeDelta animation_start_offset) {
   std::unique_ptr<ScrollOffsetAnimationCurve> curve =
@@ -55,8 +55,8 @@
 
 void ScrollOffsetAnimationsImpl::MouseWheelScrollAnimationCreate(
     ElementId element_id,
-    const gfx::ScrollOffset& target_offset,
-    const gfx::ScrollOffset& current_offset,
+    const gfx::Vector2dF& target_offset,
+    const gfx::Vector2dF& current_offset,
     base::TimeDelta delayed_by,
     base::TimeDelta animation_start_offset) {
   std::unique_ptr<ScrollOffsetAnimationCurve> curve =
@@ -92,7 +92,7 @@
 
 bool ScrollOffsetAnimationsImpl::ScrollAnimationUpdateTarget(
     const gfx::Vector2dF& scroll_delta,
-    const gfx::ScrollOffset& max_scroll_offset,
+    const gfx::Vector2dF& max_scroll_offset,
     base::TimeTicks frame_monotonic_time,
     base::TimeDelta delayed_by) {
   DCHECK(scroll_offset_animation_);
@@ -117,9 +117,8 @@
       ScrollOffsetAnimationCurve::ToScrollOffsetAnimationCurve(
           keyframe_model->curve());
 
-  gfx::ScrollOffset new_target =
-      gfx::ScrollOffsetWithDelta(curve->target_value(), scroll_delta);
-  new_target.SetToMax(gfx::ScrollOffset());
+  gfx::Vector2dF new_target = curve->target_value() + scroll_delta;
+  new_target.SetToMax(gfx::Vector2dF());
   new_target.SetToMin(max_scroll_offset);
 
   // TODO(ymalik): KeyframeModel::TrimTimeToCurrentIteration should probably
diff --git a/cc/animation/scroll_offset_animations_impl.h b/cc/animation/scroll_offset_animations_impl.h
index 9e8b380..acadbaa 100644
--- a/cc/animation/scroll_offset_animations_impl.h
+++ b/cc/animation/scroll_offset_animations_impl.h
@@ -11,7 +11,7 @@
 #include "cc/animation/animation_delegate.h"
 #include "cc/animation/scroll_offset_animation_curve.h"
 #include "cc/trees/mutator_host_client.h"
-#include "ui/gfx/geometry/scroll_offset.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 
 namespace cc {
 
@@ -35,8 +35,8 @@
       delete;
 
   void AutoScrollAnimationCreate(ElementId element_id,
-                                 const gfx::ScrollOffset& target_offset,
-                                 const gfx::ScrollOffset& current_offset,
+                                 const gfx::Vector2dF& target_offset,
+                                 const gfx::Vector2dF& current_offset,
                                  float autoscroll_velocity,
                                  base::TimeDelta animation_start_offset);
 
@@ -44,13 +44,13 @@
   // animation. |animation_start_offset| causes us to start the animation
   // partway through.
   void MouseWheelScrollAnimationCreate(ElementId element_id,
-                                       const gfx::ScrollOffset& target_offset,
-                                       const gfx::ScrollOffset& current_offset,
+                                       const gfx::Vector2dF& target_offset,
+                                       const gfx::Vector2dF& current_offset,
                                        base::TimeDelta delayed_by,
                                        base::TimeDelta animation_start_offset);
 
   bool ScrollAnimationUpdateTarget(const gfx::Vector2dF& scroll_delta,
-                                   const gfx::ScrollOffset& max_scroll_offset,
+                                   const gfx::Vector2dF& max_scroll_offset,
                                    base::TimeTicks frame_monotonic_time,
                                    base::TimeDelta delayed_by);
 
diff --git a/cc/animation/scroll_timeline.cc b/cc/animation/scroll_timeline.cc
index 2b4982c..3c3eb51b 100644
--- a/cc/animation/scroll_timeline.cc
+++ b/cc/animation/scroll_timeline.cc
@@ -11,8 +11,8 @@
 #include "cc/animation/worklet_animation.h"
 #include "cc/trees/property_tree.h"
 #include "cc/trees/scroll_node.h"
-#include "ui/gfx/geometry/scroll_offset.h"
 #include "ui/gfx/geometry/size.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 
 namespace cc {
 
@@ -97,12 +97,12 @@
   const ScrollNode* scroll_node =
       scroll_tree.FindNodeFromElementId(scroller_id);
 
-  gfx::ScrollOffset offset =
+  gfx::Vector2dF offset =
       scroll_tree.GetPixelSnappedScrollOffset(scroll_node->id);
   DCHECK_GE(offset.x(), 0);
   DCHECK_GE(offset.y(), 0);
 
-  gfx::ScrollOffset scroll_dimensions =
+  gfx::Vector2dF scroll_dimensions =
       scroll_tree.MaxScrollOffset(scroll_node->id);
 
   double max_offset =
diff --git a/cc/animation/scroll_timeline_unittest.cc b/cc/animation/scroll_timeline_unittest.cc
index 481432a..0ce18291 100644
--- a/cc/animation/scroll_timeline_unittest.cc
+++ b/cc/animation/scroll_timeline_unittest.cc
@@ -11,7 +11,7 @@
 #include "cc/trees/scroll_node.h"
 #include "cc/trees/transform_node.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/geometry/scroll_offset.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 
 namespace cc {
 
@@ -26,7 +26,7 @@
 
 void SetScrollOffset(PropertyTrees* property_trees,
                      ElementId scroller_id,
-                     gfx::ScrollOffset offset) {
+                     gfx::Vector2dF offset) {
   // Update both scroll and transform trees
   property_trees->scroll_tree.SetScrollOffset(scroller_id, offset);
   TransformNode* transform_node =
@@ -121,14 +121,14 @@
       scroller_id(), ScrollTimeline::ScrollRight, scroll_offsets);
 
   // Unscrolled, both timelines should read a current time of 0.
-  SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset());
+  SetScrollOffset(&property_trees(), scroller_id(), gfx::Vector2dF());
   EXPECT_SCROLL_TIMELINE_TIME_NEAR(
       0, vertical_timeline->CurrentTime(scroll_tree(), false));
   EXPECT_SCROLL_TIMELINE_TIME_NEAR(
       0, horizontal_timeline->CurrentTime(scroll_tree(), false));
 
   // Now do some scrolling and make sure that the ScrollTimelines update.
-  SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset(75, 50));
+  SetScrollOffset(&property_trees(), scroller_id(), gfx::Vector2dF(75, 50));
 
   EXPECT_SCROLL_TIMELINE_TIME_NEAR(
       0.5 * ScrollTimeline::kScrollTimelineDurationMs,
@@ -158,44 +158,44 @@
   // Scale necessary to convert absolute unit times to progress based values
   double scale = ScrollTimeline::kScrollTimelineDurationMs / scroll_size;
 
-  SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset());
+  SetScrollOffset(&property_trees(), scroller_id(), gfx::Vector2dF());
   EXPECT_SCROLL_TIMELINE_TIME_NEAR(
       (offset + p) * w * scroll_size * scale,
       vertical_timeline->CurrentTime(scroll_tree(), false));
 
   p = (70.0 - 0.0) / (100.0 - 0.0);
-  SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset(0, 70));
+  SetScrollOffset(&property_trees(), scroller_id(), gfx::Vector2dF(0, 70));
   EXPECT_SCROLL_TIMELINE_TIME_NEAR(
       (offset + p) * w * scroll_size * scale,
       vertical_timeline->CurrentTime(scroll_tree(), false));
 
   offset = 1;
   p = 0;
-  SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset(0, 100));
+  SetScrollOffset(&property_trees(), scroller_id(), gfx::Vector2dF(0, 100));
   EXPECT_SCROLL_TIMELINE_TIME_NEAR(
       (offset + p) * w * scroll_size * scale,
       vertical_timeline->CurrentTime(scroll_tree(), false));
 
   p = (150.0 - 100.0) / (250.0 - 100.0);
-  SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset(0, 150));
+  SetScrollOffset(&property_trees(), scroller_id(), gfx::Vector2dF(0, 150));
   EXPECT_SCROLL_TIMELINE_TIME_NEAR(
       (offset + p) * w * scroll_size * scale,
       vertical_timeline->CurrentTime(scroll_tree(), false));
 
   offset = 2;
   p = 0;
-  SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset(0, 250));
+  SetScrollOffset(&property_trees(), scroller_id(), gfx::Vector2dF(0, 250));
   EXPECT_SCROLL_TIMELINE_TIME_NEAR(
       (offset + p) * w * scroll_size * scale,
       vertical_timeline->CurrentTime(scroll_tree(), false));
 
   p = (350.0 - 250.0) / (400.0 - 250.0);
-  SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset(0, 350));
+  SetScrollOffset(&property_trees(), scroller_id(), gfx::Vector2dF(0, 350));
   EXPECT_SCROLL_TIMELINE_TIME_NEAR(
       (offset + p) * w * scroll_size * scale,
       vertical_timeline->CurrentTime(scroll_tree(), false));
 
-  SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset(0, 400));
+  SetScrollOffset(&property_trees(), scroller_id(), gfx::Vector2dF(0, 400));
   EXPECT_SCROLL_TIMELINE_TIME_NEAR(
       ScrollTimeline::kScrollTimelineDurationMs,
       vertical_timeline->CurrentTime(scroll_tree(), false));
@@ -212,7 +212,7 @@
       scroller_id(), ScrollTimeline::ScrollDown, scroll_offsets);
 
   // Offset is less than start offset ==> current time is 0.
-  SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset(0, 300));
+  SetScrollOffset(&property_trees(), scroller_id(), gfx::Vector2dF(0, 300));
   EXPECT_SCROLL_TIMELINE_TIME_NEAR(
       0, vertical_timeline->CurrentTime(scroll_tree(), false));
 
@@ -220,7 +220,7 @@
   double scale = ScrollTimeline::kScrollTimelineDurationMs / scroll_size;
 
   // Offset is greater than end offset ==> current time is 100%.
-  SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset(0, 360));
+  SetScrollOffset(&property_trees(), scroller_id(), gfx::Vector2dF(0, 360));
   EXPECT_SCROLL_TIMELINE_TIME_NEAR(
       scroll_size * scale,
       vertical_timeline->CurrentTime(scroll_tree(), false));
@@ -230,7 +230,7 @@
   vertical_timeline = ScrollTimeline::Create(
       scroller_id(), ScrollTimeline::ScrollDown, scroll_offsets);
 
-  SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset(0, 100));
+  SetScrollOffset(&property_trees(), scroller_id(), gfx::Vector2dF(0, 100));
   // Scroll offset is 25% of [0, 400) range, which maps to [0% 50%) of the
   // entire scroll range.
   EXPECT_SCROLL_TIMELINE_TIME_NEAR(
@@ -242,7 +242,7 @@
   vertical_timeline = ScrollTimeline::Create(
       scroller_id(), ScrollTimeline::ScrollDown, scroll_offsets);
 
-  SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset(0, 300));
+  SetScrollOffset(&property_trees(), scroller_id(), gfx::Vector2dF(0, 300));
   // Scroll offset is 75% of [0, 400) range, which maps to [50% 100%) of the
   // entire scroll range.
   EXPECT_SCROLL_TIMELINE_TIME_NEAR(
@@ -277,7 +277,7 @@
 
   double halfwayY = scroll_size / 2.;
   double expectedTime = 0.5 * ScrollTimeline::kScrollTimelineDurationMs;
-  SetScrollOffset(&pending_tree, scroller_id, gfx::ScrollOffset(0, halfwayY));
+  SetScrollOffset(&pending_tree, scroller_id, gfx::Vector2dF(0, halfwayY));
 
   scoped_refptr<ScrollTimeline> main_timeline = ScrollTimeline::Create(
       scroller_id, ScrollTimeline::ScrollDown, scroll_offsets);
@@ -314,7 +314,7 @@
   scoped_refptr<ScrollTimeline> timeline = ScrollTimeline::Create(
       scroller_id(), ScrollTimeline::ScrollDown, scroll_offsets);
 
-  SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset(0, 50));
+  SetScrollOffset(&property_trees(), scroller_id(), gfx::Vector2dF(0, 50));
 
   // For simplicity emulate snapping by directly setting snap_amount of
   // transform node.
@@ -340,24 +340,24 @@
 
   // Unscrolled, the timeline should read a current time of 0 since the current
   // offset (0) will be less than the startScrollOffset.
-  SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset());
+  SetScrollOffset(&property_trees(), scroller_id(), gfx::Vector2dF());
   EXPECT_SCROLL_TIMELINE_TIME_NEAR(0,
                                    timeline->CurrentTime(scroll_tree(), false));
 
-  SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset(0, 19));
+  SetScrollOffset(&property_trees(), scroller_id(), gfx::Vector2dF(0, 19));
   EXPECT_SCROLL_TIMELINE_TIME_NEAR(0,
                                    timeline->CurrentTime(scroll_tree(), false));
 
-  SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset(0, 20));
+  SetScrollOffset(&property_trees(), scroller_id(), gfx::Vector2dF(0, 20));
   EXPECT_SCROLL_TIMELINE_TIME_NEAR(0,
                                    timeline->CurrentTime(scroll_tree(), false));
 
-  SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset(0, 50));
+  SetScrollOffset(&property_trees(), scroller_id(), gfx::Vector2dF(0, 50));
   EXPECT_SCROLL_TIMELINE_TIME_NEAR(
       CalculateCurrentTime(50, start_scroll_offset, scroll_size),
       timeline->CurrentTime(scroll_tree(), false));
 
-  SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset(0, 200));
+  SetScrollOffset(&property_trees(), scroller_id(), gfx::Vector2dF(0, 200));
   EXPECT_SCROLL_TIMELINE_TIME_NEAR(
       CalculateCurrentTime(200, start_scroll_offset, scroll_size),
       timeline->CurrentTime(scroll_tree(), false));
@@ -373,23 +373,23 @@
       scroller_id(), ScrollTimeline::ScrollDown, scroll_offsets);
 
   SetScrollOffset(&property_trees(), scroller_id(),
-                  gfx::ScrollOffset(0, scroll_size));
+                  gfx::Vector2dF(0, scroll_size));
   EXPECT_SCROLL_TIMELINE_TIME_NEAR(ScrollTimeline::kScrollTimelineDurationMs,
                                    timeline->CurrentTime(scroll_tree(), false));
 
   SetScrollOffset(&property_trees(), scroller_id(),
-                  gfx::ScrollOffset(0, scroll_size - 20));
+                  gfx::Vector2dF(0, scroll_size - 20));
   EXPECT_SCROLL_TIMELINE_TIME_NEAR(ScrollTimeline::kScrollTimelineDurationMs,
                                    timeline->CurrentTime(scroll_tree(), false));
 
   SetScrollOffset(&property_trees(), scroller_id(),
-                  gfx::ScrollOffset(0, scroll_size - 50));
+                  gfx::Vector2dF(0, scroll_size - 50));
   EXPECT_SCROLL_TIMELINE_TIME_NEAR(
       CalculateCurrentTime(scroll_size - 50, 0, end_scroll_offset),
       timeline->CurrentTime(scroll_tree(), false));
 
   SetScrollOffset(&property_trees(), scroller_id(),
-                  gfx::ScrollOffset(0, scroll_size - 200));
+                  gfx::Vector2dF(0, scroll_size - 200));
   EXPECT_SCROLL_TIMELINE_TIME_NEAR(
       CalculateCurrentTime(scroll_size - 200, 0, end_scroll_offset),
       timeline->CurrentTime(scroll_tree(), false));
@@ -405,7 +405,7 @@
   scoped_refptr<ScrollTimeline> timeline = ScrollTimeline::Create(
       scroller_id(), ScrollTimeline::ScrollDown, scroll_offsets);
   SetScrollOffset(&property_trees(), scroller_id(),
-                  gfx::ScrollOffset(0, scroll_size - 150));
+                  gfx::Vector2dF(0, scroll_size - 150));
   EXPECT_SCROLL_TIMELINE_TIME_NEAR(
       CalculateCurrentTime(scroll_size - 150, start_scroll_offset,
                            end_scroll_offset),
@@ -418,7 +418,7 @@
   scroll_offsets.push_back(20);
   scoped_refptr<ScrollTimeline> timeline = ScrollTimeline::Create(
       scroller_id(), ScrollTimeline::ScrollDown, scroll_offsets);
-  SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset(0, 150));
+  SetScrollOffset(&property_trees(), scroller_id(), gfx::Vector2dF(0, 150));
 
   EXPECT_SCROLL_TIMELINE_TIME_NEAR(ScrollTimeline::kScrollTimelineDurationMs,
                                    timeline->CurrentTime(scroll_tree(), false));
@@ -431,11 +431,11 @@
   scroll_offsets.push_back(10);
   scoped_refptr<ScrollTimeline> timeline = ScrollTimeline::Create(
       scroller_id(), ScrollTimeline::ScrollDown, scroll_offsets);
-  SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset(0, 40));
+  SetScrollOffset(&property_trees(), scroller_id(), gfx::Vector2dF(0, 40));
   EXPECT_SCROLL_TIMELINE_TIME_NEAR(0,
                                    timeline->CurrentTime(scroll_tree(), false));
 
-  SetScrollOffset(&property_trees(), scroller_id(), gfx::ScrollOffset(0, 150));
+  SetScrollOffset(&property_trees(), scroller_id(), gfx::Vector2dF(0, 150));
 
   EXPECT_SCROLL_TIMELINE_TIME_NEAR(ScrollTimeline::kScrollTimelineDurationMs,
                                    timeline->CurrentTime(scroll_tree(), false));
@@ -455,19 +455,19 @@
 
   // Before the start_scroll_offset the current time should be 0
   SetScrollOffset(&property_trees(), scroller_id(),
-                  gfx::ScrollOffset(0, start_scroll_offset - 10));
+                  gfx::Vector2dF(0, start_scroll_offset - 10));
   EXPECT_SCROLL_TIMELINE_TIME_NEAR(0,
                                    timeline->CurrentTime(scroll_tree(), false));
 
   // At the end_scroll_offset the current time should be 100%
   SetScrollOffset(&property_trees(), scroller_id(),
-                  gfx::ScrollOffset(0, end_scroll_offset));
+                  gfx::Vector2dF(0, end_scroll_offset));
   EXPECT_SCROLL_TIMELINE_TIME_NEAR(ScrollTimeline::kScrollTimelineDurationMs,
                                    timeline->CurrentTime(scroll_tree(), false));
 
   // After the end_scroll_offset the current time should be 100%
   SetScrollOffset(&property_trees(), scroller_id(),
-                  gfx::ScrollOffset(0, end_scroll_offset + 10));
+                  gfx::Vector2dF(0, end_scroll_offset + 10));
   EXPECT_SCROLL_TIMELINE_TIME_NEAR(ScrollTimeline::kScrollTimelineDurationMs,
                                    timeline->CurrentTime(scroll_tree(), false));
 }
diff --git a/cc/base/math_util.cc b/cc/base/math_util.cc
index decdb8c..674e416 100644
--- a/cc/base/math_util.cc
+++ b/cc/base/math_util.cc
@@ -921,15 +921,6 @@
 }
 
 void MathUtil::AddToTracedValue(const char* name,
-                                const gfx::ScrollOffset& v,
-                                base::trace_event::TracedValue* res) {
-  res->BeginArray(name);
-  res->AppendDouble(v.x());
-  res->AppendDouble(v.y());
-  res->EndArray();
-}
-
-void MathUtil::AddToTracedValue(const char* name,
                                 const gfx::QuadF& q,
                                 base::trace_event::TracedValue* res) {
   res->BeginArray(name);
diff --git a/cc/base/math_util.h b/cc/base/math_util.h
index b7c762b..8f9f4cd 100644
--- a/cc/base/math_util.h
+++ b/cc/base/math_util.h
@@ -18,8 +18,8 @@
 #include "ui/gfx/geometry/point3_f.h"
 #include "ui/gfx/geometry/point_f.h"
 #include "ui/gfx/geometry/rounded_corners_f.h"
-#include "ui/gfx/geometry/scroll_offset.h"
 #include "ui/gfx/geometry/size.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 #include "ui/gfx/transform.h"
 
 namespace base {
@@ -294,9 +294,6 @@
                                const gfx::Vector2dF& v,
                                base::trace_event::TracedValue* res);
   static void AddToTracedValue(const char* name,
-                               const gfx::ScrollOffset& v,
-                               base::trace_event::TracedValue* res);
-  static void AddToTracedValue(const char* name,
                                const gfx::QuadF& q,
                                base::trace_event::TracedValue* res);
   static void AddToTracedValue(const char* name,
diff --git a/cc/input/browser_controls_offset_manager_client.h b/cc/input/browser_controls_offset_manager_client.h
index fc65900a..4a4842d 100644
--- a/cc/input/browser_controls_offset_manager_client.h
+++ b/cc/input/browser_controls_offset_manager_client.h
@@ -6,7 +6,7 @@
 #define CC_INPUT_BROWSER_CONTROLS_OFFSET_MANAGER_CLIENT_H_
 
 namespace gfx {
-class ScrollOffset;
+class Vector2dF;
 }
 
 namespace cc {
@@ -21,7 +21,7 @@
                                                    float bottom_ratio) = 0;
   virtual float CurrentTopControlsShownRatio() const = 0;
   virtual float CurrentBottomControlsShownRatio() const = 0;
-  virtual gfx::ScrollOffset ViewportScrollOffset() const = 0;
+  virtual gfx::Vector2dF ViewportScrollOffset() const = 0;
   virtual void DidChangeBrowserControlsPosition() = 0;
   virtual bool OnlyExpandTopControlsAtPageTop() const = 0;
   virtual bool HaveRootScrollNode() const = 0;
diff --git a/cc/input/browser_controls_offset_manager_unittest.cc b/cc/input/browser_controls_offset_manager_unittest.cc
index 679d0a2c..8761164 100644
--- a/cc/input/browser_controls_offset_manager_unittest.cc
+++ b/cc/input/browser_controls_offset_manager_unittest.cc
@@ -72,7 +72,7 @@
     return browser_controls_params_.only_expand_top_controls_at_page_top;
   }
 
-  gfx::ScrollOffset ViewportScrollOffset() const override {
+  gfx::Vector2dF ViewportScrollOffset() const override {
     return viewport_scroll_offset_;
   }
 
@@ -121,12 +121,12 @@
   }
 
   void SetViewportScrollOffset(float x, float y) {
-    viewport_scroll_offset_ = gfx::ScrollOffset(x, y);
+    viewport_scroll_offset_ = gfx::Vector2dF(x, y);
   }
 
   void ScrollVerticallyBy(float dy) {
     gfx::Vector2dF viewport_scroll_delta = manager()->ScrollBy({0.f, dy});
-    viewport_scroll_offset_.Add(gfx::ScrollOffset(viewport_scroll_delta));
+    viewport_scroll_offset_.Add(viewport_scroll_delta);
   }
 
  private:
@@ -144,7 +144,7 @@
   float top_controls_shown_ratio_;
   float browser_controls_show_threshold_;
   float browser_controls_hide_threshold_;
-  gfx::ScrollOffset viewport_scroll_offset_;
+  gfx::Vector2dF viewport_scroll_offset_;
 };
 
 TEST(BrowserControlsOffsetManagerTest, EnsureScrollThresholdApplied) {
diff --git a/cc/input/input_handler.h b/cc/input/input_handler.h
index e5e555b..8f14d393e 100644
--- a/cc/input/input_handler.h
+++ b/cc/input/input_handler.h
@@ -24,7 +24,6 @@
 
 namespace gfx {
 class Point;
-class ScrollOffset;
 class SizeF;
 class Vector2dF;
 }  // namespace gfx
@@ -60,12 +59,12 @@
       ui::ScrollGranularity::kScrollByPrecisePixel;
 
   // If the input handler processed the event as a scrollbar scroll, it will
-  // return a gfx::ScrollOffset that produces the necessary scroll. However,
+  // return a gfx::Vector2dF that produces the necessary scroll. However,
   // it is still the client's responsibility to generate the gesture scrolls
   // instead of the input handler performing it as a part of handling the
   // pointer event (due to the latency attribution that happens at the
   // InputHandlerProxy level).
-  gfx::ScrollOffset scroll_offset;
+  gfx::Vector2dF scroll_offset;
 
   // Used to determine which scroll_node needs to be scrolled. The primary
   // purpose of this is to avoid hit testing for gestures that already know
@@ -108,8 +107,8 @@
   virtual void ReconcileElasticOverscrollAndRootScroll() = 0;
   virtual void SetPrefersReducedMotion(bool prefers_reduced_motion) = 0;
   virtual void UpdateRootLayerStateForSynchronousInputHandler(
-      const gfx::ScrollOffset& total_scroll_offset,
-      const gfx::ScrollOffset& max_scroll_offset,
+      const gfx::Vector2dF& total_scroll_offset,
+      const gfx::Vector2dF& max_scroll_offset,
       const gfx::SizeF& scrollable_size,
       float page_scale_factor,
       float min_page_scale_factor,
@@ -297,7 +296,7 @@
   // input handler by the application (outside of input event handling). Offset
   // is expected in "content/page coordinates".
   virtual void SetSynchronousInputHandlerRootScrollOffset(
-      const gfx::ScrollOffset& root_content_offset) = 0;
+      const gfx::Vector2dF& root_content_offset) = 0;
 
   virtual void PinchGestureBegin() = 0;
   virtual void PinchGestureUpdate(float magnify_delta,
@@ -358,9 +357,9 @@
   // Called by the single-threaded UI Compositor to get or set the scroll offset
   // on the impl side. Returns false if |element_id| isn't in the active tree.
   virtual bool GetScrollOffsetForLayer(ElementId element_id,
-                                       gfx::ScrollOffset* offset) = 0;
+                                       gfx::Vector2dF* offset) = 0;
   virtual bool ScrollLayerTo(ElementId element_id,
-                             const gfx::ScrollOffset& offset) = 0;
+                             const gfx::Vector2dF& offset) = 0;
 
   virtual bool ScrollingShouldSwitchtoMainThread() = 0;
 
diff --git a/cc/input/scroll_elasticity_helper.cc b/cc/input/scroll_elasticity_helper.cc
index 451bfcd8..f51cce2 100644
--- a/cc/input/scroll_elasticity_helper.cc
+++ b/cc/input/scroll_elasticity_helper.cc
@@ -20,8 +20,8 @@
   gfx::Vector2dF StretchAmount() const override;
   gfx::Size ScrollBounds() const override;
   void SetStretchAmount(const gfx::Vector2dF& stretch_amount) override;
-  gfx::ScrollOffset ScrollOffset() const override;
-  gfx::ScrollOffset MaxScrollOffset() const override;
+  gfx::Vector2dF ScrollOffset() const override;
+  gfx::Vector2dF MaxScrollOffset() const override;
   void ScrollBy(const gfx::Vector2dF& delta) override;
   void RequestOneBeginFrame() override;
 
@@ -65,11 +65,11 @@
   host_impl_->SetFullViewportDamage();
 }
 
-gfx::ScrollOffset ScrollElasticityHelperImpl::ScrollOffset() const {
+gfx::Vector2dF ScrollElasticityHelperImpl::ScrollOffset() const {
   return host_impl_->active_tree()->TotalScrollOffset();
 }
 
-gfx::ScrollOffset ScrollElasticityHelperImpl::MaxScrollOffset() const {
+gfx::Vector2dF ScrollElasticityHelperImpl::MaxScrollOffset() const {
   return host_impl_->active_tree()->TotalMaxScrollOffset();
 }
 
diff --git a/cc/input/scroll_elasticity_helper.h b/cc/input/scroll_elasticity_helper.h
index a85e0f4e..cf66a01 100644
--- a/cc/input/scroll_elasticity_helper.h
+++ b/cc/input/scroll_elasticity_helper.h
@@ -6,7 +6,6 @@
 #define CC_INPUT_SCROLL_ELASTICITY_HELPER_H_
 
 #include "cc/cc_export.h"
-#include "ui/gfx/geometry/scroll_offset.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/geometry/vector2d_f.h"
 
@@ -62,8 +61,8 @@
   virtual void SetStretchAmount(const gfx::Vector2dF& stretch_amount) = 0;
 
   // Functions for the scrolling of the root scroll layer.
-  virtual gfx::ScrollOffset ScrollOffset() const = 0;
-  virtual gfx::ScrollOffset MaxScrollOffset() const = 0;
+  virtual gfx::Vector2dF ScrollOffset() const = 0;
+  virtual gfx::Vector2dF MaxScrollOffset() const = 0;
   virtual void ScrollBy(const gfx::Vector2dF& delta) = 0;
 
   // Requests that another frame happens for the controller to continue ticking
diff --git a/cc/input/scroll_snap_data.cc b/cc/input/scroll_snap_data.cc
index 9395015a..e309e78a 100644
--- a/cc/input/scroll_snap_data.cc
+++ b/cc/input/scroll_snap_data.cc
@@ -58,7 +58,7 @@
 }
 
 const absl::optional<SnapSearchResult>& ClosestSearchResult(
-    const gfx::ScrollOffset reference_point,
+    const gfx::Vector2dF reference_point,
     SearchAxis axis,
     const absl::optional<SnapSearchResult>& a,
     const absl::optional<SnapSearchResult>& b) {
@@ -108,22 +108,22 @@
 }
 
 SnapContainerData::SnapContainerData()
-    : proximity_range_(gfx::ScrollOffset(std::numeric_limits<float>::max(),
-                                         std::numeric_limits<float>::max())) {}
+    : proximity_range_(gfx::Vector2dF(std::numeric_limits<float>::max(),
+                                      std::numeric_limits<float>::max())) {}
 
 SnapContainerData::SnapContainerData(ScrollSnapType type)
     : scroll_snap_type_(type),
-      proximity_range_(gfx::ScrollOffset(std::numeric_limits<float>::max(),
-                                         std::numeric_limits<float>::max())) {}
+      proximity_range_(gfx::Vector2dF(std::numeric_limits<float>::max(),
+                                      std::numeric_limits<float>::max())) {}
 
 SnapContainerData::SnapContainerData(ScrollSnapType type,
                                      const gfx::RectF& rect,
-                                     const gfx::ScrollOffset& max)
+                                     const gfx::Vector2dF& max)
     : scroll_snap_type_(type),
       rect_(rect),
       max_position_(max),
-      proximity_range_(gfx::ScrollOffset(std::numeric_limits<float>::max(),
-                                         std::numeric_limits<float>::max())) {}
+      proximity_range_(gfx::Vector2dF(std::numeric_limits<float>::max(),
+                                      std::numeric_limits<float>::max())) {}
 
 SnapContainerData::SnapContainerData(const SnapContainerData& other) = default;
 
@@ -143,14 +143,14 @@
 
 bool SnapContainerData::FindSnapPosition(
     const SnapSelectionStrategy& strategy,
-    gfx::ScrollOffset* snap_position,
+    gfx::Vector2dF* snap_position,
     TargetSnapAreaElementIds* target_element_ids,
     const ElementId& active_element_id) const {
   *target_element_ids = TargetSnapAreaElementIds();
   if (scroll_snap_type_.is_none)
     return false;
 
-  gfx::ScrollOffset base_position = strategy.base_position();
+  gfx::Vector2dF base_position = strategy.base_position();
   SnapAxis axis = scroll_snap_type_.axis;
   bool should_snap_on_x = strategy.ShouldSnapOnX() &&
                           (axis == SnapAxis::kX || axis == SnapAxis::kBoth);
@@ -262,7 +262,7 @@
 // of the corridors.
 bool SnapContainerData::FindSnapPositionForMutualSnap(
     const SnapSelectionStrategy& strategy,
-    gfx::ScrollOffset* snap_position) const {
+    gfx::Vector2dF* snap_position) const {
   DCHECK(strategy.ShouldSnapOnX() && strategy.ShouldSnapOnY());
   bool found = false;
   gfx::Vector2dF smallest_distance(std::numeric_limits<float>::max(),
diff --git a/cc/input/scroll_snap_data.h b/cc/input/scroll_snap_data.h
index a0d9f7e..03554295 100644
--- a/cc/input/scroll_snap_data.h
+++ b/cc/input/scroll_snap_data.h
@@ -12,7 +12,7 @@
 #include "cc/paint/element_id.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/geometry/rect_f.h"
-#include "ui/gfx/geometry/scroll_offset.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 #include "ui/gfx/range/range_f.h"
 
 namespace cc {
@@ -198,7 +198,7 @@
   explicit SnapContainerData(ScrollSnapType type);
   SnapContainerData(ScrollSnapType type,
                     const gfx::RectF& rect,
-                    const gfx::ScrollOffset& max);
+                    const gfx::Vector2dF& max);
   SnapContainerData(const SnapContainerData& other);
   SnapContainerData(SnapContainerData&& other);
   ~SnapContainerData();
@@ -221,7 +221,7 @@
 
   // Returns true if a snap position was found.
   bool FindSnapPosition(const SnapSelectionStrategy& strategy,
-                        gfx::ScrollOffset* snap_position,
+                        gfx::Vector2dF* snap_position,
                         TargetSnapAreaElementIds* target_element_ids,
                         const ElementId& active_element_id = ElementId()) const;
 
@@ -239,15 +239,13 @@
   void set_rect(const gfx::RectF& rect) { rect_ = rect; }
   gfx::RectF rect() const { return rect_; }
 
-  void set_max_position(gfx::ScrollOffset position) {
-    max_position_ = position;
-  }
-  gfx::ScrollOffset max_position() const { return max_position_; }
+  void set_max_position(gfx::Vector2dF position) { max_position_ = position; }
+  gfx::Vector2dF max_position() const { return max_position_; }
 
-  void set_proximity_range(const gfx::ScrollOffset& range) {
+  void set_proximity_range(const gfx::Vector2dF& range) {
     proximity_range_ = range;
   }
-  gfx::ScrollOffset proximity_range() const { return proximity_range_; }
+  gfx::Vector2dF proximity_range() const { return proximity_range_; }
 
  private:
   // Finds the best SnapArea candidate that's optimal for the given selection
@@ -280,7 +278,7 @@
       const ElementId& active_element_id) const;
 
   bool FindSnapPositionForMutualSnap(const SnapSelectionStrategy& strategy,
-                                     gfx::ScrollOffset* snap_position) const;
+                                     gfx::Vector2dF* snap_position) const;
 
   // Finds the snap area associated with the target snap area element id for the
   // given axis.
@@ -313,11 +311,11 @@
 
   // The maximal scroll position of the SnapContainer, in the same coordinate
   // with blink's scroll position.
-  gfx::ScrollOffset max_position_;
+  gfx::Vector2dF max_position_;
 
   // A valid snap position should be within the |proximity_range_| of the
   // current offset on the snapping axis.
-  gfx::ScrollOffset proximity_range_;
+  gfx::Vector2dF proximity_range_;
 
   // The SnapAreaData for the snap areas in this snap container. When a scroll
   // happens, we iterate through the snap_area_list to find the best snap
diff --git a/cc/input/scroll_snap_data_unittest.cc b/cc/input/scroll_snap_data_unittest.cc
index 503470c..7fa0976 100644
--- a/cc/input/scroll_snap_data_unittest.cc
+++ b/cc/input/scroll_snap_data_unittest.cc
@@ -18,14 +18,14 @@
 TEST_F(ScrollSnapDataTest, StartAlignmentCalculation) {
   SnapContainerData container(
       ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
-      gfx::RectF(10, 10, 200, 300), gfx::ScrollOffset(600, 800));
+      gfx::RectF(10, 10, 200, 300), gfx::Vector2dF(600, 800));
   SnapAreaData area(ScrollSnapAlign(SnapAlignment::kStart),
                     gfx::RectF(100, 150, 100, 100), false, ElementId(10));
   container.AddSnapAreaData(area);
 
-  gfx::ScrollOffset snap_position;
+  gfx::Vector2dF snap_position;
   std::unique_ptr<SnapSelectionStrategy> strategy =
-      SnapSelectionStrategy::CreateForEndPosition(gfx::ScrollOffset(0, 0), true,
+      SnapSelectionStrategy::CreateForEndPosition(gfx::Vector2dF(0, 0), true,
                                                   true);
 
   EXPECT_TRUE(
@@ -39,14 +39,14 @@
 TEST_F(ScrollSnapDataTest, CenterAlignmentCalculation) {
   SnapContainerData container(
       ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
-      gfx::RectF(10, 10, 200, 300), gfx::ScrollOffset(600, 800));
+      gfx::RectF(10, 10, 200, 300), gfx::Vector2dF(600, 800));
   SnapAreaData area(ScrollSnapAlign(SnapAlignment::kCenter),
                     gfx::RectF(100, 150, 100, 100), false, ElementId(10));
   container.AddSnapAreaData(area);
 
-  gfx::ScrollOffset snap_position;
+  gfx::Vector2dF snap_position;
   std::unique_ptr<SnapSelectionStrategy> strategy =
-      SnapSelectionStrategy::CreateForEndPosition(gfx::ScrollOffset(0, 0), true,
+      SnapSelectionStrategy::CreateForEndPosition(gfx::Vector2dF(0, 0), true,
                                                   true);
   EXPECT_TRUE(
       container.FindSnapPosition(*strategy, &snap_position, &target_elements));
@@ -59,14 +59,14 @@
 TEST_F(ScrollSnapDataTest, EndAlignmentCalculation) {
   SnapContainerData container(
       ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
-      gfx::RectF(10, 10, 200, 200), gfx::ScrollOffset(600, 800));
+      gfx::RectF(10, 10, 200, 200), gfx::Vector2dF(600, 800));
   SnapAreaData area(ScrollSnapAlign(SnapAlignment::kEnd),
                     gfx::RectF(150, 200, 100, 100), false, ElementId(10));
   container.AddSnapAreaData(area);
 
-  gfx::ScrollOffset snap_position;
+  gfx::Vector2dF snap_position;
   std::unique_ptr<SnapSelectionStrategy> strategy =
-      SnapSelectionStrategy::CreateForEndPosition(gfx::ScrollOffset(0, 0), true,
+      SnapSelectionStrategy::CreateForEndPosition(gfx::Vector2dF(0, 0), true,
                                                   true);
   EXPECT_TRUE(
       container.FindSnapPosition(*strategy, &snap_position, &target_elements));
@@ -79,15 +79,15 @@
 TEST_F(ScrollSnapDataTest, UnreachableSnapPositionCalculation) {
   SnapContainerData container(
       ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
-      gfx::RectF(0, 0, 200, 200), gfx::ScrollOffset(100, 100));
+      gfx::RectF(0, 0, 200, 200), gfx::Vector2dF(100, 100));
   SnapAreaData area(ScrollSnapAlign(SnapAlignment::kEnd, SnapAlignment::kStart),
                     gfx::RectF(200, 0, 100, 100), false, ElementId(10));
   container.AddSnapAreaData(area);
 
-  gfx::ScrollOffset snap_position;
+  gfx::Vector2dF snap_position;
   std::unique_ptr<SnapSelectionStrategy> strategy =
-      SnapSelectionStrategy::CreateForEndPosition(gfx::ScrollOffset(50, 50),
-                                                  true, true);
+      SnapSelectionStrategy::CreateForEndPosition(gfx::Vector2dF(50, 50), true,
+                                                  true);
   EXPECT_TRUE(
       container.FindSnapPosition(*strategy, &snap_position, &target_elements));
   // Aligning to start on x would lead the scroll offset larger than max, and
@@ -102,7 +102,7 @@
 TEST_F(ScrollSnapDataTest, FindsClosestSnapPositionIndependently) {
   SnapContainerData container(
       ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
-      gfx::RectF(0, 0, 200, 200), gfx::ScrollOffset(600, 800));
+      gfx::RectF(0, 0, 200, 200), gfx::Vector2dF(600, 800));
   SnapAreaData snap_x_only(
       ScrollSnapAlign(SnapAlignment::kNone, SnapAlignment::kStart),
       gfx::RectF(80, 0, 150, 150), false, ElementId(10));
@@ -116,9 +116,9 @@
   container.AddSnapAreaData(snap_y_only);
   container.AddSnapAreaData(snap_on_both);
 
-  gfx::ScrollOffset snap_position;
+  gfx::Vector2dF snap_position;
   std::unique_ptr<SnapSelectionStrategy> strategy =
-      SnapSelectionStrategy::CreateForEndPosition(gfx::ScrollOffset(100, 100),
+      SnapSelectionStrategy::CreateForEndPosition(gfx::Vector2dF(100, 100),
                                                   true, true);
   EXPECT_TRUE(
       container.FindSnapPosition(*strategy, &snap_position, &target_elements));
@@ -131,7 +131,7 @@
 TEST_F(ScrollSnapDataTest, FindsClosestSnapPositionOnAxisValueBoth) {
   SnapContainerData container(
       ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
-      gfx::RectF(0, 0, 200, 200), gfx::ScrollOffset(600, 800));
+      gfx::RectF(0, 0, 200, 200), gfx::Vector2dF(600, 800));
   SnapAreaData snap_x_only(
       ScrollSnapAlign(SnapAlignment::kNone, SnapAlignment::kStart),
       gfx::RectF(80, 0, 150, 150), false, ElementId(10));
@@ -145,10 +145,10 @@
   container.AddSnapAreaData(snap_x_only);
   container.AddSnapAreaData(snap_y_only);
   container.AddSnapAreaData(snap_on_both);
-  gfx::ScrollOffset snap_position;
+  gfx::Vector2dF snap_position;
   std::unique_ptr<SnapSelectionStrategy> strategy =
-      SnapSelectionStrategy::CreateForEndPosition(gfx::ScrollOffset(40, 120),
-                                                  true, true);
+      SnapSelectionStrategy::CreateForEndPosition(gfx::Vector2dF(40, 120), true,
+                                                  true);
   EXPECT_TRUE(
       container.FindSnapPosition(*strategy, &snap_position, &target_elements));
   EXPECT_EQ(50, snap_position.x());
@@ -160,7 +160,7 @@
 TEST_F(ScrollSnapDataTest, DoesNotSnapOnNonScrolledAxis) {
   SnapContainerData container(
       ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
-      gfx::RectF(0, 0, 200, 200), gfx::ScrollOffset(600, 800));
+      gfx::RectF(0, 0, 200, 200), gfx::Vector2dF(600, 800));
   SnapAreaData snap_x_only(
       ScrollSnapAlign(SnapAlignment::kNone, SnapAlignment::kStart),
       gfx::RectF(80, 0, 150, 150), false, ElementId(10));
@@ -170,9 +170,9 @@
   container.AddSnapAreaData(snap_x_only);
   container.AddSnapAreaData(snap_y_only);
 
-  gfx::ScrollOffset snap_position;
+  gfx::Vector2dF snap_position;
   std::unique_ptr<SnapSelectionStrategy> strategy =
-      SnapSelectionStrategy::CreateForEndPosition(gfx::ScrollOffset(100, 100),
+      SnapSelectionStrategy::CreateForEndPosition(gfx::Vector2dF(100, 100),
                                                   true, false);
   EXPECT_TRUE(
       container.FindSnapPosition(*strategy, &snap_position, &target_elements));
@@ -185,7 +185,7 @@
 TEST_F(ScrollSnapDataTest, DoesNotSnapOnNonVisibleAreas) {
   SnapContainerData container(
       ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
-      gfx::RectF(0, 0, 200, 200), gfx::ScrollOffset(600, 800));
+      gfx::RectF(0, 0, 200, 200), gfx::Vector2dF(600, 800));
   SnapAreaData snap_x_only(
       ScrollSnapAlign(SnapAlignment::kNone, SnapAlignment::kStart),
       gfx::RectF(300, 400, 100, 100), false, ElementId(10));
@@ -195,9 +195,9 @@
 
   container.AddSnapAreaData(snap_x_only);
   container.AddSnapAreaData(snap_y_only);
-  gfx::ScrollOffset snap_position;
+  gfx::Vector2dF snap_position;
   std::unique_ptr<SnapSelectionStrategy> strategy =
-      SnapSelectionStrategy::CreateForEndPosition(gfx::ScrollOffset(0, 0), true,
+      SnapSelectionStrategy::CreateForEndPosition(gfx::Vector2dF(0, 0), true,
                                                   true);
   EXPECT_FALSE(
       container.FindSnapPosition(*strategy, &snap_position, &target_elements));
@@ -207,7 +207,7 @@
 TEST_F(ScrollSnapDataTest, SnapOnClosestAxisFirstIfVisibilityConflicts) {
   SnapContainerData container(
       ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
-      gfx::RectF(0, 0, 200, 200), gfx::ScrollOffset(600, 800));
+      gfx::RectF(0, 0, 200, 200), gfx::Vector2dF(600, 800));
 
   // Both the areas are currently visible.
   // However, if we snap to them on x and y independently, none is visible after
@@ -227,9 +227,9 @@
   container.AddSnapAreaData(snap_y1);
   container.AddSnapAreaData(snap_y2);
 
-  gfx::ScrollOffset snap_position;
+  gfx::Vector2dF snap_position;
   std::unique_ptr<SnapSelectionStrategy> strategy =
-      SnapSelectionStrategy::CreateForEndPosition(gfx::ScrollOffset(0, 0), true,
+      SnapSelectionStrategy::CreateForEndPosition(gfx::Vector2dF(0, 0), true,
                                                   true);
   EXPECT_TRUE(
       container.FindSnapPosition(*strategy, &snap_position, &target_elements));
@@ -242,16 +242,16 @@
 TEST_F(ScrollSnapDataTest, DoesNotSnapToPositionsOutsideProximityRange) {
   SnapContainerData container(
       ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
-      gfx::RectF(0, 0, 200, 200), gfx::ScrollOffset(600, 800));
-  container.set_proximity_range(gfx::ScrollOffset(50, 50));
+      gfx::RectF(0, 0, 200, 200), gfx::Vector2dF(600, 800));
+  container.set_proximity_range(gfx::Vector2dF(50, 50));
 
   SnapAreaData area(ScrollSnapAlign(SnapAlignment::kStart),
                     gfx::RectF(80, 160, 100, 100), false, ElementId(10));
   container.AddSnapAreaData(area);
 
-  gfx::ScrollOffset snap_position;
+  gfx::Vector2dF snap_position;
   std::unique_ptr<SnapSelectionStrategy> strategy =
-      SnapSelectionStrategy::CreateForEndPosition(gfx::ScrollOffset(100, 100),
+      SnapSelectionStrategy::CreateForEndPosition(gfx::Vector2dF(100, 100),
                                                   true, true);
   EXPECT_TRUE(
       container.FindSnapPosition(*strategy, &snap_position, &target_elements));
@@ -268,15 +268,15 @@
 TEST_F(ScrollSnapDataTest, MandatoryReturnsToCurrentIfNoValidAreaForward) {
   SnapContainerData container(
       ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
-      gfx::RectF(0, 0, 200, 200), gfx::ScrollOffset(2000, 2000));
+      gfx::RectF(0, 0, 200, 200), gfx::Vector2dF(2000, 2000));
   SnapAreaData area(ScrollSnapAlign(SnapAlignment::kStart),
                     gfx::RectF(600, 0, 100, 100), false, ElementId(10));
   container.AddSnapAreaData(area);
-  gfx::ScrollOffset snap_position;
+  gfx::Vector2dF snap_position;
 
   std::unique_ptr<SnapSelectionStrategy> direction_strategy =
       SnapSelectionStrategy::CreateForDirection(
-          gfx::ScrollOffset(600, 0), gfx::ScrollOffset(5, 0),
+          gfx::Vector2dF(600, 0), gfx::Vector2dF(5, 0),
           false /* use_fractional_deltas */);
   EXPECT_TRUE(container.FindSnapPosition(*direction_strategy, &snap_position,
                                          &target_elements));
@@ -290,7 +290,7 @@
 
   std::unique_ptr<SnapSelectionStrategy> end_direction_strategy =
       SnapSelectionStrategy::CreateForEndAndDirection(
-          gfx::ScrollOffset(600, 0), gfx::ScrollOffset(15, 15),
+          gfx::Vector2dF(600, 0), gfx::Vector2dF(15, 15),
           false /* use_fractional_deltas */);
   EXPECT_TRUE(container.FindSnapPosition(*end_direction_strategy,
                                          &snap_position, &target_elements));
@@ -316,15 +316,15 @@
 TEST_F(ScrollSnapDataTest, MandatorySnapsBackwardIfNoValidAreaForward) {
   SnapContainerData container(
       ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
-      gfx::RectF(0, 0, 200, 200), gfx::ScrollOffset(2000, 2000));
+      gfx::RectF(0, 0, 200, 200), gfx::Vector2dF(2000, 2000));
   SnapAreaData area(ScrollSnapAlign(SnapAlignment::kStart),
                     gfx::RectF(600, 0, 100, 100), false, ElementId(10));
   container.AddSnapAreaData(area);
-  gfx::ScrollOffset snap_position;
+  gfx::Vector2dF snap_position;
 
   std::unique_ptr<SnapSelectionStrategy> direction_strategy =
       SnapSelectionStrategy::CreateForDirection(
-          gfx::ScrollOffset(650, 0), gfx::ScrollOffset(5, 0),
+          gfx::Vector2dF(650, 0), gfx::Vector2dF(5, 0),
           false /* use_fractional_deltas */);
   EXPECT_TRUE(container.FindSnapPosition(*direction_strategy, &snap_position,
                                          &target_elements));
@@ -338,7 +338,7 @@
 
   std::unique_ptr<SnapSelectionStrategy> end_direction_strategy =
       SnapSelectionStrategy::CreateForEndAndDirection(
-          gfx::ScrollOffset(650, 10), gfx::ScrollOffset(15, 15),
+          gfx::Vector2dF(650, 10), gfx::Vector2dF(15, 15),
           false /* use_fractional_deltas */);
   EXPECT_TRUE(container.FindSnapPosition(*end_direction_strategy,
                                          &snap_position, &target_elements));
@@ -364,7 +364,7 @@
 TEST_F(ScrollSnapDataTest, ShouldNotPassScrollSnapStopAlwaysElement) {
   SnapContainerData container(
       ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
-      gfx::RectF(0, 0, 200, 200), gfx::ScrollOffset(2000, 2000));
+      gfx::RectF(0, 0, 200, 200), gfx::Vector2dF(2000, 2000));
   SnapAreaData must_snap_1(ScrollSnapAlign(SnapAlignment::kStart),
                            gfx::RectF(200, 0, 100, 100), true, ElementId(10));
   SnapAreaData must_snap_2(ScrollSnapAlign(SnapAlignment::kStart),
@@ -375,11 +375,11 @@
   container.AddSnapAreaData(must_snap_1);
   container.AddSnapAreaData(must_snap_2);
   container.AddSnapAreaData(closer_to_target);
-  gfx::ScrollOffset snap_position;
+  gfx::Vector2dF snap_position;
 
   std::unique_ptr<SnapSelectionStrategy> end_direction_strategy =
       SnapSelectionStrategy::CreateForEndAndDirection(
-          gfx::ScrollOffset(0, 0), gfx::ScrollOffset(600, 0),
+          gfx::Vector2dF(0, 0), gfx::Vector2dF(600, 0),
           false /* use_fractional_deltas */);
 
   EXPECT_TRUE(container.FindSnapPosition(*end_direction_strategy,
@@ -397,7 +397,7 @@
 TEST_F(ScrollSnapDataTest, SnapStopAlwaysOverridesCoveringSnapArea) {
   SnapContainerData container(
       ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
-      gfx::RectF(0, 0, 200, 200), gfx::ScrollOffset(600, 800));
+      gfx::RectF(0, 0, 200, 200), gfx::Vector2dF(600, 800));
   SnapAreaData stop_area(ScrollSnapAlign(SnapAlignment::kStart),
                          gfx::RectF(100, 0, 100, 100), true, ElementId(10));
   SnapAreaData covering_area(ScrollSnapAlign(SnapAlignment::kStart),
@@ -406,10 +406,10 @@
   container.AddSnapAreaData(stop_area);
   container.AddSnapAreaData(covering_area);
 
-  gfx::ScrollOffset snap_position;
+  gfx::Vector2dF snap_position;
   std::unique_ptr<SnapSelectionStrategy> strategy =
       SnapSelectionStrategy::CreateForEndAndDirection(
-          gfx::ScrollOffset(0, 0), gfx::ScrollOffset(300, 0),
+          gfx::Vector2dF(0, 0), gfx::Vector2dF(300, 0),
           false /* use_fractional_deltas */);
 
   // The fling is from (0, 0) to (300, 0), and the destination would make
@@ -427,15 +427,15 @@
 TEST_F(ScrollSnapDataTest, SnapStopAlwaysInReverseDirection) {
   SnapContainerData container(
       ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
-      gfx::RectF(0, 0, 200, 300), gfx::ScrollOffset(600, 800));
+      gfx::RectF(0, 0, 200, 300), gfx::Vector2dF(600, 800));
   SnapAreaData stop_area(ScrollSnapAlign(SnapAlignment::kStart),
                          gfx::RectF(100, 0, 100, 100), true, ElementId(10));
   container.AddSnapAreaData(stop_area);
 
-  gfx::ScrollOffset snap_position;
+  gfx::Vector2dF snap_position;
   std::unique_ptr<SnapSelectionStrategy> strategy =
       SnapSelectionStrategy::CreateForEndAndDirection(
-          gfx::ScrollOffset(150, 0), gfx::ScrollOffset(200, 0),
+          gfx::Vector2dF(150, 0), gfx::Vector2dF(200, 0),
           false /* use_fractional_deltas */);
 
   // The fling is from (150, 0) to (350, 0), but the snap position is in the
@@ -452,7 +452,7 @@
 TEST_F(ScrollSnapDataTest, SnapStopAlwaysNotInterferingWithDirectionStrategy) {
   SnapContainerData container(
       ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
-      gfx::RectF(0, 0, 200, 300), gfx::ScrollOffset(600, 800));
+      gfx::RectF(0, 0, 200, 300), gfx::Vector2dF(600, 800));
   SnapAreaData closer_area(ScrollSnapAlign(SnapAlignment::kStart),
                            gfx::RectF(100, 0, 1, 1), false, ElementId(10));
   SnapAreaData stop_area(ScrollSnapAlign(SnapAlignment::kStart),
@@ -462,12 +462,12 @@
 
   // The DirectionStrategy should always choose the first snap position
   // regardless its scroll-snap-stop value.
-  gfx::ScrollOffset snap_position;
+  gfx::Vector2dF snap_position;
   std::unique_ptr<SnapSelectionStrategy> direction_strategy =
       SnapSelectionStrategy::CreateForDirection(
-          gfx::ScrollOffset(90, 0), gfx::ScrollOffset(50, 0),
+          gfx::Vector2dF(90, 0), gfx::Vector2dF(50, 0),
           false /* use_fractional_deltas */);
-  snap_position = gfx::ScrollOffset();
+  snap_position = gfx::Vector2dF();
   EXPECT_TRUE(container.FindSnapPosition(*direction_strategy, &snap_position,
                                          &target_elements));
   EXPECT_EQ(100, snap_position.x());
@@ -479,7 +479,7 @@
 TEST_F(ScrollSnapDataTest, SnapToOneTargetElementOnX) {
   SnapContainerData container(
       ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
-      gfx::RectF(0, 0, 200, 300), gfx::ScrollOffset(600, 800));
+      gfx::RectF(0, 0, 200, 300), gfx::Vector2dF(600, 800));
 
   SnapAreaData closer_area_x(ScrollSnapAlign(SnapAlignment::kStart),
                              gfx::RectF(100, 0, 1, 1), false, ElementId(10));
@@ -498,9 +498,9 @@
   // should snap to the target for the x-axis. However, since the target is not
   // set for the y-axis, the target on the y-axis should be closer_area_y.
   std::unique_ptr<SnapSelectionStrategy> target_element_strategy =
-      SnapSelectionStrategy::CreateForTargetElement(gfx::ScrollOffset(0, 0));
+      SnapSelectionStrategy::CreateForTargetElement(gfx::Vector2dF(0, 0));
 
-  gfx::ScrollOffset snap_position = gfx::ScrollOffset();
+  gfx::Vector2dF snap_position = gfx::Vector2dF();
   EXPECT_TRUE(container.FindSnapPosition(*target_element_strategy,
                                          &snap_position, &target_elements));
 
@@ -513,7 +513,7 @@
 TEST_F(ScrollSnapDataTest, SnapToOneTargetElementOnY) {
   SnapContainerData container(
       ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
-      gfx::RectF(0, 0, 200, 300), gfx::ScrollOffset(600, 800));
+      gfx::RectF(0, 0, 200, 300), gfx::Vector2dF(600, 800));
 
   SnapAreaData closer_area_y(ScrollSnapAlign(SnapAlignment::kStart),
                              gfx::RectF(0, 100, 1, 1), false, ElementId(10));
@@ -532,9 +532,9 @@
   // should snap to the target for the y-axis. However, since the target is not
   // set for the x-axis, the target on the x-axis should be closer_area_x.
   std::unique_ptr<SnapSelectionStrategy> target_element_strategy =
-      SnapSelectionStrategy::CreateForTargetElement(gfx::ScrollOffset(0, 0));
+      SnapSelectionStrategy::CreateForTargetElement(gfx::Vector2dF(0, 0));
 
-  gfx::ScrollOffset snap_position = gfx::ScrollOffset();
+  gfx::Vector2dF snap_position = gfx::Vector2dF();
   EXPECT_TRUE(container.FindSnapPosition(*target_element_strategy,
                                          &snap_position, &target_elements));
 
@@ -547,7 +547,7 @@
 TEST_F(ScrollSnapDataTest, SnapToTwoTargetElementsMutualVisible) {
   SnapContainerData container(
       ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
-      gfx::RectF(0, 0, 300, 300), gfx::ScrollOffset(600, 800));
+      gfx::RectF(0, 0, 300, 300), gfx::Vector2dF(600, 800));
 
   SnapAreaData target_area_x(ScrollSnapAlign(SnapAlignment::kStart),
                              gfx::RectF(100, 200, 1, 1), false, ElementId(10));
@@ -565,9 +565,9 @@
   // The container should snap to both target areas since they are mutually
   // visible, while ignoring the snap area that is closest to the scroll offset.
   std::unique_ptr<SnapSelectionStrategy> target_element_strategy =
-      SnapSelectionStrategy::CreateForTargetElement(gfx::ScrollOffset(0, 0));
+      SnapSelectionStrategy::CreateForTargetElement(gfx::Vector2dF(0, 0));
 
-  gfx::ScrollOffset snap_position = gfx::ScrollOffset();
+  gfx::Vector2dF snap_position = gfx::Vector2dF();
   EXPECT_TRUE(container.FindSnapPosition(*target_element_strategy,
                                          &snap_position, &target_elements));
 
@@ -580,7 +580,7 @@
 TEST_F(ScrollSnapDataTest, SnapToTwoTargetElementsNotMutualVisible) {
   SnapContainerData container(
       ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
-      gfx::RectF(0, 0, 300, 300), gfx::ScrollOffset(600, 800));
+      gfx::RectF(0, 0, 300, 300), gfx::Vector2dF(600, 800));
 
   SnapAreaData target_area_x(ScrollSnapAlign(SnapAlignment::kStart),
                              gfx::RectF(100, 500, 1, 1), false, ElementId(10));
@@ -600,9 +600,9 @@
   // closer to the scroll offset, and then snap to the closest mutually visible
   // snap area on the other axis.
   std::unique_ptr<SnapSelectionStrategy> target_element_strategy =
-      SnapSelectionStrategy::CreateForTargetElement(gfx::ScrollOffset(10, 0));
+      SnapSelectionStrategy::CreateForTargetElement(gfx::Vector2dF(10, 0));
 
-  gfx::ScrollOffset snap_position = gfx::ScrollOffset();
+  gfx::Vector2dF snap_position = gfx::Vector2dF();
   EXPECT_TRUE(container.FindSnapPosition(*target_element_strategy,
                                          &snap_position, &target_elements));
 
@@ -615,7 +615,7 @@
 TEST_F(ScrollSnapDataTest, SnapToFocusedElementHorizontal) {
   SnapContainerData container(
       ScrollSnapType(false, SnapAxis::kX, SnapStrictness::kMandatory),
-      gfx::RectF(0, 0, 300, 300), gfx::ScrollOffset(600, 800));
+      gfx::RectF(0, 0, 300, 300), gfx::Vector2dF(600, 800));
   SnapAreaData snapped_area(ScrollSnapAlign(SnapAlignment::kStart),
                             gfx::RectF(0, 0, 100, 100), false, ElementId(10));
   SnapAreaData focused_area(ScrollSnapAlign(SnapAlignment::kStart),
@@ -624,11 +624,11 @@
   container.AddSnapAreaData(focused_area);
 
   // Initially both snap areas are horizontally aligned with the snap position.
-  gfx::ScrollOffset origin(0, 0);
+  gfx::Vector2dF origin(0, 0);
   std::unique_ptr<SnapSelectionStrategy> strategy =
       SnapSelectionStrategy::CreateForTargetElement(origin);
 
-  gfx::ScrollOffset snap_position = gfx::ScrollOffset();
+  gfx::Vector2dF snap_position = gfx::Vector2dF();
   EXPECT_TRUE(container.FindSnapPosition(*strategy, &snap_position,
                                          &target_elements, ElementId(20)));
   EXPECT_EQ(0, snap_position.x());
@@ -647,7 +647,7 @@
 TEST_F(ScrollSnapDataTest, SnapToFocusedElementVertical) {
   SnapContainerData container(
       ScrollSnapType(false, SnapAxis::kY, SnapStrictness::kMandatory),
-      gfx::RectF(0, 0, 300, 300), gfx::ScrollOffset(600, 800));
+      gfx::RectF(0, 0, 300, 300), gfx::Vector2dF(600, 800));
   SnapAreaData snapped_area(ScrollSnapAlign(SnapAlignment::kStart),
                             gfx::RectF(0, 0, 100, 100), false, ElementId(10));
   SnapAreaData focused_area(ScrollSnapAlign(SnapAlignment::kStart),
@@ -656,11 +656,11 @@
   container.AddSnapAreaData(focused_area);
 
   // Initially both snap areas are vertically aligned with the snap position.
-  gfx::ScrollOffset origin(0, 0);
+  gfx::Vector2dF origin(0, 0);
   std::unique_ptr<SnapSelectionStrategy> strategy =
       SnapSelectionStrategy::CreateForTargetElement(origin);
 
-  gfx::ScrollOffset snap_position = gfx::ScrollOffset();
+  gfx::Vector2dF snap_position = gfx::Vector2dF();
   EXPECT_TRUE(container.FindSnapPosition(*strategy, &snap_position,
                                          &target_elements, ElementId(20)));
   EXPECT_EQ(0, snap_position.y());
@@ -679,7 +679,7 @@
 TEST_F(ScrollSnapDataTest, SnapToFocusedElementBoth) {
   SnapContainerData container(
       ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
-      gfx::RectF(0, 0, 300, 300), gfx::ScrollOffset(600, 800));
+      gfx::RectF(0, 0, 300, 300), gfx::Vector2dF(600, 800));
   SnapAreaData snapped_area(ScrollSnapAlign(SnapAlignment::kStart),
                             gfx::RectF(0, 0, 100, 100), false, ElementId(10));
   SnapAreaData focused_area(ScrollSnapAlign(SnapAlignment::kStart),
@@ -688,11 +688,11 @@
   container.AddSnapAreaData(focused_area);
 
   // Initially both snap areas are coincident with the snap position.
-  gfx::ScrollOffset origin(0, 0);
+  gfx::Vector2dF origin(0, 0);
   std::unique_ptr<SnapSelectionStrategy> strategy =
       SnapSelectionStrategy::CreateForTargetElement(origin);
 
-  gfx::ScrollOffset snap_position = gfx::ScrollOffset();
+  gfx::Vector2dF snap_position = gfx::Vector2dF();
   EXPECT_TRUE(container.FindSnapPosition(*strategy, &snap_position,
                                          &target_elements, ElementId(20)));
   EXPECT_EQ(0, snap_position.x());
diff --git a/cc/input/scroll_state.cc b/cc/input/scroll_state.cc
index 7e14c22c8..1f55af4 100644
--- a/cc/input/scroll_state.cc
+++ b/cc/input/scroll_state.cc
@@ -24,11 +24,11 @@
     data_.delta_consumed_for_scroll_sequence = true;
 }
 
-gfx::ScrollOffset ScrollState::DeltaOrHint() const {
+gfx::Vector2dF ScrollState::DeltaOrHint() const {
   if (is_beginning())
-    return gfx::ScrollOffset(delta_x_hint(), delta_y_hint());
+    return gfx::Vector2dF(delta_x_hint(), delta_y_hint());
 
-  return gfx::ScrollOffset(delta_x(), delta_y());
+  return gfx::Vector2dF(delta_x(), delta_y());
 }
 
 }  // namespace cc
diff --git a/cc/input/scroll_state.h b/cc/input/scroll_state.h
index 1f27e749..9ac9020 100644
--- a/cc/input/scroll_state.h
+++ b/cc/input/scroll_state.h
@@ -8,8 +8,8 @@
 #include "cc/cc_export.h"
 #include "cc/input/scroll_state_data.h"
 #include "ui/gfx/geometry/point.h"
-#include "ui/gfx/geometry/scroll_offset.h"
 #include "ui/gfx/geometry/vector2d.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 
 namespace cc {
 
@@ -89,7 +89,7 @@
 
   // Returns a the delta hints if this is a scroll begin or the real delta if
   // it's a scroll update
-  gfx::ScrollOffset DeltaOrHint() const;
+  gfx::Vector2dF DeltaOrHint() const;
 
   ElementId target_element_id() const {
     return data_.current_native_scrolling_element();
diff --git a/cc/input/scrollbar_controller.cc b/cc/input/scrollbar_controller.cc
index b6ff6bf..bd18c87 100644
--- a/cc/input/scrollbar_controller.cc
+++ b/cc/input/scrollbar_controller.cc
@@ -322,8 +322,8 @@
     scroll_result.scroll_units = ui::ScrollGranularity::kScrollByPrecisePixel;
     scroll_result.scroll_offset =
         scrollbar->orientation() == ScrollbarOrientation::VERTICAL
-            ? gfx::ScrollOffset(0, -delta)
-            : gfx::ScrollOffset(-delta, 0);
+            ? gfx::Vector2dF(0, -delta)
+            : gfx::Vector2dF(-delta, 0);
     drag_processed_for_current_frame_ = true;
     return scroll_result;
   }
@@ -359,12 +359,12 @@
   delta -= drag_state_->scroller_displacement;
 
   // If scroll_offset can't be consumed, there's no point in continuing on.
-  const gfx::ScrollOffset scroll_offset(scrollbar->orientation() ==
-                                                ScrollbarOrientation::VERTICAL
-                                            ? gfx::ScrollOffset(0, delta)
-                                            : gfx::ScrollOffset(delta, 0));
+  const gfx::Vector2dF scroll_offset(scrollbar->orientation() ==
+                                             ScrollbarOrientation::VERTICAL
+                                         ? gfx::Vector2dF(0, delta)
+                                         : gfx::Vector2dF(delta, 0));
   const gfx::Vector2dF clamped_scroll_offset =
-      ComputeClampedDelta(*target_node, ScrollOffsetToVector2dF(scroll_offset));
+      ComputeClampedDelta(*target_node, scroll_offset);
 
   if (clamped_scroll_offset.IsZero())
     return scroll_result;
@@ -372,7 +372,7 @@
   // Thumb drags have more granularity and are purely dependent on the pointer
   // movement. Hence we use kPrecisePixel when dragging the thumb.
   scroll_result.scroll_units = ui::ScrollGranularity::kScrollByPrecisePixel;
-  scroll_result.scroll_offset = gfx::ScrollOffset(clamped_scroll_offset);
+  scroll_result.scroll_offset = clamped_scroll_offset;
   drag_processed_for_current_frame_ = true;
 
   return scroll_result;
@@ -546,7 +546,7 @@
 
 // Helper to calculate the autoscroll velocity.
 float ScrollbarController::InitialDeltaToAutoscrollVelocity(
-    gfx::ScrollOffset scroll_offset) const {
+    gfx::Vector2dF scroll_offset) const {
   DCHECK(captured_scrollbar_metadata_.has_value());
   const float scroll_delta =
       ScrollbarLayer()->orientation() == ScrollbarOrientation::VERTICAL
@@ -579,7 +579,7 @@
   layer_tree_host_impl_->active_tree()->UpdateScrollbarGeometries();
   float scroll_layer_length = scrollbar->scroll_layer_length();
 
-  gfx::ScrollOffset current_offset =
+  gfx::Vector2dF current_offset =
       scroll_tree.current_scroll_offset(scroll_node->element_id);
 
   // Determine the max offset for the scroll based on the scrolling direction.
@@ -789,7 +789,7 @@
 
 // Determines the scroll offsets based on the ScrollbarPart and the scrollbar
 // orientation.
-gfx::ScrollOffset ScrollbarController::GetScrollOffsetForScrollbarPart(
+gfx::Vector2dF ScrollbarController::GetScrollOffsetForScrollbarPart(
     const ScrollbarPart scrollbar_part,
     const bool jump_key_modifier) const {
   const ScrollbarLayerImplBase* scrollbar = ScrollbarLayer();
@@ -800,23 +800,23 @@
   // will be interpreted.
   if (scrollbar_part == ScrollbarPart::BACK_BUTTON) {
     return scrollbar->orientation() == ScrollbarOrientation::VERTICAL
-               ? gfx::ScrollOffset(0, -scroll_delta)   // Up arrow
-               : gfx::ScrollOffset(-scroll_delta, 0);  // Left arrow
+               ? gfx::Vector2dF(0, -scroll_delta)   // Up arrow
+               : gfx::Vector2dF(-scroll_delta, 0);  // Left arrow
   } else if (scrollbar_part == ScrollbarPart::FORWARD_BUTTON) {
     return scrollbar->orientation() == ScrollbarOrientation::VERTICAL
-               ? gfx::ScrollOffset(0, scroll_delta)   // Down arrow
-               : gfx::ScrollOffset(scroll_delta, 0);  // Right arrow
+               ? gfx::Vector2dF(0, scroll_delta)   // Down arrow
+               : gfx::Vector2dF(scroll_delta, 0);  // Right arrow
   } else if (scrollbar_part == ScrollbarPart::BACK_TRACK) {
     return scrollbar->orientation() == ScrollbarOrientation::VERTICAL
-               ? gfx::ScrollOffset(0, -scroll_delta)   // Track click up
-               : gfx::ScrollOffset(-scroll_delta, 0);  // Track click left
+               ? gfx::Vector2dF(0, -scroll_delta)   // Track click up
+               : gfx::Vector2dF(-scroll_delta, 0);  // Track click left
   } else if (scrollbar_part == ScrollbarPart::FORWARD_TRACK) {
     return scrollbar->orientation() == ScrollbarOrientation::VERTICAL
-               ? gfx::ScrollOffset(0, scroll_delta)   // Track click down
-               : gfx::ScrollOffset(scroll_delta, 0);  // Track click right
+               ? gfx::Vector2dF(0, scroll_delta)   // Track click down
+               : gfx::Vector2dF(scroll_delta, 0);  // Track click right
   }
 
-  return gfx::ScrollOffset(0, 0);
+  return gfx::Vector2dF(0, 0);
 }
 
 }  // namespace cc
diff --git a/cc/input/scrollbar_controller.h b/cc/input/scrollbar_controller.h
index 8748e65..82f0d8d 100644
--- a/cc/input/scrollbar_controller.h
+++ b/cc/input/scrollbar_controller.h
@@ -216,14 +216,14 @@
   float ScreenSpaceScaleFactor() const;
 
   // Helper to convert scroll offset to autoscroll velocity.
-  float InitialDeltaToAutoscrollVelocity(gfx::ScrollOffset scroll_offset) const;
+  float InitialDeltaToAutoscrollVelocity(gfx::Vector2dF scroll_offset) const;
 
   // Returns the hit tested ScrollbarPart based on the position_in_widget.
   ScrollbarPart GetScrollbarPartFromPointerDown(
       const gfx::PointF position_in_widget) const;
 
   // Returns scroll offsets based on which ScrollbarPart was hit tested.
-  gfx::ScrollOffset GetScrollOffsetForScrollbarPart(
+  gfx::Vector2dF GetScrollOffsetForScrollbarPart(
       const ScrollbarPart scrollbar_part,
       const bool jump_key_modifier) const;
 
diff --git a/cc/input/snap_selection_strategy.cc b/cc/input/snap_selection_strategy.cc
index fb28e81..c2b5a01 100644
--- a/cc/input/snap_selection_strategy.cc
+++ b/cc/input/snap_selection_strategy.cc
@@ -10,7 +10,7 @@
 
 std::unique_ptr<SnapSelectionStrategy>
 SnapSelectionStrategy::CreateForEndPosition(
-    const gfx::ScrollOffset& current_position,
+    const gfx::Vector2dF& current_position,
     bool scrolled_x,
     bool scrolled_y,
     SnapTargetsPrioritization prioritization) {
@@ -19,8 +19,8 @@
 }
 
 std::unique_ptr<SnapSelectionStrategy>
-SnapSelectionStrategy::CreateForDirection(gfx::ScrollOffset current_position,
-                                          gfx::ScrollOffset step,
+SnapSelectionStrategy::CreateForDirection(gfx::Vector2dF current_position,
+                                          gfx::Vector2dF step,
                                           bool use_fractional_offsets,
                                           SnapStopAlwaysFilter filter) {
   return std::make_unique<DirectionStrategy>(current_position, step, filter,
@@ -28,17 +28,15 @@
 }
 
 std::unique_ptr<SnapSelectionStrategy>
-SnapSelectionStrategy::CreateForEndAndDirection(
-    gfx::ScrollOffset current_position,
-    gfx::ScrollOffset displacement,
-    bool use_fractional_offsets) {
+SnapSelectionStrategy::CreateForEndAndDirection(gfx::Vector2dF current_position,
+                                                gfx::Vector2dF displacement,
+                                                bool use_fractional_offsets) {
   return std::make_unique<EndAndDirectionStrategy>(
       current_position, displacement, use_fractional_offsets);
 }
 
 std::unique_ptr<SnapSelectionStrategy>
-SnapSelectionStrategy::CreateForTargetElement(
-    gfx::ScrollOffset current_position) {
+SnapSelectionStrategy::CreateForTargetElement(gfx::Vector2dF current_position) {
   return std::make_unique<EndPositionStrategy>(
       current_position, true /* scrolled_x */, true /* scrolled_y */,
       SnapTargetsPrioritization::kRequire);
@@ -75,11 +73,11 @@
   return scrolled_y_;
 }
 
-gfx::ScrollOffset EndPositionStrategy::intended_position() const {
+gfx::Vector2dF EndPositionStrategy::intended_position() const {
   return current_position_;
 }
 
-gfx::ScrollOffset EndPositionStrategy::base_position() const {
+gfx::Vector2dF EndPositionStrategy::base_position() const {
   return current_position_;
 }
 
@@ -112,11 +110,11 @@
   return step_.y() != 0;
 }
 
-gfx::ScrollOffset DirectionStrategy::intended_position() const {
+gfx::Vector2dF DirectionStrategy::intended_position() const {
   return current_position_ + step_;
 }
 
-gfx::ScrollOffset DirectionStrategy::base_position() const {
+gfx::Vector2dF DirectionStrategy::base_position() const {
   return current_position_;
 }
 
@@ -186,11 +184,11 @@
   return displacement_.y() != 0;
 }
 
-gfx::ScrollOffset EndAndDirectionStrategy::intended_position() const {
+gfx::Vector2dF EndAndDirectionStrategy::intended_position() const {
   return current_position_ + displacement_;
 }
 
-gfx::ScrollOffset EndAndDirectionStrategy::base_position() const {
+gfx::Vector2dF EndAndDirectionStrategy::base_position() const {
   return current_position_ + displacement_;
 }
 
diff --git a/cc/input/snap_selection_strategy.h b/cc/input/snap_selection_strategy.h
index 1580deec..0814767f 100644
--- a/cc/input/snap_selection_strategy.h
+++ b/cc/input/snap_selection_strategy.h
@@ -23,7 +23,7 @@
   SnapSelectionStrategy() = default;
   virtual ~SnapSelectionStrategy() = default;
   static std::unique_ptr<SnapSelectionStrategy> CreateForEndPosition(
-      const gfx::ScrollOffset& current_position,
+      const gfx::Vector2dF& current_position,
       bool scrolled_x,
       bool scrolled_y,
       SnapTargetsPrioritization prioritization =
@@ -32,20 +32,20 @@
   // |use_fractional_offsets| should be true when the current position is
   // provided in fractional pixels.
   static std::unique_ptr<SnapSelectionStrategy> CreateForDirection(
-      gfx::ScrollOffset current_position,
-      gfx::ScrollOffset step,
+      gfx::Vector2dF current_position,
+      gfx::Vector2dF step,
       bool use_fractional_offsets,
       SnapStopAlwaysFilter filter = SnapStopAlwaysFilter::kIgnore);
   static std::unique_ptr<SnapSelectionStrategy> CreateForEndAndDirection(
-      gfx::ScrollOffset current_position,
-      gfx::ScrollOffset displacement,
+      gfx::Vector2dF current_position,
+      gfx::Vector2dF displacement,
       bool use_fractional_offsets);
 
   // Creates a selection strategy that attempts to snap to previously snapped
   // targets if possible, but defaults to finding the closest snap point if
   // the target no longer exists.
   static std::unique_ptr<SnapSelectionStrategy> CreateForTargetElement(
-      gfx::ScrollOffset current_position);
+      gfx::Vector2dF current_position);
 
   // Returns whether it's snappable on x or y depending on the scroll performed.
   virtual bool ShouldSnapOnX() const = 0;
@@ -56,14 +56,12 @@
   virtual bool ShouldPrioritizeSnapTargets() const;
 
   // Returns the end position of the scroll if no snap interferes.
-  virtual gfx::ScrollOffset intended_position() const = 0;
+  virtual gfx::Vector2dF intended_position() const = 0;
   // Returns the scroll position from which the snap position should minimize
   // its distance.
-  virtual gfx::ScrollOffset base_position() const = 0;
+  virtual gfx::Vector2dF base_position() const = 0;
   // Returns the current scroll position of the snap container.
-  const gfx::ScrollOffset& current_position() const {
-    return current_position_;
-  }
+  const gfx::Vector2dF& current_position() const { return current_position_; }
 
   // Returns true if the selection strategy considers the given snap offset
   // valid for the current axis.
@@ -91,9 +89,9 @@
   virtual bool UsingFractionalOffsets() const;
 
  protected:
-  explicit SnapSelectionStrategy(const gfx::ScrollOffset& current_position)
+  explicit SnapSelectionStrategy(const gfx::Vector2dF& current_position)
       : current_position_(current_position) {}
-  const gfx::ScrollOffset current_position_;
+  const gfx::Vector2dF current_position_;
 };
 
 // Examples for intended end position scrolls include
@@ -108,7 +106,7 @@
 // * Return the end position if that makes a snap area covers the snapport.
 class EndPositionStrategy : public SnapSelectionStrategy {
  public:
-  EndPositionStrategy(const gfx::ScrollOffset& current_position,
+  EndPositionStrategy(const gfx::Vector2dF& current_position,
                       bool scrolled_x,
                       bool scrolled_y,
                       SnapTargetsPrioritization snap_targets_prioritization)
@@ -121,8 +119,8 @@
   bool ShouldSnapOnX() const override;
   bool ShouldSnapOnY() const override;
 
-  gfx::ScrollOffset intended_position() const override;
-  gfx::ScrollOffset base_position() const override;
+  gfx::Vector2dF intended_position() const override;
+  gfx::Vector2dF base_position() const override;
 
   bool IsValidSnapPosition(SearchAxis axis, float position) const override;
   bool HasIntendedDirection() const override;
@@ -151,8 +149,8 @@
  public:
   // |use_fractional_offsets| should be true when the current position is
   // provided in fractional pixels.
-  DirectionStrategy(const gfx::ScrollOffset& current_position,
-                    const gfx::ScrollOffset& step,
+  DirectionStrategy(const gfx::Vector2dF& current_position,
+                    const gfx::Vector2dF& step,
                     SnapStopAlwaysFilter filter,
                     bool use_fractional_offsets)
       : SnapSelectionStrategy(current_position),
@@ -164,8 +162,8 @@
   bool ShouldSnapOnX() const override;
   bool ShouldSnapOnY() const override;
 
-  gfx::ScrollOffset intended_position() const override;
-  gfx::ScrollOffset base_position() const override;
+  gfx::Vector2dF intended_position() const override;
+  gfx::Vector2dF base_position() const override;
 
   bool IsValidSnapPosition(SearchAxis axis, float position) const override;
   bool IsValidSnapArea(SearchAxis axis,
@@ -179,7 +177,7 @@
 
  private:
   // The default step for this DirectionStrategy.
-  const gfx::ScrollOffset step_;
+  const gfx::Vector2dF step_;
   SnapStopAlwaysFilter snap_stop_always_filter_;
   bool use_fractional_offsets_;
 };
@@ -196,8 +194,8 @@
  public:
   // |use_fractional_offsets| should be true when the current position is
   // provided in fractional pixels.
-  EndAndDirectionStrategy(const gfx::ScrollOffset& current_position,
-                          const gfx::ScrollOffset& displacement,
+  EndAndDirectionStrategy(const gfx::Vector2dF& current_position,
+                          const gfx::Vector2dF& displacement,
                           bool use_fractional_offsets)
       : SnapSelectionStrategy(current_position),
         displacement_(displacement),
@@ -207,8 +205,8 @@
   bool ShouldSnapOnX() const override;
   bool ShouldSnapOnY() const override;
 
-  gfx::ScrollOffset intended_position() const override;
-  gfx::ScrollOffset base_position() const override;
+  gfx::Vector2dF intended_position() const override;
+  gfx::Vector2dF base_position() const override;
 
   bool IsValidSnapPosition(SearchAxis axis, float position) const override;
 
@@ -221,7 +219,7 @@
   bool UsingFractionalOffsets() const override;
 
  private:
-  const gfx::ScrollOffset displacement_;
+  const gfx::Vector2dF displacement_;
   bool use_fractional_offsets_;
 };
 
diff --git a/cc/input/threaded_input_handler.cc b/cc/input/threaded_input_handler.cc
index 872bf40..26877aa2 100644
--- a/cc/input/threaded_input_handler.cc
+++ b/cc/input/threaded_input_handler.cc
@@ -462,7 +462,7 @@
   }
 
   scroll_result.current_visual_offset =
-      ScrollOffsetToVector2dF(GetVisualScrollOffset(*CurrentlyScrollingNode()));
+      GetVisualScrollOffset(*CurrentlyScrollingNode());
   float scale_factor = ActiveTree().page_scale_factor_for_scroll();
   scroll_result.current_visual_offset.Scale(scale_factor);
 
@@ -489,15 +489,15 @@
   // properly set. Currently, track and arrow scrolls both use a direction
   // strategy; however, the track should be using an "end and direction"
   // strategy.
-  gfx::ScrollOffset current_position = GetVisualScrollOffset(*scroll_node);
+  gfx::Vector2dF current_position = GetVisualScrollOffset(*scroll_node);
   const SnapContainerData& data = scroll_node->snap_container_data.value();
   std::unique_ptr<SnapSelectionStrategy> strategy =
       SnapSelectionStrategy::CreateForDirection(
-          gfx::ScrollOffset(current_position.x(), current_position.y()),
-          gfx::ScrollOffset(scroll_state->delta_x(), scroll_state->delta_y()),
+          current_position,
+          gfx::Vector2dF(scroll_state->delta_x(), scroll_state->delta_y()),
           true);
 
-  gfx::ScrollOffset snap_position;
+  gfx::Vector2dF snap_position;
   TargetSnapAreaElementIds snap_target_ids;
   if (!data.FindSnapPosition(*strategy, &snap_position, &snap_target_ids))
     return;
@@ -693,13 +693,13 @@
 }
 
 void ThreadedInputHandler::SetSynchronousInputHandlerRootScrollOffset(
-    const gfx::ScrollOffset& root_content_offset) {
+    const gfx::Vector2dF& root_content_offset) {
   TRACE_EVENT2(
       "cc", "ThreadedInputHandler::SetSynchronousInputHandlerRootScrollOffset",
       "offset_x", root_content_offset.x(), "offset_y", root_content_offset.y());
 
   gfx::Vector2dF physical_delta =
-      root_content_offset.DeltaFrom(GetViewport().TotalScrollOffset());
+      root_content_offset - GetViewport().TotalScrollOffset();
   physical_delta.Scale(ActiveTree().page_scale_factor_for_scroll());
 
   bool changed = !GetViewport()
@@ -879,7 +879,7 @@
 }
 
 bool ThreadedInputHandler::GetScrollOffsetForLayer(ElementId element_id,
-                                                   gfx::ScrollOffset* offset) {
+                                                   gfx::Vector2dF* offset) {
   ScrollTree& scroll_tree = GetScrollTree();
   ScrollNode* scroll_node = scroll_tree.FindNodeFromElementId(element_id);
   if (!scroll_node)
@@ -889,17 +889,15 @@
 }
 
 bool ThreadedInputHandler::ScrollLayerTo(ElementId element_id,
-                                         const gfx::ScrollOffset& offset) {
+                                         const gfx::Vector2dF& offset) {
   ScrollTree& scroll_tree = GetScrollTree();
   ScrollNode* scroll_node = scroll_tree.FindNodeFromElementId(element_id);
   if (!scroll_node)
     return false;
 
-  scroll_tree.ScrollBy(
-      *scroll_node,
-      ScrollOffsetToVector2dF(offset -
-                              scroll_tree.current_scroll_offset(element_id)),
-      &ActiveTree());
+  scroll_tree.ScrollBy(*scroll_node,
+                       offset - scroll_tree.current_scroll_offset(element_id),
+                       &ActiveTree());
   return true;
 }
 
@@ -933,22 +931,20 @@
   gfx::Vector2dF natural_displacement_in_content =
       gfx::ScaleVector2d(natural_displacement_in_viewport, 1.f / scale_factor);
 
-  gfx::ScrollOffset current_offset = GetVisualScrollOffset(*scroll_node);
-  *out_initial_position = ScrollOffsetToVector2dF(current_offset);
+  gfx::Vector2dF current_offset = GetVisualScrollOffset(*scroll_node);
+  *out_initial_position = current_offset;
 
   // CC side always uses fractional scroll deltas.
   bool use_fractional_offsets = true;
-  gfx::ScrollOffset snap_offset;
   TargetSnapAreaElementIds snap_target_ids;
   std::unique_ptr<SnapSelectionStrategy> strategy =
       SnapSelectionStrategy::CreateForEndAndDirection(
-          current_offset, gfx::ScrollOffset(natural_displacement_in_content),
+          current_offset, natural_displacement_in_content,
           use_fractional_offsets);
-  if (!data.FindSnapPosition(*strategy, &snap_offset, &snap_target_ids))
+  if (!data.FindSnapPosition(*strategy, out_target_position, &snap_target_ids))
     return false;
   scroll_animating_snap_target_ids_ = snap_target_ids;
 
-  *out_target_position = ScrollOffsetToVector2dF(snap_offset);
   out_target_position->Scale(scale_factor);
   out_initial_position->Scale(scale_factor);
   return true;
@@ -1320,7 +1316,7 @@
   // The a viewport node should be scrolled even if it has no scroll extent
   // since it'll scroll using the Viewport class which will generate browser
   // controls movement and overscroll delta.
-  gfx::ScrollOffset max_scroll_offset =
+  gfx::Vector2dF max_scroll_offset =
       scroll_tree.MaxScrollOffset(scroll_node->id);
   if (max_scroll_offset.x() <= 0 && max_scroll_offset.y() <= 0 &&
       !GetViewport().ShouldScroll(*scroll_node)) {
@@ -1597,13 +1593,12 @@
   adjusted_scroll.Scale(1.f / scale_factor);
   adjusted_scroll = UserScrollableDelta(scroll_node, adjusted_scroll);
 
-  gfx::ScrollOffset old_offset =
+  gfx::Vector2dF old_offset =
       scroll_tree.current_scroll_offset(scroll_node.element_id);
-  gfx::ScrollOffset new_offset = scroll_tree.ClampScrollOffsetToLimits(
-      old_offset + gfx::ScrollOffset(adjusted_scroll), scroll_node);
+  gfx::Vector2dF new_offset = scroll_tree.ClampScrollOffsetToLimits(
+      old_offset + adjusted_scroll, scroll_node);
 
-  gfx::ScrollOffset scrolled = new_offset - old_offset;
-  return gfx::Vector2dF(scrolled.x(), scrolled.y());
+  return new_offset - old_offset;
 }
 
 bool ThreadedInputHandler::CalculateLocalScrollDeltaAndStartPoint(
@@ -1671,10 +1666,10 @@
                local_scroll_delta.y(), "is_outer", scrolls_outer_viewport);
 
   // Apply the scroll delta.
-  gfx::ScrollOffset previous_offset =
+  gfx::Vector2dF previous_offset =
       scroll_tree.current_scroll_offset(scroll_node.element_id);
   scroll_tree.ScrollBy(scroll_node, local_scroll_delta, &ActiveTree());
-  gfx::ScrollOffset scrolled =
+  gfx::Vector2dF scrolled =
       scroll_tree.current_scroll_offset(scroll_node.element_id) -
       previous_offset;
 
@@ -1683,8 +1678,7 @@
 
   // Get the end point in the layer's content space so we can apply its
   // ScreenSpaceTransform.
-  gfx::PointF actual_local_end_point =
-      local_start_point + gfx::Vector2dF(scrolled.x(), scrolled.y());
+  gfx::PointF actual_local_end_point = local_start_point + scrolled;
 
   // Calculate the applied scroll delta in viewport space coordinates.
   bool end_clipped;
@@ -1712,12 +1706,12 @@
   float page_scale_factor = compositor_delegate_.PageScaleFactor();
 
   ScrollTree& scroll_tree = GetScrollTree();
-  gfx::ScrollOffset previous_offset =
+  gfx::Vector2dF previous_offset =
       scroll_tree.current_scroll_offset(scroll_node.element_id);
   gfx::Vector2dF delta = local_delta;
   delta.Scale(1.f / page_scale_factor);
   scroll_tree.ScrollBy(scroll_node, delta, &ActiveTree());
-  gfx::ScrollOffset scrolled =
+  gfx::Vector2dF scrolled =
       scroll_tree.current_scroll_offset(scroll_node.element_id) -
       previous_offset;
   gfx::Vector2dF consumed_scroll(scrolled.x(), scrolled.y());
@@ -2030,7 +2024,7 @@
     return false;
 
   SnapContainerData& data = scroll_node->snap_container_data.value();
-  gfx::ScrollOffset current_position = GetVisualScrollOffset(*scroll_node);
+  gfx::Vector2dF current_position = GetVisualScrollOffset(*scroll_node);
 
   // You might think that if a scroll never received a scroll update we could
   // just drop the snap. However, if the GSB+GSE arrived while we were mid-snap
@@ -2045,7 +2039,7 @@
       latched_scroll_type_ == ui::ScrollInputType::kWheel &&
       last_scroll_state.delta_granularity() !=
           ui::ScrollGranularity::kScrollByPrecisePixel;
-  gfx::ScrollOffset last_scroll_delta = last_scroll_state.DeltaOrHint();
+  gfx::Vector2dF last_scroll_delta = last_scroll_state.DeltaOrHint();
 
   std::unique_ptr<SnapSelectionStrategy> strategy;
   if (imprecise_wheel_scrolling && !last_scroll_delta.IsZero() &&
@@ -2064,7 +2058,7 @@
         did_scroll_y_for_scroll_gesture_);
   }
 
-  gfx::ScrollOffset snap_position;
+  gfx::Vector2dF snap_position;
   TargetSnapAreaElementIds snap_target_ids;
   if (!data.FindSnapPosition(*strategy, &snap_position, &snap_target_ids))
     return false;
@@ -2074,8 +2068,7 @@
     compositor_delegate_.WillScrollContent(scroll_node->element_id);
   }
 
-  gfx::Vector2dF delta =
-      ScrollOffsetToVector2dF(snap_position - current_position);
+  gfx::Vector2dF delta = snap_position - current_position;
   bool did_animate = false;
   if (scroll_node->scrolls_outer_viewport) {
     gfx::Vector2dF scaled_delta(delta);
@@ -2103,7 +2096,7 @@
   return scroll_animating_snap_target_ids_ != TargetSnapAreaElementIds();
 }
 
-gfx::ScrollOffset ThreadedInputHandler::GetVisualScrollOffset(
+gfx::Vector2dF ThreadedInputHandler::GetVisualScrollOffset(
     const ScrollNode& scroll_node) const {
   if (scroll_node.scrolls_outer_viewport)
     return GetViewport().TotalScrollOffset();
diff --git a/cc/input/threaded_input_handler.h b/cc/input/threaded_input_handler.h
index 38bafb8a..65a908f 100644
--- a/cc/input/threaded_input_handler.h
+++ b/cc/input/threaded_input_handler.h
@@ -26,7 +26,7 @@
 namespace gfx {
 class Point;
 class PointF;
-class ScrollOffset;
+class Vector2dF;
 }  // namespace gfx
 
 namespace cc {
@@ -71,7 +71,7 @@
       const gfx::PointF& viewport_point) override;
   void RequestUpdateForSynchronousInputHandler() override;
   void SetSynchronousInputHandlerRootScrollOffset(
-      const gfx::ScrollOffset& root_content_offset) override;
+      const gfx::Vector2dF& root_content_offset) override;
   void PinchGestureBegin() override;
   void PinchGestureUpdate(float magnify_delta,
                           const gfx::Point& anchor) override;
@@ -94,9 +94,9 @@
   ScrollElasticityHelper* CreateScrollElasticityHelper() override;
   void DestroyScrollElasticityHelper() override;
   bool GetScrollOffsetForLayer(ElementId element_id,
-                               gfx::ScrollOffset* offset) override;
+                               gfx::Vector2dF* offset) override;
   bool ScrollLayerTo(ElementId element_id,
-                     const gfx::ScrollOffset& offset) override;
+                     const gfx::Vector2dF& offset) override;
   bool ScrollingShouldSwitchtoMainThread() override;
   bool GetSnapFlingInfoAndSetAnimatingSnapTarget(
       const gfx::Vector2dF& natural_displacement_in_viewport,
@@ -184,7 +184,7 @@
 
   // This method gets the scroll offset for a regular scroller, or the combined
   // visual and layout offsets of the viewport.
-  gfx::ScrollOffset GetVisualScrollOffset(const ScrollNode& scroll_node) const;
+  gfx::Vector2dF GetVisualScrollOffset(const ScrollNode& scroll_node) const;
   bool IsScrolledBy(LayerImpl* child, ScrollNode* ancestor);
   bool IsAnimatingForSnap() const;
 
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc
index 03cb730..641892f3 100644
--- a/cc/layers/layer.cc
+++ b/cc/layers/layer.cc
@@ -940,7 +940,7 @@
   SetNeedsCommit();
 }
 
-void Layer::SetScrollOffset(const gfx::ScrollOffset& scroll_offset) {
+void Layer::SetScrollOffset(const gfx::Vector2dF& scroll_offset) {
   DCHECK(IsPropertyChangeAllowed());
 
   auto& inputs = EnsureLayerTreeInputs();
@@ -956,8 +956,7 @@
   SetNeedsCommit();
 }
 
-void Layer::SetScrollOffsetFromImplSide(
-    const gfx::ScrollOffset& scroll_offset) {
+void Layer::SetScrollOffsetFromImplSide(const gfx::Vector2dF& scroll_offset) {
   DCHECK(IsPropertyChangeAllowed());
   // This function only gets called during a BeginMainFrame, so there
   // is no need to call SetNeedsUpdate here.
@@ -1002,7 +1001,7 @@
 }
 
 void Layer::SetDidScrollCallback(
-    base::RepeatingCallback<void(const gfx::ScrollOffset&, const ElementId&)>
+    base::RepeatingCallback<void(const gfx::Vector2dF&, const ElementId&)>
         callback) {
   EnsureLayerTreeInputs().did_scroll_callback = std::move(callback);
 }
diff --git a/cc/layers/layer.h b/cc/layers/layer.h
index db032e93..9fcb421 100644
--- a/cc/layers/layer.h
+++ b/cc/layers/layer.h
@@ -34,7 +34,7 @@
 #include "ui/gfx/geometry/point3_f.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/rounded_corners_f.h"
-#include "ui/gfx/geometry/scroll_offset.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 #include "ui/gfx/rrect_f.h"
 #include "ui/gfx/transform.h"
 
@@ -387,16 +387,16 @@
   // position of its subtree, as well as other layers for which this layer is
   // their scroll parent, and their subtrees) is moved up by the amount of
   // offset specified here.
-  void SetScrollOffset(const gfx::ScrollOffset& scroll_offset);
-  gfx::ScrollOffset scroll_offset() const {
+  void SetScrollOffset(const gfx::Vector2dF& scroll_offset);
+  gfx::Vector2dF scroll_offset() const {
     return layer_tree_inputs() ? layer_tree_inputs()->scroll_offset
-                               : gfx::ScrollOffset();
+                               : gfx::Vector2dF();
   }
 
   // For layer tree mode only.
   // Called internally during commit to update the layer with state from the
   // compositor thread. Not to be called externally by users of this class.
-  void SetScrollOffsetFromImplSide(const gfx::ScrollOffset& scroll_offset);
+  void SetScrollOffsetFromImplSide(const gfx::Vector2dF& scroll_offset);
 
   // For layer tree mode only.
   // Marks this layer as being scrollable and needing an associated scroll node,
@@ -465,8 +465,8 @@
   // main thread in single-thread mode). It may be set to a null callback, in
   // which case nothing is called. This is for layer tree mode only. Should use
   // ScrollTree::SetScrollCallbacks() in layer list mode.
-  void SetDidScrollCallback(base::RepeatingCallback<
-                            void(const gfx::ScrollOffset&, const ElementId&)>);
+  void SetDidScrollCallback(
+      base::RepeatingCallback<void(const gfx::Vector2dF&, const ElementId&)>);
 
   // For layer tree mode only.
   // Sets the given |subtree_id| on this layer, so that the layer subtree rooted
@@ -918,7 +918,7 @@
 
     int mirror_count = 0;
 
-    gfx::ScrollOffset scroll_offset;
+    gfx::Vector2dF scroll_offset;
     // Size of the scroll container that this layer scrolls in.
     gfx::Size scroll_container_bounds;
 
@@ -926,7 +926,7 @@
     //     top left, top right, bottom right, bottom left
     gfx::RoundedCornersF corner_radii;
 
-    base::RepeatingCallback<void(const gfx::ScrollOffset&, const ElementId&)>
+    base::RepeatingCallback<void(const gfx::Vector2dF&, const ElementId&)>
         did_scroll_callback;
     std::vector<std::unique_ptr<viz::CopyOutputRequest>> copy_requests;
   };
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc
index 0a6ed0c..070ad3d 100644
--- a/cc/layers/layer_impl.cc
+++ b/cc/layers/layer_impl.cc
@@ -603,7 +603,7 @@
   return gfx::Rect();
 }
 
-void LayerImpl::SetCurrentScrollOffset(const gfx::ScrollOffset& scroll_offset) {
+void LayerImpl::SetCurrentScrollOffset(const gfx::Vector2dF& scroll_offset) {
   DCHECK(IsActive());
   if (GetScrollTree().SetScrollOffset(element_id(), scroll_offset))
     layer_tree_impl()->DidUpdateScrollOffset(element_id());
diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h
index 2aa624c1..51caf22 100644
--- a/cc/layers/layer_impl.h
+++ b/cc/layers/layer_impl.h
@@ -36,7 +36,7 @@
 #include "ui/gfx/geometry/point3_f.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/rect_f.h"
-#include "ui/gfx/geometry/scroll_offset.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 #include "ui/gfx/transform.h"
 
 namespace viz {
@@ -243,7 +243,7 @@
     is_inner_viewport_scroll_layer_ = true;
   }
 
-  void SetCurrentScrollOffset(const gfx::ScrollOffset& scroll_offset);
+  void SetCurrentScrollOffset(const gfx::Vector2dF& scroll_offset);
 
   // Returns the delta of the scroll that was outside of the bounds of the
   // initial scroll
diff --git a/cc/layers/layer_impl_unittest.cc b/cc/layers/layer_impl_unittest.cc
index cda0607..dd454f2 100644
--- a/cc/layers/layer_impl_unittest.cc
+++ b/cc/layers/layer_impl_unittest.cc
@@ -66,14 +66,6 @@
   code_to_test;                                                             \
   EXPECT_FALSE(host_impl()->active_tree()->needs_update_draw_properties());
 
-static gfx::Vector2dF ScrollDelta(LayerImpl* layer_impl) {
-  gfx::ScrollOffset delta = layer_impl->layer_tree_impl()
-                                ->property_trees()
-                                ->scroll_tree.GetScrollOffsetDeltaForTesting(
-                                    layer_impl->element_id());
-  return gfx::Vector2dF(delta.x(), delta.y());
-}
-
 class LayerImplTest : public LayerTreeImplTestBase, public ::testing::Test {
  public:
   using LayerTreeImplTestBase::LayerTreeImplTestBase;
@@ -215,10 +207,10 @@
       ->property_trees()
       ->scroll_tree.SetScrollOffsetDeltaForTesting(layer->element_id(),
                                                    gfx::Vector2dF());
-  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetCurrentScrollOffset(
-      gfx::ScrollOffset(arbitrary_vector2d.x(), arbitrary_vector2d.y())));
-  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetCurrentScrollOffset(
-      gfx::ScrollOffset(arbitrary_vector2d.x(), arbitrary_vector2d.y())));
+  VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(
+      layer->SetCurrentScrollOffset(arbitrary_vector2d));
+  VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(
+      layer->SetCurrentScrollOffset(arbitrary_vector2d));
 
   // Unrelated functions, always set to new values, always set needs update.
   host_impl()->active_tree()->set_needs_update_draw_properties();
@@ -369,7 +361,7 @@
 }
 
 TEST_F(LayerImplScrollTest, ScrollByWithNonZeroOffset) {
-  gfx::ScrollOffset scroll_offset(10, 5);
+  gfx::Vector2dF scroll_offset(10, 5);
   scroll_tree(layer())->UpdateScrollOffsetBaseForTesting(layer()->element_id(),
                                                          scroll_offset);
 
@@ -382,9 +374,8 @@
   layer()->ScrollBy(gfx::Vector2dF(-100, 100));
   EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 80), CurrentScrollOffset(layer()));
 
-  EXPECT_VECTOR_EQ(
-      gfx::ScrollOffsetWithDelta(scroll_offset, ScrollDelta(layer())),
-      CurrentScrollOffset(layer()));
+  EXPECT_VECTOR_EQ(scroll_offset + ScrollDelta(layer()),
+                   CurrentScrollOffset(layer()));
   EXPECT_VECTOR_EQ(scroll_offset,
                    scroll_tree(layer())->GetScrollOffsetBaseForTesting(
                        layer()->element_id()));
@@ -392,16 +383,15 @@
   layer()->ScrollBy(gfx::Vector2dF(100, -100));
   EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 0), CurrentScrollOffset(layer()));
 
-  EXPECT_VECTOR_EQ(
-      gfx::ScrollOffsetWithDelta(scroll_offset, ScrollDelta(layer())),
-      CurrentScrollOffset(layer()));
+  EXPECT_VECTOR_EQ(scroll_offset + ScrollDelta(layer()),
+                   CurrentScrollOffset(layer()));
   EXPECT_VECTOR_EQ(scroll_offset,
                    scroll_tree(layer())->GetScrollOffsetBaseForTesting(
                        layer()->element_id()));
 }
 
 TEST_F(LayerImplScrollTest, ApplySentScrollsNoListener) {
-  gfx::ScrollOffset scroll_offset(10, 5);
+  gfx::Vector2dF scroll_offset(10, 5);
   gfx::Vector2dF scroll_delta(20.5f, 8.5f);
   gfx::Vector2d sent_scroll_delta(12, -3);
 
@@ -409,11 +399,9 @@
                                                          scroll_offset);
   layer()->ScrollBy(sent_scroll_delta);
   scroll_tree(layer())->CollectScrollDeltasForTesting();
-  layer()->SetCurrentScrollOffset(scroll_offset +
-                                  gfx::ScrollOffset(scroll_delta));
+  layer()->SetCurrentScrollOffset(scroll_offset + scroll_delta);
 
-  EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(scroll_offset, scroll_delta),
-                   CurrentScrollOffset(layer()));
+  EXPECT_VECTOR_EQ(scroll_offset + scroll_delta, CurrentScrollOffset(layer()));
   EXPECT_VECTOR_EQ(scroll_delta, ScrollDelta(layer()));
   EXPECT_VECTOR_EQ(scroll_offset,
                    scroll_tree(layer())->GetScrollOffsetBaseForTesting(
@@ -421,16 +409,15 @@
 
   scroll_tree(layer())->ApplySentScrollDeltasFromAbortedCommit();
 
-  EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(scroll_offset, scroll_delta),
-                   CurrentScrollOffset(layer()));
+  EXPECT_VECTOR_EQ(scroll_offset + scroll_delta, CurrentScrollOffset(layer()));
   EXPECT_VECTOR_EQ(scroll_delta - sent_scroll_delta, ScrollDelta(layer()));
-  EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(scroll_offset, sent_scroll_delta),
+  EXPECT_VECTOR_EQ(scroll_offset + sent_scroll_delta,
                    scroll_tree(layer())->GetScrollOffsetBaseForTesting(
                        layer()->element_id()));
 }
 
 TEST_F(LayerImplScrollTest, ScrollUserUnscrollableLayer) {
-  gfx::ScrollOffset scroll_offset(10, 5);
+  gfx::Vector2dF scroll_offset(10, 5);
   gfx::Vector2dF scroll_delta(20.5f, 8.5f);
 
   GetScrollNode(layer())->user_scrollable_vertical = false;
@@ -470,7 +457,7 @@
 
 TEST_F(CommitToPendingTreeLayerImplScrollTest,
        PushPropertiesToMirrorsCurrentScrollOffset) {
-  gfx::ScrollOffset scroll_offset(10, 5);
+  gfx::Vector2dF scroll_offset(10, 5);
   gfx::Vector2dF scroll_delta(12, 18);
 
   host_impl()->CreatePendingTree();
@@ -522,7 +509,7 @@
     accumulated_scroll += scroll;
     SetScrollOffset(
         host_impl()->active_tree()->InnerViewportScrollLayerForTesting(),
-        gfx::ScrollOffset(0, accumulated_scroll));
+        gfx::Vector2dF(0, accumulated_scroll));
     UpdateActiveTreeDrawProperties();
 
     host_impl()->CreatePendingTree();
@@ -530,7 +517,7 @@
     pending_tree->set_source_frame_number(i + 1);
     pending_tree->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
     // Simulate scroll offset pushed from the main thread.
-    SetScrollOffset(scroll_layer, gfx::ScrollOffset(0, accumulated_scroll));
+    SetScrollOffset(scroll_layer, gfx::Vector2dF(0, accumulated_scroll));
     // The scroll done on the active tree is undone on the pending tree.
     content_layer->SetOffsetToTransformParent(
         gfx::Vector2dF(0, accumulated_scroll));
diff --git a/cc/layers/layer_unittest.cc b/cc/layers/layer_unittest.cc
index 06f8829..ef39e50 100644
--- a/cc/layers/layer_unittest.cc
+++ b/cc/layers/layer_unittest.cc
@@ -41,7 +41,6 @@
 #include "ui/gfx/animation/keyframe/keyframed_animation_curve.h"
 #include "ui/gfx/geometry/point3_f.h"
 #include "ui/gfx/geometry/point_f.h"
-#include "ui/gfx/geometry/scroll_offset.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/geometry/vector2d_f.h"
 #include "ui/gfx/transform.h"
@@ -930,8 +929,8 @@
   // We can use any layer pointer here since we aren't syncing for real.
   EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetScrollable(gfx::Size(1, 1)));
   EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetUserScrollable(true, false));
-  EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetScrollOffset(
-      gfx::ScrollOffset(10, 10)));
+  EXPECT_SET_NEEDS_COMMIT(1,
+                          test_layer->SetScrollOffset(gfx::Vector2dF(10, 10)));
   EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetNonFastScrollableRegion(
       Region(gfx::Rect(1, 1, 2, 2))));
   EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetTransform(
@@ -1518,7 +1517,7 @@
   // handled similarly to normal compositor scroll updates.
   EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()).Times(0);
   layer_tree_host_->SetElementScrollOffsetMutated(
-      element_id, ElementListType::ACTIVE, gfx::ScrollOffset(10, 10));
+      element_id, ElementListType::ACTIVE, gfx::Vector2dF(10, 10));
   Mock::VerifyAndClearExpectations(layer_tree_host_.get());
 }
 
diff --git a/cc/layers/picture_layer_impl_perftest.cc b/cc/layers/picture_layer_impl_perftest.cc
index 8d504e9e..d4567bce 100644
--- a/cc/layers/picture_layer_impl_perftest.cc
+++ b/cc/layers/picture_layer_impl_perftest.cc
@@ -98,7 +98,7 @@
         ->property_trees()
         ->scroll_tree.UpdateScrollOffsetBaseForTesting(
             pending_layer_->element_id(),
-            gfx::ScrollOffset(viewport.x(), viewport.y()));
+            gfx::Vector2dF(viewport.x(), viewport.y()));
     host_impl()->pending_tree()->UpdateDrawProperties();
 
     timer_.Reset();
@@ -146,7 +146,7 @@
         ->property_trees()
         ->scroll_tree.UpdateScrollOffsetBaseForTesting(
             pending_layer_->element_id(),
-            gfx::ScrollOffset(viewport.x(), viewport.y()));
+            gfx::Vector2dF(viewport.x(), viewport.y()));
     host_impl()->pending_tree()->UpdateDrawProperties();
 
     timer_.Reset();
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc
index 77ea603..2bd4a01 100644
--- a/cc/layers/picture_layer_impl_unittest.cc
+++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -5226,7 +5226,7 @@
 
   SetupDefaultTrees(layer_bounds);
 
-  active_layer()->SetCurrentScrollOffset(gfx::ScrollOffset(0.0, 50.0));
+  active_layer()->SetCurrentScrollOffset(gfx::Vector2dF(0.0, 50.0));
   UpdateDrawProperties(host_impl()->active_tree());
   EXPECT_EQ("0,50 100x100", active_layer()
                                 ->HighResTiling()
diff --git a/cc/layers/scrollbar_layer_unittest.cc b/cc/layers/scrollbar_layer_unittest.cc
index 025ea1d..afb22bd 100644
--- a/cc/layers/scrollbar_layer_unittest.cc
+++ b/cc/layers/scrollbar_layer_unittest.cc
@@ -380,7 +380,7 @@
 
   // Choose bounds to give max_scroll_offset = (30, 50).
   layer_tree_root->SetBounds(gfx::Size(70, 150));
-  scroll_layer->SetScrollOffset(gfx::ScrollOffset(10, 20));
+  scroll_layer->SetScrollOffset(gfx::Vector2dF(10, 20));
   scroll_layer->SetBounds(gfx::Size(100, 200));
   scroll_layer->SetScrollable(gfx::Size(70, 150));
   content_layer->SetBounds(gfx::Size(100, 200));
@@ -407,7 +407,7 @@
   layer_tree_root->SetBounds(gfx::Size(700, 1500));
   scroll_layer->SetScrollable(gfx::Size(700, 1500));
   scroll_layer->SetBounds(gfx::Size(1000, 2000));
-  scroll_layer->SetScrollOffset(gfx::ScrollOffset(100, 200));
+  scroll_layer->SetScrollOffset(gfx::Vector2dF(100, 200));
   content_layer->SetBounds(gfx::Size(1000, 2000));
 
   layer_tree_host_->UpdateLayers();
@@ -453,7 +453,7 @@
   root_layer->AddChild(content_layer);
   root_layer->AddChild(scrollbar_layer);
 
-  root_layer->SetScrollOffset(gfx::ScrollOffset(0, 0));
+  root_layer->SetScrollOffset(gfx::Vector2dF(0, 0));
   scrollbar_layer->SetBounds(gfx::Size(70, 10));
 
   // The track_rect should be relative to the scrollbar's origin.
@@ -491,7 +491,7 @@
   root_layer->AddChild(content_layer);
   root_layer->AddChild(scrollbar_layer);
 
-  root_layer->SetScrollOffset(gfx::ScrollOffset(0, 0));
+  root_layer->SetScrollOffset(gfx::Vector2dF(0, 0));
   scrollbar_layer->SetBounds(gfx::Size(70, 10));
 
   // The track_rect should be relative to the scrollbar's origin.
@@ -510,14 +510,14 @@
             scrollbar_layer_impl->ComputeThumbQuadRect().ToString());
 
   // Under-scroll (thumb position should clamp and be unchanged).
-  root_layer->SetScrollOffset(gfx::ScrollOffset(-5, 0));
+  root_layer->SetScrollOffset(gfx::Vector2dF(-5, 0));
 
   UPDATE_AND_EXTRACT_LAYER_POINTERS();
   EXPECT_EQ(gfx::Rect(10, 0, 4, 10).ToString(),
             scrollbar_layer_impl->ComputeThumbQuadRect().ToString());
 
   // Over-scroll (thumb position should clamp on the far side).
-  root_layer->SetScrollOffset(gfx::ScrollOffset(85, 0));
+  root_layer->SetScrollOffset(gfx::Vector2dF(85, 0));
   layer_tree_host_->UpdateLayers();
 
   UPDATE_AND_EXTRACT_LAYER_POINTERS();
@@ -562,7 +562,7 @@
   layer_tree_host_->SetRootLayer(root_layer);
   root_layer->AddChild(scrollbar_layer);
 
-  root_layer->SetScrollOffset(gfx::ScrollOffset(0, 0));
+  root_layer->SetScrollOffset(gfx::Vector2dF(0, 0));
   scrollbar_layer->SetBounds(gfx::Size(10, 20));
   scrollbar_layer->fake_scrollbar()->set_track_rect(gfx::Rect(0, 0, 10, 20));
   scrollbar_layer->fake_scrollbar()->set_thumb_size(gfx::Size(10, 4));
@@ -1138,7 +1138,7 @@
     scrollbar_layer->SetIsDrawable(true);
     scrollbar_layer->SetBounds(gfx::Size(100, 100));
     layer_tree_root->SetScrollable(gfx::Size(100, 200));
-    layer_tree_root->SetScrollOffset(gfx::ScrollOffset(10, 20));
+    layer_tree_root->SetScrollOffset(gfx::Vector2dF(10, 20));
     layer_tree_root->SetBounds(gfx::Size(100, 200));
     content_layer->SetBounds(gfx::Size(100, 200));
 
diff --git a/cc/layers/viewport.cc b/cc/layers/viewport.cc
index 39a73bc..f34476d 100644
--- a/cc/layers/viewport.cc
+++ b/cc/layers/viewport.cc
@@ -267,7 +267,7 @@
           gfx::PointF(anchor + pinch_anchor_adjustment_);
       adjusted_anchor =
           gfx::ScalePoint(adjusted_anchor, min_scale / page_scale);
-      adjusted_anchor += ScrollOffsetToVector2dF(TotalScrollOffset());
+      adjusted_anchor += TotalScrollOffset();
       host_impl_->StartPageScaleAnimation(
           ToRoundedVector2d(adjusted_anchor.OffsetFromOrigin()), true,
           min_scale, kSnapToMinZoomAnimationDuration);
@@ -325,8 +325,8 @@
   return adjusted;
 }
 
-gfx::ScrollOffset Viewport::MaxTotalScrollOffset() const {
-  gfx::ScrollOffset offset;
+gfx::Vector2dF Viewport::MaxTotalScrollOffset() const {
+  gfx::Vector2dF offset;
 
   offset += scroll_tree().MaxScrollOffset(InnerScrollNode()->id);
 
@@ -336,8 +336,8 @@
   return offset;
 }
 
-gfx::ScrollOffset Viewport::TotalScrollOffset() const {
-  gfx::ScrollOffset offset;
+gfx::Vector2dF Viewport::TotalScrollOffset() const {
+  gfx::Vector2dF offset;
 
   if (!InnerScrollNode())
     return offset;
diff --git a/cc/layers/viewport.h b/cc/layers/viewport.h
index ed6b861..3f885c9 100644
--- a/cc/layers/viewport.h
+++ b/cc/layers/viewport.h
@@ -73,7 +73,7 @@
   gfx::Vector2dF ScrollAnimated(const gfx::Vector2dF& delta,
                                 base::TimeDelta delayed_by);
 
-  gfx::ScrollOffset TotalScrollOffset() const;
+  gfx::Vector2dF TotalScrollOffset() const;
 
   void PinchUpdate(float magnify_delta, const gfx::Point& anchor);
   void PinchEnd(const gfx::Point& anchor, bool snap_to_min);
@@ -117,7 +117,7 @@
   // Sends the delta to the browser controls, returns the amount applied.
   gfx::Vector2dF ScrollBrowserControls(const gfx::Vector2dF& delta);
 
-  gfx::ScrollOffset MaxTotalScrollOffset() const;
+  gfx::Vector2dF MaxTotalScrollOffset() const;
 
   ScrollNode* InnerScrollNode() const;
   ScrollNode* OuterScrollNode() const;
diff --git a/cc/test/animation_test_common.cc b/cc/test/animation_test_common.cc
index 2d925fe..10f59ee 100644
--- a/cc/test/animation_test_common.cc
+++ b/cc/test/animation_test_common.cc
@@ -221,8 +221,8 @@
 }
 
 int AddScrollOffsetAnimationToAnimation(Animation* animation,
-                                        gfx::ScrollOffset initial_value,
-                                        gfx::ScrollOffset target_value) {
+                                        gfx::Vector2dF initial_value,
+                                        gfx::Vector2dF target_value) {
   std::unique_ptr<ScrollOffsetAnimationCurve> curve(
       ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
           target_value));
diff --git a/cc/test/animation_test_common.h b/cc/test/animation_test_common.h
index 30b71d9..a04c016 100644
--- a/cc/test/animation_test_common.h
+++ b/cc/test/animation_test_common.h
@@ -16,7 +16,7 @@
 #include "ui/gfx/transform_operations.h"
 
 namespace gfx {
-class ScrollOffset;
+class Vector2dF;
 }
 
 namespace cc {
@@ -68,8 +68,8 @@
 };
 
 int AddScrollOffsetAnimationToAnimation(Animation* animation,
-                                        gfx::ScrollOffset initial_value,
-                                        gfx::ScrollOffset target_value);
+                                        gfx::Vector2dF initial_value,
+                                        gfx::Vector2dF target_value);
 
 int AddAnimatedTransformToAnimation(Animation* animation,
                                     double duration,
diff --git a/cc/test/animation_timelines_test_common.cc b/cc/test/animation_timelines_test_common.cc
index d65443e..9d1bb6bc 100644
--- a/cc/test/animation_timelines_test_common.cc
+++ b/cc/test/animation_timelines_test_common.cc
@@ -35,7 +35,7 @@
   opacity_ = 0;
   filters_ = FilterOperations();
   backdrop_filters_ = FilterOperations();
-  scroll_offset_ = gfx::ScrollOffset();
+  scroll_offset_ = gfx::Vector2dF();
 
   has_potential_animation_.reset();
   is_currently_animating_.reset();
@@ -141,7 +141,7 @@
 void TestHostClient::SetElementScrollOffsetMutated(
     ElementId element_id,
     ElementListType list_type,
-    const gfx::ScrollOffset& scroll_offset) {
+    const gfx::Vector2dF& scroll_offset) {
   TestLayer* layer = FindTestLayer(element_id, list_type);
   if (layer)
     layer->set_scroll_offset(scroll_offset);
@@ -176,11 +176,11 @@
 }
 
 void TestHostClient::SetScrollOffsetForAnimation(
-    const gfx::ScrollOffset& scroll_offset) {
+    const gfx::Vector2dF& scroll_offset) {
   scroll_offset_ = scroll_offset;
 }
 
-gfx::ScrollOffset TestHostClient::GetScrollOffsetForAnimation(
+gfx::Vector2dF TestHostClient::GetScrollOffsetForAnimation(
     ElementId element_id) const {
   return scroll_offset_;
 }
@@ -247,7 +247,7 @@
   return layer->transform();
 }
 
-gfx::ScrollOffset TestHostClient::GetScrollOffset(
+gfx::Vector2dF TestHostClient::GetScrollOffset(
     ElementId element_id,
     ElementListType list_type) const {
   TestLayer* layer = FindTestLayer(element_id, list_type);
diff --git a/cc/test/animation_timelines_test_common.h b/cc/test/animation_timelines_test_common.h
index 660a949..5494757 100644
--- a/cc/test/animation_timelines_test_common.h
+++ b/cc/test/animation_timelines_test_common.h
@@ -15,7 +15,7 @@
 #include "cc/trees/mutator_host_client.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/animation/keyframe/target_property.h"
-#include "ui/gfx/geometry/scroll_offset.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 #include "ui/gfx/transform.h"
 
 namespace cc {
@@ -59,8 +59,8 @@
     mutated_properties_[TargetProperty::BACKDROP_FILTER] = true;
   }
 
-  gfx::ScrollOffset scroll_offset() const { return scroll_offset_; }
-  void set_scroll_offset(const gfx::ScrollOffset& scroll_offset) {
+  gfx::Vector2dF scroll_offset() const { return scroll_offset_; }
+  void set_scroll_offset(const gfx::Vector2dF& scroll_offset) {
     scroll_offset_ = scroll_offset;
     mutated_properties_[TargetProperty::SCROLL_OFFSET] = true;
   }
@@ -97,7 +97,7 @@
   float opacity_;
   FilterOperations filters_;
   FilterOperations backdrop_filters_;
-  gfx::ScrollOffset scroll_offset_;
+  gfx::Vector2dF scroll_offset_;
 
   gfx::TargetProperties has_potential_animation_;
   gfx::TargetProperties is_currently_animating_;
@@ -138,7 +138,7 @@
   void SetElementScrollOffsetMutated(
       ElementId element_id,
       ElementListType list_type,
-      const gfx::ScrollOffset& scroll_offset) override;
+      const gfx::Vector2dF& scroll_offset) override;
 
   void ElementIsAnimatingChanged(const PropertyToElementIdMap& element_id_map,
                                  ElementListType list_type,
@@ -150,8 +150,8 @@
 
   void ScrollOffsetAnimationFinished() override {}
 
-  void SetScrollOffsetForAnimation(const gfx::ScrollOffset& scroll_offset);
-  gfx::ScrollOffset GetScrollOffsetForAnimation(
+  void SetScrollOffsetForAnimation(const gfx::Vector2dF& scroll_offset);
+  gfx::Vector2dF GetScrollOffsetForAnimation(
       ElementId element_id) const override;
 
   void NotifyAnimationWorkletStateChange(AnimationWorkletMutationState state,
@@ -183,8 +183,8 @@
   float GetOpacity(ElementId element_id, ElementListType list_type) const;
   gfx::Transform GetTransform(ElementId element_id,
                               ElementListType list_type) const;
-  gfx::ScrollOffset GetScrollOffset(ElementId element_id,
-                                    ElementListType list_type) const;
+  gfx::Vector2dF GetScrollOffset(ElementId element_id,
+                                 ElementListType list_type) const;
   bool GetHasPotentialTransformAnimation(ElementId element_id,
                                          ElementListType list_type) const;
   bool GetTransformIsCurrentlyAnimating(ElementId element_id,
@@ -227,7 +227,7 @@
   ElementIdToTestLayer layers_in_active_tree_;
   ElementIdToTestLayer layers_in_pending_tree_;
 
-  gfx::ScrollOffset scroll_offset_;
+  gfx::Vector2dF scroll_offset_;
   bool mutators_need_commit_;
 };
 
diff --git a/cc/test/layer_tree_pixel_test.cc b/cc/test/layer_tree_pixel_test.cc
index f843de7..7aa00d14 100644
--- a/cc/test/layer_tree_pixel_test.cc
+++ b/cc/test/layer_tree_pixel_test.cc
@@ -257,8 +257,7 @@
   layer->SetHitTestable(true);
   layer->SetBounds(rect.size());
   layer->SetPosition(gfx::PointF(rect.origin()));
-  layer->SetOffsetToTransformParent(
-      gfx::Vector2dF(rect.origin().x(), rect.origin().y()));
+  layer->SetOffsetToTransformParent(gfx::Vector2dF(rect.OffsetFromOrigin()));
   layer->SetBackgroundColor(color);
   return layer;
 }
diff --git a/cc/test/mock_mutator_host.h b/cc/test/mock_mutator_host.h
index 8cdb567f..dbd4b3f 100644
--- a/cc/test/mock_mutator_host.h
+++ b/cc/test/mock_mutator_host.h
@@ -75,19 +75,19 @@
                      bool(ElementId element_id));
   MOCK_METHOD5(ImplOnlyAutoScrollAnimationCreate,
                void(ElementId element_id,
-                    const gfx::ScrollOffset& target_offset,
-                    const gfx::ScrollOffset& current_offset,
+                    const gfx::Vector2dF& target_offset,
+                    const gfx::Vector2dF& current_offset,
                     float autoscroll_velocity,
                     base::TimeDelta animation_start_offset));
   MOCK_METHOD5(ImplOnlyScrollAnimationCreate,
                void(ElementId element_id,
-                    const gfx::ScrollOffset& target_offset,
-                    const gfx::ScrollOffset& current_offset,
+                    const gfx::Vector2dF& target_offset,
+                    const gfx::Vector2dF& current_offset,
                     base::TimeDelta delayed_by,
                     base::TimeDelta animation_start_offset));
   MOCK_METHOD4(ImplOnlyScrollAnimationUpdateTarget,
                bool(const gfx::Vector2dF& scroll_delta,
-                    const gfx::ScrollOffset& max_scroll_offset,
+                    const gfx::Vector2dF& max_scroll_offset,
                     base::TimeTicks frame_monotonic_time,
                     base::TimeDelta delayed_by));
   MOCK_METHOD0(ScrollAnimationAbort, void());
diff --git a/cc/test/property_tree_test_utils.cc b/cc/test/property_tree_test_utils.cc
index f03a79a..ba12b3c 100644
--- a/cc/test/property_tree_test_utils.cc
+++ b/cc/test/property_tree_test_utils.cc
@@ -4,6 +4,9 @@
 
 #include "cc/test/property_tree_test_utils.h"
 
+#include <memory>
+#include <utility>
+
 #include "cc/layers/picture_layer.h"
 #include "cc/layers/picture_layer_impl.h"
 #include "cc/trees/clip_node.h"
@@ -163,7 +166,7 @@
   transform_node->should_be_snapped = true;
   transform_node->scrolls = true;
 
-  scroll_tree.SetScrollOffset(layer->element_id(), gfx::ScrollOffset());
+  scroll_tree.SetScrollOffset(layer->element_id(), gfx::Vector2dF());
   return *node;
 }
 
@@ -190,7 +193,7 @@
 
 template <typename LayerType>
 void SetScrollOffsetInternal(LayerType* layer,
-                             const gfx::ScrollOffset& scroll_offset) {
+                             const gfx::Vector2dF& scroll_offset) {
   DCHECK(layer->has_transform_node());
   auto* transform_node = GetTransformNode(layer);
   transform_node->scroll_offset = scroll_offset;
@@ -373,7 +376,7 @@
     node->transform_id = transform_node->id;
   }
 
-  scroll_tree.SetScrollOffset(element_id, gfx::ScrollOffset());
+  scroll_tree.SetScrollOffset(element_id, gfx::Vector2dF());
   return *node;
 }
 
@@ -388,7 +391,7 @@
   SetupMaskPropertiesInternal(masked_layer, mask_layer);
 }
 
-void SetScrollOffset(Layer* layer, const gfx::ScrollOffset& scroll_offset) {
+void SetScrollOffset(Layer* layer, const gfx::Vector2dF& scroll_offset) {
   if (layer->layer_tree_host()->IsUsingLayerLists()) {
     if (CurrentScrollOffset(layer) != scroll_offset)
       layer->SetNeedsCommit();
@@ -399,14 +402,14 @@
 }
 
 void SetScrollOffsetFromImplSide(Layer* layer,
-                                 const gfx::ScrollOffset& scroll_offset) {
+                                 const gfx::Vector2dF& scroll_offset) {
   if (layer->layer_tree_host()->IsUsingLayerLists())
     SetScrollOffsetInternal(layer, scroll_offset);
   else
     layer->SetScrollOffsetFromImplSide(scroll_offset);
 }
 
-void SetScrollOffset(LayerImpl* layer, const gfx::ScrollOffset& scroll_offset) {
+void SetScrollOffset(LayerImpl* layer, const gfx::Vector2dF& scroll_offset) {
   if (layer->IsActive())
     layer->SetCurrentScrollOffset(scroll_offset);
   SetScrollOffsetInternal(layer, scroll_offset);
@@ -491,17 +494,17 @@
   return effect_tree.GetRenderSurface(GetEffectNode(layer)->target_id);
 }
 
-gfx::ScrollOffset ScrollOffsetBase(const LayerImpl* layer) {
+gfx::Vector2dF ScrollOffsetBase(const LayerImpl* layer) {
   return GetPropertyTrees(layer)->scroll_tree.GetScrollOffsetBaseForTesting(
       layer->element_id());
 }
 
-gfx::ScrollOffset ScrollDelta(const LayerImpl* layer) {
+gfx::Vector2dF ScrollDelta(const LayerImpl* layer) {
   return GetPropertyTrees(layer)->scroll_tree.GetScrollOffsetDeltaForTesting(
       layer->element_id());
 }
 
-gfx::ScrollOffset CurrentScrollOffset(const Layer* layer) {
+gfx::Vector2dF CurrentScrollOffset(const Layer* layer) {
   auto result = GetPropertyTrees(layer)->scroll_tree.current_scroll_offset(
       layer->element_id());
   if (!layer->layer_tree_host()->IsUsingLayerLists())
@@ -509,12 +512,12 @@
   return result;
 }
 
-gfx::ScrollOffset CurrentScrollOffset(const LayerImpl* layer) {
+gfx::Vector2dF CurrentScrollOffset(const LayerImpl* layer) {
   return GetPropertyTrees(layer)->scroll_tree.current_scroll_offset(
       layer->element_id());
 }
 
-gfx::ScrollOffset MaxScrollOffset(const LayerImpl* layer) {
+gfx::Vector2dF MaxScrollOffset(const LayerImpl* layer) {
   return GetPropertyTrees(layer)->scroll_tree.MaxScrollOffset(
       layer->scroll_tree_index());
 }
diff --git a/cc/test/property_tree_test_utils.h b/cc/test/property_tree_test_utils.h
index 95ef9d3..d25ff1d 100644
--- a/cc/test/property_tree_test_utils.h
+++ b/cc/test/property_tree_test_utils.h
@@ -10,7 +10,7 @@
 #include "cc/trees/property_tree.h"
 #include "cc/trees/scroll_node.h"
 #include "cc/trees/transform_node.h"
-#include "ui/gfx/geometry/scroll_offset.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 
 namespace cc {
 
@@ -96,11 +96,11 @@
   return GetPropertyTrees(layer)->scroll_tree.Node(layer->scroll_tree_index());
 }
 
-void SetScrollOffset(Layer*, const gfx::ScrollOffset&);
-void SetScrollOffset(LayerImpl*, const gfx::ScrollOffset&);
+void SetScrollOffset(Layer*, const gfx::Vector2dF&);
+void SetScrollOffset(LayerImpl*, const gfx::Vector2dF&);
 // Used to synchronize the main-thread scroll offset with the impl-side. The
 // difference from SetScrollOffset() is this function doesn't schedule commit.
-void SetScrollOffsetFromImplSide(Layer*, const gfx::ScrollOffset&);
+void SetScrollOffsetFromImplSide(Layer*, const gfx::Vector2dF&);
 
 template <typename LayerType>
 void SetLocalTransformChanged(const LayerType* layer) {
@@ -207,11 +207,11 @@
 // Returns the RenderSurfaceImpl into which the given layer draws.
 RenderSurfaceImpl* GetRenderSurface(const LayerImpl* layer);
 
-gfx::ScrollOffset ScrollOffsetBase(const LayerImpl* layer);
-gfx::ScrollOffset ScrollDelta(const LayerImpl* layer);
-gfx::ScrollOffset CurrentScrollOffset(const Layer* layer);
-gfx::ScrollOffset CurrentScrollOffset(const LayerImpl* layer);
-gfx::ScrollOffset MaxScrollOffset(const LayerImpl* layer);
+gfx::Vector2dF ScrollOffsetBase(const LayerImpl* layer);
+gfx::Vector2dF ScrollDelta(const LayerImpl* layer);
+gfx::Vector2dF CurrentScrollOffset(const Layer* layer);
+gfx::Vector2dF CurrentScrollOffset(const LayerImpl* layer);
+gfx::Vector2dF MaxScrollOffset(const LayerImpl* layer);
 
 }  // namespace cc
 
diff --git a/cc/trees/compositor_commit_data.cc b/cc/trees/compositor_commit_data.cc
index c7e0ec8..f20e03d 100644
--- a/cc/trees/compositor_commit_data.cc
+++ b/cc/trees/compositor_commit_data.cc
@@ -16,7 +16,7 @@
 
 CompositorCommitData::ScrollUpdateInfo::ScrollUpdateInfo(
     ElementId id,
-    gfx::ScrollOffset delta,
+    gfx::Vector2dF delta,
     absl::optional<TargetSnapAreaElementIds> snap_target_ids)
     : element_id(id),
       scroll_delta(delta),
diff --git a/cc/trees/compositor_commit_data.h b/cc/trees/compositor_commit_data.h
index 4fb1482..e4b179c 100644
--- a/cc/trees/compositor_commit_data.h
+++ b/cc/trees/compositor_commit_data.h
@@ -14,7 +14,6 @@
 #include "cc/paint/element_id.h"
 #include "cc/trees/layer_tree_host_client.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
-#include "ui/gfx/geometry/scroll_offset.h"
 #include "ui/gfx/geometry/vector2d.h"
 #include "ui/gfx/transform.h"
 
@@ -32,12 +31,12 @@
   struct CC_EXPORT ScrollUpdateInfo {
     ScrollUpdateInfo();
     ScrollUpdateInfo(ElementId id,
-                     gfx::ScrollOffset delta,
+                     gfx::Vector2dF delta,
                      absl::optional<TargetSnapAreaElementIds> snap_target_ids);
     ScrollUpdateInfo(const ScrollUpdateInfo& other);
     ScrollUpdateInfo& operator=(const ScrollUpdateInfo&);
     ElementId element_id;
-    gfx::ScrollOffset scroll_delta;
+    gfx::Vector2dF scroll_delta;
 
     // The target snap area element ids of the scrolling element.
     // This will have a value if the scrolled element's scroll node has snap
diff --git a/cc/trees/draw_properties_unittest.cc b/cc/trees/draw_properties_unittest.cc
index 5645823..5c1a9629 100644
--- a/cc/trees/draw_properties_unittest.cc
+++ b/cc/trees/draw_properties_unittest.cc
@@ -314,7 +314,7 @@
 }
 
 TEST_F(DrawPropertiesTest, TransformsAboutScrollOffset) {
-  const gfx::ScrollOffset kScrollOffset(50, 100);
+  const gfx::Vector2dF kScrollOffset(50, 100);
   const gfx::Vector2dF kScrollDelta(2.34f, 5.67f);
   const gfx::Vector2d kMaxScrollOffset(200, 200);
   const gfx::PointF kScrollLayerPosition(-kScrollOffset.x(),
@@ -4213,7 +4213,7 @@
   CopyProperties(render_surface2, clip_child);
   clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());
 
-  SetScrollOffset(intervening, gfx::ScrollOffset(3, 3));
+  SetScrollOffset(intervening, gfx::Vector2dF(3, 3));
   UpdateActiveTreeDrawProperties();
 
   EXPECT_TRUE(GetRenderSurface(root));
@@ -5157,7 +5157,7 @@
       sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 
   // Now the main thread commits the new position of the sticky element.
-  SetScrollOffset(scroller_.get(), gfx::ScrollOffset(15, 15));
+  SetScrollOffset(scroller_.get(), gfx::Vector2dF(15, 15));
   // Shift the layer by -offset_for_position_sticky.
   SetPostTranslation(sticky_pos_.get(),
                      gfx::PointF(10, 25) - gfx::PointF(0, 5));
@@ -5228,7 +5228,7 @@
       sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
 
   // Now the main thread commits the new position of the sticky element.
-  SetScrollOffset(scroller_.get(), gfx::ScrollOffset(0, 25));
+  SetScrollOffset(scroller_.get(), gfx::Vector2dF(0, 25));
   // Shift the layer by -offset_for_position_sticky.
   SetPostTranslation(sticky_pos_.get(),
                      gfx::PointF(0, 15) - gfx::PointF(0, 5) +
@@ -6401,7 +6401,7 @@
   UpdateActiveTreeDrawProperties();
   EXPECT_EQ(gfx::Rect(25, 25), scroll_child->visible_layer_rect());
 
-  SetScrollOffset(scroll_parent, gfx::ScrollOffset(0.f, 10.f));
+  SetScrollOffset(scroll_parent, gfx::Vector2dF(0.f, 10.f));
   UpdateActiveTreeDrawProperties();
   EXPECT_EQ(gfx::Rect(0, 5, 25, 25), scroll_child->visible_layer_rect());
 
diff --git a/cc/trees/draw_property_utils.cc b/cc/trees/draw_property_utils.cc
index 5196b018..752d7d20 100644
--- a/cc/trees/draw_property_utils.cc
+++ b/cc/trees/draw_property_utils.cc
@@ -1192,12 +1192,10 @@
 
   // On other platforms, we modify the translation offset to match the
   // overscroll amount.
-  if (overscroll_elasticity_transform_node->scroll_offset ==
-      gfx::ScrollOffset(elastic_overscroll))
+  if (overscroll_elasticity_transform_node->scroll_offset == elastic_overscroll)
     return;
 
-  overscroll_elasticity_transform_node->scroll_offset =
-      gfx::ScrollOffset(elastic_overscroll);
+  overscroll_elasticity_transform_node->scroll_offset = elastic_overscroll;
 
   overscroll_elasticity_transform_node->needs_local_transform_update = true;
   property_trees->transform_tree.set_needs_update(true);
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index b3b5bda..060996e9 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -924,7 +924,7 @@
 
 void LayerTreeHost::ApplyViewportChanges(
     const CompositorCommitData& commit_data) {
-  gfx::ScrollOffset inner_viewport_scroll_delta;
+  gfx::Vector2dF inner_viewport_scroll_delta;
   if (commit_data.inner_viewport_scroll.element_id)
     inner_viewport_scroll_delta =
         commit_data.inner_viewport_scroll.scroll_delta;
@@ -982,7 +982,7 @@
 
 void LayerTreeHost::UpdateScrollOffsetFromImpl(
     const ElementId& id,
-    const gfx::ScrollOffset& delta,
+    const gfx::Vector2dF& delta,
     const absl::optional<TargetSnapAreaElementIds>& snap_target_ids) {
   if (IsUsingLayerLists()) {
     auto& scroll_tree = property_trees()->scroll_tree;
@@ -1909,7 +1909,7 @@
 void LayerTreeHost::SetElementScrollOffsetMutated(
     ElementId element_id,
     ElementListType list_type,
-    const gfx::ScrollOffset& scroll_offset) {
+    const gfx::Vector2dF& scroll_offset) {
   // Do nothing. Scroll deltas will be sent from the compositor thread back
   // to the main thread in the same manner as during non-animated
   // compositor-driven scrolling.
@@ -1932,7 +1932,7 @@
   property_trees()->MaximumAnimationScaleChanged(element_id, maximum_scale);
 }
 
-gfx::ScrollOffset LayerTreeHost::GetScrollOffsetForAnimation(
+gfx::Vector2dF LayerTreeHost::GetScrollOffsetForAnimation(
     ElementId element_id) const {
   return property_trees()->scroll_tree.current_scroll_offset(element_id);
 }
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h
index ec195995..eee887e 100644
--- a/cc/trees/layer_tree_host.h
+++ b/cc/trees/layer_tree_host.h
@@ -708,7 +708,7 @@
   void SetElementScrollOffsetMutated(
       ElementId element_id,
       ElementListType list_type,
-      const gfx::ScrollOffset& scroll_offset) override;
+      const gfx::Vector2dF& scroll_offset) override;
 
   void ElementIsAnimatingChanged(const PropertyToElementIdMap& element_id_map,
                                  ElementListType list_type,
@@ -723,7 +723,7 @@
       PaintWorkletInput::PropertyValue property_value) override {}
 
   void ScrollOffsetAnimationFinished() override {}
-  gfx::ScrollOffset GetScrollOffsetForAnimation(
+  gfx::Vector2dF GetScrollOffsetForAnimation(
       ElementId element_id) const override;
 
   void NotifyAnimationWorkletStateChange(AnimationWorkletMutationState state,
@@ -829,7 +829,7 @@
   // client. This lets the client skip a commit if the value does not change.
   void UpdateScrollOffsetFromImpl(
       const ElementId&,
-      const gfx::ScrollOffset& delta,
+      const gfx::Vector2dF& delta,
       const absl::optional<TargetSnapAreaElementIds>&);
 
   const CompositorMode compositor_mode_;
diff --git a/cc/trees/layer_tree_host_client.h b/cc/trees/layer_tree_host_client.h
index 1d085ee..ff05cf6 100644
--- a/cc/trees/layer_tree_host_client.h
+++ b/cc/trees/layer_tree_host_client.h
@@ -13,7 +13,6 @@
 #include "cc/metrics/frame_sequence_tracker_collection.h"
 #include "cc/trees/paint_holding_reason.h"
 #include "cc/trees/property_tree.h"
-#include "ui/gfx/geometry/scroll_offset.h"
 #include "ui/gfx/geometry/vector2d_f.h"
 
 namespace gfx {
@@ -30,7 +29,7 @@
 
 struct ApplyViewportChangesArgs {
   // Scroll offset delta of the inner (visual) viewport.
-  gfx::ScrollOffset inner_delta;
+  gfx::Vector2dF inner_delta;
 
   // Elastic overscroll effect offset delta. This is used only on Mac. a.k.a
   // "rubber-banding" overscroll.
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index d002beb..eb239e55 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -132,7 +132,6 @@
 #include "ui/gfx/display_color_spaces.h"
 #include "ui/gfx/geometry/point_conversions.h"
 #include "ui/gfx/geometry/rect_conversions.h"
-#include "ui/gfx/geometry/scroll_offset.h"
 #include "ui/gfx/geometry/size_conversions.h"
 #include "ui/gfx/geometry/vector2d_conversions.h"
 #include "ui/gfx/geometry/vector2d_f.h"
@@ -947,16 +946,15 @@
   if (!InnerViewportScrollNode())
     return;
 
-  gfx::ScrollOffset scroll_total = active_tree_->TotalScrollOffset();
+  gfx::Vector2dF scroll_total = active_tree_->TotalScrollOffset();
   gfx::SizeF scrollable_size = active_tree_->ScrollableSize();
   gfx::SizeF viewport_size(
       active_tree_->InnerViewportScrollNode()->container_bounds);
 
   // TODO(miletus) : Pass in ScrollOffset.
-  page_scale_animation_ =
-      PageScaleAnimation::Create(ScrollOffsetToVector2dF(scroll_total),
-                                 active_tree_->current_page_scale_factor(),
-                                 viewport_size, scrollable_size);
+  page_scale_animation_ = PageScaleAnimation::Create(
+      scroll_total, active_tree_->current_page_scale_factor(), viewport_size,
+      scrollable_size);
 
   if (anchor_point) {
     gfx::Vector2dF anchor(target_offset);
@@ -2224,8 +2222,7 @@
 
   if (InnerViewportScrollNode()) {
     // TODO(miletus) : Change the metadata to hold ScrollOffset.
-    metadata.root_scroll_offset =
-        gfx::ScrollOffsetToVector2dF(active_tree_->TotalScrollOffset());
+    metadata.root_scroll_offset = active_tree_->TotalScrollOffset();
   }
 
   metadata.display_transform_hint = active_tree_->display_transform_hint();
@@ -2245,8 +2242,7 @@
 RenderFrameMetadata LayerTreeHostImpl::MakeRenderFrameMetadata(
     FrameData* frame) {
   RenderFrameMetadata metadata;
-  metadata.root_scroll_offset =
-      gfx::ScrollOffsetToVector2dF(active_tree_->TotalScrollOffset());
+  metadata.root_scroll_offset = active_tree_->TotalScrollOffset();
 
   metadata.root_background_color = active_tree_->background_color();
   metadata.is_scroll_offset_at_top = active_tree_->TotalScrollOffset().y() == 0;
@@ -3874,7 +3870,7 @@
   return active_tree_->CurrentBottomControlsShownRatio();
 }
 
-gfx::ScrollOffset LayerTreeHostImpl::ViewportScrollOffset() const {
+gfx::Vector2dF LayerTreeHostImpl::ViewportScrollOffset() const {
   return viewport_->TotalScrollOffset();
 }
 
@@ -3910,10 +3906,10 @@
     return false;
   }
 
-  gfx::ScrollOffset current_offset =
+  gfx::Vector2dF current_offset =
       scroll_tree.current_scroll_offset(scroll_node.element_id);
-  gfx::ScrollOffset target_offset = scroll_tree.ClampScrollOffsetToLimits(
-      current_offset + gfx::ScrollOffset(delta), scroll_node);
+  gfx::Vector2dF target_offset = scroll_tree.ClampScrollOffsetToLimits(
+      current_offset + delta, scroll_node);
 
   // Start the animation one full frame in. Without any offset, the animation
   // doesn't start until next frame, increasing latency, and preventing our
@@ -3922,7 +3918,7 @@
 
   if (autoscroll_velocity) {
     mutator_host_->ImplOnlyAutoScrollAnimationCreate(
-        scroll_node.element_id, gfx::ScrollOffset(delta), current_offset,
+        scroll_node.element_id, delta, current_offset,
         autoscroll_velocity.value(), animation_start_offset);
   } else {
     mutator_host_->ImplOnlyScrollAnimationCreate(
@@ -4091,17 +4087,17 @@
   if (!page_scale_animation_)
     return false;
 
-  gfx::ScrollOffset scroll_total = active_tree_->TotalScrollOffset();
+  gfx::Vector2dF scroll_total = active_tree_->TotalScrollOffset();
 
   if (!page_scale_animation_->IsAnimationStarted())
     page_scale_animation_->StartAnimation(monotonic_time);
 
   active_tree_->SetPageScaleOnActiveTree(
       page_scale_animation_->PageScaleFactorAtTime(monotonic_time));
-  gfx::ScrollOffset next_scroll = gfx::ScrollOffset(
-      page_scale_animation_->ScrollOffsetAtTime(monotonic_time));
+  gfx::Vector2dF next_scroll =
+      gfx::Vector2dF(page_scale_animation_->ScrollOffsetAtTime(monotonic_time));
 
-  viewport().ScrollByInnerFirst(next_scroll.DeltaFrom(scroll_total));
+  viewport().ScrollByInnerFirst(next_scroll - scroll_total);
 
   if (page_scale_animation_->IsAnimationCompleteAtTime(monotonic_time)) {
     page_scale_animation_ = nullptr;
@@ -4757,7 +4753,7 @@
 void LayerTreeHostImpl::SetTreeLayerScrollOffsetMutated(
     ElementId element_id,
     LayerTreeImpl* tree,
-    const gfx::ScrollOffset& scroll_offset) {
+    const gfx::Vector2dF& scroll_offset) {
   if (!tree)
     return;
 
@@ -4839,7 +4835,7 @@
 void LayerTreeHostImpl::SetElementScrollOffsetMutated(
     ElementId element_id,
     ElementListType list_type,
-    const gfx::ScrollOffset& scroll_offset) {
+    const gfx::Vector2dF& scroll_offset) {
   if (list_type == ElementListType::ACTIVE) {
     SetTreeLayerScrollOffsetMutated(element_id, active_tree(), scroll_offset);
     ShowScrollbarsForImplScroll(element_id);
@@ -4894,14 +4890,14 @@
   }
 }
 
-gfx::ScrollOffset LayerTreeHostImpl::GetScrollOffsetForAnimation(
+gfx::Vector2dF LayerTreeHostImpl::GetScrollOffsetForAnimation(
     ElementId element_id) const {
   if (active_tree()) {
     return active_tree()->property_trees()->scroll_tree.current_scroll_offset(
         element_id);
   }
 
-  return gfx::ScrollOffset();
+  return gfx::Vector2dF();
 }
 
 bool LayerTreeHostImpl::CommitToActiveTree() const {
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index d9a9065..472c924 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -77,7 +77,7 @@
 #include "ui/gfx/geometry/rect.h"
 
 namespace gfx {
-class ScrollOffset;
+class Vector2dF;
 }
 
 namespace viz {
@@ -309,7 +309,7 @@
                                            float bottom_ratio) override;
   float CurrentTopControlsShownRatio() const override;
   float CurrentBottomControlsShownRatio() const override;
-  gfx::ScrollOffset ViewportScrollOffset() const override;
+  gfx::Vector2dF ViewportScrollOffset() const override;
   void DidChangeBrowserControlsPosition() override;
   void DidObserveScrollDelay(base::TimeDelta scroll_delay,
                              base::TimeTicks scroll_timestamp);
@@ -419,7 +419,7 @@
 
   void SetTreeLayerScrollOffsetMutated(ElementId element_id,
                                        LayerTreeImpl* tree,
-                                       const gfx::ScrollOffset& scroll_offset);
+                                       const gfx::Vector2dF& scroll_offset);
   void SetNeedUpdateGpuRasterizationStatus();
   bool NeedUpdateGpuRasterizationStatusForTesting() const {
     return need_update_gpu_rasterization_status_;
@@ -446,7 +446,7 @@
   void SetElementScrollOffsetMutated(
       ElementId element_id,
       ElementListType list_type,
-      const gfx::ScrollOffset& scroll_offset) override;
+      const gfx::Vector2dF& scroll_offset) override;
   void ElementIsAnimatingChanged(const PropertyToElementIdMap& element_id_map,
                                  ElementListType list_type,
                                  const PropertyAnimationState& mask,
@@ -459,7 +459,7 @@
       PaintWorkletInput::PropertyValue property_value) override;
 
   void ScrollOffsetAnimationFinished() override;
-  gfx::ScrollOffset GetScrollOffsetForAnimation(
+  gfx::Vector2dF GetScrollOffsetForAnimation(
       ElementId element_id) const override;
 
   void NotifyAnimationWorkletStateChange(AnimationWorkletMutationState state,
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index fdb9098..ab0f992 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -353,14 +353,6 @@
         size, host_impl_->active_tree()->device_scale_factor());
   }
 
-  static gfx::Vector2dF ScrollDelta(LayerImpl* layer_impl) {
-    gfx::ScrollOffset delta = layer_impl->layer_tree_impl()
-                                  ->property_trees()
-                                  ->scroll_tree.GetScrollOffsetDeltaForTesting(
-                                      layer_impl->element_id());
-    return gfx::Vector2dF(delta.x(), delta.y());
-  }
-
   static void ExpectClearedScrollDeltasRecursive(LayerImpl* root) {
     for (auto* layer : *root->layer_tree_impl())
       ASSERT_EQ(ScrollDelta(layer), gfx::Vector2d());
@@ -369,7 +361,7 @@
   static ::testing::AssertionResult ScrollInfoContains(
       const CompositorCommitData& commit_data,
       ElementId id,
-      const gfx::ScrollOffset& scroll_delta) {
+      const gfx::Vector2dF& scroll_delta) {
     int times_encountered = 0;
 
     for (size_t i = 0; i < commit_data.scrolls.size(); ++i) {
@@ -758,7 +750,7 @@
         OuterViewportScrollLayer(), gfx::Size(100, 100), overflow_size);
     SnapContainerData container_data(
         ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
-        gfx::RectF(0, 0, 200, 200), gfx::ScrollOffset(300, 300));
+        gfx::RectF(0, 0, 200, 200), gfx::Vector2dF(300, 300));
     SnapAreaData area_data(ScrollSnapAlign(SnapAlignment::kStart),
                            gfx::RectF(50, 50, 100, 100), false, ElementId(10));
     container_data.AddSnapAreaData(area_data);
@@ -929,8 +921,8 @@
   void ReconcileElasticOverscrollAndRootScroll() override {}
   void SetPrefersReducedMotion(bool prefers_reduced_motion) override {}
   void UpdateRootLayerStateForSynchronousInputHandler(
-      const gfx::ScrollOffset& total_scroll_offset,
-      const gfx::ScrollOffset& max_scroll_offset,
+      const gfx::Vector2dF& total_scroll_offset,
+      const gfx::Vector2dF& max_scroll_offset,
       const gfx::SizeF& scrollable_size,
       float page_scale_factor,
       float min_page_scale_factor,
@@ -947,9 +939,9 @@
   void DeliverInputForBeginFrame(const viz::BeginFrameArgs& args) override {}
   void DeliverInputForHighLatencyMode() override {}
 
-  gfx::ScrollOffset last_set_scroll_offset() { return last_set_scroll_offset_; }
+  gfx::Vector2dF last_set_scroll_offset() { return last_set_scroll_offset_; }
 
-  gfx::ScrollOffset max_scroll_offset() const { return max_scroll_offset_; }
+  gfx::Vector2dF max_scroll_offset() const { return max_scroll_offset_; }
 
   gfx::SizeF scrollable_size() const { return scrollable_size_; }
 
@@ -960,8 +952,8 @@
   float max_page_scale_factor() const { return max_page_scale_factor_; }
 
  private:
-  gfx::ScrollOffset last_set_scroll_offset_;
-  gfx::ScrollOffset max_scroll_offset_;
+  gfx::Vector2dF last_set_scroll_offset_;
+  gfx::Vector2dF max_scroll_offset_;
   gfx::SizeF scrollable_size_;
   float page_scale_factor_;
   float min_page_scale_factor_;
@@ -1087,8 +1079,8 @@
 }
 
 TEST_P(ScrollUnifiedLayerTreeHostImplTest, ScrollDeltaRepeatedScrolls) {
-  gfx::ScrollOffset scroll_offset(20, 30);
-  gfx::ScrollOffset scroll_delta(11, -15);
+  gfx::Vector2dF scroll_offset(20, 30);
+  gfx::Vector2dF scroll_delta(11, -15);
 
   auto* root = SetupDefaultRootLayer(gfx::Size(110, 110));
   root->SetHitTestable(true);
@@ -1101,14 +1093,14 @@
 
   std::unique_ptr<CompositorCommitData> commit_data;
 
-  root->ScrollBy(gfx::ScrollOffsetToVector2dF(scroll_delta));
+  root->ScrollBy(scroll_delta);
   commit_data = host_impl_->ProcessCompositorDeltas();
   ASSERT_EQ(commit_data->scrolls.size(), 1u);
   EXPECT_TRUE(
       ScrollInfoContains(*commit_data, root->element_id(), scroll_delta));
 
-  gfx::ScrollOffset scroll_delta2(-5, 27);
-  root->ScrollBy(gfx::ScrollOffsetToVector2dF(scroll_delta2));
+  gfx::Vector2dF scroll_delta2(-5, 27);
+  root->ScrollBy(scroll_delta2);
   commit_data = host_impl_->ProcessCompositorDeltas();
   ASSERT_EQ(commit_data->scrolls.size(), 1u);
   EXPECT_TRUE(ScrollInfoContains(*commit_data, root->element_id(),
@@ -1422,16 +1414,14 @@
   DrawFrame();
 
   // We should not crash if the tree is replaced while we are scrolling.
-  gfx::ScrollOffset scroll_delta(0, 10);
-  EXPECT_EQ(
-      ScrollThread::SCROLL_ON_IMPL_THREAD,
-      GetInputHandler()
-          .ScrollBegin(BeginState(gfx::Point(),
-                                  gfx::ScrollOffsetToVector2dF(scroll_delta),
-                                  ui::ScrollInputType::kWheel)
-                           .get(),
-                       ui::ScrollInputType::kWheel)
-          .thread);
+  gfx::Vector2dF scroll_delta(0, 10);
+  EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD,
+            GetInputHandler()
+                .ScrollBegin(BeginState(gfx::Point(), scroll_delta,
+                                        ui::ScrollInputType::kWheel)
+                                 .get(),
+                             ui::ScrollInputType::kWheel)
+                .thread);
   ClearLayersAndPropertyTrees(host_impl_->active_tree());
 
   SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100));
@@ -1440,8 +1430,7 @@
   // We should still be scrolling, because the scrolled layer also exists in the
   // new tree.
   GetInputHandler().ScrollUpdate(
-      UpdateState(gfx::Point(), gfx::ScrollOffsetToVector2dF(scroll_delta),
-                  ui::ScrollInputType::kWheel)
+      UpdateState(gfx::Point(), scroll_delta, ui::ScrollInputType::kWheel)
           .get());
   GetInputHandler().ScrollEnd();
   std::unique_ptr<CompositorCommitData> commit_data =
@@ -2667,7 +2656,7 @@
   BeginImplFrameAndAnimate(begin_frame_args,
                            start_time + base::Milliseconds(50));
   EXPECT_FALSE(GetInputHandler().animating_for_snap_for_testing());
-  gfx::ScrollOffset current_offset = CurrentScrollOffset(overflow);
+  gfx::Vector2dF current_offset = CurrentScrollOffset(overflow);
   EXPECT_LT(0, current_offset.x());
   EXPECT_GT(20, current_offset.x());
   EXPECT_LT(0, current_offset.y());
@@ -2725,7 +2714,7 @@
   EXPECT_EQ(TargetSnapAreaElementIds(),
             GetSnapContainerData(overflow)->GetTargetSnapAreaElementIds());
 
-  gfx::ScrollOffset current_offset = CurrentScrollOffset(overflow);
+  gfx::Vector2dF current_offset = CurrentScrollOffset(overflow);
   EXPECT_GT(50, current_offset.y());
   EXPECT_LT(20, current_offset.y());
 
@@ -2791,7 +2780,7 @@
   EXPECT_EQ(TargetSnapAreaElementIds(),
             GetSnapContainerData(overflow)->GetTargetSnapAreaElementIds());
 
-  gfx::ScrollOffset current_offset = CurrentScrollOffset(overflow);
+  gfx::Vector2dF current_offset = CurrentScrollOffset(overflow);
   EXPECT_GT(50, current_offset.x());
   EXPECT_LT(20, current_offset.x());
   EXPECT_EQ(0, current_offset.y());
@@ -2811,8 +2800,7 @@
 
   BeginImplFrameAndAnimate(begin_frame_args,
                            start_time + base::Milliseconds(150));
-  EXPECT_VECTOR_EQ(gfx::ScrollOffsetToVector2dF(current_offset),
-                   CurrentScrollOffset(overflow));
+  EXPECT_VECTOR_EQ(current_offset, CurrentScrollOffset(overflow));
   BeginImplFrameAndAnimate(begin_frame_args,
                            start_time + base::Milliseconds(1000));
   // Ensure that the snap target was not updated at the end of the scroll
@@ -2959,7 +2947,7 @@
   gfx::Size overflow_size(400, 400);
   LayerImpl* overflow = AddScrollableLayer(OuterViewportScrollLayer(),
                                            gfx::Size(100, 100), overflow_size);
-  SetScrollOffset(scroll_layer, gfx::ScrollOffset(30, 30));
+  SetScrollOffset(scroll_layer, gfx::Vector2dF(30, 30));
 
   DrawFrame();
   gfx::Point pointer_position(50, 50);
@@ -3523,13 +3511,11 @@
   // interaction to be "actively scrolling". Expect this to be false.
   EXPECT_FALSE(host_impl_->CurrentScrollCheckerboardsDueToNoRecording());
 
-  gfx::ScrollOffset scroll_delta(0, 10);
+  gfx::Vector2dF scroll_delta(0, 10);
 
   // Send scroll update.
   GetInputHandler().ScrollUpdate(
-      UpdateState(gfx::Point(10, 10),
-                  gfx::ScrollOffsetToVector2dF(scroll_delta),
-                  ui::ScrollInputType::kWheel)
+      UpdateState(gfx::Point(10, 10), scroll_delta, ui::ScrollInputType::kWheel)
           .get());
 
   host_impl_->SetFullViewportDamage();
@@ -3586,7 +3572,7 @@
         host_impl_->ProcessCompositorDeltas();
     EXPECT_EQ(commit_data->page_scale_delta, page_scale_delta);
 
-    EXPECT_EQ(gfx::ScrollOffset(75.0, 75.0), MaxScrollOffset(scroll_layer));
+    EXPECT_EQ(gfx::Vector2dF(75.0, 75.0), MaxScrollOffset(scroll_layer));
   }
 
   // Scrolling after a pinch gesture should always be in local space.  The
@@ -3624,7 +3610,7 @@
         host_impl_->ProcessCompositorDeltas();
     EXPECT_TRUE(ScrollInfoContains(
         *commit_data.get(), scroll_layer->element_id(),
-        gfx::ScrollOffset(0, scroll_delta.y() / page_scale_delta)));
+        gfx::Vector2dF(0, scroll_delta.y() / page_scale_delta)));
   }
 }
 
@@ -4218,7 +4204,7 @@
     scroll_layer->layer_tree_impl()
         ->property_trees()
         ->scroll_tree.UpdateScrollOffsetBaseForTesting(
-            scroll_layer->element_id(), gfx::ScrollOffset(50, 50));
+            scroll_layer->element_id(), gfx::Vector2dF(50, 50));
 
     float page_scale_delta = 0.1f;
     GetInputHandler().ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF(),
@@ -4248,7 +4234,7 @@
     scroll_layer->layer_tree_impl()
         ->property_trees()
         ->scroll_tree.UpdateScrollOffsetBaseForTesting(
-            scroll_layer->element_id(), gfx::ScrollOffset(20, 20));
+            scroll_layer->element_id(), gfx::Vector2dF(20, 20));
 
     float page_scale_delta = 1;
     GetInputHandler().ScrollBegin(
@@ -4279,7 +4265,7 @@
     scroll_layer->layer_tree_impl()
         ->property_trees()
         ->scroll_tree.UpdateScrollOffsetBaseForTesting(
-            scroll_layer->element_id(), gfx::ScrollOffset(20, 20));
+            scroll_layer->element_id(), gfx::Vector2dF(20, 20));
 
     float page_scale_delta = 1;
     GetInputHandler().ScrollBegin(
@@ -4301,7 +4287,7 @@
         host_impl_->ProcessCompositorDeltas();
     EXPECT_EQ(commit_data->page_scale_delta, page_scale_delta);
     EXPECT_TRUE(ScrollInfoContains(*commit_data, scroll_layer->element_id(),
-                                   gfx::ScrollOffset(-10, -10)));
+                                   gfx::Vector2dF(-10, -10)));
   }
 
   // Two-finger panning should work when starting fully zoomed out.
@@ -4314,7 +4300,7 @@
     scroll_layer->layer_tree_impl()
         ->property_trees()
         ->scroll_tree.UpdateScrollOffsetBaseForTesting(
-            scroll_layer->element_id(), gfx::ScrollOffset(0, 0));
+            scroll_layer->element_id(), gfx::Vector2dF(0, 0));
 
     GetInputHandler().ScrollBegin(BeginState(gfx::Point(0, 0), gfx::Vector2dF(),
                                              ui::ScrollInputType::kTouchscreen)
@@ -4339,7 +4325,7 @@
         host_impl_->ProcessCompositorDeltas();
     EXPECT_EQ(commit_data->page_scale_delta, 2);
     EXPECT_TRUE(ScrollInfoContains(*commit_data, scroll_layer->element_id(),
-                                   gfx::ScrollOffset(10, 10)));
+                                   gfx::Vector2dF(10, 10)));
   }
 }
 
@@ -4362,7 +4348,7 @@
   scroll_layer->layer_tree_impl()
       ->property_trees()
       ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->element_id(),
-                                                     gfx::ScrollOffset(0, 20));
+                                                     gfx::Vector2dF(0, 20));
 
   float page_scale_delta = 1;
   GetInputHandler().ScrollBegin(BeginState(gfx::Point(10, 10), gfx::Vector2dF(),
@@ -4383,7 +4369,7 @@
       host_impl_->ProcessCompositorDeltas();
   EXPECT_EQ(commit_data->page_scale_delta, page_scale_delta);
   EXPECT_TRUE(ScrollInfoContains(*commit_data, scroll_layer->element_id(),
-                                 gfx::ScrollOffset(0, -1)));
+                                 gfx::Vector2dF(0, -1)));
 
   // Verify this scroll delta is consistent with the snapped position of the
   // scroll layer.
@@ -4407,8 +4393,8 @@
       ->scroll_tree.CollectScrollDeltasForTesting();
   scroll_layer->layer_tree_impl()
       ->property_trees()
-      ->scroll_tree.UpdateScrollOffsetBaseForTesting(
-          scroll_layer->element_id(), gfx::ScrollOffset(0, 20.5f));
+      ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->element_id(),
+                                                     gfx::Vector2dF(0, 20.5f));
 
   GetInputHandler().ScrollBegin(
       BeginState(gfx::Point(10, 10), gfx::Vector2dF(0, -1),
@@ -4421,11 +4407,10 @@
                                      .get());
   GetInputHandler().ScrollEnd();
 
-  gfx::ScrollOffset active_base =
-      host_impl_->active_tree()
-          ->property_trees()
-          ->scroll_tree.GetScrollOffsetBaseForTesting(
-              scroll_layer->element_id());
+  gfx::Vector2dF active_base = host_impl_->active_tree()
+                                   ->property_trees()
+                                   ->scroll_tree.GetScrollOffsetBaseForTesting(
+                                       scroll_layer->element_id());
   EXPECT_VECTOR_EQ(active_base, gfx::Vector2dF(0, 20.5));
   // Fractional active base should not affect the scroll delta.
   std::unique_ptr<CompositorCommitData> commit_data =
@@ -4580,7 +4565,7 @@
     scroll_layer->layer_tree_impl()
         ->property_trees()
         ->scroll_tree.UpdateScrollOffsetBaseForTesting(
-            scroll_layer->element_id(), gfx::ScrollOffset(50, 50));
+            scroll_layer->element_id(), gfx::Vector2dF(50, 50));
 
     did_request_redraw_ = false;
     did_request_next_frame_ = false;
@@ -4626,7 +4611,7 @@
         host_impl_->ProcessCompositorDeltas();
     EXPECT_EQ(commit_data->page_scale_delta, 2);
     EXPECT_TRUE(ScrollInfoContains(*commit_data, scroll_layer->element_id(),
-                                   gfx::ScrollOffset(-50, -50)));
+                                   gfx::Vector2dF(-50, -50)));
   }
 
   start_time += base::Seconds(10);
@@ -4640,7 +4625,7 @@
     scroll_layer->layer_tree_impl()
         ->property_trees()
         ->scroll_tree.UpdateScrollOffsetBaseForTesting(
-            scroll_layer->element_id(), gfx::ScrollOffset(50, 50));
+            scroll_layer->element_id(), gfx::Vector2dF(50, 50));
 
     did_request_redraw_ = false;
     did_request_next_frame_ = false;
@@ -4678,7 +4663,7 @@
     EXPECT_EQ(commit_data->page_scale_delta, min_page_scale);
     // Pushed to (0,0) via clamping against contents layer size.
     EXPECT_TRUE(ScrollInfoContains(*commit_data, scroll_layer->element_id(),
-                                   gfx::ScrollOffset(-50, -50)));
+                                   gfx::Vector2dF(-50, -50)));
   }
 }
 
@@ -4706,7 +4691,7 @@
     scroll_layer->layer_tree_impl()
         ->property_trees()
         ->scroll_tree.UpdateScrollOffsetBaseForTesting(
-            scroll_layer->element_id(), gfx::ScrollOffset(50, 50));
+            scroll_layer->element_id(), gfx::Vector2dF(50, 50));
 
     host_impl_->active_tree()->SetPendingPageScaleAnimation(
         std::make_unique<PendingPageScaleAnimation>(gfx::Vector2d(), true, 1,
@@ -4770,7 +4755,7 @@
   scroll_layer->layer_tree_impl()
       ->property_trees()
       ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->element_id(),
-                                                     gfx::ScrollOffset(50, 50));
+                                                     gfx::Vector2dF(50, 50));
 
   // Make sure TakePageScaleAnimation works properly.
 
@@ -4860,7 +4845,7 @@
       host_impl_->ProcessCompositorDeltas();
   EXPECT_EQ(commit_data->page_scale_delta, target_scale);
   EXPECT_TRUE(ScrollInfoContains(*commit_data, scroll_layer->element_id(),
-                                 gfx::ScrollOffset(-50, -50)));
+                                 gfx::Vector2dF(-50, -50)));
 }
 
 TEST_P(ScrollUnifiedLayerTreeHostImplTest,
@@ -4883,7 +4868,7 @@
   scroll_layer->layer_tree_impl()
       ->property_trees()
       ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->element_id(),
-                                                     gfx::ScrollOffset(50, 50));
+                                                     gfx::Vector2dF(50, 50));
 
   did_complete_page_scale_animation_ = false;
   host_impl_->active_tree()->SetPendingPageScaleAnimation(
@@ -4922,7 +4907,7 @@
   DCHECK(inner_scroll);
   EXPECT_EQ(gfx::SizeF(50, 50),
             host_impl_->active_tree()->ScrollableViewportSize());
-  EXPECT_EQ(gfx::ScrollOffset(50, 50), MaxScrollOffset(inner_scroll));
+  EXPECT_EQ(gfx::Vector2dF(50, 50), MaxScrollOffset(inner_scroll));
 
   PropertyTrees* property_trees = host_impl_->active_tree()->property_trees();
   property_trees->SetInnerViewportContainerBoundsDelta(gfx::Vector2dF(15, 15));
@@ -4930,7 +4915,7 @@
   // Container grows in response to the inner viewport bounds delta.
   EXPECT_EQ(gfx::SizeF(65, 65),
             host_impl_->active_tree()->ScrollableViewportSize());
-  EXPECT_EQ(gfx::ScrollOffset(42, 42), MaxScrollOffset(inner_scroll));
+  EXPECT_EQ(gfx::Vector2dF(42, 42), MaxScrollOffset(inner_scroll));
 
   property_trees->SetInnerViewportContainerBoundsDelta(gfx::Vector2dF());
   property_trees->SetOuterViewportContainerBoundsDelta(gfx::Vector2dF());
@@ -4939,7 +4924,7 @@
   DrawFrame();
 
   property_trees->SetOuterViewportContainerBoundsDelta(gfx::Vector2dF(60, 60));
-  EXPECT_EQ(gfx::ScrollOffset(10, 10), MaxScrollOffset(inner_scroll));
+  EXPECT_EQ(gfx::Vector2dF(10, 10), MaxScrollOffset(inner_scroll));
 }
 
 // Ensures scroll gestures coming from scrollbars cause animations in the
@@ -5269,8 +5254,7 @@
     if (host_impl_->active_tree()
             ->property_trees()
             ->scroll_tree.UpdateScrollOffsetBaseForTesting(
-                InnerViewportScrollLayer()->element_id(),
-                gfx::ScrollOffset(5, 5)))
+                InnerViewportScrollLayer()->element_id(), gfx::Vector2dF(5, 5)))
       host_impl_->active_tree()->DidUpdateScrollOffset(
           InnerViewportScrollLayer()->element_id());
     EXPECT_FALSE(did_request_next_frame_);
@@ -6668,7 +6652,7 @@
   host_impl_->ActivateSyncTree();
 
   CreatePendingTree();
-  const gfx::ScrollOffset pending_scroll = gfx::ScrollOffset(-100, -100);
+  const gfx::Vector2dF pending_scroll = gfx::Vector2dF(-100, -100);
   LayerImpl* active_outer_layer = OuterViewportScrollLayer();
   LayerImpl* pending_outer_layer =
       host_impl_->pending_tree()->OuterViewportScrollLayerForTesting();
@@ -6679,7 +6663,7 @@
 
   host_impl_->ActivateSyncTree();
   // Scrolloffsets on the active tree will be clamped after activation.
-  EXPECT_EQ(CurrentScrollOffset(active_outer_layer), gfx::ScrollOffset(0, 0));
+  EXPECT_EQ(CurrentScrollOffset(active_outer_layer), gfx::Vector2dF(0, 0));
 }
 
 class LayerTreeHostImplBrowserControlsTest
@@ -7112,7 +7096,7 @@
                                      .get());
   EXPECT_EQ(50, CurrentScrollOffset(inner_scroll).y());
   EXPECT_EQ(0, CurrentScrollOffset(outer_scroll).y());
-  EXPECT_EQ(gfx::ScrollOffset(), MaxScrollOffset(outer_scroll));
+  EXPECT_EQ(gfx::Vector2dF(), MaxScrollOffset(outer_scroll));
 
   GetInputHandler().ScrollEnd();
 
@@ -7488,7 +7472,7 @@
   SetScrollOffsetDelta(outer_scroll, gfx::Vector2dF(0, 200));
   SetScrollOffsetDelta(inner_scroll, gfx::Vector2dF(100, 100));
 
-  gfx::ScrollOffset viewport_offset =
+  gfx::Vector2dF viewport_offset =
       host_impl_->active_tree()->TotalScrollOffset();
   EXPECT_EQ(host_impl_->active_tree()->TotalMaxScrollOffset(), viewport_offset);
 
@@ -7720,7 +7704,7 @@
   GetInputHandler().ScrollEnd();
 
   // Verify the layer is once-again non-scrollable.
-  EXPECT_EQ(gfx::ScrollOffset(), MaxScrollOffset(InnerViewportScrollLayer()));
+  EXPECT_EQ(gfx::Vector2dF(), MaxScrollOffset(InnerViewportScrollLayer()));
 
   EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD,
             GetInputHandler()
@@ -8022,9 +8006,9 @@
   DrawFrame();
 
   gfx::Vector2d scroll_delta(0, 10);
-  gfx::ScrollOffset expected_scroll_delta(scroll_delta);
+  gfx::Vector2dF expected_scroll_delta(scroll_delta);
   LayerImpl* outer_scroll = OuterViewportScrollLayer();
-  gfx::ScrollOffset expected_max_scroll = MaxScrollOffset(outer_scroll);
+  gfx::Vector2dF expected_max_scroll = MaxScrollOffset(outer_scroll);
   EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD,
             GetInputHandler()
                 .ScrollBegin(BeginState(gfx::Point(5, 5), scroll_delta,
@@ -8066,9 +8050,9 @@
   DrawFrame();
 
   gfx::Vector2d scroll_delta(0, 10);
-  gfx::ScrollOffset expected_scroll_delta(scroll_delta);
+  gfx::Vector2dF expected_scroll_delta(scroll_delta);
   LayerImpl* outer_scroll = OuterViewportScrollLayer();
-  gfx::ScrollOffset expected_max_scroll = MaxScrollOffset(outer_scroll);
+  gfx::Vector2dF expected_max_scroll = MaxScrollOffset(outer_scroll);
   EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD,
             GetInputHandler()
                 .ScrollBegin(BeginState(gfx::Point(5, 5), scroll_delta,
@@ -8168,8 +8152,8 @@
   DrawFrame();
 
   gfx::Vector2d scroll_delta(0, 10);
-  gfx::ScrollOffset expected_scroll_delta(scroll_delta);
-  gfx::ScrollOffset expected_max_scroll(MaxScrollOffset(outer_scroll));
+  gfx::Vector2dF expected_scroll_delta(scroll_delta);
+  gfx::Vector2dF expected_max_scroll(MaxScrollOffset(outer_scroll));
   EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD,
             GetInputHandler()
                 .ScrollBegin(BeginState(gfx::Point(5, 5), scroll_delta,
@@ -8219,11 +8203,11 @@
   grand_child_layer->layer_tree_impl()
       ->property_trees()
       ->scroll_tree.UpdateScrollOffsetBaseForTesting(
-          grand_child_layer->element_id(), gfx::ScrollOffset(0, 5));
+          grand_child_layer->element_id(), gfx::Vector2dF(0, 5));
   child_layer->layer_tree_impl()
       ->property_trees()
       ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->element_id(),
-                                                     gfx::ScrollOffset(3, 0));
+                                                     gfx::Vector2dF(3, 0));
 
   DrawFrame();
   {
@@ -8246,7 +8230,7 @@
     // The grand child should have scrolled up to its limit.
     EXPECT_TRUE(ScrollInfoContains(*commit_data.get(),
                                    grand_child_layer->element_id(),
-                                   gfx::ScrollOffset(0, -5)));
+                                   gfx::Vector2dF(0, -5)));
 
     // The child should not have scrolled.
     ExpectNone(*commit_data.get(), child_layer->element_id());
@@ -8272,11 +8256,11 @@
   grand_child_layer->layer_tree_impl()
       ->property_trees()
       ->scroll_tree.UpdateScrollOffsetBaseForTesting(
-          grand_child_layer->element_id(), gfx::ScrollOffset(0, 30));
+          grand_child_layer->element_id(), gfx::Vector2dF(0, 30));
   child_layer->layer_tree_impl()
       ->property_trees()
       ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->element_id(),
-                                                     gfx::ScrollOffset(0, 50));
+                                                     gfx::Vector2dF(0, 50));
 
   DrawFrame();
 
@@ -8302,7 +8286,7 @@
   host_impl_->UpdateAnimationState(true);
 
   // Should have started scrolling.
-  EXPECT_NE(gfx::ScrollOffset(0, 30), CurrentScrollOffset(grand_child_layer));
+  EXPECT_NE(gfx::Vector2dF(0, 30), CurrentScrollOffset(grand_child_layer));
   host_impl_->DidFinishImplFrame(begin_frame_args);
 
   begin_frame_args.frame_time = start_time + base::Milliseconds(200);
@@ -8311,8 +8295,8 @@
   host_impl_->Animate();
   host_impl_->UpdateAnimationState(true);
 
-  EXPECT_EQ(gfx::ScrollOffset(0, 0), CurrentScrollOffset(grand_child_layer));
-  EXPECT_EQ(gfx::ScrollOffset(0, 50), CurrentScrollOffset(child_layer));
+  EXPECT_EQ(gfx::Vector2dF(0, 0), CurrentScrollOffset(grand_child_layer));
+  EXPECT_EQ(gfx::Vector2dF(0, 50), CurrentScrollOffset(child_layer));
   host_impl_->DidFinishImplFrame(begin_frame_args);
 
   // Second ScrollAnimated should remain latched to the grand_child_layer.
@@ -8332,8 +8316,8 @@
   host_impl_->Animate();
   host_impl_->UpdateAnimationState(true);
 
-  EXPECT_EQ(gfx::ScrollOffset(0, 0), CurrentScrollOffset(grand_child_layer));
-  EXPECT_EQ(gfx::ScrollOffset(0, 50), CurrentScrollOffset(child_layer));
+  EXPECT_EQ(gfx::Vector2dF(0, 0), CurrentScrollOffset(grand_child_layer));
+  EXPECT_EQ(gfx::Vector2dF(0, 50), CurrentScrollOffset(child_layer));
   host_impl_->DidFinishImplFrame(begin_frame_args);
 
   // Tear down the LayerTreeHostImpl before the InputHandlerClient.
@@ -8357,11 +8341,11 @@
   grand_child_layer->layer_tree_impl()
       ->property_trees()
       ->scroll_tree.UpdateScrollOffsetBaseForTesting(
-          grand_child_layer->element_id(), gfx::ScrollOffset(0, 2));
+          grand_child_layer->element_id(), gfx::Vector2dF(0, 2));
   child_layer->layer_tree_impl()
       ->property_trees()
       ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->element_id(),
-                                                     gfx::ScrollOffset(0, 3));
+                                                     gfx::Vector2dF(0, 3));
 
   DrawFrame();
   {
@@ -8385,7 +8369,7 @@
     // The grand child should have scrolled up to its limit.
     EXPECT_TRUE(ScrollInfoContains(*commit_data.get(),
                                    grand_child_layer->element_id(),
-                                   gfx::ScrollOffset(0, -2)));
+                                   gfx::Vector2dF(0, -2)));
 
     // The child should not have scrolled.
     ExpectNone(*commit_data.get(), child_layer->element_id());
@@ -8412,14 +8396,13 @@
     commit_data = host_impl_->ProcessCompositorDeltas();
 
     // The child should have scrolled up to its limit.
-    EXPECT_TRUE(ScrollInfoContains(*commit_data.get(),
-                                   child_layer->element_id(),
-                                   gfx::ScrollOffset(0, -3)));
+    EXPECT_TRUE(ScrollInfoContains(
+        *commit_data.get(), child_layer->element_id(), gfx::Vector2dF(0, -3)));
 
     // The grand child should not have scrolled.
     EXPECT_TRUE(ScrollInfoContains(*commit_data.get(),
                                    grand_child_layer->element_id(),
-                                   gfx::ScrollOffset(0, -2)));
+                                   gfx::Vector2dF(0, -2)));
 
     // After scrolling the parent, another scroll on the opposite direction
     // should still scroll the child.
@@ -8446,12 +8429,11 @@
     // The grand child should have scrolled.
     EXPECT_TRUE(ScrollInfoContains(*commit_data.get(),
                                    grand_child_layer->element_id(),
-                                   gfx::ScrollOffset(0, 5)));
+                                   gfx::Vector2dF(0, 5)));
 
     // The child should not have scrolled.
-    EXPECT_TRUE(ScrollInfoContains(*commit_data.get(),
-                                   child_layer->element_id(),
-                                   gfx::ScrollOffset(0, -3)));
+    EXPECT_TRUE(ScrollInfoContains(
+        *commit_data.get(), child_layer->element_id(), gfx::Vector2dF(0, -3)));
 
     // Scrolling should be adjusted from viewport space.
     host_impl_->active_tree()->PushPageScaleFromMainThread(2, 2, 2);
@@ -8478,7 +8460,7 @@
     // Should have scrolled by half the amount in layer space (5 - 2/2)
     EXPECT_TRUE(ScrollInfoContains(*commit_data.get(),
                                    grand_child_layer->element_id(),
-                                   gfx::ScrollOffset(0, 4)));
+                                   gfx::Vector2dF(0, 4)));
   }
 }
 
@@ -8501,20 +8483,17 @@
   host_impl_->active_tree()->DidBecomeActive();
   DrawFrame();
   {
-    gfx::ScrollOffset scroll_delta(0, 4);
+    gfx::Vector2dF scroll_delta(0, 4);
     // Scrolling should be able to happen on the compositor thread here.
-    EXPECT_EQ(
-        ScrollThread::SCROLL_ON_IMPL_THREAD,
-        GetInputHandler()
-            .ScrollBegin(BeginState(gfx::Point(5, 5),
-                                    gfx::ScrollOffsetToVector2dF(scroll_delta),
-                                    ui::ScrollInputType::kWheel)
-                             .get(),
-                         ui::ScrollInputType::kWheel)
-            .thread);
+    EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD,
+              GetInputHandler()
+                  .ScrollBegin(BeginState(gfx::Point(5, 5), scroll_delta,
+                                          ui::ScrollInputType::kWheel)
+                                   .get(),
+                               ui::ScrollInputType::kWheel)
+                  .thread);
     GetInputHandler().ScrollUpdate(
-        UpdateState(gfx::Point(), gfx::ScrollOffsetToVector2dF(scroll_delta),
-                    ui::ScrollInputType::kWheel)
+        UpdateState(gfx::Point(), scroll_delta, ui::ScrollInputType::kWheel)
             .get());
     GetInputHandler().ScrollEnd();
 
@@ -8545,19 +8524,16 @@
   host_impl_->active_tree()->DidBecomeActive();
   DrawFrame();
   {
-    gfx::ScrollOffset scroll_delta(0, 4);
-    EXPECT_EQ(
-        ScrollThread::SCROLL_ON_IMPL_THREAD,
-        GetInputHandler()
-            .ScrollBegin(BeginState(gfx::Point(5, 5),
-                                    gfx::ScrollOffsetToVector2dF(scroll_delta),
-                                    ui::ScrollInputType::kWheel)
-                             .get(),
-                         ui::ScrollInputType::kWheel)
-            .thread);
+    gfx::Vector2dF scroll_delta(0, 4);
+    EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD,
+              GetInputHandler()
+                  .ScrollBegin(BeginState(gfx::Point(5, 5), scroll_delta,
+                                          ui::ScrollInputType::kWheel)
+                                   .get(),
+                               ui::ScrollInputType::kWheel)
+                  .thread);
     GetInputHandler().ScrollUpdate(
-        UpdateState(gfx::Point(), gfx::ScrollOffsetToVector2dF(scroll_delta),
-                    ui::ScrollInputType::kWheel)
+        UpdateState(gfx::Point(), scroll_delta, ui::ScrollInputType::kWheel)
             .get());
     GetInputHandler().ScrollEnd();
 
@@ -8624,26 +8600,21 @@
   // The layer should have scrolled down in its local coordinates.
   std::unique_ptr<CompositorCommitData> commit_data =
       host_impl_->ProcessCompositorDeltas();
-  EXPECT_TRUE(
-      ScrollInfoContains(*commit_data.get(), scroll_layer->element_id(),
-                         gfx::ScrollOffset(0, gesture_scroll_delta.x())));
+  EXPECT_TRUE(ScrollInfoContains(*commit_data.get(), scroll_layer->element_id(),
+                                 gfx::Vector2dF(0, gesture_scroll_delta.x())));
 
   // Reset and scroll down with the wheel.
   SetScrollOffsetDelta(scroll_layer, gfx::Vector2dF());
-  gfx::ScrollOffset wheel_scroll_delta(0, 10);
+  gfx::Vector2dF wheel_scroll_delta(0, 10);
   EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD,
             GetInputHandler()
-                .ScrollBegin(
-                    BeginState(gfx::Point(),
-                               gfx::ScrollOffsetToVector2dF(wheel_scroll_delta),
-                               ui::ScrollInputType::kWheel)
-                        .get(),
-                    ui::ScrollInputType::kWheel)
+                .ScrollBegin(BeginState(gfx::Point(), wheel_scroll_delta,
+                                        ui::ScrollInputType::kWheel)
+                                 .get(),
+                             ui::ScrollInputType::kWheel)
                 .thread);
   GetInputHandler().ScrollUpdate(
-      UpdateState(gfx::Point(),
-                  gfx::ScrollOffsetToVector2dF(wheel_scroll_delta),
-                  ui::ScrollInputType::kWheel)
+      UpdateState(gfx::Point(), wheel_scroll_delta, ui::ScrollInputType::kWheel)
           .get());
   GetInputHandler().ScrollEnd();
 
@@ -8703,7 +8674,7 @@
 
     // The child layer should have scrolled down in its local coordinates an
     // amount proportional to the angle between it and the input scroll delta.
-    gfx::ScrollOffset expected_scroll_delta(
+    gfx::Vector2dF expected_scroll_delta(
         0, std::floor(gesture_scroll_delta.y() *
                       std::cos(gfx::DegToRad(child_layer_angle))));
     std::unique_ptr<CompositorCommitData> commit_data =
@@ -8735,7 +8706,7 @@
 
     // The child layer should have scrolled down in its local coordinates an
     // amount proportional to the angle between it and the input scroll delta.
-    gfx::ScrollOffset expected_scroll_delta(
+    gfx::Vector2dF expected_scroll_delta(
         0, std::floor(-gesture_scroll_delta.x() *
                       std::sin(gfx::DegToRad(child_layer_angle))));
     std::unique_ptr<CompositorCommitData> commit_data =
@@ -8778,21 +8749,21 @@
 
   std::unique_ptr<CompositorCommitData> commit_data;
 
-  gfx::ScrollOffset gesture_scroll_deltas[4];
-  gesture_scroll_deltas[0] = gfx::ScrollOffset(4, 10);
-  gesture_scroll_deltas[1] = gfx::ScrollOffset(4, 10);
-  gesture_scroll_deltas[2] = gfx::ScrollOffset(10, 0);
-  gesture_scroll_deltas[3] = gfx::ScrollOffset(10, 0);
+  gfx::Vector2dF gesture_scroll_deltas[4];
+  gesture_scroll_deltas[0] = gfx::Vector2dF(4, 10);
+  gesture_scroll_deltas[1] = gfx::Vector2dF(4, 10);
+  gesture_scroll_deltas[2] = gfx::Vector2dF(10, 0);
+  gesture_scroll_deltas[3] = gfx::Vector2dF(10, 0);
 
-  gfx::ScrollOffset expected_scroll_deltas[4];
+  gfx::Vector2dF expected_scroll_deltas[4];
   // Perspective affects the vertical delta by a different
   // amount depending on the vertical position of the |viewport_point|.
-  expected_scroll_deltas[0] = gfx::ScrollOffset(2, 9);
-  expected_scroll_deltas[1] = gfx::ScrollOffset(1, 4);
+  expected_scroll_deltas[0] = gfx::Vector2dF(2, 9);
+  expected_scroll_deltas[1] = gfx::Vector2dF(1, 4);
   // Deltas which start with the same vertical position of the
   // |viewport_point| are subject to identical perspective effects.
-  expected_scroll_deltas[2] = gfx::ScrollOffset(5, 0);
-  expected_scroll_deltas[3] = gfx::ScrollOffset(5, 0);
+  expected_scroll_deltas[2] = gfx::Vector2dF(5, 0);
+  expected_scroll_deltas[3] = gfx::Vector2dF(5, 0);
 
   gfx::Point viewport_point(1, 1);
 
@@ -8802,22 +8773,19 @@
   for (int i = 0; i < 4; ++i) {
     SetScrollOffsetDelta(child, gfx::Vector2dF());
     DrawFrame();
-    EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD,
-              GetInputHandler()
-                  .ScrollBegin(BeginState(viewport_point,
-                                          gfx::ScrollOffsetToVector2dF(
-                                              gesture_scroll_deltas[i]),
-                                          ui::ScrollInputType::kTouchscreen)
-                                   .get(),
-                               ui::ScrollInputType::kTouchscreen)
-                  .thread);
+    EXPECT_EQ(
+        ScrollThread::SCROLL_ON_IMPL_THREAD,
+        GetInputHandler()
+            .ScrollBegin(BeginState(viewport_point, gesture_scroll_deltas[i],
+                                    ui::ScrollInputType::kTouchscreen)
+                             .get(),
+                         ui::ScrollInputType::kTouchscreen)
+            .thread);
     GetInputHandler().ScrollUpdate(
-        UpdateState(viewport_point,
-                    gfx::ScrollOffsetToVector2dF(gesture_scroll_deltas[i]),
+        UpdateState(viewport_point, gesture_scroll_deltas[i],
                     ui::ScrollInputType::kTouchscreen)
             .get());
-    viewport_point +=
-        gfx::ScrollOffsetToFlooredVector2d(gesture_scroll_deltas[i]);
+    viewport_point += gfx::ToFlooredVector2d(gesture_scroll_deltas[i]);
     GetInputHandler().ScrollEnd();
 
     commit_data = host_impl_->ProcessCompositorDeltas();
@@ -8860,26 +8828,21 @@
   // amount.
   std::unique_ptr<CompositorCommitData> commit_data =
       host_impl_->ProcessCompositorDeltas();
-  EXPECT_TRUE(
-      ScrollInfoContains(*commit_data.get(), scroll_layer->element_id(),
-                         gfx::ScrollOffset(0, scroll_delta.y() / scale)));
+  EXPECT_TRUE(ScrollInfoContains(*commit_data.get(), scroll_layer->element_id(),
+                                 gfx::Vector2dF(0, scroll_delta.y() / scale)));
 
   // Reset and scroll down with the wheel.
   SetScrollOffsetDelta(scroll_layer, gfx::Vector2dF());
-  gfx::ScrollOffset wheel_scroll_delta(0, 10);
+  gfx::Vector2dF wheel_scroll_delta(0, 10);
   EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD,
             GetInputHandler()
-                .ScrollBegin(
-                    BeginState(gfx::Point(),
-                               gfx::ScrollOffsetToVector2dF(wheel_scroll_delta),
-                               ui::ScrollInputType::kWheel)
-                        .get(),
-                    ui::ScrollInputType::kWheel)
+                .ScrollBegin(BeginState(gfx::Point(), wheel_scroll_delta,
+                                        ui::ScrollInputType::kWheel)
+                                 .get(),
+                             ui::ScrollInputType::kWheel)
                 .thread);
   GetInputHandler().ScrollUpdate(
-      UpdateState(gfx::Point(),
-                  gfx::ScrollOffsetToVector2dF(wheel_scroll_delta),
-                  ui::ScrollInputType::kWheel)
+      UpdateState(gfx::Point(), wheel_scroll_delta, ui::ScrollInputType::kWheel)
           .get());
   GetInputHandler().ScrollEnd();
 
@@ -8901,8 +8864,7 @@
   host_impl_->active_tree()->PushPageScaleFromMainThread(1, 0.5f, 4);
 
   LayerImpl* inner_viewport_scroll_layer = InnerViewportScrollLayer();
-  EXPECT_EQ(gfx::ScrollOffset(0, 0),
-            MaxScrollOffset(inner_viewport_scroll_layer));
+  EXPECT_EQ(gfx::Vector2dF(0, 0), MaxScrollOffset(inner_viewport_scroll_layer));
 }
 
 TEST_P(ScrollUnifiedLayerTreeHostImplTest, RootLayerScrollOffsetDelegation) {
@@ -8917,20 +8879,19 @@
   scroll_layer->layer_tree_impl()
       ->property_trees()
       ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->element_id(),
-                                                     gfx::ScrollOffset());
+                                                     gfx::Vector2dF());
   SetScrollOffsetDelta(scroll_layer, initial_scroll_delta);
 
-  EXPECT_EQ(gfx::ScrollOffset(), scroll_watcher.last_set_scroll_offset());
+  EXPECT_EQ(gfx::Vector2dF(), scroll_watcher.last_set_scroll_offset());
 
   // Requesting an update results in the current scroll offset being set.
   GetInputHandler().RequestUpdateForSynchronousInputHandler();
-  EXPECT_EQ(gfx::ScrollOffset(initial_scroll_delta),
-            scroll_watcher.last_set_scroll_offset());
+  EXPECT_EQ(initial_scroll_delta, scroll_watcher.last_set_scroll_offset());
 
   // Setting the delegate results in the scrollable_size, max_scroll_offset,
   // page_scale_factor and {min|max}_page_scale_factor being set.
   EXPECT_EQ(gfx::SizeF(100, 100), scroll_watcher.scrollable_size());
-  EXPECT_EQ(gfx::ScrollOffset(90, 80), scroll_watcher.max_scroll_offset());
+  EXPECT_EQ(gfx::Vector2dF(90, 80), scroll_watcher.max_scroll_offset());
   EXPECT_EQ(1, scroll_watcher.page_scale_factor());
   EXPECT_EQ(1, scroll_watcher.min_page_scale_factor());
   EXPECT_EQ(1, scroll_watcher.max_page_scale_factor());
@@ -8970,7 +8931,7 @@
 
   // Scrolling should be relative to the offset as given by the delegate.
   gfx::Vector2dF scroll_delta(0, 10);
-  gfx::ScrollOffset current_offset(7, 8);
+  gfx::Vector2dF current_offset(7, 8);
 
   EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD,
             GetInputHandler()
@@ -8984,19 +8945,19 @@
   GetInputHandler().ScrollUpdate(
       UpdateState(gfx::Point(), scroll_delta, ui::ScrollInputType::kTouchscreen)
           .get());
-  EXPECT_EQ(ScrollOffsetWithDelta(current_offset, scroll_delta),
+  EXPECT_EQ(current_offset + scroll_delta,
             scroll_watcher.last_set_scroll_offset());
 
-  current_offset = gfx::ScrollOffset(42, 41);
+  current_offset = gfx::Vector2dF(42, 41);
   GetInputHandler().SetSynchronousInputHandlerRootScrollOffset(current_offset);
   GetInputHandler().ScrollUpdate(
       UpdateState(gfx::Point(), scroll_delta, ui::ScrollInputType::kTouchscreen)
           .get());
-  EXPECT_EQ(current_offset + gfx::ScrollOffset(scroll_delta),
+  EXPECT_EQ(current_offset + scroll_delta,
             scroll_watcher.last_set_scroll_offset());
   GetInputHandler().ScrollEnd();
   GetInputHandler().SetSynchronousInputHandlerRootScrollOffset(
-      gfx::ScrollOffset());
+      gfx::Vector2dF());
 
   // Forces a full tree synchronization and ensures that the scroll delegate
   // sees the correct size of the new tree.
@@ -9036,7 +8997,7 @@
   EXPECT_FALSE(host_impl_->active_tree()->needs_update_draw_properties());
 
   // Set external scroll delta on delegate and notify LayerTreeHost.
-  gfx::ScrollOffset scroll_offset(10, 10);
+  gfx::Vector2dF scroll_offset(10, 10);
   GetInputHandler().SetSynchronousInputHandlerRootScrollOffset(scroll_offset);
   CheckLayerScrollDelta(scroll_layer, gfx::Vector2dF(0, 0));
   EXPECT_TRUE(host_impl_->active_tree()->needs_update_draw_properties());
@@ -9052,8 +9013,7 @@
   host_impl_->DidDrawAllLayers(frame);
   host_impl_->DidFinishImplFrame(args);
   EXPECT_FALSE(frame.has_no_damage);
-  CheckLayerScrollDelta(scroll_layer,
-                        gfx::ScrollOffsetToVector2dF(scroll_offset));
+  CheckLayerScrollDelta(scroll_layer, scroll_offset);
 }
 
 // Ensure the viewport correctly handles the user_scrollable bits. That is, if
@@ -9099,9 +9059,9 @@
                                     ui::ScrollInputType::kTouchscreen);
     GetInputHandler().ScrollUpdate(update_state.get());
 
-    EXPECT_VECTOR_EQ(gfx::ScrollOffset(30, 0),
+    EXPECT_VECTOR_EQ(gfx::Vector2dF(30, 0),
                      scroll_tree.current_scroll_offset(inner_element_id));
-    EXPECT_VECTOR_EQ(gfx::ScrollOffset(0, 0),
+    EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0),
                      scroll_tree.current_scroll_offset(outer_element_id));
 
     // Continue scrolling. The inner viewport should scroll until its extent,
@@ -9116,17 +9076,17 @@
                                ui::ScrollInputType::kTouchscreen);
     GetInputHandler().ScrollUpdate(update_state.get());
 
-    EXPECT_VECTOR_EQ(gfx::ScrollOffset(50, 0),
+    EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 0),
                      scroll_tree.current_scroll_offset(inner_element_id));
-    EXPECT_VECTOR_EQ(gfx::ScrollOffset(0, 0),
+    EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0),
                      scroll_tree.current_scroll_offset(outer_element_id));
 
     GetInputHandler().ScrollEnd();
   }
 
   // Reset. Try the same test above but using animated scrolls.
-  SetScrollOffset(outer_scroll, gfx::ScrollOffset(0, 0));
-  SetScrollOffset(inner_scroll, gfx::ScrollOffset(0, 0));
+  SetScrollOffset(outer_scroll, gfx::Vector2dF(0, 0));
+  SetScrollOffset(inner_scroll, gfx::Vector2dF(0, 0));
 
   {
     auto begin_state =
@@ -9158,9 +9118,9 @@
     ANIMATE(0);
     ANIMATE(200);
 
-    EXPECT_VECTOR_EQ(gfx::ScrollOffset(30, 0),
+    EXPECT_VECTOR_EQ(gfx::Vector2dF(30, 0),
                      scroll_tree.current_scroll_offset(inner_element_id));
-    EXPECT_VECTOR_EQ(gfx::ScrollOffset(0, 0),
+    EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0),
                      scroll_tree.current_scroll_offset(outer_element_id));
 
     // Continue scrolling. The inner viewport should scroll until its extent,
@@ -9170,9 +9130,9 @@
     ANIMATE(10);
     ANIMATE(200);
 
-    EXPECT_VECTOR_EQ(gfx::ScrollOffset(50, 0),
+    EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 0),
                      scroll_tree.current_scroll_offset(inner_element_id));
-    EXPECT_VECTOR_EQ(gfx::ScrollOffset(0, 0),
+    EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0),
                      scroll_tree.current_scroll_offset(outer_element_id));
 
     // Continue scrolling. the outer viewport should still not scroll.
@@ -9181,16 +9141,16 @@
     ANIMATE(10);
     ANIMATE(200);
 
-    EXPECT_VECTOR_EQ(gfx::ScrollOffset(50, 0),
+    EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 0),
                      scroll_tree.current_scroll_offset(inner_element_id));
-    EXPECT_VECTOR_EQ(gfx::ScrollOffset(0, 0),
+    EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0),
                      scroll_tree.current_scroll_offset(outer_element_id));
 
     // Fully scroll the inner viewport. We'll now try to start an animation on
     // the outer viewport in the vertical direction, which is scrollable. We'll
     // then try to update the curve to scroll horizontally. Ensure that doesn't
     // allow any horizontal scroll.
-    SetScrollOffset(inner_scroll, gfx::ScrollOffset(50, 50));
+    SetScrollOffset(inner_scroll, gfx::Vector2dF(50, 50));
     update_state = AnimatedUpdateState(gfx::Point(), gfx::Vector2dF(0, 100));
     GetInputHandler().ScrollUpdate(update_state.get());
     ANIMATE(16);
@@ -9201,7 +9161,7 @@
     ASSERT_LT(0, scroll_tree.current_scroll_offset(outer_element_id).y());
     ASSERT_GT(50, scroll_tree.current_scroll_offset(outer_element_id).y());
     ASSERT_EQ(0, scroll_tree.current_scroll_offset(outer_element_id).x());
-    EXPECT_VECTOR_EQ(gfx::ScrollOffset(50, 50),
+    EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 50),
                      scroll_tree.current_scroll_offset(inner_element_id));
 
     // Now when we scroll we should do so by updating the ongoing animation
@@ -9210,9 +9170,9 @@
     GetInputHandler().ScrollUpdate(update_state.get());
     ANIMATE(200);
 
-    EXPECT_VECTOR_EQ(gfx::ScrollOffset(0, 100),
+    EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 100),
                      scroll_tree.current_scroll_offset(outer_element_id));
-    EXPECT_VECTOR_EQ(gfx::ScrollOffset(50, 50),
+    EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 50),
                      scroll_tree.current_scroll_offset(inner_element_id));
 
 #undef ANIMATE
@@ -9252,9 +9212,9 @@
     GetScrollNode(inner_scroll)->user_scrollable_vertical = false;
     GetScrollNode(inner_scroll)->user_scrollable_horizontal = false;
 
-    gfx::ScrollOffset scroll_offset(25, 30);
+    gfx::Vector2dF scroll_offset(25, 30);
     GetInputHandler().SetSynchronousInputHandlerRootScrollOffset(scroll_offset);
-    EXPECT_VECTOR_EQ(gfx::ScrollOffset(),
+    EXPECT_VECTOR_EQ(gfx::Vector2dF(),
                      scroll_tree.current_scroll_offset(inner_element_id));
     EXPECT_VECTOR_EQ(scroll_offset,
                      scroll_tree.current_scroll_offset(outer_element_id));
@@ -9264,7 +9224,7 @@
     did_request_redraw_ = false;
     GetScrollNode(inner_scroll)->user_scrollable_vertical = true;
     GetScrollNode(inner_scroll)->user_scrollable_horizontal = true;
-    SetScrollOffset(outer_scroll, gfx::ScrollOffset(0, 0));
+    SetScrollOffset(outer_scroll, gfx::Vector2dF(0, 0));
   }
 
   // Disable scrolling the outer viewport. The inner should scroll to its
@@ -9274,11 +9234,11 @@
     GetScrollNode(outer_scroll)->user_scrollable_vertical = false;
     GetScrollNode(outer_scroll)->user_scrollable_horizontal = false;
 
-    gfx::ScrollOffset scroll_offset(120, 140);
+    gfx::Vector2dF scroll_offset(120, 140);
     GetInputHandler().SetSynchronousInputHandlerRootScrollOffset(scroll_offset);
-    EXPECT_VECTOR_EQ(gfx::ScrollOffset(50, 50),
+    EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 50),
                      scroll_tree.current_scroll_offset(inner_element_id));
-    EXPECT_VECTOR_EQ(gfx::ScrollOffset(),
+    EXPECT_VECTOR_EQ(gfx::Vector2dF(),
                      scroll_tree.current_scroll_offset(outer_element_id));
     EXPECT_TRUE(did_request_redraw_);
 
@@ -9286,7 +9246,7 @@
     did_request_redraw_ = false;
     GetScrollNode(outer_scroll)->user_scrollable_vertical = true;
     GetScrollNode(outer_scroll)->user_scrollable_horizontal = true;
-    SetScrollOffset(inner_scroll, gfx::ScrollOffset(0, 0));
+    SetScrollOffset(inner_scroll, gfx::Vector2dF(0, 0));
   }
 
   // Disable both viewports. No scrolling should take place, no redraw should
@@ -9298,11 +9258,11 @@
     GetScrollNode(outer_scroll)->user_scrollable_vertical = false;
     GetScrollNode(outer_scroll)->user_scrollable_horizontal = false;
 
-    gfx::ScrollOffset scroll_offset(60, 70);
+    gfx::Vector2dF scroll_offset(60, 70);
     GetInputHandler().SetSynchronousInputHandlerRootScrollOffset(scroll_offset);
-    EXPECT_VECTOR_EQ(gfx::ScrollOffset(),
+    EXPECT_VECTOR_EQ(gfx::Vector2dF(),
                      scroll_tree.current_scroll_offset(inner_element_id));
-    EXPECT_VECTOR_EQ(gfx::ScrollOffset(),
+    EXPECT_VECTOR_EQ(gfx::Vector2dF(),
                      scroll_tree.current_scroll_offset(outer_element_id));
     EXPECT_FALSE(did_request_redraw_);
 
@@ -9319,13 +9279,13 @@
     ASSERT_FALSE(did_request_redraw_);
     GetScrollNode(outer_scroll)->user_scrollable_vertical = false;
     GetScrollNode(outer_scroll)->user_scrollable_horizontal = false;
-    SetScrollOffset(inner_scroll, gfx::ScrollOffset(50, 50));
+    SetScrollOffset(inner_scroll, gfx::Vector2dF(50, 50));
 
-    gfx::ScrollOffset scroll_offset(60, 70);
+    gfx::Vector2dF scroll_offset(60, 70);
     GetInputHandler().SetSynchronousInputHandlerRootScrollOffset(scroll_offset);
-    EXPECT_VECTOR_EQ(gfx::ScrollOffset(50, 50),
+    EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 50),
                      scroll_tree.current_scroll_offset(inner_element_id));
-    EXPECT_VECTOR_EQ(gfx::ScrollOffset(),
+    EXPECT_VECTOR_EQ(gfx::Vector2dF(),
                      scroll_tree.current_scroll_offset(outer_element_id));
     EXPECT_FALSE(did_request_redraw_);
 
@@ -9340,7 +9300,7 @@
 TEST_P(ScrollUnifiedLayerTreeHostImplTest, SetRootScrollOffsetNoViewportCrash) {
   auto* inner_scroll = InnerViewportScrollLayer();
   ASSERT_FALSE(inner_scroll);
-  gfx::ScrollOffset scroll_offset(25, 30);
+  gfx::Vector2dF scroll_offset(25, 30);
   GetInputHandler().SetSynchronousInputHandlerRootScrollOffset(scroll_offset);
 }
 
@@ -9531,11 +9491,11 @@
   child_layer->layer_tree_impl()
       ->property_trees()
       ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->element_id(),
-                                                     gfx::ScrollOffset(0, 3));
+                                                     gfx::Vector2dF(0, 3));
   grand_child_layer->layer_tree_impl()
       ->property_trees()
       ->scroll_tree.UpdateScrollOffsetBaseForTesting(
-          grand_child_layer->element_id(), gfx::ScrollOffset(0, 2));
+          grand_child_layer->element_id(), gfx::Vector2dF(0, 2));
 
   DrawFrame();
   {
@@ -10065,7 +10025,7 @@
 
   // Reset the parent scrolling layer (i.e. the current outer viewport) so that
   // we can ensure viewport scrolling works correctly.
-  scroll_layer->SetCurrentScrollOffset(gfx::ScrollOffset(0, 0));
+  scroll_layer->SetCurrentScrollOffset(gfx::Vector2dF(0, 0));
 
   // Scrolling the content layer should now scroll the inner viewport first,
   // and then chain up to the current outer viewport (i.e. the parent scroll
@@ -10181,7 +10141,7 @@
                                    viewport_size.height());
 
   // Reset the scroll offset.
-  sibling_scroll_layer->SetCurrentScrollOffset(gfx::ScrollOffset());
+  sibling_scroll_layer->SetCurrentScrollOffset(gfx::Vector2dF());
 
   // Now pinch-zoom in. Anchoring should cause scrolling only on the inner
   // viewport layer.
@@ -10220,9 +10180,9 @@
   }
 
   // Reset the scroll offsets
-  sibling_scroll_layer->SetCurrentScrollOffset(gfx::ScrollOffset());
-  inner_scroll_layer->SetCurrentScrollOffset(gfx::ScrollOffset());
-  outer_scroll_layer->SetCurrentScrollOffset(gfx::ScrollOffset());
+  sibling_scroll_layer->SetCurrentScrollOffset(gfx::Vector2dF());
+  inner_scroll_layer->SetCurrentScrollOffset(gfx::Vector2dF());
+  outer_scroll_layer->SetCurrentScrollOffset(gfx::Vector2dF());
 
   // Scrolls over the sibling while pinched in should scroll the sibling first,
   // but then chain up to the inner viewport so that the user can still pan
@@ -11275,7 +11235,7 @@
 
   UpdateDrawProperties(host_impl_->pending_tree());
 
-  gfx::ScrollOffset scroll_offset(100000, 0);
+  gfx::Vector2dF scroll_offset(100000, 0);
   scrolling_layer->layer_tree_impl()
       ->property_trees()
       ->scroll_tree.UpdateScrollOffsetBaseForTesting(
@@ -12142,7 +12102,7 @@
   scroll_layer->layer_tree_impl()
       ->property_trees()
       ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->element_id(),
-                                                     gfx::ScrollOffset(0, 10));
+                                                     gfx::Vector2dF(0, 10));
   viz::BeginFrameArgs begin_frame_args =
       viz::CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 2);
   host_impl_->WillBeginImplFrame(begin_frame_args);
@@ -12186,7 +12146,7 @@
   scroll_layer->layer_tree_impl()
       ->property_trees()
       ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->element_id(),
-                                                     gfx::ScrollOffset(0, 10));
+                                                     gfx::Vector2dF(0, 10));
   host_impl_->DidChangeBrowserControlsPosition();
   EXPECT_TRUE(did_request_next_frame_);
   EXPECT_TRUE(did_request_redraw_);
@@ -12425,8 +12385,7 @@
   scroll_layer->layer_tree_impl()
       ->property_trees()
       ->scroll_tree.UpdateScrollOffsetBaseForTesting(
-          scroll_layer->element_id(),
-          gfx::ScrollOffset(0, initial_scroll_offset));
+          scroll_layer->element_id(), gfx::Vector2dF(0, initial_scroll_offset));
   DrawFrame();
 
   const float residue = 15;
@@ -12741,22 +12700,22 @@
 
   DrawFrame();
   {
-    gfx::ScrollOffset inner_expected;
-    gfx::ScrollOffset outer_expected;
+    gfx::Vector2dF inner_expected;
+    gfx::Vector2dF outer_expected;
     EXPECT_EQ(inner_expected, CurrentScrollOffset(inner_scroll));
     EXPECT_EQ(outer_expected, CurrentScrollOffset(outer_scroll));
 
-    gfx::ScrollOffset current_offset(70, 100);
+    gfx::Vector2dF current_offset(70, 100);
 
     GetInputHandler().SetSynchronousInputHandlerRootScrollOffset(
         current_offset);
-    EXPECT_EQ(gfx::ScrollOffset(25, 40), MaxScrollOffset(inner_scroll));
-    EXPECT_EQ(gfx::ScrollOffset(50, 80), MaxScrollOffset(outer_scroll));
+    EXPECT_EQ(gfx::Vector2dF(25, 40), MaxScrollOffset(inner_scroll));
+    EXPECT_EQ(gfx::Vector2dF(50, 80), MaxScrollOffset(outer_scroll));
 
     // Inner viewport scrolls first. Then the rest is applied to the outer
     // viewport.
-    EXPECT_EQ(gfx::ScrollOffset(25, 40), CurrentScrollOffset(inner_scroll));
-    EXPECT_EQ(gfx::ScrollOffset(45, 60), CurrentScrollOffset(outer_scroll));
+    EXPECT_EQ(gfx::Vector2dF(25, 40), CurrentScrollOffset(inner_scroll));
+    EXPECT_EQ(gfx::Vector2dF(45, 60), CurrentScrollOffset(outer_scroll));
   }
 }
 
@@ -13404,7 +13363,7 @@
   host_impl_->Animate();
   host_impl_->UpdateAnimationState(true);
 
-  EXPECT_NE(gfx::ScrollOffset(), CurrentScrollOffset(scrolling_layer));
+  EXPECT_NE(gfx::Vector2dF(), CurrentScrollOffset(scrolling_layer));
   host_impl_->DidFinishImplFrame(begin_frame_args);
 
   begin_frame_args.frame_time = start_time + base::Milliseconds(50);
@@ -13453,7 +13412,7 @@
   host_impl_->Animate();
   host_impl_->UpdateAnimationState(true);
 
-  EXPECT_VECTOR_EQ(gfx::ScrollOffset(0, 100),
+  EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 100),
                    CurrentScrollOffset(scrolling_layer));
   EXPECT_EQ(nullptr, host_impl_->CurrentlyScrollingNode());
   host_impl_->DidFinishImplFrame(begin_frame_args);
@@ -13497,7 +13456,7 @@
     host_impl_->UpdateAnimationState(true);
     host_impl_->DidFinishImplFrame(begin_frame_args);
 
-    EXPECT_NE(gfx::ScrollOffset(), CurrentScrollOffset(outer_scroll));
+    EXPECT_NE(gfx::Vector2dF(), CurrentScrollOffset(outer_scroll));
     EXPECT_TRUE(GetImplAnimationHost()->ImplOnlyScrollAnimatingElement());
   }
 
@@ -14915,7 +14874,7 @@
   begin_frame_args.frame_id.sequence_number++;
   host_impl_->WillBeginImplFrame(begin_frame_args);
   host_impl_->UpdateAnimationState(true);
-  EXPECT_NE(gfx::ScrollOffset(), CurrentScrollOffset(scrolling_layer));
+  EXPECT_NE(gfx::Vector2dF(), CurrentScrollOffset(scrolling_layer));
   host_impl_->DidFinishImplFrame(begin_frame_args);
 
   // Second tick after 50ms, animation should be half way done since the
@@ -14985,7 +14944,7 @@
   EXPECT_TRUE(GetImplAnimationHost()->HasAnyAnimationTargetingProperty(
       scrolling_layer->element_id(), TargetProperty::SCROLL_OFFSET));
 
-  EXPECT_NE(gfx::ScrollOffset(), CurrentScrollOffset(scrolling_layer));
+  EXPECT_NE(gfx::Vector2dF(), CurrentScrollOffset(scrolling_layer));
   host_impl_->DidFinishImplFrame(begin_frame_args);
 
   begin_frame_args.frame_time = start_time + base::Milliseconds(50);
@@ -15022,7 +14981,7 @@
   EXPECT_FALSE(GetImplAnimationHost()->HasTickingKeyframeModelForTesting(
       scrolling_layer->element_id()));
 
-  EXPECT_VECTOR2DF_EQ(gfx::ScrollOffset(0, y + 50),
+  EXPECT_VECTOR2DF_EQ(gfx::Vector2dF(0, y + 50),
                       CurrentScrollOffset(scrolling_layer));
   EXPECT_EQ(nullptr, host_impl_->CurrentlyScrollingNode());
   host_impl_->DidFinishImplFrame(begin_frame_args);
@@ -15061,7 +15020,7 @@
   host_impl_->Animate();
   host_impl_->UpdateAnimationState(true);
 
-  EXPECT_NE(gfx::ScrollOffset(), CurrentScrollOffset(scrolling_layer));
+  EXPECT_NE(gfx::Vector2dF(), CurrentScrollOffset(scrolling_layer));
   host_impl_->DidFinishImplFrame(begin_frame_args);
 
   begin_frame_args.frame_time = start_time + base::Milliseconds(50);
@@ -15097,7 +15056,7 @@
   host_impl_->Animate();
   host_impl_->UpdateAnimationState(true);
 
-  EXPECT_VECTOR_EQ(gfx::ScrollOffset(0, 100),
+  EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 100),
                    CurrentScrollOffset(scrolling_layer));
   EXPECT_EQ(nullptr, host_impl_->CurrentlyScrollingNode());
   host_impl_->DidFinishImplFrame(begin_frame_args);
@@ -15304,7 +15263,7 @@
   host_impl_->Animate();
   host_impl_->UpdateAnimationState(true);
 
-  EXPECT_NE(gfx::ScrollOffset(), CurrentScrollOffset(scrolling_layer));
+  EXPECT_NE(gfx::Vector2dF(), CurrentScrollOffset(scrolling_layer));
   host_impl_->DidFinishImplFrame(begin_frame_args);
 
   begin_frame_args.frame_time = start_time + base::Milliseconds(50);
@@ -15341,7 +15300,7 @@
   host_impl_->Animate();
   host_impl_->UpdateAnimationState(true);
 
-  EXPECT_VECTOR_EQ(gfx::ScrollOffset(0, 100),
+  EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 100),
                    CurrentScrollOffset(scrolling_layer));
   // The CurrentlyScrollingNode shouldn't be cleared until a GestureScrollEnd.
   EXPECT_EQ(scrolling_layer->scroll_tree_index(),
@@ -15397,7 +15356,7 @@
   host_impl_->UpdateAnimationState(true);
   host_impl_->DidFinishImplFrame(begin_frame_args);
 
-  EXPECT_EQ(gfx::ScrollOffset(250, 250), CurrentScrollOffset(scrolling_layer));
+  EXPECT_EQ(gfx::Vector2dF(250, 250), CurrentScrollOffset(scrolling_layer));
 }
 
 TEST_P(ScrollUnifiedLayerTreeHostImplTest, InvalidLayerNotAddedToRasterQueue) {
@@ -17620,10 +17579,10 @@
   BeginImplFrameAndAnimate(begin_frame_args,
                            start_time + base::Milliseconds(2000));
 
-  const gfx::ScrollOffset kExpectedDelta(
+  const gfx::Vector2dF kExpectedDelta(
       kPageDelta.x() * kViewportSize.width() * kMinFractionToStepWhenPaging,
       kPageDelta.y() * kViewportSize.height() * kMinFractionToStepWhenPaging);
-  const gfx::ScrollOffset kCurrentDelta =
+  const gfx::Vector2dF kCurrentDelta =
       host_impl_->active_tree()
           ->property_trees()
           ->scroll_tree.current_scroll_offset(
@@ -17636,13 +17595,7 @@
 
 class UnifiedScrollingTest : public LayerTreeHostImplTest {
  public:
-  using Point = gfx::Point;
-  using ScrollInputType = ui::ScrollInputType;
-  using ScrollOffset = gfx::ScrollOffset;
   using ScrollStatus = InputHandler::ScrollStatus;
-  using Size = gfx::Size;
-  using Rect = gfx::Rect;
-  using Vector2d = gfx::Vector2d;
 
   void SetUp() override {
     scoped_feature_list.InitAndEnableFeature(features::kScrollUnification);
@@ -17658,12 +17611,12 @@
   void CreateUncompositedScrollerAndNonFastScrollableRegion() {
     // Create an uncompositd scroll node that corresponds to a non fast
     // scrollable region on the outer viewport scroll layer.
-    Size scrollable_content_bounds(100, 100);
-    Size container_bounds(50, 50);
+    gfx::Size scrollable_content_bounds(100, 100);
+    gfx::Size container_bounds(50, 50);
     CreateScrollNodeForUncompositedScroller(
         GetPropertyTrees(), host_impl_->OuterViewportScrollNode()->id,
         ScrollerElementId(), scrollable_content_bounds, container_bounds);
-    OuterViewportScrollLayer()->SetNonFastScrollableRegion(Rect(0, 0, 50, 50));
+    OuterViewportScrollLayer()->SetNonFastScrollableRegion(gfx::Rect(50, 50));
 
     host_impl_->active_tree()->set_needs_update_draw_properties();
     UpdateDrawProperties(host_impl_->active_tree());
@@ -17674,8 +17627,8 @@
   void CreateScroller(uint32_t main_thread_scrolling_reasons) {
     // Creates a regular compositeds scroller that comes with a ScrollNode and
     // Layer.
-    Size scrollable_content_bounds(100, 100);
-    Size container_bounds(50, 50);
+    gfx::Size scrollable_content_bounds(100, 100);
+    gfx::Size container_bounds(50, 50);
 
     LayerImpl* layer =
         AddScrollableLayer(OuterViewportScrollLayer(), container_bounds,
@@ -17702,11 +17655,11 @@
     UpdateDrawProperties(host_impl_->active_tree());
   }
 
-  ScrollStatus ScrollBegin(const Vector2d& delta) {
+  ScrollStatus ScrollBegin(const gfx::Vector2d& delta) {
     auto scroll_state =
-        BeginState(Point(25, 25), delta, ScrollInputType::kWheel);
+        BeginState(gfx::Point(25, 25), delta, ui::ScrollInputType::kWheel);
     ScrollStatus status = GetInputHandler().ScrollBegin(
-        scroll_state.get(), ScrollInputType::kWheel);
+        scroll_state.get(), ui::ScrollInputType::kWheel);
 
     if (status.needs_main_thread_hit_test)
       to_be_continued_scroll_begin_ = std::move(scroll_state);
@@ -17725,17 +17678,17 @@
     scroll_state->data()->is_main_thread_hit_tested = true;
 
     return GetInputHandler().ScrollBegin(scroll_state.get(),
-                                         ScrollInputType::kWheel);
+                                         ui::ScrollInputType::kWheel);
   }
 
-  InputHandlerScrollResult ScrollUpdate(const Vector2d& delta) {
+  InputHandlerScrollResult ScrollUpdate(const gfx::Vector2d& delta) {
     auto scroll_state =
-        UpdateState(Point(25, 25), delta, ScrollInputType::kWheel);
+        UpdateState(gfx::Point(25, 25), delta, ui::ScrollInputType::kWheel);
     return GetInputHandler().ScrollUpdate(scroll_state.get());
   }
 
-  InputHandlerScrollResult AnimatedScrollUpdate(const Vector2d& delta) {
-    auto scroll_state = AnimatedUpdateState(Point(25, 25), delta);
+  InputHandlerScrollResult AnimatedScrollUpdate(const gfx::Vector2d& delta) {
+    auto scroll_state = AnimatedUpdateState(gfx::Point(25, 25), delta);
     return GetInputHandler().ScrollUpdate(scroll_state.get());
   }
 
@@ -17756,12 +17709,12 @@
     host_impl_->DidFinishImplFrame(begin_frame_args_);
   }
 
-  ScrollOffset GetScrollOffset(ScrollNode* node) {
+  gfx::Vector2dF GetScrollOffset(ScrollNode* node) {
     return GetPropertyTrees()->scroll_tree.current_scroll_offset(
         node->element_id);
   }
 
-  ScrollOffset ScrollerOffset() {
+  gfx::Vector2dF ScrollerOffset() {
     return GetPropertyTrees()->scroll_tree.current_scroll_offset(
         ScrollerElementId());
   }
@@ -17812,7 +17765,7 @@
   // responsibility to request a hit test from Blink. It can then call
   // ScrollBegin again, providing the element_id to scroll.
   {
-    ScrollStatus status = ScrollBegin(Vector2d(0, 10));
+    ScrollStatus status = ScrollBegin(gfx::Vector2d(0, 10));
 
     EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread);
     EXPECT_TRUE(status.needs_main_thread_hit_test);
@@ -17837,20 +17790,20 @@
   // Ensure ScrollUpdates can successfully scroll this node. They shouldn't
   // mutate the associated transform node.
   {
-    EXPECT_TRUE(ScrollUpdate(Vector2d(0, 10)).did_scroll);
-    EXPECT_EQ(ScrollOffset(0, 10), ScrollerOffset());
+    EXPECT_TRUE(ScrollUpdate(gfx::Vector2d(0, 10)).did_scroll);
+    EXPECT_EQ(gfx::Vector2dF(0, 10), ScrollerOffset());
   }
 
   // Try to scroll past the end. Ensure the max scrolling bounds are respected.
   {
-    EXPECT_TRUE(ScrollUpdate(Vector2d(0, 1000)).did_scroll);
-    EXPECT_EQ(ScrollOffset(0, 50), ScrollerOffset());
+    EXPECT_TRUE(ScrollUpdate(gfx::Vector2d(0, 1000)).did_scroll);
+    EXPECT_EQ(gfx::Vector2dF(0, 50), ScrollerOffset());
   }
 
   // Overscrolling should cause the scroll update to be dropped.
   {
-    EXPECT_FALSE(ScrollUpdate(Vector2d(0, 10)).did_scroll);
-    EXPECT_EQ(ScrollOffset(0, 50), ScrollerOffset());
+    EXPECT_FALSE(ScrollUpdate(gfx::Vector2d(0, 10)).did_scroll);
+    EXPECT_EQ(gfx::Vector2dF(0, 50), ScrollerOffset());
   }
 
   GetInputHandler().ScrollEnd();
@@ -17864,15 +17817,15 @@
 
   // Start with the scroller fully scrolled.
   {
-    ScrollBegin(Vector2d(0, 1000));
+    ScrollBegin(gfx::Vector2d(0, 1000));
     ContinuedScrollBegin(ScrollerElementId());
-    ScrollUpdate(Vector2d(0, 1000));
+    ScrollUpdate(gfx::Vector2d(0, 1000));
     ScrollEnd();
-    ASSERT_EQ(ScrollOffset(0, 50), ScrollerOffset());
+    ASSERT_EQ(gfx::Vector2dF(0, 50), ScrollerOffset());
   }
 
   {
-    ScrollStatus status = ScrollBegin(Vector2d(0, 10));
+    ScrollStatus status = ScrollBegin(gfx::Vector2d(0, 10));
     ASSERT_TRUE(status.needs_main_thread_hit_test);
     status = ContinuedScrollBegin(ScrollerElementId());
 
@@ -17893,7 +17846,7 @@
     ElementId kInvalidId;
     DCHECK(!kInvalidId);
 
-    ScrollStatus status = ScrollBegin(Vector2d(0, 10));
+    ScrollStatus status = ScrollBegin(gfx::Vector2d(0, 10));
 
     // Note, we have a NOTREACHED here to make sure this cannot happen. If
     // DCHECKs are enabled we can just make sure we get killed when we end up
@@ -17919,7 +17872,7 @@
     ElementId kUnknown(42);
     DCHECK(!GetPropertyTrees()->scroll_tree.FindNodeFromElementId(kUnknown));
 
-    ScrollStatus status = ScrollBegin(Vector2d(0, 10));
+    ScrollStatus status = ScrollBegin(gfx::Vector2d(0, 10));
     status = ContinuedScrollBegin(kUnknown);
     EXPECT_EQ(ScrollThread::SCROLL_IGNORED, status.thread);
     EXPECT_EQ(MainThreadScrollingReason::kNoScrollingLayer,
@@ -17945,7 +17898,7 @@
   // that cannot be reliably hit tested on the compositor should request a main
   // thread hit test.
   {
-    ScrollStatus status = ScrollBegin(Vector2d(0, 10));
+    ScrollStatus status = ScrollBegin(gfx::Vector2d(0, 10));
     EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread);
     EXPECT_TRUE(status.needs_main_thread_hit_test);
   }
@@ -17970,7 +17923,7 @@
       MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects);
 
   {
-    ScrollStatus status = ScrollBegin(Vector2d(0, 10));
+    ScrollStatus status = ScrollBegin(gfx::Vector2d(0, 10));
     EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread);
     EXPECT_FALSE(status.needs_main_thread_hit_test);
   }
@@ -17988,7 +17941,7 @@
     ASSERT_EQ(transform_node->element_id, ScrollerElementId());
     ASSERT_TRUE(transform_node->scrolls);
 
-    ASSERT_EQ(ScrollOffset(0, 0), transform_node->scroll_offset);
+    ASSERT_EQ(gfx::Vector2dF(0, 0), transform_node->scroll_offset);
     ASSERT_FALSE(transform_node->transform_changed);
     ASSERT_FALSE(transform_node->needs_local_transform_update);
     ASSERT_FALSE(tree.needs_update());
@@ -17998,7 +17951,7 @@
   // requested. Check that the transform tree mutation was as expected for the
   // test parameter.
   {
-    ScrollStatus status = ScrollBegin(Vector2d(0, 10));
+    ScrollStatus status = ScrollBegin(gfx::Vector2d(0, 10));
     if (status.needs_main_thread_hit_test)
       ContinuedScrollBegin(ScrollerElementId());
 
@@ -18006,15 +17959,15 @@
 
     did_request_commit_ = false;
 
-    ScrollUpdate(Vector2d(0, 10));
-    ASSERT_EQ(ScrollOffset(0, 10), ScrollerOffset());
+    ScrollUpdate(gfx::Vector2d(0, 10));
+    ASSERT_EQ(gfx::Vector2dF(0, 10), ScrollerOffset());
     EXPECT_TRUE(did_request_commit_);
 
     // Ensure the transform tree was updated only if expected.
     if (mutates_transform_tree)
-      EXPECT_EQ(ScrollOffset(0, 10), transform_node->scroll_offset);
+      EXPECT_EQ(gfx::Vector2dF(0, 10), transform_node->scroll_offset);
     else
-      EXPECT_EQ(ScrollOffset(0, 0), transform_node->scroll_offset);
+      EXPECT_EQ(gfx::Vector2dF(0, 0), transform_node->scroll_offset);
     EXPECT_EQ(mutates_transform_tree, transform_node->transform_changed);
     EXPECT_EQ(mutates_transform_tree,
               transform_node->needs_local_transform_update);
@@ -18025,22 +17978,22 @@
   {
     did_request_commit_ = false;
 
-    AnimatedScrollUpdate(Vector2d(0, 10));
+    AnimatedScrollUpdate(gfx::Vector2d(0, 10));
     ASSERT_TRUE(host_impl_->mutator_host()->ImplOnlyScrollAnimatingElement());
-    ASSERT_EQ(ScrollOffset(0, 10), ScrollerOffset());
+    ASSERT_EQ(gfx::Vector2dF(0, 10), ScrollerOffset());
 
     StartAnimation();
     BeginFrame(kFrameInterval);
     BeginFrame(base::Milliseconds(500));
     BeginFrame(kFrameInterval);
 
-    ASSERT_EQ(ScrollOffset(0, 20), ScrollerOffset());
+    ASSERT_EQ(gfx::Vector2dF(0, 20), ScrollerOffset());
     EXPECT_TRUE(did_request_commit_);
 
     if (mutates_transform_tree)
-      EXPECT_EQ(ScrollOffset(0, 20), transform_node->scroll_offset);
+      EXPECT_EQ(gfx::Vector2dF(0, 20), transform_node->scroll_offset);
     else
-      EXPECT_EQ(ScrollOffset(0, 0), transform_node->scroll_offset);
+      EXPECT_EQ(gfx::Vector2dF(0, 0), transform_node->scroll_offset);
     EXPECT_EQ(mutates_transform_tree, transform_node->transform_changed);
     EXPECT_EQ(mutates_transform_tree,
               transform_node->needs_local_transform_update);
@@ -18072,11 +18025,11 @@
     UpdateDrawProperties(host_impl_->active_tree());
     host_impl_->active_tree()->DidBecomeActive();
 
-    ScrollUpdate(Vector2d(0, 10));
-    ASSERT_EQ(ScrollOffset(0, 30), ScrollerOffset());
+    ScrollUpdate(gfx::Vector2d(0, 10));
+    ASSERT_EQ(gfx::Vector2dF(0, 30), ScrollerOffset());
 
     // The transform node should now be updated by the scroll.
-    EXPECT_EQ(ScrollOffset(0, 30), transform_node->scroll_offset);
+    EXPECT_EQ(gfx::Vector2dF(0, 30), transform_node->scroll_offset);
     EXPECT_TRUE(transform_node->transform_changed);
     EXPECT_TRUE(transform_node->needs_local_transform_update);
     EXPECT_TRUE(tree.needs_update());
@@ -18103,11 +18056,11 @@
     UpdateDrawProperties(host_impl_->active_tree());
     host_impl_->active_tree()->DidBecomeActive();
 
-    ScrollUpdate(Vector2d(0, 10));
-    ASSERT_EQ(ScrollOffset(0, 30), ScrollerOffset());
+    ScrollUpdate(gfx::Vector2d(0, 10));
+    ASSERT_EQ(gfx::Vector2dF(0, 30), ScrollerOffset());
 
     // The transform node should now be updated by the scroll.
-    EXPECT_EQ(ScrollOffset(0, 30), transform_node->scroll_offset);
+    EXPECT_EQ(gfx::Vector2dF(0, 30), transform_node->scroll_offset);
     EXPECT_TRUE(transform_node->transform_changed);
     EXPECT_TRUE(transform_node->needs_local_transform_update);
     EXPECT_TRUE(tree.needs_update());
diff --git a/cc/trees/layer_tree_host_perftest.cc b/cc/trees/layer_tree_host_perftest.cc
index f855dbea..92759e7 100644
--- a/cc/trees/layer_tree_host_perftest.cc
+++ b/cc/trees/layer_tree_host_perftest.cc
@@ -15,6 +15,7 @@
 #include "base/strings/string_piece.h"
 #include "base/time/time.h"
 #include "base/timer/lap_timer.h"
+#include "build/build_config.h"
 #include "cc/layers/nine_patch_layer.h"
 #include "cc/layers/solid_color_layer.h"
 #include "cc/layers/texture_layer.h"
@@ -263,8 +264,7 @@
       return;
     static const gfx::Vector2d delta = gfx::Vector2d(0, 10);
     SetScrollOffset(scrollable_.get(),
-                    gfx::ScrollOffsetWithDelta(
-                        CurrentScrollOffset(scrollable_.get()), delta));
+                    CurrentScrollOffset(scrollable_.get()) + delta);
   }
 
  private:
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc
index d50f93d2..adcdc43 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -3475,7 +3475,7 @@
 
     scroll_layer_->SetBounds(gfx::Size(2 * root_layer->bounds().width(),
                                        2 * root_layer->bounds().height()));
-    scroll_layer_->SetScrollOffset(gfx::ScrollOffset());
+    scroll_layer_->SetScrollOffset(gfx::Vector2dF());
 
     SetupViewport(root_layer, scroll_layer_, root_layer->bounds());
 
@@ -3486,7 +3486,7 @@
   void BeginTest() override { PostSetNeedsCommitToMainThread(); }
 
   void ApplyViewportChanges(const ApplyViewportChangesArgs& args) override {
-    gfx::ScrollOffset offset = CurrentScrollOffset(scroll_layer_.get());
+    gfx::Vector2dF offset = CurrentScrollOffset(scroll_layer_.get());
     SetScrollOffset(scroll_layer_.get(), offset + args.inner_delta);
     layer_tree_host()->SetPageScaleFactorAndLimits(args.page_scale_delta, 0.5f,
                                                    2.f);
@@ -3561,18 +3561,18 @@
 
   void ApplyViewportChanges(const ApplyViewportChangesArgs& args) override {
     EXPECT_TRUE(sent_gesture_);
-    EXPECT_EQ(gfx::ScrollOffset(50, 50), args.inner_delta);
+    EXPECT_EQ(gfx::Vector2dF(50, 50), args.inner_delta);
     EXPECT_EQ(2, args.page_scale_delta);
 
     auto* scroll_layer =
         layer_tree_host()->InnerViewportScrollLayerForTesting();
     EXPECT_EQ(scroll_layer->element_id(), last_scrolled_element_id_);
-    EXPECT_EQ(gfx::ScrollOffset(50, 50), last_scrolled_offset_);
+    EXPECT_EQ(gfx::Vector2dF(50, 50), last_scrolled_offset_);
     // The scroll offset in the scroll tree is typically updated from blink
     // which doesn't exist in this test. Because we preemptively apply the
     // scroll offset in LayerTreeHost::UpdateScrollOffsetFromImpl, the current
     // scroll offset will still be updated.
-    EXPECT_EQ(gfx::ScrollOffset(50, 50), CurrentScrollOffset(scroll_layer));
+    EXPECT_EQ(gfx::Vector2dF(50, 50), CurrentScrollOffset(scroll_layer));
     EndTest();
   }
 
@@ -3580,7 +3580,7 @@
 
   // ScrollCallbacks
   void DidCompositorScroll(ElementId element_id,
-                           const gfx::ScrollOffset& scroll_offset,
+                           const gfx::Vector2dF& scroll_offset,
                            const absl::optional<TargetSnapAreaElementIds>&
                                snap_target_ids) override {
     last_scrolled_element_id_ = element_id;
@@ -3591,7 +3591,7 @@
  private:
   bool sent_gesture_;
   ElementId last_scrolled_element_id_;
-  gfx::ScrollOffset last_scrolled_offset_;
+  gfx::Vector2dF last_scrolled_offset_;
   base::WeakPtrFactory<ViewportDeltasAppliedDuringPinch> weak_ptr_factory_{
       this};
 };
diff --git a/cc/trees/layer_tree_host_unittest_animation.cc b/cc/trees/layer_tree_host_unittest_animation.cc
index b7483d7..785495c 100644
--- a/cc/trees/layer_tree_host_unittest_animation.cc
+++ b/cc/trees/layer_tree_host_unittest_animation.cc
@@ -779,7 +779,7 @@
     scroll_layer_->SetScrollable(gfx::Size(100, 100));
     scroll_layer_->SetBounds(gfx::Size(1000, 1000));
     client_.set_bounds(scroll_layer_->bounds());
-    scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20));
+    scroll_layer_->SetScrollOffset(gfx::Vector2dF(10, 20));
     layer_tree_host()->root_layer()->AddChild(scroll_layer_);
 
     AttachAnimationsToTimeline();
@@ -794,7 +794,7 @@
         std::unique_ptr<ScrollOffsetAnimationCurve> curve(
             ScrollOffsetAnimationCurveFactory::
                 CreateEaseInOutAnimationForTesting(
-                    gfx::ScrollOffset(500.f, 550.f)));
+                    gfx::Vector2dF(500.f, 550.f)));
         std::unique_ptr<KeyframeModel> keyframe_model(KeyframeModel::Create(
             std::move(curve), 1, 0,
             KeyframeModel::TargetPropertyId(TargetProperty::SCROLL_OFFSET)));
@@ -832,7 +832,7 @@
     scroll_layer_ = FakePictureLayer::Create(&client_);
     scroll_layer_->SetBounds(gfx::Size(10000, 10000));
     client_.set_bounds(scroll_layer_->bounds());
-    scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20));
+    scroll_layer_->SetScrollOffset(gfx::Vector2dF(10, 20));
     scroll_layer_->SetScrollable(gfx::Size(10, 10));
     layer_tree_host()->root_layer()->AddChild(scroll_layer_);
 
@@ -858,8 +858,8 @@
   void WillCommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
     if (host_impl->sync_tree()->source_frame_number() == 0) {
       GetImplAnimationHost(host_impl)->ImplOnlyScrollAnimationCreate(
-          scroll_layer_->element_id(), gfx::ScrollOffset(650.f, 750.f),
-          gfx::ScrollOffset(10, 20), base::TimeDelta(), base::TimeDelta());
+          scroll_layer_->element_id(), gfx::Vector2dF(650.f, 750.f),
+          gfx::Vector2dF(10, 20), base::TimeDelta(), base::TimeDelta());
     }
   }
 
@@ -893,7 +893,7 @@
     scroll_layer_ = FakePictureLayer::Create(&client_);
     scroll_layer_->SetBounds(gfx::Size(10000, 10000));
     client_.set_bounds(scroll_layer_->bounds());
-    scroll_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20));
+    scroll_layer_->SetScrollOffset(gfx::Vector2dF(10, 20));
     scroll_layer_->SetScrollable(gfx::Size(10, 10));
     layer_tree_host()->root_layer()->AddChild(scroll_layer_);
 
@@ -947,17 +947,16 @@
 
       // Verifiy the initial and target position before the scroll offset
       // update from MT.
-      EXPECT_EQ(gfx::ScrollOffset(10.f, 20.f),
-                curve->GetValue(base::TimeDelta()));
-      EXPECT_EQ(gfx::ScrollOffset(650.f, 750.f), curve->target_value());
+      EXPECT_EQ(gfx::Vector2dF(10.f, 20.f), curve->GetValue(base::TimeDelta()));
+      EXPECT_EQ(gfx::Vector2dF(650.f, 750.f), curve->target_value());
     }
   }
 
   void WillCommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
     if (host_impl->sync_tree()->source_frame_number() == 0) {
       GetImplAnimationHost(host_impl)->ImplOnlyScrollAnimationCreate(
-          scroll_layer_->element_id(), gfx::ScrollOffset(650.f, 750.f),
-          gfx::ScrollOffset(10, 20), base::TimeDelta(), base::TimeDelta());
+          scroll_layer_->element_id(), gfx::Vector2dF(650.f, 750.f),
+          gfx::Vector2dF(10, 20), base::TimeDelta(), base::TimeDelta());
     }
   }
 
@@ -973,9 +972,9 @@
       // Verifiy the initial and target position after the scroll offset
       // update from MT
       EXPECT_EQ(KeyframeModel::RunState::STARTING, keyframe_model->run_state());
-      EXPECT_EQ(gfx::ScrollOffset(110.f, 120.f),
+      EXPECT_EQ(gfx::Vector2dF(110.f, 120.f),
                 curve->GetValue(base::TimeDelta()));
-      EXPECT_EQ(gfx::ScrollOffset(750.f, 850.f), curve->target_value());
+      EXPECT_EQ(gfx::Vector2dF(750.f, 850.f), curve->target_value());
 
       EndTest();
     }
@@ -1001,12 +1000,12 @@
     scroll_layer_->SetScrollable(gfx::Size(100, 100));
     scroll_layer_->SetBounds(gfx::Size(10000, 10000));
     client_.set_bounds(scroll_layer_->bounds());
-    scroll_layer_->SetScrollOffset(gfx::ScrollOffset(100.0, 200.0));
+    scroll_layer_->SetScrollOffset(gfx::Vector2dF(100.0, 200.0));
     layer_tree_host()->root_layer()->AddChild(scroll_layer_);
 
     std::unique_ptr<ScrollOffsetAnimationCurve> curve(
         ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
-            gfx::ScrollOffset(6500.f, 7500.f)));
+            gfx::Vector2dF(6500.f, 7500.f)));
     std::unique_ptr<KeyframeModel> keyframe_model(KeyframeModel::Create(
         std::move(curve), 1, 0,
         KeyframeModel::TargetPropertyId(TargetProperty::SCROLL_OFFSET)));
@@ -1086,12 +1085,12 @@
     scroll_layer_->SetScrollable(gfx::Size(100, 100));
     scroll_layer_->SetBounds(gfx::Size(10000, 10000));
     client_.set_bounds(scroll_layer_->bounds());
-    scroll_layer_->SetScrollOffset(gfx::ScrollOffset(100.0, 200.0));
+    scroll_layer_->SetScrollOffset(gfx::Vector2dF(100.0, 200.0));
     layer_tree_host()->root_layer()->AddChild(scroll_layer_);
 
     std::unique_ptr<ScrollOffsetAnimationCurve> curve(
         ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
-            gfx::ScrollOffset(6500.f, 7500.f)));
+            gfx::Vector2dF(6500.f, 7500.f)));
     std::unique_ptr<KeyframeModel> keyframe_model(KeyframeModel::Create(
         std::move(curve), 1, 0,
         KeyframeModel::TargetPropertyId(TargetProperty::SCROLL_OFFSET)));
@@ -1181,7 +1180,7 @@
 
     // Block activation until the running animation has a chance to produce a
     // scroll delta.
-    gfx::ScrollOffset scroll_delta = ScrollDelta(scroll_layer_impl);
+    gfx::Vector2dF scroll_delta = ScrollDelta(scroll_layer_impl);
     if (scroll_delta.x() > 0.f || scroll_delta.y() > 0.f)
       return false;
 
@@ -1190,7 +1189,7 @@
 
   FakeContentLayerClient client_;
   scoped_refptr<FakePictureLayer> scroll_layer_;
-  const gfx::ScrollOffset final_postion_;
+  const gfx::Vector2dF final_postion_;
 };
 
 MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestScrollOffsetAnimationRemoval);
@@ -1213,7 +1212,7 @@
     scroll_layer_->SetScrollable(gfx::Size(100, 100));
     scroll_layer_->SetBounds(gfx::Size(10000, 10000));
     client_.set_bounds(scroll_layer_->bounds());
-    scroll_layer_->SetScrollOffset(gfx::ScrollOffset(100.0, 200.0));
+    scroll_layer_->SetScrollOffset(gfx::Vector2dF(100.0, 200.0));
     layer_tree_host()->root_layer()->AddChild(scroll_layer_);
 
     std::unique_ptr<ScrollOffsetAnimationCurve> curve(
@@ -1291,7 +1290,7 @@
  private:
   FakeContentLayerClient client_;
   scoped_refptr<FakePictureLayer> scroll_layer_;
-  const gfx::ScrollOffset final_position_;
+  const gfx::Vector2dF final_position_;
   bool ran_animation_ = false;
 };
 
@@ -2175,13 +2174,13 @@
     layer_->SetScrollable(gfx::Size(100, 100));
     layer_->SetBounds(gfx::Size(1000, 1000));
     client_.set_bounds(layer_->bounds());
-    layer_->SetScrollOffset(gfx::ScrollOffset(10.f, 20.f));
+    layer_->SetScrollOffset(gfx::Vector2dF(10.f, 20.f));
   }
 
   void BeginTest() override {
     std::unique_ptr<ScrollOffsetAnimationCurve> curve(
         ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
-            gfx::ScrollOffset(500.f, 550.f)));
+            gfx::Vector2dF(500.f, 550.f)));
     std::unique_ptr<KeyframeModel> keyframe_model(KeyframeModel::Create(
         std::move(curve), 1, 0,
         KeyframeModel::TargetPropertyId(TargetProperty::SCROLL_OFFSET)));
@@ -2195,14 +2194,14 @@
       return;
     EXPECT_EQ(0, host_impl->active_tree()->source_frame_number());
     LayerImpl* layer_impl = host_impl->active_tree()->LayerById(layer_->id());
-    EXPECT_EQ(gfx::ScrollOffset(10.f, 20.f), CurrentScrollOffset(layer_impl));
+    EXPECT_EQ(gfx::Vector2dF(10.f, 20.f), CurrentScrollOffset(layer_impl));
   }
 
   void DidInvalidateContentOnImplSide(LayerTreeHostImpl* host_impl) override {
     ASSERT_TRUE(did_request_impl_side_invalidation_);
     EXPECT_EQ(0, host_impl->sync_tree()->source_frame_number());
     LayerImpl* layer_impl = host_impl->pending_tree()->LayerById(layer_->id());
-    EXPECT_EQ(gfx::ScrollOffset(500.f, 550.f), CurrentScrollOffset(layer_impl));
+    EXPECT_EQ(gfx::Vector2dF(500.f, 550.f), CurrentScrollOffset(layer_impl));
     LayerTreeHostAnimationTestImplSideInvalidationWithoutCommit::
         DidInvalidateContentOnImplSide(host_impl);
   }
diff --git a/cc/trees/layer_tree_host_unittest_damage.cc b/cc/trees/layer_tree_host_unittest_damage.cc
index 479801c..2201ad1 100644
--- a/cc/trees/layer_tree_host_unittest_damage.cc
+++ b/cc/trees/layer_tree_host_unittest_damage.cc
@@ -341,7 +341,7 @@
     // The size of the container in which scrolling contents are visible need
     // to be smaller than the bounds of the layer itself.
     content_layer_->SetScrollable(gfx::Size(80, 180));
-    content_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20));
+    content_layer_->SetScrollOffset(gfx::Vector2dF(10, 20));
     content_layer_->SetBounds(gfx::Size(100, 200));
     content_layer_->SetIsDrawable(true);
     root_layer->AddChild(content_layer_);
diff --git a/cc/trees/layer_tree_host_unittest_masks.cc b/cc/trees/layer_tree_host_unittest_masks.cc
index 1bd57a7..12de044 100644
--- a/cc/trees/layer_tree_host_unittest_masks.cc
+++ b/cc/trees/layer_tree_host_unittest_masks.cc
@@ -68,7 +68,7 @@
     scroll_layer->AddChild(content_layer);
 
     client_.set_bounds(root->bounds());
-    scroll_layer->SetScrollOffset(gfx::ScrollOffset(50, 50));
+    scroll_layer->SetScrollOffset(gfx::Vector2dF(50, 50));
   }
 
   void BeginTest() override { PostSetNeedsCommitToMainThread(); }
@@ -132,7 +132,7 @@
     SetupViewport(root, gfx::Size(50, 50), layer_size);
 
     auto* scroll = layer_tree_host()->OuterViewportScrollLayerForTesting();
-    SetScrollOffset(scroll, gfx::ScrollOffset(50, 50));
+    SetScrollOffset(scroll, gfx::Vector2dF(50, 50));
 
     client_.set_bounds(root->bounds());
     auto content_layer = FakePictureLayer::Create(&client_);
diff --git a/cc/trees/layer_tree_host_unittest_scroll.cc b/cc/trees/layer_tree_host_unittest_scroll.cc
index 2fcebb1..c797089 100644
--- a/cc/trees/layer_tree_host_unittest_scroll.cc
+++ b/cc/trees/layer_tree_host_unittest_scroll.cc
@@ -88,7 +88,7 @@
 
   // ScrollCallbacks
   void DidCompositorScroll(ElementId element_id,
-                           const gfx::ScrollOffset& scroll_offset,
+                           const gfx::Vector2dF& scroll_offset,
                            const absl::optional<TargetSnapAreaElementIds>&
                                snap_target_ids) override {
     // Simulates cc client (e.g Blink) behavior when handling impl-side scrolls.
@@ -110,7 +110,7 @@
   }
   void DidChangeScrollbarsHidden(ElementId, bool) override {}
 
-  virtual void DidScrollOuterViewport(const gfx::ScrollOffset& scroll_offset) {
+  virtual void DidScrollOuterViewport(const gfx::Vector2dF& scroll_offset) {
     num_outer_viewport_scrolls_++;
   }
 
@@ -138,9 +138,8 @@
       EXPECT_VECTOR_EQ(initial_scroll_,
                        GetTransformNode(scroll_layer)->scroll_offset);
     } else {
-      EXPECT_VECTOR_EQ(
-          gfx::ScrollOffsetWithDelta(initial_scroll_, scroll_amount_),
-          GetTransformNode(scroll_layer)->scroll_offset);
+      EXPECT_VECTOR_EQ(initial_scroll_ + scroll_amount_,
+                       GetTransformNode(scroll_layer)->scroll_offset);
 
       // Pretend like Javascript updated the scroll position itself.
       SetScrollOffset(scroll_layer, second_scroll_);
@@ -174,8 +173,8 @@
   void AfterTest() override { EXPECT_EQ(1, num_outer_viewport_scrolls_); }
 
  private:
-  gfx::ScrollOffset initial_scroll_;
-  gfx::ScrollOffset second_scroll_;
+  gfx::Vector2dF initial_scroll_;
+  gfx::Vector2dF second_scroll_;
   gfx::Vector2dF scroll_amount_;
 };
 
@@ -201,8 +200,7 @@
         break;
       case 1:
       case 2:
-        EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(
-                             initial_scroll_, scroll_amount_ + scroll_amount_),
+        EXPECT_VECTOR_EQ(initial_scroll_ + scroll_amount_ + scroll_amount_,
                          CurrentScrollOffset(scroll_layer_.get()));
         break;
     }
@@ -234,8 +232,7 @@
     } else if (impl->active_tree()->source_frame_number() == 1) {
       // Third or later draw after second commit.
       EXPECT_GE(impl->SourceAnimationFrameNumberForTesting(), 3u);
-      EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(
-                           initial_scroll_, scroll_amount_ + scroll_amount_),
+      EXPECT_VECTOR_EQ(initial_scroll_ + scroll_amount_ + scroll_amount_,
                        CurrentScrollOffset(scroll_layer_.get()));
       EndTest();
     }
@@ -244,7 +241,7 @@
   void AfterTest() override { EXPECT_EQ(1, num_outer_viewport_scrolls_); }
 
  private:
-  gfx::ScrollOffset initial_scroll_;
+  gfx::Vector2dF initial_scroll_;
   gfx::Vector2dF scroll_amount_;
   scoped_refptr<Layer> scroll_layer_;
 };
@@ -298,9 +295,8 @@
         // initiated from the redraw.
         EXPECT_EQ(1, num_outer_viewport_scrolls_);
         EXPECT_EQ(1, layer_tree_host()->SourceFrameNumber());
-        EXPECT_VECTOR_EQ(
-            gfx::ScrollOffsetWithDelta(initial_scroll_, impl_scroll_),
-            CurrentScrollOffset(root_scroll_layer));
+        EXPECT_VECTOR_EQ(initial_scroll_ + impl_scroll_,
+                         CurrentScrollOffset(root_scroll_layer));
         EXPECT_EQ(impl_scale_, layer_tree_host()->page_scale_factor());
         PostSetNeedsRedrawToMainThread();
         break;
@@ -309,15 +305,13 @@
         EXPECT_EQ(2, num_outer_viewport_scrolls_);
         // The source frame number still increases even with the abort.
         EXPECT_EQ(2, layer_tree_host()->SourceFrameNumber());
-        EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(
-                             initial_scroll_, impl_scroll_ + impl_scroll_),
+        EXPECT_VECTOR_EQ(initial_scroll_ + impl_scroll_ + impl_scroll_,
                          CurrentScrollOffset(root_scroll_layer));
         EXPECT_EQ(impl_scale_ * impl_scale_,
                   layer_tree_host()->page_scale_factor());
         SetScrollOffset(
             root_scroll_layer,
-            gfx::ScrollOffsetWithDelta(CurrentScrollOffset(root_scroll_layer),
-                                       second_main_scroll_));
+            CurrentScrollOffset(root_scroll_layer) + second_main_scroll_);
         break;
       case 4:
         // This commit will also be aborted.
@@ -325,7 +319,7 @@
         EXPECT_EQ(3, layer_tree_host()->SourceFrameNumber());
         gfx::Vector2dF delta =
             impl_scroll_ + impl_scroll_ + impl_scroll_ + second_main_scroll_;
-        EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(initial_scroll_, delta),
+        EXPECT_VECTOR_EQ(initial_scroll_ + delta,
                          CurrentScrollOffset(root_scroll_layer));
 
         // End the test by drawing to verify this commit is also aborted.
@@ -372,9 +366,8 @@
       EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(root_scroll_layer));
       root_scroll_layer->ScrollBy(impl_scroll_);
       EXPECT_VECTOR_EQ(impl_scroll_, ScrollDelta(root_scroll_layer));
-      EXPECT_VECTOR_EQ(
-          gfx::ScrollOffsetWithDelta(initial_scroll_, impl_scroll_),
-          ScrollOffsetBase(root_scroll_layer));
+      EXPECT_VECTOR_EQ(initial_scroll_ + impl_scroll_,
+                       ScrollOffsetBase(root_scroll_layer));
 
       EXPECT_EQ(1.f, impl->active_tree()->page_scale_delta());
       EXPECT_EQ(impl_scale_, impl->active_tree()->current_page_scale_factor());
@@ -390,12 +383,12 @@
     } else if (impl->active_tree()->source_frame_number() == 2 &&
                impl->SourceAnimationFrameNumberForTesting() == 3) {
       // Third draw after the second full commit.
-      EXPECT_EQ(ScrollDelta(root_scroll_layer), gfx::ScrollOffset());
+      EXPECT_EQ(ScrollDelta(root_scroll_layer), gfx::Vector2dF());
       root_scroll_layer->ScrollBy(impl_scroll_);
       impl->SetNeedsCommit();
       EXPECT_VECTOR_EQ(impl_scroll_, ScrollDelta(root_scroll_layer));
       gfx::Vector2dF delta = impl_scroll_ + impl_scroll_ + second_main_scroll_;
-      EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(initial_scroll_, delta),
+      EXPECT_VECTOR_EQ(initial_scroll_ + delta,
                        ScrollOffsetBase(root_scroll_layer));
     } else if (impl->active_tree()->source_frame_number() == 2 &&
                impl->SourceAnimationFrameNumberForTesting() == 4) {
@@ -403,7 +396,7 @@
       EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(root_scroll_layer));
       gfx::Vector2dF delta =
           impl_scroll_ + impl_scroll_ + impl_scroll_ + second_main_scroll_;
-      EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(initial_scroll_, delta),
+      EXPECT_VECTOR_EQ(initial_scroll_ + delta,
                        ScrollOffsetBase(root_scroll_layer));
       EndTest();
     } else {
@@ -424,7 +417,7 @@
   }
 
  private:
-  gfx::ScrollOffset initial_scroll_;
+  gfx::Vector2dF initial_scroll_;
   gfx::Vector2dF impl_scroll_;
   gfx::Vector2dF second_main_scroll_;
   float impl_scale_;
@@ -622,7 +615,7 @@
   }
 
   void DidCompositorScroll(ElementId element_id,
-                           const gfx::ScrollOffset& offset,
+                           const gfx::Vector2dF& offset,
                            const absl::optional<TargetSnapAreaElementIds>&
                                snap_target_ids) override {
     LayerTreeHostScrollTest::DidCompositorScroll(element_id, offset,
@@ -646,17 +639,15 @@
                          CurrentScrollOffset(expected_scroll_layer_));
         break;
       case 1:
-        EXPECT_VECTOR_EQ(
-            gfx::ScrollOffsetWithDelta(initial_offset_, scroll_amount_),
-            CurrentScrollOffset(expected_scroll_layer_));
+        EXPECT_VECTOR_EQ(initial_offset_ + scroll_amount_,
+                         CurrentScrollOffset(expected_scroll_layer_));
 
         // Pretend like Javascript updated the scroll position itself.
         SetScrollOffset(expected_scroll_layer_, javascript_scroll_);
         break;
       case 2:
-        EXPECT_VECTOR_EQ(
-            gfx::ScrollOffsetWithDelta(javascript_scroll_, scroll_amount_),
-            CurrentScrollOffset(expected_scroll_layer_));
+        EXPECT_VECTOR_EQ(javascript_scroll_ + scroll_amount_,
+                         CurrentScrollOffset(expected_scroll_layer_));
         break;
     }
   }
@@ -735,9 +726,8 @@
       }
       case 2:
 
-        EXPECT_VECTOR_EQ(
-            gfx::ScrollOffsetWithDelta(javascript_scroll_, scroll_amount_),
-            ScrollOffsetBase(expected_scroll_layer_impl));
+        EXPECT_VECTOR_EQ(javascript_scroll_ + scroll_amount_,
+                         ScrollOffsetBase(expected_scroll_layer_impl));
         EXPECT_VECTOR_EQ(gfx::Vector2d(),
                          ScrollDelta(expected_scroll_layer_impl));
 
@@ -748,19 +738,17 @@
 
   void AfterTest() override {
     EXPECT_EQ(scroll_child_layer_ ? 0 : 2, num_outer_viewport_scrolls_);
-    EXPECT_VECTOR_EQ(
-        gfx::ScrollOffsetWithDelta(javascript_scroll_, scroll_amount_),
-        final_scroll_offset_);
+    EXPECT_VECTOR_EQ(javascript_scroll_ + scroll_amount_, final_scroll_offset_);
   }
 
  protected:
   float device_scale_factor_;
   bool scroll_child_layer_;
 
-  gfx::ScrollOffset initial_offset_;
-  gfx::ScrollOffset javascript_scroll_;
+  gfx::Vector2dF initial_offset_;
+  gfx::Vector2dF javascript_scroll_;
   gfx::Vector2d scroll_amount_;
-  gfx::ScrollOffset final_scroll_offset_;
+  gfx::Vector2dF final_scroll_offset_;
 
   scoped_refptr<Layer> child_layer_;
   Layer* expected_scroll_layer_;
@@ -831,16 +819,13 @@
     if (!layer_tree_host()->SourceFrameNumber()) {
       EXPECT_VECTOR_EQ(initial_scroll_, CurrentScrollOffset(scroll_layer));
     } else {
-      EXPECT_VECTOR_EQ(
-          CurrentScrollOffset(scroll_layer),
-          gfx::ScrollOffsetWithDelta(initial_scroll_, impl_thread_scroll1_));
+      EXPECT_VECTOR_EQ(CurrentScrollOffset(scroll_layer),
+                       initial_scroll_ + impl_thread_scroll1_);
 
       // Pretend like Javascript updated the scroll position itself with a
       // change of main_thread_scroll.
-      SetScrollOffset(
-          scroll_layer,
-          gfx::ScrollOffsetWithDelta(
-              initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_));
+      SetScrollOffset(scroll_layer, initial_scroll_ + main_thread_scroll_ +
+                                        impl_thread_scroll1_);
     }
   }
 
@@ -887,8 +872,7 @@
           LayerImpl* pending_scroll_layer =
               impl->pending_tree()->OuterViewportScrollLayerForTesting();
           EXPECT_VECTOR_EQ(
-              gfx::ScrollOffsetWithDelta(
-                  initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_),
+              initial_scroll_ + main_thread_scroll_ + impl_thread_scroll1_,
               ScrollOffsetBase(pending_scroll_layer));
           EXPECT_VECTOR_EQ(impl_thread_scroll2_,
                            ScrollDelta(pending_scroll_layer));
@@ -897,8 +881,7 @@
       case 1:
         EXPECT_FALSE(impl->pending_tree());
         EXPECT_VECTOR_EQ(
-            gfx::ScrollOffsetWithDelta(
-                initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_),
+            initial_scroll_ + main_thread_scroll_ + impl_thread_scroll1_,
             ScrollOffsetBase(scroll_layer));
         EXPECT_VECTOR_EQ(impl_thread_scroll2_, ScrollDelta(scroll_layer));
         EndTest();
@@ -909,7 +892,7 @@
   void AfterTest() override { EXPECT_EQ(1, num_outer_viewport_scrolls_); }
 
  private:
-  gfx::ScrollOffset initial_scroll_;
+  gfx::Vector2dF initial_scroll_;
   gfx::Vector2dF main_thread_scroll_;
   gfx::Vector2dF impl_thread_scroll1_;
   gfx::Vector2dF impl_thread_scroll2_;
@@ -1005,9 +988,8 @@
         break;
       case 2:
         // On the next commit, this delta should have been sent and applied.
-        EXPECT_VECTOR_EQ(
-            gfx::ScrollOffsetWithDelta(initial_scroll_, impl_thread_scroll_),
-            ScrollOffsetBase(pending_scroll_layer));
+        EXPECT_VECTOR_EQ(initial_scroll_ + impl_thread_scroll_,
+                         ScrollOffsetBase(pending_scroll_layer));
         EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(pending_scroll_layer));
         break;
     }
@@ -1019,9 +1001,9 @@
 
     LayerImpl* scroll_layer =
         impl->pending_tree()->OuterViewportScrollLayerForTesting();
-    gfx::ScrollOffset scroll_offset = CurrentScrollOffset(scroll_layer);
+    gfx::Vector2dF scroll_offset = CurrentScrollOffset(scroll_layer);
     int transform_index = scroll_layer->transform_tree_index();
-    gfx::ScrollOffset transform_tree_scroll_offset =
+    gfx::Vector2dF transform_tree_scroll_offset =
         impl->pending_tree()
             ->property_trees()
             ->transform_tree.Node(transform_index)
@@ -1062,7 +1044,7 @@
   }
 
  private:
-  gfx::ScrollOffset initial_scroll_;
+  gfx::Vector2dF initial_scroll_;
   gfx::Vector2dF impl_thread_scroll_;
   float impl_scale_;
 };
@@ -1247,7 +1229,7 @@
     // Set up snap container data.
     SnapContainerData snap_container_data(
         ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
-        gfx::RectF(0, 0, 100, 100), gfx::ScrollOffset(900, 900));
+        gfx::RectF(0, 0, 100, 100), gfx::Vector2dF(900, 900));
     snap_container_data.AddSnapAreaData(snap_area_data);
     CreateScrollNode(scroller_.get(), container_->bounds())
         .snap_container_data = snap_container_data;
@@ -1314,7 +1296,7 @@
   scoped_refptr<Layer> scroller_;
   scoped_refptr<Layer> snap_area_;
 
-  gfx::ScrollOffset initial_scroll_;
+  gfx::Vector2dF initial_scroll_;
   gfx::Vector2dF impl_thread_scroll_;
 
   ElementId snap_area_id_;
@@ -1385,7 +1367,7 @@
     // Set up snap container data.
     SnapContainerData snap_container_data_a(
         ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
-        gfx::RectF(0, 0, 100, 100), gfx::ScrollOffset(900, 900));
+        gfx::RectF(0, 0, 100, 100), gfx::Vector2dF(900, 900));
     snap_container_data_a.AddSnapAreaData(snap_area_data_a);
     CreateScrollNode(scroller_a_.get(), container_->bounds())
         .snap_container_data = snap_container_data_a;
@@ -1393,7 +1375,7 @@
     // Set up snap container data.
     SnapContainerData snap_container_data_b(
         ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
-        gfx::RectF(0, 0, 100, 100), gfx::ScrollOffset(900, 900));
+        gfx::RectF(0, 0, 100, 100), gfx::Vector2dF(900, 900));
     snap_container_data_b.AddSnapAreaData(snap_area_data_b);
     CreateScrollNode(scroller_b_.get(), container_->bounds())
         .snap_container_data = snap_container_data_b;
@@ -1463,7 +1445,7 @@
   scoped_refptr<Layer> snap_area_a_;
   scoped_refptr<Layer> snap_area_b_;
 
-  gfx::ScrollOffset initial_scroll_;
+  gfx::Vector2dF initial_scroll_;
   gfx::Vector2dF impl_thread_scroll_a_;
   gfx::Vector2dF impl_thread_scroll_b_;
 
@@ -1603,7 +1585,7 @@
     layer_tree_host()->OuterViewportScrollLayerForTesting()->SetIsDrawable(
         false);
     SetScrollOffset(layer_tree_host()->OuterViewportScrollLayerForTesting(),
-                    gfx::ScrollOffset(20.f, 20.f));
+                    gfx::Vector2dF(20.f, 20.f));
     layer_tree_host()
         ->OuterViewportScrollLayerForTesting()
         ->SetNonFastScrollableRegion(gfx::Rect(20, 20, 20, 20));
@@ -1773,8 +1755,8 @@
   void SetPrefersReducedMotion(bool prefers_reduced_motion) override {}
 
   void UpdateRootLayerStateForSynchronousInputHandler(
-      const gfx::ScrollOffset& total_scroll_offset,
-      const gfx::ScrollOffset& max_scroll_offset,
+      const gfx::Vector2dF& total_scroll_offset,
+      const gfx::Vector2dF& max_scroll_offset,
       const gfx::SizeF& scrollable_size,
       float page_scale_factor,
       float min_page_scale_factor,
@@ -1847,7 +1829,7 @@
 
   void DidCompositorScroll(
       ElementId element_id,
-      const gfx::ScrollOffset&,
+      const gfx::Vector2dF&,
       const absl::optional<TargetSnapAreaElementIds>&) override {
     if (scroll_destroy_whole_tree_) {
       layer_tree_host()->SetRootLayer(nullptr);
@@ -1951,9 +1933,8 @@
         EXPECT_VECTOR_EQ(initial_scroll_, CurrentScrollOffset(scroll_layer));
         break;
       case 1:
-        EXPECT_VECTOR_EQ(
-            gfx::ScrollOffsetWithDelta(initial_scroll_, scroll_amount_),
-            CurrentScrollOffset(scroll_layer));
+        EXPECT_VECTOR_EQ(initial_scroll_ + scroll_amount_,
+                         CurrentScrollOffset(scroll_layer));
         // Pretend like Javascript updated the scroll position itself.
         SetScrollOffset(scroll_layer, second_scroll_);
         break;
@@ -2010,9 +1991,9 @@
     scroll_layer->ScrollBy(scroll_amount_);
   }
 
-  gfx::ScrollOffset initial_scroll_;
-  gfx::ScrollOffset second_scroll_;
-  gfx::ScrollOffset third_scroll_;
+  gfx::Vector2dF initial_scroll_;
+  gfx::Vector2dF second_scroll_;
+  gfx::Vector2dF third_scroll_;
   gfx::Vector2dF scroll_amount_;
   int num_commits_;
 };
@@ -2070,13 +2051,11 @@
         // This commit will not be aborted because of the scroll change.
         EXPECT_EQ(1, num_outer_viewport_scrolls_);
         EXPECT_EQ(1, layer_tree_host()->SourceFrameNumber());
-        EXPECT_VECTOR_EQ(
-            gfx::ScrollOffsetWithDelta(initial_scroll_, impl_scroll_),
-            CurrentScrollOffset(root_scroll_layer));
+        EXPECT_VECTOR_EQ(initial_scroll_ + impl_scroll_,
+                         CurrentScrollOffset(root_scroll_layer));
         SetScrollOffset(
             root_scroll_layer,
-            gfx::ScrollOffsetWithDelta(CurrentScrollOffset(root_scroll_layer),
-                                       second_main_scroll_));
+            CurrentScrollOffset(root_scroll_layer) + second_main_scroll_);
         break;
       case 3: {
         // This commit will be aborted.
@@ -2085,7 +2064,7 @@
         EXPECT_EQ(2, layer_tree_host()->SourceFrameNumber());
         gfx::Vector2dF delta =
             impl_scroll_ + impl_scroll_ + second_main_scroll_;
-        EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(initial_scroll_, delta),
+        EXPECT_VECTOR_EQ(initial_scroll_ + delta,
                          CurrentScrollOffset(root_scroll_layer));
         break;
       }
@@ -2095,7 +2074,7 @@
         EXPECT_EQ(3, layer_tree_host()->SourceFrameNumber());
         gfx::Vector2dF delta =
             impl_scroll_ + impl_scroll_ + impl_scroll_ + second_main_scroll_;
-        EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(initial_scroll_, delta),
+        EXPECT_VECTOR_EQ(initial_scroll_ + delta,
                          CurrentScrollOffset(root_scroll_layer));
         break;
       }
@@ -2173,16 +2152,15 @@
       case 1: {
         EXPECT_EQ(2, num_impl_commits_);
         // All scroll deltas so far should be consumed.
-        EXPECT_EQ(gfx::ScrollOffset(), ScrollDelta(root_scroll_layer));
+        EXPECT_EQ(gfx::Vector2dF(), ScrollDelta(root_scroll_layer));
         switch (num_aborted_commits_) {
           case 1: {
             root_scroll_layer->ScrollBy(impl_scroll_);
             EXPECT_VECTOR_EQ(impl_scroll_, ScrollDelta(root_scroll_layer));
             gfx::Vector2dF prev_delta =
                 impl_scroll_ + impl_scroll_ + second_main_scroll_;
-            EXPECT_VECTOR_EQ(
-                gfx::ScrollOffsetWithDelta(initial_scroll_, prev_delta),
-                ScrollOffsetBase(root_scroll_layer));
+            EXPECT_VECTOR_EQ(initial_scroll_ + prev_delta,
+                             ScrollOffsetBase(root_scroll_layer));
             // Ask for another commit (which will abort).
             impl->SetNeedsCommit();
             break;
@@ -2190,7 +2168,7 @@
           case 2: {
             gfx::Vector2dF delta = impl_scroll_ + impl_scroll_ + impl_scroll_ +
                                    second_main_scroll_;
-            EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(initial_scroll_, delta),
+            EXPECT_VECTOR_EQ(initial_scroll_ + delta,
                              ScrollOffsetBase(root_scroll_layer));
             // End test after second aborted commit (fourth commit request).
             EndTest();
@@ -2219,7 +2197,7 @@
   }
 
  private:
-  gfx::ScrollOffset initial_scroll_;
+  gfx::Vector2dF initial_scroll_;
   gfx::Vector2dF impl_scroll_;
   gfx::Vector2dF second_main_scroll_;
   int num_will_begin_main_frames_;
@@ -2243,8 +2221,8 @@
   void Animate(base::TimeTicks) override {}
   void SetPrefersReducedMotion(bool prefers_reduced_motion) override {}
   void UpdateRootLayerStateForSynchronousInputHandler(
-      const gfx::ScrollOffset& total_scroll_offset,
-      const gfx::ScrollOffset& max_scroll_offset,
+      const gfx::Vector2dF& total_scroll_offset,
+      const gfx::Vector2dF& max_scroll_offset,
       const gfx::SizeF& scrollable_size,
       float page_scale_factor,
       float min_page_scale_factor,
@@ -2429,9 +2407,8 @@
     if (layer_tree_host()->SourceFrameNumber() == 0) {
       EXPECT_VECTOR_EQ(initial_scroll_, CurrentScrollOffset(scroll_layer));
     } else {
-      EXPECT_VECTOR_EQ(
-          gfx::ScrollOffsetWithDelta(initial_scroll_, scroll_amount_),
-          CurrentScrollOffset(scroll_layer));
+      EXPECT_VECTOR_EQ(initial_scroll_ + scroll_amount_,
+                       CurrentScrollOffset(scroll_layer));
       SetScrollOffset(scroll_layer, second_scroll_);
       SetOpacity(scroll_layer, 0.5f);
     }
@@ -2458,8 +2435,8 @@
   }
 
  private:
-  gfx::ScrollOffset initial_scroll_;
-  gfx::ScrollOffset second_scroll_;
+  gfx::Vector2dF initial_scroll_;
+  gfx::Vector2dF second_scroll_;
   gfx::Vector2dF scroll_amount_;
 };
 
@@ -2469,7 +2446,7 @@
     : public LayerTreeHostScrollTest {
   void BeginTest() override { PostSetNeedsCommitToMainThread(); }
 
-  void DidScrollOuterViewport(const gfx::ScrollOffset& offset) override {
+  void DidScrollOuterViewport(const gfx::Vector2dF& offset) override {
     LayerTreeHostScrollTest::DidScrollOuterViewport(offset);
 
     // Defer responding to the main frame until an impl-side pending tree is
@@ -2491,7 +2468,7 @@
         // takes us to the final value.
         Layer* outer_viewport_layer =
             layer_tree_host()->OuterViewportScrollLayerForTesting();
-        gfx::ScrollOffset delta_to_send =
+        gfx::Vector2dF delta_to_send =
             outer_viewport_offsets_[2] - outer_viewport_offsets_[1];
         SetScrollOffset(
             outer_viewport_layer,
@@ -2524,9 +2501,9 @@
 
     LayerImpl* scroll_layer =
         host_impl->pending_tree()->OuterViewportScrollLayerForTesting();
-    gfx::ScrollOffset scroll_offset = CurrentScrollOffset(scroll_layer);
+    gfx::Vector2dF scroll_offset = CurrentScrollOffset(scroll_layer);
     int transform_index = scroll_layer->transform_tree_index();
-    gfx::ScrollOffset transform_tree_scroll_offset =
+    gfx::Vector2dF transform_tree_scroll_offset =
         host_impl->pending_tree()
             ->property_trees()
             ->transform_tree.Node(transform_index)
@@ -2630,9 +2607,8 @@
     EXPECT_EQ(3, num_of_main_frames_);
   }
 
-  const gfx::ScrollOffset outer_viewport_offsets_[3] = {
-      gfx::ScrollOffset(20, 20), gfx::ScrollOffset(50, 50),
-      gfx::ScrollOffset(70, 70)};
+  const gfx::Vector2dF outer_viewport_offsets_[3] = {
+      gfx::Vector2dF(20, 20), gfx::Vector2dF(50, 50), gfx::Vector2dF(70, 70)};
 
   // Impl thread.
   int num_of_activations_ = 0;
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index a281aa6f8..cff5d1f 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -82,12 +82,11 @@
     scroll_tree().ClampScrollToMaxScrollOffset(*inner_, tree_impl_);
     scroll_tree().ClampScrollToMaxScrollOffset(*outer_, tree_impl_);
 
-    gfx::ScrollOffset viewport_location =
+    gfx::Vector2dF viewport_location =
         scroll_tree().current_scroll_offset(inner_->element_id) +
         scroll_tree().current_scroll_offset(outer_->element_id);
 
-    gfx::Vector2dF delta =
-        viewport_in_content_coordinates_.DeltaFrom(viewport_location);
+    gfx::Vector2dF delta = viewport_in_content_coordinates_ - viewport_location;
 
     delta = scroll_tree().ScrollBy(*inner_, delta, tree_impl_);
     scroll_tree().ScrollBy(*outer_, delta, tree_impl_);
@@ -101,7 +100,7 @@
   ScrollNode* inner_;
   ScrollNode* outer_;
   LayerTreeImpl* tree_impl_;
-  gfx::ScrollOffset viewport_in_content_coordinates_;
+  gfx::Vector2dF viewport_in_content_coordinates_;
 };
 
 std::pair<gfx::PointF, gfx::PointF> GetVisibleSelectionEndPoints(
@@ -110,8 +109,7 @@
     const gfx::PointF& bottom) {
   gfx::PointF start(base::clamp(top.x(), rect.x(), rect.right()),
                     base::clamp(top.y(), rect.y(), rect.bottom()));
-  gfx::PointF end =
-      start + gfx::Vector2dF(bottom.x() - top.x(), bottom.y() - top.y());
+  gfx::PointF end = start + (bottom - top);
   return {start, end};
 }
 
@@ -275,7 +273,7 @@
     auto* scroll_node = scroll_tree.FindNodeFromElementId(scrolling_element_id);
     if (!scroll_node)
       continue;
-    gfx::ScrollOffset current_offset =
+    gfx::Vector2dF current_offset =
         scroll_tree.current_scroll_offset(scrolling_element_id);
     gfx::SizeF scrolling_size(scroll_node->bounds);
     gfx::Size bounds_size(scroll_tree.container_bounds(scroll_node->id));
@@ -470,8 +468,8 @@
   return !layer_list_.empty() && layer_list_[0].get() == layer;
 }
 
-gfx::ScrollOffset LayerTreeImpl::TotalScrollOffset() const {
-  gfx::ScrollOffset offset;
+gfx::Vector2dF LayerTreeImpl::TotalScrollOffset() const {
+  gfx::Vector2dF offset;
   const auto& scroll_tree = property_trees()->scroll_tree;
 
   if (auto* inner_scroll = InnerViewportScrollNode()) {
@@ -484,8 +482,8 @@
   return offset;
 }
 
-gfx::ScrollOffset LayerTreeImpl::TotalMaxScrollOffset() const {
-  gfx::ScrollOffset offset;
+gfx::Vector2dF LayerTreeImpl::TotalMaxScrollOffset() const {
+  gfx::Vector2dF offset;
   const auto& scroll_tree = property_trees()->scroll_tree;
 
   if (viewport_property_ids_.inner_scroll != ScrollTree::kInvalidNodeId)
diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h
index ed66e8a..76ea3c12 100644
--- a/cc/trees/layer_tree_impl.h
+++ b/cc/trees/layer_tree_impl.h
@@ -280,8 +280,8 @@
     hud_layer_ = layer_impl;
   }
 
-  gfx::ScrollOffset TotalScrollOffset() const;
-  gfx::ScrollOffset TotalMaxScrollOffset() const;
+  gfx::Vector2dF TotalScrollOffset() const;
+  gfx::Vector2dF TotalMaxScrollOffset() const;
 
   void AddPresentationCallbacks(
       std::vector<PresentationTimeCallbackBuffer::MainCallback> callbacks);
diff --git a/cc/trees/layer_tree_impl_unittest.cc b/cc/trees/layer_tree_impl_unittest.cc
index ff133af..9840506 100644
--- a/cc/trees/layer_tree_impl_unittest.cc
+++ b/cc/trees/layer_tree_impl_unittest.cc
@@ -25,8 +25,7 @@
     const gfx::PointF& bottom) {
   gfx::PointF start(base::clamp(top.x(), rect.x(), rect.right()),
                     base::clamp(top.y(), rect.y(), rect.bottom()));
-  gfx::PointF end =
-      start + gfx::Vector2dF(bottom.x() - top.x(), bottom.y() - top.y());
+  gfx::PointF end = start + (bottom - top);
   return {start, end};
 }
 
diff --git a/cc/trees/mutator_host.h b/cc/trees/mutator_host.h
index e0ac5bc..6e9533b 100644
--- a/cc/trees/mutator_host.h
+++ b/cc/trees/mutator_host.h
@@ -15,10 +15,6 @@
 #include "ui/gfx/geometry/box_f.h"
 #include "ui/gfx/geometry/vector2d_f.h"
 
-namespace gfx {
-class ScrollOffset;
-}
-
 namespace cc {
 
 class MutatorEvents;
@@ -129,20 +125,20 @@
 
   virtual void ImplOnlyAutoScrollAnimationCreate(
       ElementId element_id,
-      const gfx::ScrollOffset& target_offset,
-      const gfx::ScrollOffset& current_offset,
+      const gfx::Vector2dF& target_offset,
+      const gfx::Vector2dF& current_offset,
       float autoscroll_velocity,
       base::TimeDelta animation_start_offset) = 0;
 
   virtual void ImplOnlyScrollAnimationCreate(
       ElementId element_id,
-      const gfx::ScrollOffset& target_offset,
-      const gfx::ScrollOffset& current_offset,
+      const gfx::Vector2dF& target_offset,
+      const gfx::Vector2dF& current_offset,
       base::TimeDelta delayed_by,
       base::TimeDelta animation_start_offset) = 0;
   virtual bool ImplOnlyScrollAnimationUpdateTarget(
       const gfx::Vector2dF& scroll_delta,
-      const gfx::ScrollOffset& max_scroll_offset,
+      const gfx::Vector2dF& max_scroll_offset,
       base::TimeTicks frame_monotonic_time,
       base::TimeDelta delayed_by) = 0;
 
diff --git a/cc/trees/mutator_host_client.h b/cc/trees/mutator_host_client.h
index 4a794d7..5f995ff 100644
--- a/cc/trees/mutator_host_client.h
+++ b/cc/trees/mutator_host_client.h
@@ -12,7 +12,7 @@
 
 namespace gfx {
 class Transform;
-class ScrollOffset;
+class Vector2dF;
 }
 
 namespace cc {
@@ -52,7 +52,7 @@
   virtual void SetElementScrollOffsetMutated(
       ElementId element_id,
       ElementListType list_type,
-      const gfx::ScrollOffset& scroll_offset) = 0;
+      const gfx::Vector2dF& scroll_offset) = 0;
 
   // Allows to change IsAnimating value for a set of properties.
   virtual void ElementIsAnimatingChanged(
@@ -66,7 +66,7 @@
                                    float maximum_scale) = 0;
 
   virtual void ScrollOffsetAnimationFinished() = 0;
-  virtual gfx::ScrollOffset GetScrollOffsetForAnimation(
+  virtual gfx::Vector2dF GetScrollOffsetForAnimation(
       ElementId element_id) const = 0;
 
   virtual void NotifyAnimationWorkletStateChange(
diff --git a/cc/trees/property_tree.cc b/cc/trees/property_tree.cc
index 0767972..d78b70a 100644
--- a/cc/trees/property_tree.cc
+++ b/cc/trees/property_tree.cc
@@ -438,7 +438,7 @@
       sticky_offset;
 
   // return
-  return gfx::Vector2dF(roundf(sticky_offset.x()), roundf(sticky_offset.y()));
+  return gfx::ToRoundedVector2d(sticky_offset);
 }
 
 void TransformTree::UpdateLocalTransform(TransformNode* node) {
@@ -1281,12 +1281,12 @@
 #endif
 }
 
-gfx::ScrollOffset ScrollTree::MaxScrollOffset(int scroll_node_id) const {
+gfx::Vector2dF ScrollTree::MaxScrollOffset(int scroll_node_id) const {
   const ScrollNode* scroll_node = Node(scroll_node_id);
   gfx::SizeF scroll_bounds = this->scroll_bounds(scroll_node_id);
 
   if (!scroll_node->scrollable || scroll_bounds.IsEmpty())
-    return gfx::ScrollOffset();
+    return gfx::Vector2dF();
 
   TransformTree& transform_tree = property_trees()->transform_tree;
   float scale_factor = 1.f;
@@ -1299,12 +1299,12 @@
 
   gfx::Size clip_layer_bounds = container_bounds(scroll_node->id);
 
-  gfx::ScrollOffset max_offset(
+  gfx::Vector2dF max_offset(
       scaled_scroll_bounds.width() - clip_layer_bounds.width(),
       scaled_scroll_bounds.height() - clip_layer_bounds.height());
 
   max_offset.Scale(1 / scale_factor);
-  max_offset.SetToMax(gfx::ScrollOffset());
+  max_offset.SetToMax(gfx::Vector2dF());
   return max_offset;
 }
 
@@ -1320,7 +1320,7 @@
 
 void ScrollTree::OnScrollOffsetAnimated(ElementId id,
                                         int scroll_tree_index,
-                                        const gfx::ScrollOffset& scroll_offset,
+                                        const gfx::Vector2dF& scroll_offset,
                                         LayerTreeImpl* layer_tree_impl) {
   // Only active tree needs to be updated, pending tree will find out about
   // these changes as a result of the shared SyncedProperty.
@@ -1408,30 +1408,29 @@
 gfx::Vector2dF ScrollTree::ClampScrollToMaxScrollOffset(
     const ScrollNode& node,
     LayerTreeImpl* layer_tree_impl) {
-  gfx::ScrollOffset old_offset = current_scroll_offset(node.element_id);
-  gfx::ScrollOffset clamped_offset =
-      ClampScrollOffsetToLimits(old_offset, node);
-  gfx::Vector2dF delta = clamped_offset.DeltaFrom(old_offset);
+  gfx::Vector2dF old_offset = current_scroll_offset(node.element_id);
+  gfx::Vector2dF clamped_offset = ClampScrollOffsetToLimits(old_offset, node);
+  gfx::Vector2dF delta = clamped_offset - old_offset;
   if (!delta.IsZero())
     ScrollBy(node, delta, layer_tree_impl);
   return delta;
 }
 
-const gfx::ScrollOffset ScrollTree::current_scroll_offset(ElementId id) const {
+const gfx::Vector2dF ScrollTree::current_scroll_offset(ElementId id) const {
   if (property_trees()->is_main_thread) {
     auto it = scroll_offset_map_.find(id);
-    return it != scroll_offset_map_.end() ? it->second : gfx::ScrollOffset();
+    return it != scroll_offset_map_.end() ? it->second : gfx::Vector2dF();
   }
   return GetSyncedScrollOffset(id)
              ? GetSyncedScrollOffset(id)->Current(property_trees()->is_active)
-             : gfx::ScrollOffset();
+             : gfx::Vector2dF();
 }
 
-const gfx::ScrollOffset ScrollTree::GetPixelSnappedScrollOffset(
+const gfx::Vector2dF ScrollTree::GetPixelSnappedScrollOffset(
     int scroll_node_id) const {
   const ScrollNode* scroll_node = Node(scroll_node_id);
   DCHECK(scroll_node);
-  gfx::ScrollOffset offset = current_scroll_offset(scroll_node->element_id);
+  gfx::Vector2dF offset = current_scroll_offset(scroll_node->element_id);
 
   const TransformNode* transform_node =
       property_trees()->transform_tree.Node(scroll_node->transform_id);
@@ -1453,14 +1452,14 @@
     // that case here.
     // TODO(crbug.com/1076878): Remove the clamping when scroll timeline effects
     // always match the snapping.
-    offset = ClampScrollOffsetToLimits(
-        offset - gfx::ScrollOffset(transform_node->snap_amount), *scroll_node);
+    offset = ClampScrollOffsetToLimits(offset - transform_node->snap_amount,
+                                       *scroll_node);
   }
 
   return offset;
 }
 
-gfx::ScrollOffset ScrollTree::PullDeltaForMainThread(
+gfx::Vector2dF ScrollTree::PullDeltaForMainThread(
     SyncedScrollOffset* scroll_offset,
     bool use_fractional_deltas) {
   DCHECK(property_trees()->is_active);
@@ -1475,18 +1474,16 @@
   // TODO(flackr): We should ideally round the fractional scrolls in the same
   // direction as the scroll will be snapped but for common cases this is
   // equivalent to rounding to the nearest integer offset.
-  gfx::ScrollOffset current_offset =
+  gfx::Vector2dF current_offset =
       scroll_offset->Current(/* is_active_tree */ true);
-  gfx::ScrollOffset rounded_offset =
-      gfx::ScrollOffset(roundf(current_offset.x()), roundf(current_offset.y()));
+  gfx::Vector2dF rounded_offset = gfx::ToRoundedVector2d(current_offset);
   // The calculation of the difference from the rounded active base is to
   // represent the integer delta that the main thread should know about.
-  gfx::ScrollOffset active_base = scroll_offset->ActiveBase();
-  gfx::ScrollOffset diff_active_base =
-      gfx::ScrollOffset(active_base.x() - roundf(active_base.x()),
-                        active_base.y() - roundf(active_base.y()));
+  gfx::Vector2dF active_base = scroll_offset->ActiveBase();
+  gfx::Vector2dF diff_active_base =
+      active_base - gfx::ToRoundedVector2d(active_base);
   scroll_offset->SetCurrent(rounded_offset + diff_active_base);
-  gfx::ScrollOffset delta = scroll_offset->PullDeltaForMainThread();
+  gfx::Vector2dF delta = scroll_offset->PullDeltaForMainThread();
   scroll_offset->SetCurrent(current_offset);
   return delta;
 }
@@ -1500,7 +1497,7 @@
   DCHECK(!property_trees()->is_main_thread);
   TRACE_EVENT0("cc", "ScrollTree::CollectScrollDeltas");
   for (auto map_entry : synced_scroll_offset_map_) {
-    gfx::ScrollOffset scroll_delta =
+    gfx::Vector2dF scroll_delta =
         PullDeltaForMainThread(map_entry.second.get(), use_fractional_deltas);
 
     ElementId id = map_entry.first;
@@ -1570,9 +1567,8 @@
     // PullDeltaForMainThread where only an integer delta is extracted and
     // prevents unnecessary property change in this case.
     if (!use_fractional_deltas) {
-      gfx::ScrollOffset pending_offset = synced_scroll_offset->Current(false);
-      gfx::ScrollOffset rounded_offset = gfx::ScrollOffset(
-          roundf(pending_offset.x()), roundf(pending_offset.y()));
+      gfx::Vector2dF pending_offset = synced_scroll_offset->Current(false);
+      gfx::Vector2dF rounded_offset = gfx::ToRoundedVector2d(pending_offset);
       needs_scroll_update = map_entry.second != rounded_offset;
     }
 
@@ -1616,7 +1612,7 @@
 }
 
 void ScrollTree::SetBaseScrollOffset(ElementId id,
-                                     const gfx::ScrollOffset& scroll_offset) {
+                                     const gfx::Vector2dF& scroll_offset) {
   if (property_trees()->is_main_thread) {
     scroll_offset_map_[id] = scroll_offset;
     return;
@@ -1629,7 +1625,7 @@
 }
 
 bool ScrollTree::SetScrollOffset(ElementId id,
-                                 const gfx::ScrollOffset& scroll_offset) {
+                                 const gfx::Vector2dF& scroll_offset) {
   // TODO(crbug.com/1087088): Remove TRACE_EVENT call when the bug is fixed
   TRACE_EVENT2("cc", "ScrollTree::SetScrollOffset", "x", scroll_offset.x(), "y",
                scroll_offset.y());
@@ -1649,7 +1645,7 @@
 
 bool ScrollTree::UpdateScrollOffsetBaseForTesting(
     ElementId id,
-    const gfx::ScrollOffset& offset) {
+    const gfx::Vector2dF& offset) {
   DCHECK(!property_trees()->is_main_thread);
   SyncedScrollOffset* synced_scroll_offset = GetOrCreateSyncedScrollOffset(id);
   bool changed = synced_scroll_offset->PushMainToPending(offset);
@@ -1661,57 +1657,55 @@
 bool ScrollTree::SetScrollOffsetDeltaForTesting(ElementId id,
                                                 const gfx::Vector2dF& delta) {
   return GetOrCreateSyncedScrollOffset(id)->SetCurrent(
-      GetOrCreateSyncedScrollOffset(id)->ActiveBase() +
-      gfx::ScrollOffset(delta));
+      GetOrCreateSyncedScrollOffset(id)->ActiveBase() + delta);
 }
 
-const gfx::ScrollOffset ScrollTree::GetScrollOffsetBaseForTesting(
+const gfx::Vector2dF ScrollTree::GetScrollOffsetBaseForTesting(
     ElementId id) const {
   DCHECK(!property_trees()->is_main_thread);
-  if (GetSyncedScrollOffset(id))
+  if (GetSyncedScrollOffset(id)) {
     return property_trees()->is_active
                ? GetSyncedScrollOffset(id)->ActiveBase()
                : GetSyncedScrollOffset(id)->PendingBase();
-  else
-    return gfx::ScrollOffset();
+  }
+  return gfx::Vector2dF();
 }
 
-const gfx::ScrollOffset ScrollTree::GetScrollOffsetDeltaForTesting(
+const gfx::Vector2dF ScrollTree::GetScrollOffsetDeltaForTesting(
     ElementId id) const {
   DCHECK(!property_trees()->is_main_thread);
-  if (GetSyncedScrollOffset(id))
+  if (GetSyncedScrollOffset(id)) {
     return property_trees()->is_active
                ? GetSyncedScrollOffset(id)->Delta()
                : GetSyncedScrollOffset(id)->PendingDelta().get();
-  else
-    return gfx::ScrollOffset();
+  }
+  return gfx::Vector2dF();
 }
 
 gfx::Vector2dF ScrollTree::ScrollBy(const ScrollNode& scroll_node,
                                     const gfx::Vector2dF& scroll,
                                     LayerTreeImpl* layer_tree_impl) {
-  gfx::ScrollOffset adjusted_scroll(scroll);
+  gfx::Vector2dF adjusted_scroll(scroll);
   if (!scroll_node.user_scrollable_horizontal)
     adjusted_scroll.set_x(0);
   if (!scroll_node.user_scrollable_vertical)
     adjusted_scroll.set_y(0);
   DCHECK(scroll_node.scrollable);
-  gfx::ScrollOffset old_offset = current_scroll_offset(scroll_node.element_id);
-  gfx::ScrollOffset new_offset =
+  gfx::Vector2dF old_offset = current_scroll_offset(scroll_node.element_id);
+  gfx::Vector2dF new_offset =
       ClampScrollOffsetToLimits(old_offset + adjusted_scroll, scroll_node);
   if (SetScrollOffset(scroll_node.element_id, new_offset))
     layer_tree_impl->DidUpdateScrollOffset(scroll_node.element_id);
 
-  gfx::ScrollOffset unscrolled =
-      old_offset + gfx::ScrollOffset(scroll) - new_offset;
-  return gfx::Vector2dF(unscrolled.x(), unscrolled.y());
+  // Return the amount of scroll delta we could not consume for this node.
+  return old_offset + scroll - new_offset;
 }
 
-gfx::ScrollOffset ScrollTree::ClampScrollOffsetToLimits(
-    gfx::ScrollOffset offset,
+gfx::Vector2dF ScrollTree::ClampScrollOffsetToLimits(
+    gfx::Vector2dF offset,
     const ScrollNode& scroll_node) const {
   offset.SetToMin(MaxScrollOffset(scroll_node.id));
-  offset.SetToMax(gfx::ScrollOffset());
+  offset.SetToMax(gfx::Vector2dF());
   return offset;
 }
 
@@ -1722,7 +1716,7 @@
 
 void ScrollTree::NotifyDidCompositorScroll(
     ElementId scroll_element_id,
-    const gfx::ScrollOffset& scroll_offset,
+    const gfx::Vector2dF& scroll_offset,
     const absl::optional<TargetSnapAreaElementIds>& snap_target_ids) {
   DCHECK(property_trees()->is_main_thread);
   if (callbacks_) {
diff --git a/cc/trees/property_tree.h b/cc/trees/property_tree.h
index 3ac68f8..3fa34edd 100644
--- a/cc/trees/property_tree.h
+++ b/cc/trees/property_tree.h
@@ -25,7 +25,7 @@
 #include "cc/trees/sticky_position_constraint.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/geometry/rect_f.h"
-#include "ui/gfx/geometry/scroll_offset.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 #include "ui/gfx/transform.h"
 
 namespace base {
@@ -49,7 +49,7 @@
 struct TransformNode;
 struct TransformCachedNodeData;
 
-typedef SyncedProperty<AdditionGroup<gfx::ScrollOffset>> SyncedScrollOffset;
+typedef SyncedProperty<AdditionGroup<gfx::Vector2dF>> SyncedScrollOffset;
 
 class PropertyTrees;
 
@@ -383,7 +383,7 @@
   // Called after the composited scroll offset changed.
   virtual void DidCompositorScroll(
       ElementId scroll_element_id,
-      const gfx::ScrollOffset&,
+      const gfx::Vector2dF&,
       const absl::optional<TargetSnapAreaElementIds>&) = 0;
   // Called after the hidden status of composited scrollbars changed. Note that
   // |scroll_element_id| is the element id of the scroll not of the scrollbars.
@@ -407,10 +407,10 @@
 
   void clear();
 
-  gfx::ScrollOffset MaxScrollOffset(int scroll_node_id) const;
+  gfx::Vector2dF MaxScrollOffset(int scroll_node_id) const;
   void OnScrollOffsetAnimated(ElementId id,
                               int scroll_tree_index,
-                              const gfx::ScrollOffset& scroll_offset,
+                              const gfx::Vector2dF& scroll_offset,
                               LayerTreeImpl* layer_tree_impl);
   gfx::Size container_bounds(int scroll_node_id) const;
   gfx::SizeF scroll_bounds(int scroll_node_id) const;
@@ -429,7 +429,7 @@
   // Returns the current scroll offset. On the main thread this would return the
   // value for the LayerTree while on the impl thread this is the current value
   // on the active tree.
-  const gfx::ScrollOffset current_scroll_offset(ElementId id) const;
+  const gfx::Vector2dF current_scroll_offset(ElementId id) const;
 
   // Returns the scroll offset taking into account any adjustments that may be
   // included due to pixel snapping.
@@ -441,7 +441,7 @@
   // simple cases but we really should update the whole transform tree otherwise
   // we are ignoring any parent transform node that needs updating and thus our
   // snap amount can be incorrect.
-  const gfx::ScrollOffset GetPixelSnappedScrollOffset(int scroll_node_id) const;
+  const gfx::Vector2dF GetPixelSnappedScrollOffset(int scroll_node_id) const;
 
   // Collects deltas for scroll changes on the impl thread that need to be
   // reported to the main thread during the main frame. As such, should only be
@@ -468,27 +468,25 @@
   void PushScrollUpdatesFromPendingTree(PropertyTrees* pending_property_trees,
                                         LayerTreeImpl* active_tree);
 
-  void SetBaseScrollOffset(ElementId id,
-                           const gfx::ScrollOffset& scroll_offset);
+  void SetBaseScrollOffset(ElementId id, const gfx::Vector2dF& scroll_offset);
   // Returns true if the scroll offset is changed.
-  bool SetScrollOffset(ElementId id, const gfx::ScrollOffset& scroll_offset);
+  bool SetScrollOffset(ElementId id, const gfx::Vector2dF& scroll_offset);
   void SetScrollOffsetClobberActiveValue(ElementId id) {
     GetOrCreateSyncedScrollOffset(id)->set_clobber_active_value();
   }
   bool UpdateScrollOffsetBaseForTesting(ElementId id,
-                                        const gfx::ScrollOffset& offset);
+                                        const gfx::Vector2dF& offset);
   bool SetScrollOffsetDeltaForTesting(ElementId id,
                                       const gfx::Vector2dF& delta);
-  const gfx::ScrollOffset GetScrollOffsetBaseForTesting(ElementId id) const;
-  const gfx::ScrollOffset GetScrollOffsetDeltaForTesting(ElementId id) const;
+  const gfx::Vector2dF GetScrollOffsetBaseForTesting(ElementId id) const;
+  const gfx::Vector2dF GetScrollOffsetDeltaForTesting(ElementId id) const;
   void CollectScrollDeltasForTesting(bool use_fractional_deltas = false);
 
   gfx::Vector2dF ScrollBy(const ScrollNode& scroll_node,
                           const gfx::Vector2dF& scroll,
                           LayerTreeImpl* layer_tree_impl);
-  gfx::ScrollOffset ClampScrollOffsetToLimits(
-      gfx::ScrollOffset offset,
-      const ScrollNode& scroll_node) const;
+  gfx::Vector2dF ClampScrollOffsetToLimits(gfx::Vector2dF offset,
+                                           const ScrollNode& scroll_node) const;
 
   const SyncedScrollOffset* GetSyncedScrollOffset(ElementId id) const;
 
@@ -503,7 +501,7 @@
 
   void NotifyDidCompositorScroll(
       ElementId scroll_element_id,
-      const gfx::ScrollOffset& scroll_offset,
+      const gfx::Vector2dF& scroll_offset,
       const absl::optional<TargetSnapAreaElementIds>& snap_target_ids);
   void NotifyDidChangeScrollbarsHidden(ElementId scroll_element_id,
                                        bool hidden);
@@ -518,7 +516,7 @@
   using PropertyTree::needs_update;
   using PropertyTree::set_needs_update;
 
-  using ScrollOffsetMap = base::flat_map<ElementId, gfx::ScrollOffset>;
+  using ScrollOffsetMap = base::flat_map<ElementId, gfx::Vector2dF>;
   using SyncedScrollOffsetMap =
       base::flat_map<ElementId, scoped_refptr<SyncedScrollOffset>>;
 
@@ -535,8 +533,8 @@
   base::WeakPtr<ScrollCallbacks> callbacks_;
 
   SyncedScrollOffset* GetOrCreateSyncedScrollOffset(ElementId id);
-  gfx::ScrollOffset PullDeltaForMainThread(SyncedScrollOffset* scroll_offset,
-                                           bool use_fractional_deltas);
+  gfx::Vector2dF PullDeltaForMainThread(SyncedScrollOffset* scroll_offset,
+                                        bool use_fractional_deltas);
 };
 
 constexpr int kInvalidUpdateNumber = -1;
diff --git a/cc/trees/property_tree_unittest.cc b/cc/trees/property_tree_unittest.cc
index 7792c5d8..df8918e 100644
--- a/cc/trees/property_tree_unittest.cc
+++ b/cc/trees/property_tree_unittest.cc
@@ -618,17 +618,17 @@
   scroll_tree.Node(scroll_node_id)->element_id = element_id;
 
   // Set a scroll value close to 0.
-  scroll_tree.SetScrollOffset(element_id, gfx::ScrollOffset(0, 0.1));
+  scroll_tree.SetScrollOffset(element_id, gfx::Vector2dF(0, 0.1));
   transform_tree.Node(transform_node_id)->scrolls = true;
   transform_tree.Node(transform_node_id)->scroll_offset =
-      gfx::ScrollOffset(0, 0.1);
+      gfx::Vector2dF(0, 0.1);
 
   // Pretend that the snap amount was slightly larger than 0.1.
   transform_tree.Node(transform_node_id)->snap_amount = gfx::Vector2dF(0, 0.2);
   transform_tree.Node(transform_node_id)->needs_local_transform_update = false;
 
   // The returned offset should be clamped at a minimum of 0.
-  gfx::ScrollOffset offset =
+  gfx::Vector2dF offset =
       scroll_tree.GetPixelSnappedScrollOffset(scroll_node_id);
   EXPECT_EQ(offset.y(), 0);
 }
@@ -672,7 +672,7 @@
       scroll_node_id;
 
   // Push main scroll to pending.
-  main_scroll_tree.SetScrollOffset(element_id, gfx::ScrollOffset(0, 1));
+  main_scroll_tree.SetScrollOffset(element_id, gfx::Vector2dF(0, 1));
   pending_scroll_tree.PushScrollUpdatesFromMainThread(
       &property_trees, host_impl.pending_tree(), use_fractional_deltas);
   const SyncedScrollOffset* scroll_offset =
@@ -684,7 +684,7 @@
   pending_scroll_tree.SetScrollOffsetDeltaForTesting(element_id,
                                                      gfx::Vector2dF(0, 0.25));
   main_scroll_tree.CollectScrollDeltasForTesting(use_fractional_deltas);
-  EXPECT_EQ(gfx::ScrollOffset(0, 1),
+  EXPECT_EQ(gfx::Vector2dF(0, 1),
             main_scroll_tree.current_scroll_offset(element_id));
 
   // Rounding logic turned on should not cause property change on push.
diff --git a/cc/trees/transform_node.h b/cc/trees/transform_node.h
index 2e62467..17088f9 100644
--- a/cc/trees/transform_node.h
+++ b/cc/trees/transform_node.h
@@ -9,7 +9,7 @@
 #include "cc/paint/element_id.h"
 #include "ui/gfx/geometry/point3_f.h"
 #include "ui/gfx/geometry/point_f.h"
-#include "ui/gfx/geometry/scroll_offset.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 #include "ui/gfx/transform.h"
 
 namespace base {
@@ -116,7 +116,7 @@
   // Set to true, if the node or it's parent |will_change_transform| is true.
   bool node_or_ancestors_will_change_transform : 1;
 
-  gfx::ScrollOffset scroll_offset;
+  gfx::Vector2dF scroll_offset;
 
   // This value stores the snapped amount whenever we snap. If the snap is due
   // to a scroll, we need it to calculate fixed-pos elements adjustment, even
diff --git a/cc/trees/tree_synchronizer_unittest.cc b/cc/trees/tree_synchronizer_unittest.cc
index 6b89b13..f556fd1 100644
--- a/cc/trees/tree_synchronizer_unittest.cc
+++ b/cc/trees/tree_synchronizer_unittest.cc
@@ -7,6 +7,7 @@
 #include <stddef.h>
 
 #include <algorithm>
+#include <memory>
 #include <set>
 #include <utility>
 #include <vector>
@@ -615,8 +616,8 @@
 
   transient_scroll_layer->SetScrollable(gfx::Size(1, 1));
   scroll_layer->SetScrollable(gfx::Size(1, 1));
-  transient_scroll_layer->SetScrollOffset(gfx::ScrollOffset(1, 2));
-  scroll_layer->SetScrollOffset(gfx::ScrollOffset(10, 20));
+  transient_scroll_layer->SetScrollOffset(gfx::Vector2dF(1, 2));
+  scroll_layer->SetScrollOffset(gfx::Vector2dF(10, 20));
 
   host_->SetRootLayer(layer_tree_root);
   host_->BuildPropertyTreesForTesting();
@@ -652,13 +653,13 @@
                                 ->scroll_tree.GetSyncedScrollOffset(
                                     transient_scroll_layer->element_id())));
 
-  // Set ScrollOffset active delta: gfx::ScrollOffset(10, 10)
+  // Set ScrollOffset active delta: gfx::Vector2dF(10, 10)
   LayerImpl* scroll_layer_impl =
       host_impl->active_tree()->LayerById(scroll_layer->id());
   ScrollTree& scroll_tree =
       host_impl->active_tree()->property_trees()->scroll_tree;
   scroll_tree.SetScrollOffset(scroll_layer_impl->element_id(),
-                              gfx::ScrollOffset(20, 30));
+                              gfx::Vector2dF(20, 30));
 
   // Pull ScrollOffset delta for main thread, and change offset on main thread
   std::unique_ptr<CompositorCommitData> commit_data(new CompositorCommitData());
@@ -667,12 +668,12 @@
       base::flat_map<ElementId, TargetSnapAreaElementIds>());
   host_->proxy()->SetNeedsCommit();
   host_->ApplyCompositorChanges(commit_data.get());
-  EXPECT_EQ(gfx::ScrollOffset(20, 30), scroll_layer->scroll_offset());
-  scroll_layer->SetScrollOffset(gfx::ScrollOffset(100, 100));
+  EXPECT_EQ(gfx::Vector2dF(20, 30), scroll_layer->scroll_offset());
+  scroll_layer->SetScrollOffset(gfx::Vector2dF(100, 100));
 
-  // More update to ScrollOffset active delta: gfx::ScrollOffset(20, 20)
+  // More update to ScrollOffset active delta: gfx::Vector2dF(20, 20)
   scroll_tree.SetScrollOffset(scroll_layer_impl->element_id(),
-                              gfx::ScrollOffset(40, 50));
+                              gfx::Vector2dF(40, 50));
   host_impl->active_tree()->SetCurrentlyScrollingNode(
       scroll_tree.Node(scroll_layer_impl->scroll_tree_index()));
 
@@ -687,10 +688,10 @@
 
   EXPECT_EQ(scroll_layer->scroll_tree_index(),
             host_impl->active_tree()->CurrentlyScrollingNode()->id);
-  scroll_layer_offset->SetCurrent(gfx::ScrollOffset(20, 30));
+  scroll_layer_offset->SetCurrent(gfx::Vector2dF(20, 30));
   scroll_layer_offset->PullDeltaForMainThread();
-  scroll_layer_offset->SetCurrent(gfx::ScrollOffset(40, 50));
-  scroll_layer_offset->PushMainToPending(gfx::ScrollOffset(100, 100));
+  scroll_layer_offset->SetCurrent(gfx::Vector2dF(40, 50));
+  scroll_layer_offset->PushMainToPending(gfx::Vector2dF(100, 100));
   scroll_layer_offset->PushPendingToActive();
   EXPECT_TRUE(AreScrollOffsetsEqual(
       scroll_layer_offset.get(),
diff --git a/components/paint_preview/common/mojom/paint_preview_recorder.mojom b/components/paint_preview/common/mojom/paint_preview_recorder.mojom
index 44b4d1f34..f115b1d 100644
--- a/components/paint_preview/common/mojom/paint_preview_recorder.mojom
+++ b/components/paint_preview/common/mojom/paint_preview_recorder.mojom
@@ -115,7 +115,6 @@
 
   // Scroll offsets of the viewport relative to the captured region of the
   // frame at capture time.
-  // TODO(crbug.com/738465): This should likely be a gfx.mojom.ScrollOffset.
   gfx.mojom.Point scroll_offsets;
 
   // Offset of the captured content relative to the top-left corner of the
diff --git a/components/paint_preview/renderer/paint_preview_recorder_browsertest.cc b/components/paint_preview/renderer/paint_preview_recorder_browsertest.cc
index 45c75491..f6ff65f2 100644
--- a/components/paint_preview/renderer/paint_preview_recorder_browsertest.cc
+++ b/components/paint_preview/renderer/paint_preview_recorder_browsertest.cc
@@ -510,7 +510,7 @@
   auto* child_frame = content::RenderFrame::FromWebFrame(child_web_frame);
   ASSERT_TRUE(child_frame);
 
-  child_web_frame->SetScrollOffset(gfx::ScrollOffset(0, 400));
+  child_web_frame->SetScrollOffset(gfx::Vector2dF(0, 400));
 
   base::FilePath skp_path = RunCapture(child_frame, &out_response, false);
 
diff --git a/content/browser/android/synchronous_compositor_host.cc b/content/browser/android/synchronous_compositor_host.cc
index f5f587f9..b2bf626 100644
--- a/content/browser/android/synchronous_compositor_host.cc
+++ b/content/browser/android/synchronous_compositor_host.cc
@@ -531,7 +531,7 @@
 }
 
 void SynchronousCompositorHost::DidChangeRootLayerScrollOffset(
-    const gfx::ScrollOffset& root_offset) {
+    const gfx::Vector2dF& root_offset) {
   if (root_scroll_offset_ == root_offset)
     return;
   root_scroll_offset_ = root_offset;
@@ -642,8 +642,7 @@
   // for that case here.
   if (page_scale_factor_) {
     client_->UpdateRootLayerState(
-        this, gfx::ScrollOffsetToVector2dF(root_scroll_offset_),
-        gfx::ScrollOffsetToVector2dF(max_scroll_offset_), scrollable_size_,
+        this, root_scroll_offset_, max_scroll_offset_, scrollable_size_,
         page_scale_factor_, min_page_scale_factor_, max_page_scale_factor_);
   }
 }
diff --git a/content/browser/android/synchronous_compositor_host.h b/content/browser/android/synchronous_compositor_host.h
index ebfa9950..624027d 100644
--- a/content/browser/android/synchronous_compositor_host.h
+++ b/content/browser/android/synchronous_compositor_host.h
@@ -25,8 +25,8 @@
 #include "third_party/blink/public/mojom/input/input_event_result.mojom-shared.h"
 #include "third_party/blink/public/mojom/input/synchronous_compositor.mojom.h"
 #include "ui/android/view_android.h"
-#include "ui/gfx/geometry/scroll_offset.h"
 #include "ui/gfx/geometry/size_f.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 
 namespace ui {
 struct DidOverscrollParams;
@@ -72,7 +72,7 @@
   void SetMemoryPolicy(size_t bytes_limit) override;
   void DidBecomeActive() override;
   void DidChangeRootLayerScrollOffset(
-      const gfx::ScrollOffset& root_offset) override;
+      const gfx::Vector2dF& root_offset) override;
   void SynchronouslyZoomBy(float zoom_delta, const gfx::Point& anchor) override;
   void OnComputeScroll(base::TimeTicks animation_time) override;
   void SetBeginFrameSource(viz::BeginFrameSource* begin_frame_source) override;
@@ -178,7 +178,7 @@
 
   // Updated by both renderer and browser. This is in physical pixel when
   // use-zoom-for-dsf is enabled, otherwise in dip.
-  gfx::ScrollOffset root_scroll_offset_;
+  gfx::Vector2dF root_scroll_offset_;
 
   // Indicates that whether OnComputeScroll is called or overridden. The
   // fling_controller should advance the fling only when OnComputeScroll is not
@@ -192,7 +192,7 @@
   uint32_t did_activate_pending_tree_count_;
   uint32_t frame_metadata_version_ = 0u;
   // Physical pixel when use-zoom-for-dsf is enabled, otherwise in dip.
-  gfx::ScrollOffset max_scroll_offset_;
+  gfx::Vector2dF max_scroll_offset_;
   gfx::SizeF scrollable_size_;
   float page_scale_factor_ = 0.f;
   float min_page_scale_factor_ = 0.f;
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index f3df4e6..cddce81 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -1287,10 +1287,9 @@
                                      absl::nullopt);
 }
 
-
 void RenderWidgetHostViewAndroid::FrameTokenChangedForSynchronousCompositor(
     uint32_t frame_token,
-    const gfx::ScrollOffset& root_scroll_offset) {
+    const gfx::Vector2dF& root_scroll_offset) {
   if (!viz::FrameTokenGT(frame_token, sync_compositor_last_frame_token_))
     return;
   sync_compositor_last_frame_token_ = frame_token;
@@ -1308,8 +1307,7 @@
         // trigger a new RenderFrameMetadata, and it may be out of date. This
         // is needed for devtools DOM node selection.
         cc::RenderFrameMetadata updated_metadata = *last_render_frame_metadata_;
-        updated_metadata.root_scroll_offset =
-            gfx::ScrollOffsetToVector2dF(root_scroll_offset);
+        updated_metadata.root_scroll_offset = root_scroll_offset;
         RenderFrameDevToolsAgentHost::SignalSynchronousSwapCompositorFrame(
             frame_host, updated_metadata);
       }
diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h
index b61bacd..dd191b7 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.h
+++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -296,11 +296,11 @@
                                 int start_adjust,
                                 int end_adjust);
 
-  // TODO(ericrk): Ideally we'd reemove |root_scroll_offset| from this function
+  // TODO(ericrk): Ideally we'd remove |root_scroll_offset| from this function
   // once we have a reliable way to get it through RenderFrameMetadata.
   void FrameTokenChangedForSynchronousCompositor(
       uint32_t frame_token,
-      const gfx::ScrollOffset& root_scroll_offset);
+      const gfx::Vector2dF& root_scroll_offset);
 
   void SetSynchronousCompositorClient(SynchronousCompositorClient* client);
 
diff --git a/content/public/browser/android/synchronous_compositor.h b/content/public/browser/android/synchronous_compositor.h
index 9a9052bd..5c1be18 100644
--- a/content/public/browser/android/synchronous_compositor.h
+++ b/content/public/browser/android/synchronous_compositor.h
@@ -25,7 +25,6 @@
 
 namespace gfx {
 class Point;
-class ScrollOffset;
 class Transform;
 }  // namespace gfx
 
@@ -120,7 +119,7 @@
   // scroll offset of the root layer. |root_offset| must be in physical pixel
   // scale if --use-zoom-for-dsf is enabled. Otherwise, it must be in DIP scale.
   virtual void DidChangeRootLayerScrollOffset(
-      const gfx::ScrollOffset& root_offset) = 0;
+      const gfx::Vector2dF& root_offset) = 0;
 
   // Allows embedder to synchronously update the zoom level, ie page scale
   // factor, around the anchor point.
diff --git a/content/public/test/test_synchronous_compositor_android.h b/content/public/test/test_synchronous_compositor_android.h
index c10ea4c..bd366bb3 100644
--- a/content/public/test/test_synchronous_compositor_android.h
+++ b/content/public/test/test_synchronous_compositor_android.h
@@ -41,7 +41,7 @@
   void SetMemoryPolicy(size_t bytes_limit) override {}
   void DidBecomeActive() override {}
   void DidChangeRootLayerScrollOffset(
-      const gfx::ScrollOffset& root_offset) override {}
+      const gfx::Vector2dF& root_offset) override {}
   void SynchronouslyZoomBy(float zoom_delta,
                            const gfx::Point& anchor) override {}
   void OnComputeScroll(base::TimeTicks animate_time) override {}
diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.cc b/content/renderer/pepper/pepper_plugin_instance_impl.cc
index 33254ff1..0ef05d68 100644
--- a/content/renderer/pepper/pepper_plugin_instance_impl.cc
+++ b/content/renderer/pepper/pepper_plugin_instance_impl.cc
@@ -118,6 +118,8 @@
 #include "ui/gfx/geometry/point.h"
 #include "ui/gfx/geometry/rect_conversions.h"
 #include "ui/gfx/geometry/size.h"
+#include "ui/gfx/geometry/vector2d_conversions.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 #include "ui/gfx/image/image_skia.h"
 #include "ui/gfx/image/image_skia_rep.h"
 #include "ui/gfx/range/range.h"
@@ -1201,12 +1203,11 @@
   view_data_.css_scale *= viewport_to_dip_scale_;
   view_data_.device_scale /= viewport_to_dip_scale_;
 
-  gfx::ScrollOffset scroll_offset =
+  gfx::Vector2dF scroll_offset =
       container_->GetDocument().GetFrame()->GetScrollOffset();
   scroll_offset.Scale(viewport_to_dip_scale_);
 
-  gfx::Vector2d floored_scroll_offset =
-      ScrollOffsetToFlooredVector2d(scroll_offset);
+  gfx::Vector2d floored_scroll_offset = gfx::ToFlooredVector2d(scroll_offset);
   view_data_.scroll_offset =
       PP_MakePoint(floored_scroll_offset.x(), floored_scroll_offset.y());
 
diff --git a/content/web_test/renderer/layout_dump.cc b/content/web_test/renderer/layout_dump.cc
index 7f87fb1..36d5916 100644
--- a/content/web_test/renderer/layout_dump.cc
+++ b/content/web_test/renderer/layout_dump.cc
@@ -38,7 +38,7 @@
 
 std::string DumpFrameScrollPosition(WebLocalFrame* frame) {
   std::string result;
-  gfx::ScrollOffset offset = frame->GetScrollOffset();
+  gfx::Vector2dF offset = frame->GetScrollOffset();
   if (offset.x() > 0 || offset.y() > 0) {
     if (frame->Parent()) {
       auto* frame_proxy = static_cast<WebFrameTestProxy*>(frame->Client());
diff --git a/pdf/pdf_view_web_plugin.cc b/pdf/pdf_view_web_plugin.cc
index 689ec2e5..6e8aeac0 100644
--- a/pdf/pdf_view_web_plugin.cc
+++ b/pdf/pdf_view_web_plugin.cc
@@ -75,7 +75,6 @@
 #include "ui/events/keycodes/keyboard_codes.h"
 #include "ui/gfx/geometry/point.h"
 #include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/scroll_offset.h"
 #include "ui/gfx/geometry/vector2d_f.h"
 #include "ui/gfx/range/range.h"
 #include "ui/gfx/skia_util.h"
@@ -927,10 +926,8 @@
                                     css_to_device_pixel_scale),
       new_device_scale);
 
-  if (IsPrintPreview()) {
-    UpdateScroll(gfx::ScrollOffsetToVector2dF(
-        container_wrapper_->GetFrame()->GetScrollOffset()));
-  }
+  if (IsPrintPreview())
+    UpdateScroll(container_wrapper_->GetFrame()->GetScrollOffset());
 
   // Scrolling in the main PDF Viewer UI is already handled by
   // `HandleUpdateScrollMessage()`.
diff --git a/third_party/blink/public/mojom/input/synchronous_compositor.mojom b/third_party/blink/public/mojom/input/synchronous_compositor.mojom
index 9479763e..93e3c827 100644
--- a/third_party/blink/public/mojom/input/synchronous_compositor.mojom
+++ b/third_party/blink/public/mojom/input/synchronous_compositor.mojom
@@ -31,8 +31,8 @@
 
 struct SyncCompositorCommonRendererParams {
   uint32 version = 0;
-  gfx.mojom.ScrollOffset total_scroll_offset;
-  gfx.mojom.ScrollOffset max_scroll_offset;
+  gfx.mojom.Vector2dF total_scroll_offset;
+  gfx.mojom.Vector2dF max_scroll_offset;
   gfx.mojom.SizeF scrollable_size;
   float page_scale_factor = 0;
   float min_page_scale_factor = 0;
@@ -102,7 +102,7 @@
                    array<viz.mojom.ReturnedResource> resources);
 
   // Adjust the scroll to the given offset.
-  SetScroll(gfx.mojom.ScrollOffset offset);
+  SetScroll(gfx.mojom.Vector2dF offset);
 
   // BeginFrame, update will be pushed via SynchronousCompositorControlHost
   // BeginFrameResponse.
diff --git a/third_party/blink/public/platform/input/input_handler_proxy.h b/third_party/blink/public/platform/input/input_handler_proxy.h
index ab527bb..fb23c5b 100644
--- a/third_party/blink/public/platform/input/input_handler_proxy.h
+++ b/third_party/blink/public/platform/input/input_handler_proxy.h
@@ -174,8 +174,8 @@
   void ReconcileElasticOverscrollAndRootScroll() override;
   void SetPrefersReducedMotion(bool prefers_reduced_motion) override;
   void UpdateRootLayerStateForSynchronousInputHandler(
-      const gfx::ScrollOffset& total_scroll_offset,
-      const gfx::ScrollOffset& max_scroll_offset,
+      const gfx::Vector2dF& total_scroll_offset,
+      const gfx::Vector2dF& max_scroll_offset,
       const gfx::SizeF& scrollable_size,
       float page_scale_factor,
       float min_page_scale_factor,
@@ -187,7 +187,7 @@
   void SetSynchronousInputHandler(
       SynchronousInputHandler* synchronous_input_handler) override;
   void SynchronouslySetRootScrollOffset(
-      const gfx::ScrollOffset& root_offset) override;
+      const gfx::Vector2dF& root_offset) override;
   void SynchronouslyZoomBy(float magnify_delta,
                            const gfx::Point& anchor) override;
 
diff --git a/third_party/blink/public/platform/input/synchronous_input_handler_proxy.h b/third_party/blink/public/platform/input/synchronous_input_handler_proxy.h
index 2e0c4399..d6e257a7 100644
--- a/third_party/blink/public/platform/input/synchronous_input_handler_proxy.h
+++ b/third_party/blink/public/platform/input/synchronous_input_handler_proxy.h
@@ -8,8 +8,8 @@
 
 namespace gfx {
 class Point;
-class ScrollOffset;
 class SizeF;
+class Vector2dF;
 }  // namespace gfx
 
 namespace blink {
@@ -20,13 +20,12 @@
 
   // Informs the Android WebView embedder of the current root scroll and page
   // scale state.
-  virtual void UpdateRootLayerState(
-      const gfx::ScrollOffset& total_scroll_offset,
-      const gfx::ScrollOffset& max_scroll_offset,
-      const gfx::SizeF& scrollable_size,
-      float page_scale_factor,
-      float min_page_scale_factor,
-      float max_page_scale_factor) = 0;
+  virtual void UpdateRootLayerState(const gfx::Vector2dF& total_scroll_offset,
+                                    const gfx::Vector2dF& max_scroll_offset,
+                                    const gfx::SizeF& scrollable_size,
+                                    float page_scale_factor,
+                                    float min_page_scale_factor,
+                                    float max_page_scale_factor) = 0;
 };
 
 // Android WebView requires synchronous scrolling from the WebView application.
@@ -47,7 +46,7 @@
   // SynchronousInputHandler should be given back the result in case it differs
   // from what was sent.
   virtual void SynchronouslySetRootScrollOffset(
-      const gfx::ScrollOffset& root_offset) = 0;
+      const gfx::Vector2dF& root_offset) = 0;
 
   // Similar to SetRootScrollOffset above, to control the zoom level, ie scale
   // factor. Note |magnify_delta| is an incremental rather than absolute value.
diff --git a/third_party/blink/public/web/web_local_frame.h b/third_party/blink/public/web/web_local_frame.h
index 9644d372..7953d74 100644
--- a/third_party/blink/public/web/web_local_frame.h
+++ b/third_party/blink/public/web/web_local_frame.h
@@ -54,7 +54,7 @@
 
 namespace gfx {
 class Point;
-class ScrollOffset;
+class Vector2dF;
 }  // namespace gfx
 
 namespace ui {
@@ -681,8 +681,8 @@
   // not be accurate if the page layout is out-of-date.
 
   // The scroll offset from the top-left corner of the frame in pixels.
-  virtual gfx::ScrollOffset GetScrollOffset() const = 0;
-  virtual void SetScrollOffset(const gfx::ScrollOffset&) = 0;
+  virtual gfx::Vector2dF GetScrollOffset() const = 0;
+  virtual void SetScrollOffset(const gfx::Vector2dF&) = 0;
 
   // The size of the document in this frame.
   virtual gfx::Size DocumentSize() const = 0;
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index f5002ab..b9e9156 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -1625,8 +1625,7 @@
                             scrollable_area->GetScrollOffset().Height());
     std::unique_ptr<cc::SnapSelectionStrategy> strategy =
         cc::SnapSelectionStrategy::CreateForEndPosition(
-            gfx::ScrollOffset(
-                scrollable_area->ScrollOffsetToPosition(end_offset)),
+            gfx::Vector2dF(scrollable_area->ScrollOffsetToPosition(end_offset)),
             true, false);
     absl::optional<FloatPoint> snap_point =
         scrollable_area->GetSnapPositionAndSetTarget(*strategy);
@@ -1678,8 +1677,7 @@
                             new_top * box->Style()->EffectiveZoom());
     std::unique_ptr<cc::SnapSelectionStrategy> strategy =
         cc::SnapSelectionStrategy::CreateForEndPosition(
-            gfx::ScrollOffset(
-                scrollable_area->ScrollOffsetToPosition(end_offset)),
+            gfx::Vector2dF(scrollable_area->ScrollOffsetToPosition(end_offset)),
             false, true);
     absl::optional<FloatPoint> snap_point =
         scrollable_area->GetSnapPositionAndSetTarget(*strategy);
@@ -1786,7 +1784,7 @@
 }
 
 void Element::ScrollLayoutBoxBy(const ScrollToOptions* scroll_to_options) {
-  gfx::ScrollOffset displacement;
+  gfx::Vector2dF displacement;
   if (scroll_to_options->hasLeft()) {
     displacement.set_x(
         ScrollableArea::NormalizeNonFiniteScroll(scroll_to_options->left()));
@@ -1805,10 +1803,10 @@
     return;
   if (PaintLayerScrollableArea* scrollable_area = box->GetScrollableArea()) {
     DCHECK(box);
-    gfx::ScrollOffset current_position(scrollable_area->ScrollPosition().X(),
-                                       scrollable_area->ScrollPosition().Y());
+    gfx::Vector2dF current_position(scrollable_area->ScrollPosition().X(),
+                                    scrollable_area->ScrollPosition().Y());
     displacement.Scale(box->Style()->EffectiveZoom());
-    gfx::ScrollOffset new_offset(current_position + displacement);
+    gfx::Vector2dF new_offset(current_position + displacement);
     FloatPoint new_position(new_offset.x(), new_offset.y());
 
     std::unique_ptr<cc::SnapSelectionStrategy> strategy =
@@ -1871,8 +1869,7 @@
 
     std::unique_ptr<cc::SnapSelectionStrategy> strategy =
         cc::SnapSelectionStrategy::CreateForEndPosition(
-            gfx::ScrollOffset(
-                scrollable_area->ScrollOffsetToPosition(new_offset)),
+            gfx::Vector2dF(scrollable_area->ScrollOffsetToPosition(new_offset)),
             scroll_to_options->hasLeft(), scroll_to_options->hasTop());
     absl::optional<FloatPoint> snap_point =
         scrollable_area->GetSnapPositionAndSetTarget(*strategy);
@@ -1886,7 +1883,7 @@
 }
 
 void Element::ScrollFrameBy(const ScrollToOptions* scroll_to_options) {
-  gfx::ScrollOffset displacement;
+  gfx::Vector2dF displacement;
   if (scroll_to_options->hasLeft()) {
     displacement.set_x(
         ScrollableArea::NormalizeNonFiniteScroll(scroll_to_options->left()));
@@ -1912,7 +1909,7 @@
   FloatPoint new_position = viewport->ScrollPosition() +
                             FloatPoint(displacement.x(), displacement.y());
 
-  gfx::ScrollOffset current_position(viewport->ScrollPosition());
+  gfx::Vector2dF current_position(viewport->ScrollPosition());
   std::unique_ptr<cc::SnapSelectionStrategy> strategy =
       cc::SnapSelectionStrategy::CreateForEndAndDirection(
           current_position, displacement,
@@ -1952,7 +1949,7 @@
   FloatPoint new_position = viewport->ScrollOffsetToPosition(new_offset);
   std::unique_ptr<cc::SnapSelectionStrategy> strategy =
       cc::SnapSelectionStrategy::CreateForEndPosition(
-          gfx::ScrollOffset(new_position), scroll_to_options->hasLeft(),
+          gfx::Vector2dF(new_position), scroll_to_options->hasLeft(),
           scroll_to_options->hasTop());
   new_position =
       viewport->GetSnapPositionAndSetTarget(*strategy).value_or(new_position);
diff --git a/third_party/blink/renderer/core/events/web_input_event_conversion_test.cc b/third_party/blink/renderer/core/events/web_input_event_conversion_test.cc
index db5a8bc9..2938878 100644
--- a/third_party/blink/renderer/core/events/web_input_event_conversion_test.cc
+++ b/third_party/blink/renderer/core/events/web_input_event_conversion_test.cc
@@ -758,7 +758,7 @@
 
   gfx::Vector2dF elastic_overscroll(10, -20);
   web_view->MainFrameViewWidget()->ApplyViewportChangesForTesting(
-      {gfx::ScrollOffset(), elastic_overscroll, 1.0f, false, 0.0f});
+      {gfx::Vector2dF(), elastic_overscroll, 1.0f, false, 0.0f});
 
   // Just elastic overscroll.
   {
@@ -832,7 +832,7 @@
 
   gfx::Vector2dF elastic_overscroll(10, -20);
   web_view->MainFrameViewWidget()->ApplyViewportChangesForTesting(
-      {gfx::ScrollOffset(), elastic_overscroll, 1.0f, false, 0.0f});
+      {gfx::Vector2dF(), elastic_overscroll, 1.0f, false, 0.0f});
   frame_test_helpers::ReloadFrame(
       web_view_helper.GetWebView()->MainFrameImpl());
   LocalFrameView* view =
diff --git a/third_party/blink/renderer/core/exported/web_plugin_container_test.cc b/third_party/blink/renderer/core/exported/web_plugin_container_test.cc
index b99f18f..862b7393 100644
--- a/third_party/blink/renderer/core/exported/web_plugin_container_test.cc
+++ b/third_party/blink/renderer/core/exported/web_plugin_container_test.cc
@@ -1321,8 +1321,8 @@
       web_view->SmoothScroll(root_document_scroll_to.Width(),
                              root_document_scroll_to.Height(),
                              base::TimeDelta());
-      iframe->SetScrollOffset(gfx::ScrollOffset(iframe_scroll_to.Width(),
-                                                iframe_scroll_to.Height()));
+      iframe->SetScrollOffset(
+          gfx::Vector2dF(iframe_scroll_to.Width(), iframe_scroll_to.Height()));
       UpdateAllLifecyclePhases(web_view);
       RunPendingTasks();
 
diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc
index f2d60cd..594a21e 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -672,7 +672,7 @@
   DCHECK(MainFrame());
   DCHECK(MainFrame()->IsWebLocalFrame());
   gfx::Size max_size = MainFrame()->ToWebLocalFrame()->DocumentSize();
-  gfx::ScrollOffset scroll_offset =
+  gfx::Vector2dF scroll_offset =
       MainFrame()->ToWebLocalFrame()->GetScrollOffset();
 
   int left_margin = target_margin;
diff --git a/third_party/blink/renderer/core/exported/web_view_test.cc b/third_party/blink/renderer/core/exported/web_view_test.cc
index 49959d8..efcfa2df 100644
--- a/third_party/blink/renderer/core/exported/web_view_test.cc
+++ b/third_party/blink/renderer/core/exported/web_view_test.cc
@@ -1575,7 +1575,7 @@
       web_view_helper_.InitializeAndLoad(base_url_ + "form_with_input.html");
   web_view->MainFrameViewWidget()->Resize(gfx::Size(800, 600));
   web_view->MainFrameImpl()->GetFrame()->SetInitialFocus(false);
-  EXPECT_EQ(gfx::ScrollOffset(), web_view->MainFrameImpl()->GetScrollOffset());
+  EXPECT_EQ(gfx::Vector2dF(), web_view->MainFrameImpl()->GetScrollOffset());
 
   // Set up a composition from existing text that needs to be committed.
   Vector<ImeTextSpan> empty_ime_text_spans;
@@ -2432,12 +2432,12 @@
       web_view_helper_.InitializeAndLoad(base_url_ + "200-by-300.html");
   web_view_impl->MainFrameViewWidget()->Resize(gfx::Size(100, 150));
   UpdateAllLifecyclePhases();
-  EXPECT_EQ(gfx::ScrollOffset(),
+  EXPECT_EQ(gfx::Vector2dF(),
             web_view_impl->MainFrameImpl()->GetScrollOffset());
 
   // Make the page scale and scroll with the given paremeters.
   web_view_impl->SetPageScaleFactor(2.0f);
-  web_view_impl->MainFrameImpl()->SetScrollOffset(gfx::ScrollOffset(94, 111));
+  web_view_impl->MainFrameImpl()->SetScrollOffset(gfx::Vector2dF(94, 111));
   EXPECT_EQ(2.0f, web_view_impl->PageScaleFactor());
   EXPECT_EQ(94, web_view_impl->MainFrameImpl()->GetScrollOffset().x());
   EXPECT_EQ(111, web_view_impl->MainFrameImpl()->GetScrollOffset().y());
@@ -2463,7 +2463,7 @@
   // Confirm that resetting the page state resets the saved scroll position.
   web_view_impl->ResetScrollAndScaleState();
   EXPECT_EQ(1.0f, web_view_impl->PageScaleFactor());
-  EXPECT_EQ(gfx::ScrollOffset(),
+  EXPECT_EQ(gfx::Vector2dF(),
             web_view_impl->MainFrameImpl()->GetScrollOffset());
   EXPECT_FALSE(main_frame_local->Loader()
                    .GetDocumentLoader()
@@ -2481,7 +2481,7 @@
       DocumentUpdateReason::kTest);
 
   // Emulate a user scroll
-  web_view_impl->MainFrameImpl()->SetScrollOffset(gfx::ScrollOffset(0, 900));
+  web_view_impl->MainFrameImpl()->SetScrollOffset(gfx::Vector2dF(0, 900));
   auto* main_frame_local =
       To<LocalFrame>(web_view_impl->GetPage()->MainFrame());
   Persistent<HistoryItem> item1 =
@@ -2561,7 +2561,7 @@
   UpdateAllLifecyclePhases();
 
   // Scroll the page down.
-  web_view_impl->MainFrameImpl()->SetScrollOffset(gfx::ScrollOffset(0, 2000));
+  web_view_impl->MainFrameImpl()->SetScrollOffset(gfx::Vector2dF(0, 2000));
   ASSERT_EQ(2000, web_view_impl->MainFrameImpl()->GetScrollOffset().y());
 
   // Enter fullscreen.
@@ -2576,7 +2576,7 @@
   // Assert the scroll position on the document element doesn't change.
   ASSERT_EQ(2000, web_view_impl->MainFrameImpl()->GetScrollOffset().y());
 
-  web_view_impl->MainFrameImpl()->SetScrollOffset(gfx::ScrollOffset(0, 2100));
+  web_view_impl->MainFrameImpl()->SetScrollOffset(gfx::Vector2dF(0, 2100));
 
   web_view_impl->DidExitFullscreen();
   UpdateAllLifecyclePhases();
diff --git a/third_party/blink/renderer/core/frame/browser_controls_test.cc b/third_party/blink/renderer/core/frame/browser_controls_test.cc
index 98f7f3c6..cdea4fa 100644
--- a/third_party/blink/renderer/core/frame/browser_controls_test.cc
+++ b/third_party/blink/renderer/core/frame/browser_controls_test.cc
@@ -726,7 +726,7 @@
   web_view->SetPageScaleFactor(2.0);
 
   // Fully scroll frameview but visualviewport remains scrollable
-  web_view->MainFrameImpl()->SetScrollOffset(gfx::ScrollOffset(0, 10000));
+  web_view->MainFrameImpl()->SetScrollOffset(gfx::Vector2dF(0, 10000));
   GetVisualViewport().SetLocation(FloatPoint(0, 0));
   GetWebView()->MainFrameViewWidget()->HandleInputEvent(
       GenerateEvent(WebInputEvent::Type::kGestureScrollBegin, 0, -10.f));
@@ -740,7 +740,7 @@
 
   web_view->GetBrowserControls().SetShownRatio(1, 1);
   // Fully scroll visual veiwport but frameview remains scrollable
-  web_view->MainFrameImpl()->SetScrollOffset(gfx::ScrollOffset(0, 0));
+  web_view->MainFrameImpl()->SetScrollOffset(gfx::Vector2dF(0, 0));
   GetVisualViewport().SetLocation(FloatPoint(0, 10000));
   GetWebView()->MainFrameViewWidget()->HandleInputEvent(
       GenerateEvent(WebInputEvent::Type::kGestureScrollBegin, 0, -20.f));
@@ -754,7 +754,7 @@
 
   web_view->GetBrowserControls().SetShownRatio(1, 1);
   // Fully scroll both frameview and visual viewport
-  web_view->MainFrameImpl()->SetScrollOffset(gfx::ScrollOffset(0, 10000));
+  web_view->MainFrameImpl()->SetScrollOffset(gfx::Vector2dF(0, 10000));
   GetVisualViewport().SetLocation(FloatPoint(0, 10000));
   VerticalScroll(-30.f);
   // Browser controls should not move because neither frameview nor visual
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc
index 41a1158d..1cab0b9 100644
--- a/third_party/blink/renderer/core/frame/local_dom_window.cc
+++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -1598,7 +1598,7 @@
 
   std::unique_ptr<cc::SnapSelectionStrategy> strategy =
       cc::SnapSelectionStrategy::CreateForEndAndDirection(
-          gfx::ScrollOffset(current_position), gfx::ScrollOffset(scaled_delta),
+          gfx::Vector2dF(current_position), gfx::Vector2dF(scaled_delta),
           RuntimeEnabledFeatures::FractionalScrollOffsetsEnabled());
   new_scaled_position =
       viewport->GetSnapPositionAndSetTarget(*strategy).value_or(
@@ -1664,7 +1664,7 @@
 
   std::unique_ptr<cc::SnapSelectionStrategy> strategy =
       cc::SnapSelectionStrategy::CreateForEndPosition(
-          gfx::ScrollOffset(new_scaled_position), scroll_to_options->hasLeft(),
+          gfx::Vector2dF(new_scaled_position), scroll_to_options->hasLeft(),
           scroll_to_options->hasTop());
   new_scaled_position =
       viewport->GetSnapPositionAndSetTarget(*strategy).value_or(
diff --git a/third_party/blink/renderer/core/frame/root_frame_viewport.cc b/third_party/blink/renderer/core/frame/root_frame_viewport.cc
index 25c21b0..8fa668b 100644
--- a/third_party/blink/renderer/core/frame/root_frame_viewport.cc
+++ b/third_party/blink/renderer/core/frame/root_frame_viewport.cc
@@ -347,8 +347,8 @@
 
   FloatPoint end_point = ScrollOffsetToPosition(new_scroll_offset);
   std::unique_ptr<cc::SnapSelectionStrategy> strategy =
-      cc::SnapSelectionStrategy::CreateForEndPosition(
-          gfx::ScrollOffset(end_point), true, true);
+      cc::SnapSelectionStrategy::CreateForEndPosition(gfx::Vector2dF(end_point),
+                                                      true, true);
   if (GetLayoutBox()) {
     end_point = GetSnapPositionAndSetTarget(*strategy).value_or(end_point);
     new_scroll_offset = ScrollPositionToOffset(end_point);
diff --git a/third_party/blink/renderer/core/frame/visual_viewport_test.cc b/third_party/blink/renderer/core/frame/visual_viewport_test.cc
index c91f2806..59f5222f 100644
--- a/third_party/blink/renderer/core/frame/visual_viewport_test.cc
+++ b/third_party/blink/renderer/core/frame/visual_viewport_test.cc
@@ -291,7 +291,7 @@
   UpdateAllLifecyclePhases();
 
   // Scroll layout viewport and verify visibleContentRect.
-  WebView()->MainFrameImpl()->SetScrollOffset(gfx::ScrollOffset(0, 50));
+  WebView()->MainFrameImpl()->SetScrollOffset(gfx::Vector2dF(0, 50));
 
   VisualViewport& visual_viewport = GetFrame()->GetPage()->GetVisualViewport();
   EXPECT_EQ(IntRect(IntPoint(0, 0), size - scrollbar_size),
@@ -399,7 +399,7 @@
   WebView()->MainFrameViewWidget()->Resize(gfx::Size(100, 200));
 
   // Scroll main frame to the bottom of the document
-  WebView()->MainFrameImpl()->SetScrollOffset(gfx::ScrollOffset(0, 400));
+  WebView()->MainFrameImpl()->SetScrollOffset(gfx::Vector2dF(0, 400));
   EXPECT_EQ(ScrollOffset(0, 400),
             GetFrame()->View()->LayoutViewport()->GetScrollOffset());
 
@@ -1358,7 +1358,7 @@
 
   // Simulate bringing down the browser controls by 20px.
   WebView()->MainFrameViewWidget()->ApplyViewportChangesForTesting(
-      {gfx::ScrollOffset(), gfx::Vector2dF(), 1, false, 1, 0,
+      {gfx::Vector2dF(), gfx::Vector2dF(), 1, false, 1, 0,
        cc::BrowserControlsState::kBoth});
   EXPECT_EQ(FloatSize(500, 430), visual_viewport.VisibleRect().Size());
 
@@ -1377,7 +1377,7 @@
 
   // Simulate bringing up the browser controls by 10.5px.
   WebView()->MainFrameViewWidget()->ApplyViewportChangesForTesting(
-      {gfx::ScrollOffset(), gfx::Vector2dF(), 1, false, -10.5f / 20, 0,
+      {gfx::Vector2dF(), gfx::Vector2dF(), 1, false, -10.5f / 20, 0,
        cc::BrowserControlsState::kBoth});
   EXPECT_FLOAT_SIZE_EQ(FloatSize(500, 440.5f),
                        visual_viewport.VisibleRect().Size());
@@ -1414,7 +1414,7 @@
   // the browser controls take up half as much space (in document-space) than
   // they do at an unzoomed level.
   WebView()->MainFrameViewWidget()->ApplyViewportChangesForTesting(
-      {gfx::ScrollOffset(), gfx::Vector2dF(), 1, false, 1, 0,
+      {gfx::Vector2dF(), gfx::Vector2dF(), 1, false, 1, 0,
        cc::BrowserControlsState::kBoth});
   EXPECT_EQ(FloatSize(250, 215), visual_viewport.VisibleRect().Size());
 
@@ -1432,7 +1432,7 @@
   // Scale back out, LocalFrameView max scroll shouldn't have changed. Visual
   // viewport should be moved up to accommodate larger view.
   WebView()->MainFrameViewWidget()->ApplyViewportChangesForTesting(
-      {gfx::ScrollOffset(), gfx::Vector2dF(), 0.5f, false, 0, 0,
+      {gfx::Vector2dF(), gfx::Vector2dF(), 0.5f, false, 0, 0,
        cc::BrowserControlsState::kBoth});
   EXPECT_EQ(1, visual_viewport.Scale());
   EXPECT_EQ(expected, frame_view.LayoutViewport()->GetScrollOffset());
@@ -1446,13 +1446,13 @@
 
   // Scale out, use a scale that causes fractional rects.
   WebView()->MainFrameViewWidget()->ApplyViewportChangesForTesting(
-      {gfx::ScrollOffset(), gfx::Vector2dF(), 0.8f, false, -1, 0,
+      {gfx::Vector2dF(), gfx::Vector2dF(), 0.8f, false, -1, 0,
        cc::BrowserControlsState::kBoth});
   EXPECT_EQ(FloatSize(625, 562.5), visual_viewport.VisibleRect().Size());
 
   // Bring out the browser controls by 11
   WebView()->MainFrameViewWidget()->ApplyViewportChangesForTesting(
-      {gfx::ScrollOffset(), gfx::Vector2dF(), 1, false, 11 / 20.f, 0,
+      {gfx::Vector2dF(), gfx::Vector2dF(), 1, false, 11 / 20.f, 0,
        cc::BrowserControlsState::kBoth});
   EXPECT_EQ(FloatSize(625, 548.75), visual_viewport.VisibleRect().Size());
 
@@ -1640,7 +1640,7 @@
       gfx::Size(WebView()->MainFrameViewWidget()->Size()), 500, 0, false);
   UpdateAllLifecyclePhases();
   WebView()->MainFrameViewWidget()->ApplyViewportChangesForTesting(
-      {gfx::ScrollOffset(), gfx::Vector2dF(), 1, false, 1, 0,
+      {gfx::Vector2dF(), gfx::Vector2dF(), 1, false, 1, 0,
        cc::BrowserControlsState::kBoth});
   WebView()->ResizeWithBrowserControls(gfx::Size(1000, 1000), 500, 0, true);
   UpdateAllLifecyclePhases();
@@ -1653,7 +1653,7 @@
   // controls on the compositor side so the max scroll position should account
   // for the full viewport height.
   WebView()->MainFrameViewWidget()->ApplyViewportChangesForTesting(
-      {gfx::ScrollOffset(), gfx::Vector2dF(), 1, false, -1, 0,
+      {gfx::Vector2dF(), gfx::Vector2dF(), 1, false, -1, 0,
        cc::BrowserControlsState::kBoth});
   LocalFrameView& frame_view = *WebView()->MainFrameImpl()->GetFrameView();
   frame_view.LayoutViewport()->SetScrollOffset(
@@ -1921,7 +1921,7 @@
 
   // Apply some scroll and scale from the impl-side.
   WebView()->MainFrameViewWidget()->ApplyViewportChangesForTesting(
-      {gfx::ScrollOffset(300, 200), gfx::Vector2dF(0, 0), 2, false, 0, 0,
+      {gfx::Vector2dF(300, 200), gfx::Vector2dF(0, 0), 2, false, 0, 0,
        cc::BrowserControlsState::kBoth});
 
   EXPECT_EQ(FloatSize(300, 200), visual_viewport.GetScrollOffset());
@@ -2523,7 +2523,7 @@
             visual_viewport.GetScrollNode()->ContentsSize());
 
   WebView().MainFrameViewWidget()->ApplyViewportChangesForTesting(
-      {gfx::ScrollOffset(1, 1), gfx::Vector2dF(), 2, false, 1, 0,
+      {gfx::Vector2dF(1, 1), gfx::Vector2dF(), 2, false, 1, 0,
        cc::BrowserControlsState::kBoth});
   EXPECT_EQ(gfx::Size(320, 480), visual_viewport.LayerForScrolling()->bounds());
 
@@ -2849,7 +2849,7 @@
 
   auto* layer_tree_host = GetFrame()->View()->RootCcLayer()->layer_tree_host();
   EXPECT_EQ(
-      gfx::ScrollOffset(12, 34),
+      gfx::Vector2dF(12, 34),
       layer_tree_host->property_trees()->scroll_tree.current_scroll_offset(
           visual_viewport.GetScrollElementId()));
 }
diff --git a/third_party/blink/renderer/core/frame/web_frame_test.cc b/third_party/blink/renderer/core/frame/web_frame_test.cc
index c5299e7a..f5ce9fc 100644
--- a/third_party/blink/renderer/core/frame/web_frame_test.cc
+++ b/third_party/blink/renderer/core/frame/web_frame_test.cc
@@ -3012,7 +3012,7 @@
   void TestResizeYieldsCorrectScrollAndScale(
       const char* url,
       const float initial_page_scale_factor,
-      const gfx::ScrollOffset& scroll_offset,
+      const gfx::Vector2dF& scroll_offset,
       const gfx::Size& viewport_size,
       const bool should_scale_relative_to_viewport_width) {
     RegisterMockedHttpURLLoad(url);
@@ -3041,7 +3041,7 @@
           (should_scale_relative_to_viewport_width ? 1 / aspect_ratio : 1);
       EXPECT_NEAR(expected_page_scale_factor,
                   web_view_helper.GetWebView()->PageScaleFactor(), 0.05f);
-      EXPECT_EQ(gfx::ScrollOffset(),
+      EXPECT_EQ(gfx::Vector2dF(),
                 web_view_helper.LocalMainFrame()->GetScrollOffset());
     }
 
@@ -3053,7 +3053,7 @@
           initial_page_scale_factor);
       web_view_helper.LocalMainFrame()->SetScrollOffset(scroll_offset);
       UpdateAllLifecyclePhases(web_view_helper.GetWebView());
-      const gfx::ScrollOffset expected_scroll_offset =
+      const gfx::Vector2dF expected_scroll_offset =
           web_view_helper.LocalMainFrame()->GetScrollOffset();
       web_view_helper.Resize(
           gfx::Size(viewport_size.width(), viewport_size.height() * 0.8f));
@@ -3077,7 +3077,7 @@
   // long as the content adjusts according to the device-width.
   const char* url = "resize_scroll_mobile.html";
   const float kInitialPageScaleFactor = 1;
-  const gfx::ScrollOffset scroll_offset(0, 50);
+  const gfx::Vector2dF scroll_offset(0, 50);
   const gfx::Size viewport_size(120, 160);
   const bool kShouldScaleRelativeToViewportWidth = true;
 
@@ -3093,7 +3093,7 @@
   // on rotation and not do anything strange.
   const char* url = "resize_scroll_minimum_scale.html";
   const float kInitialPageScaleFactor = 1;
-  const gfx::ScrollOffset scroll_offset(0, 0);
+  const gfx::Vector2dF scroll_offset(0, 0);
   const gfx::Size viewport_size(240, 320);
   const bool kShouldScaleRelativeToViewportWidth = false;
 
@@ -3107,7 +3107,7 @@
   // viewport width.
   const char* url = "resize_scroll_fixed_width.html";
   const float kInitialPageScaleFactor = 2;
-  const gfx::ScrollOffset scroll_offset(0, 200);
+  const gfx::Vector2dF scroll_offset(0, 200);
   const gfx::Size viewport_size(240, 320);
   const bool kShouldScaleRelativeToViewportWidth = true;
 
@@ -3121,7 +3121,7 @@
   // viewport width.
   const char* url = "resize_scroll_fixed_layout.html";
   const float kInitialPageScaleFactor = 2;
-  const gfx::ScrollOffset scroll_offset(200, 400);
+  const gfx::Vector2dF scroll_offset(200, 400);
   const gfx::Size viewport_size(320, 240);
   const bool kShouldScaleRelativeToViewportWidth = true;
 
@@ -3220,7 +3220,7 @@
                                 float scale) {
   web_view->SetPageScaleFactor(scale);
   web_view->MainFrameImpl()->SetScrollOffset(
-      gfx::ScrollOffset(scroll.x(), scroll.y()));
+      gfx::Vector2dF(scroll.x(), scroll.y()));
   web_view->MainFrameWidget()->UpdateAllLifecyclePhases(
       DocumentUpdateReason::kTest);
 }
@@ -3230,7 +3230,7 @@
       web_view_impl->FakePageScaleAnimationPageScaleForTesting() /
       web_view_impl->PageScaleFactor();
   web_view_impl->MainFrameWidget()->ApplyViewportChangesForTesting(
-      {gfx::ScrollOffset(), gfx::Vector2dF(), scale_delta, false, 0, 0,
+      {gfx::Vector2dF(), gfx::Vector2dF(), scale_delta, false, 0, 0,
        cc::BrowserControlsState::kBoth});
   scale = web_view_impl->PageScaleFactor();
 }
@@ -3429,7 +3429,7 @@
   EXPECT_FLOAT_EQ(1, scale);
   web_view_helper.GetWebView()
       ->MainFrameWidget()
-      ->ApplyViewportChangesForTesting({gfx::ScrollOffset(), gfx::Vector2dF(),
+      ->ApplyViewportChangesForTesting({gfx::Vector2dF(), gfx::Vector2dF(),
                                         0.6f, false, 0, 0,
                                         cc::BrowserControlsState::kBoth});
   SimulateDoubleTap(web_view_helper.GetWebView(), bottom_point, scale);
@@ -3442,7 +3442,7 @@
   // should go back to minimum scale.
   web_view_helper.GetWebView()
       ->MainFrameWidget()
-      ->ApplyViewportChangesForTesting({gfx::ScrollOffset(), gfx::Vector2dF(),
+      ->ApplyViewportChangesForTesting({gfx::Vector2dF(), gfx::Vector2dF(),
                                         1.1f, false, 0, 0,
                                         cc::BrowserControlsState::kBoth});
 
@@ -3500,7 +3500,7 @@
   // Zoom in to reset double_tap_zoom_in_effect flag.
   web_view_helper.GetWebView()
       ->MainFrameWidget()
-      ->ApplyViewportChangesForTesting({gfx::ScrollOffset(), gfx::Vector2dF(),
+      ->ApplyViewportChangesForTesting({gfx::Vector2dF(), gfx::Vector2dF(),
                                         1.1f, false, 0, 0,
                                         cc::BrowserControlsState::kBoth});
   // 1 < minimumPageScale < doubleTapZoomAlreadyLegibleScale
@@ -3524,7 +3524,7 @@
   // Zoom in to reset double_tap_zoom_in_effect flag.
   web_view_helper.GetWebView()
       ->MainFrameWidget()
-      ->ApplyViewportChangesForTesting({gfx::ScrollOffset(), gfx::Vector2dF(),
+      ->ApplyViewportChangesForTesting({gfx::Vector2dF(), gfx::Vector2dF(),
                                         1.1f, false, 0, 0,
                                         cc::BrowserControlsState::kBoth});
   // minimumPageScale < 1 < doubleTapZoomAlreadyLegibleScale
@@ -3596,7 +3596,7 @@
   // Zoom in to reset double_tap_zoom_in_effect flag.
   web_view_helper.GetWebView()
       ->MainFrameWidget()
-      ->ApplyViewportChangesForTesting({gfx::ScrollOffset(), gfx::Vector2dF(),
+      ->ApplyViewportChangesForTesting({gfx::Vector2dF(), gfx::Vector2dF(),
                                         1.1f, false, 0, 0,
                                         cc::BrowserControlsState::kBoth});
   // 1 < maximumLegibleScaleFactor < minimumPageScale <
@@ -3621,7 +3621,7 @@
   // Zoom in to reset double_tap_zoom_in_effect flag.
   web_view_helper.GetWebView()
       ->MainFrameWidget()
-      ->ApplyViewportChangesForTesting({gfx::ScrollOffset(), gfx::Vector2dF(),
+      ->ApplyViewportChangesForTesting({gfx::Vector2dF(), gfx::Vector2dF(),
                                         1.1f, false, 0, 0,
                                         cc::BrowserControlsState::kBoth});
   // minimumPageScale < 1 < maximumLegibleScaleFactor <
@@ -3646,7 +3646,7 @@
   // Zoom in to reset double_tap_zoom_in_effect flag.
   web_view_helper.GetWebView()
       ->MainFrameWidget()
-      ->ApplyViewportChangesForTesting({gfx::ScrollOffset(), gfx::Vector2dF(),
+      ->ApplyViewportChangesForTesting({gfx::Vector2dF(), gfx::Vector2dF(),
                                         1.1f, false, 0, 0,
                                         cc::BrowserControlsState::kBoth});
   // minimumPageScale < 1 < doubleTapZoomAlreadyLegibleScale <
@@ -3722,7 +3722,7 @@
   // Zoom in to reset double_tap_zoom_in_effect flag.
   web_view_helper.GetWebView()
       ->MainFrameWidget()
-      ->ApplyViewportChangesForTesting({gfx::ScrollOffset(), gfx::Vector2dF(),
+      ->ApplyViewportChangesForTesting({gfx::Vector2dF(), gfx::Vector2dF(),
                                         1.1f, false, 0, 0,
                                         cc::BrowserControlsState::kBoth});
   // 1 < accessibilityFontScaleFactor < minimumPageScale <
@@ -3747,7 +3747,7 @@
   // Zoom in to reset double_tap_zoom_in_effect flag.
   web_view_helper.GetWebView()
       ->MainFrameWidget()
-      ->ApplyViewportChangesForTesting({gfx::ScrollOffset(), gfx::Vector2dF(),
+      ->ApplyViewportChangesForTesting({gfx::Vector2dF(), gfx::Vector2dF(),
                                         1.1f, false, 0, 0,
                                         cc::BrowserControlsState::kBoth});
   // minimumPageScale < 1 < accessibilityFontScaleFactor <
@@ -3772,7 +3772,7 @@
   // Zoom in to reset double_tap_zoom_in_effect flag.
   web_view_helper.GetWebView()
       ->MainFrameWidget()
-      ->ApplyViewportChangesForTesting({gfx::ScrollOffset(), gfx::Vector2dF(),
+      ->ApplyViewportChangesForTesting({gfx::Vector2dF(), gfx::Vector2dF(),
                                         1.1f, false, 0, 0,
                                         cc::BrowserControlsState::kBoth});
   // minimumPageScale < 1 < doubleTapZoomAlreadyLegibleScale <
@@ -4311,7 +4311,7 @@
   web_view_helper.InitializeAndLoad(base_url_ + url, &client);
   web_view_helper.Resize(gfx::Size(kPageWidth, kPageHeight));
   web_view_helper.LocalMainFrame()->SetScrollOffset(
-      gfx::ScrollOffset(kPageWidth / 4, kPageHeight / 4));
+      gfx::Vector2dF(kPageWidth / 4, kPageHeight / 4));
   web_view_helper.GetWebView()->SetPageScaleFactor(kPageScaleFactor);
 
   // Reload the page and end up at the same url. State should not be propagated.
@@ -4319,7 +4319,7 @@
       WebFrameLoadType::kReload);
   frame_test_helpers::PumpPendingRequestsForFrameToLoad(
       web_view_helper.LocalMainFrame());
-  EXPECT_EQ(gfx::ScrollOffset(),
+  EXPECT_EQ(gfx::Vector2dF(),
             web_view_helper.LocalMainFrame()->GetScrollOffset());
   EXPECT_EQ(1.0f, web_view_helper.GetWebView()->PageScaleFactor());
 }
@@ -7099,7 +7099,7 @@
   scrollable_area->DidCompositorScroll(FloatPoint(0, 1));
   web_view_helper.GetWebView()
       ->MainFrameWidget()
-      ->ApplyViewportChangesForTesting({gfx::ScrollOffset(), gfx::Vector2dF(),
+      ->ApplyViewportChangesForTesting({gfx::Vector2dF(), gfx::Vector2dF(),
                                         1.7f, false, 0, 0,
                                         cc::BrowserControlsState::kBoth});
   EXPECT_TRUE(client.WasFrameScrolled());
@@ -7112,7 +7112,7 @@
   scrollable_area->DidCompositorScroll(FloatPoint(0, 2));
   web_view_helper.GetWebView()
       ->MainFrameWidget()
-      ->ApplyViewportChangesForTesting({gfx::ScrollOffset(), gfx::Vector2dF(),
+      ->ApplyViewportChangesForTesting({gfx::Vector2dF(), gfx::Vector2dF(),
                                         1.0f, false, 0, 0,
                                         cc::BrowserControlsState::kBoth});
   EXPECT_TRUE(client.WasFrameScrolled());
@@ -7124,7 +7124,7 @@
   scrollable_area->DidCompositorScroll(FloatPoint(0, 2));
   web_view_helper.GetWebView()
       ->MainFrameWidget()
-      ->ApplyViewportChangesForTesting({gfx::ScrollOffset(), gfx::Vector2dF(),
+      ->ApplyViewportChangesForTesting({gfx::Vector2dF(), gfx::Vector2dF(),
                                         1.0f, false, 0, 0,
                                         cc::BrowserControlsState::kBoth});
   EXPECT_FALSE(client.WasFrameScrolled());
@@ -7135,7 +7135,7 @@
   scrollable_area->DidCompositorScroll(FloatPoint(9, 15));
   web_view_helper.GetWebView()
       ->MainFrameWidget()
-      ->ApplyViewportChangesForTesting({gfx::ScrollOffset(), gfx::Vector2dF(),
+      ->ApplyViewportChangesForTesting({gfx::Vector2dF(), gfx::Vector2dF(),
                                         0.6f, false, 0, 0,
                                         cc::BrowserControlsState::kBoth});
   EXPECT_TRUE(client.WasFrameScrolled());
@@ -7902,29 +7902,29 @@
   web_view->SetPageScaleFactor(2.0f);
   UpdateAllLifecyclePhases(web_view_helper.GetWebView());
 
-  web_view->MainFrameImpl()->SetScrollOffset(gfx::ScrollOffset(0, 2000));
+  web_view->MainFrameImpl()->SetScrollOffset(gfx::Vector2dF(0, 2000));
   EXPECT_EQ(ScrollOffset(0, 1900),
             frame_view->LayoutViewport()->GetScrollOffset());
 
   // Simulate the browser controls showing by 20px, thus shrinking the viewport
   // and allowing it to scroll an additional 20px.
   web_view->MainFrameWidget()->ApplyViewportChangesForTesting(
-      {gfx::ScrollOffset(), gfx::Vector2dF(), 1.0f, false,
+      {gfx::Vector2dF(), gfx::Vector2dF(), 1.0f, false,
        20.0f / browser_controls_height, 0, cc::BrowserControlsState::kBoth});
   EXPECT_EQ(ScrollOffset(0, 1920),
             frame_view->LayoutViewport()->MaximumScrollOffset());
 
   // Show more, make sure the scroll actually gets clamped.
   web_view->MainFrameWidget()->ApplyViewportChangesForTesting(
-      {gfx::ScrollOffset(), gfx::Vector2dF(), 1.0f, false,
+      {gfx::Vector2dF(), gfx::Vector2dF(), 1.0f, false,
        20.0f / browser_controls_height, 0, cc::BrowserControlsState::kBoth});
-  web_view->MainFrameImpl()->SetScrollOffset(gfx::ScrollOffset(0, 2000));
+  web_view->MainFrameImpl()->SetScrollOffset(gfx::Vector2dF(0, 2000));
   EXPECT_EQ(ScrollOffset(0, 1940),
             frame_view->LayoutViewport()->GetScrollOffset());
 
   // Hide until there's 10px showing.
   web_view->MainFrameWidget()->ApplyViewportChangesForTesting(
-      {gfx::ScrollOffset(), gfx::Vector2dF(), 1.0f, false,
+      {gfx::Vector2dF(), gfx::Vector2dF(), 1.0f, false,
        -30.0f / browser_controls_height, 0, cc::BrowserControlsState::kBoth});
   EXPECT_EQ(ScrollOffset(0, 1910),
             frame_view->LayoutViewport()->MaximumScrollOffset());
@@ -7933,7 +7933,7 @@
   // accommodate the browser controls and Blink's view of the browser controls
   // matches that of the CC
   web_view->MainFrameWidget()->ApplyViewportChangesForTesting(
-      {gfx::ScrollOffset(), gfx::Vector2dF(), 1.0f, false,
+      {gfx::Vector2dF(), gfx::Vector2dF(), 1.0f, false,
        30.0f / browser_controls_height, 0, cc::BrowserControlsState::kBoth});
   web_view->ResizeWithBrowserControls(gfx::Size(100, 60), 40.0f, 0, true);
   UpdateAllLifecyclePhases(web_view_helper.GetWebView());
@@ -7942,7 +7942,7 @@
 
   // Now simulate hiding.
   web_view->MainFrameWidget()->ApplyViewportChangesForTesting(
-      {gfx::ScrollOffset(), gfx::Vector2dF(), 1.0f, false,
+      {gfx::Vector2dF(), gfx::Vector2dF(), 1.0f, false,
        -10.0f / browser_controls_height, 0, cc::BrowserControlsState::kBoth});
   EXPECT_EQ(ScrollOffset(0, 1930),
             frame_view->LayoutViewport()->MaximumScrollOffset());
@@ -7950,7 +7950,7 @@
   // Reset to original state: 100px widget height, browser controls fully
   // hidden.
   web_view->MainFrameWidget()->ApplyViewportChangesForTesting(
-      {gfx::ScrollOffset(), gfx::Vector2dF(), 1.0f, false,
+      {gfx::Vector2dF(), gfx::Vector2dF(), 1.0f, false,
        -30.0f / browser_controls_height, 0, cc::BrowserControlsState::kBoth});
   web_view->ResizeWithBrowserControls(gfx::Size(100, 100),
                                       browser_controls_height, 0, false);
@@ -7963,13 +7963,13 @@
   // sure we're not losing any pixels when applying the adjustment on the
   // main frame.
   web_view->MainFrameWidget()->ApplyViewportChangesForTesting(
-      {gfx::ScrollOffset(), gfx::Vector2dF(), 1.0f, false,
+      {gfx::Vector2dF(), gfx::Vector2dF(), 1.0f, false,
        1.0f / browser_controls_height, 0, cc::BrowserControlsState::kBoth});
   EXPECT_EQ(ScrollOffset(0, 1901),
             frame_view->LayoutViewport()->MaximumScrollOffset());
 
   web_view->MainFrameWidget()->ApplyViewportChangesForTesting(
-      {gfx::ScrollOffset(), gfx::Vector2dF(), 1.0f, false,
+      {gfx::Vector2dF(), gfx::Vector2dF(), 1.0f, false,
        2.0f / browser_controls_height, 0, cc::BrowserControlsState::kBoth});
   EXPECT_EQ(ScrollOffset(0, 1903),
             frame_view->LayoutViewport()->MaximumScrollOffset());
@@ -13389,7 +13389,7 @@
   // Make the page scale and scroll with the given parameters.
   EXPECT_EQ(0.5f, WebView().PageScaleFactor());
   WebView().SetPageScaleFactor(2.0f);
-  WebView().MainFrameImpl()->SetScrollOffset(gfx::ScrollOffset(94, 111));
+  WebView().MainFrameImpl()->SetScrollOffset(gfx::Vector2dF(94, 111));
   WebView().SetVisualViewportOffset(gfx::PointF(12, 20));
   EXPECT_EQ(2.0f, WebView().PageScaleFactor());
   EXPECT_EQ(94, WebView().MainFrameImpl()->GetScrollOffset().x());
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
index 1c125dc..d3a7dc3 100644
--- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
+++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -761,14 +761,14 @@
     GetFrame()->GetSystemClipboard()->CopyToFindPboard(SelectionAsText());
 }
 
-gfx::ScrollOffset WebLocalFrameImpl::GetScrollOffset() const {
+gfx::Vector2dF WebLocalFrameImpl::GetScrollOffset() const {
   if (ScrollableArea* scrollable_area = LayoutViewport()) {
-    return gfx::ScrollOffset(scrollable_area->GetScrollOffset());
+    return gfx::Vector2dF(scrollable_area->GetScrollOffset());
   }
-  return gfx::ScrollOffset();
+  return gfx::Vector2dF();
 }
 
-void WebLocalFrameImpl::SetScrollOffset(const gfx::ScrollOffset& offset) {
+void WebLocalFrameImpl::SetScrollOffset(const gfx::Vector2dF& offset) {
   if (ScrollableArea* scrollable_area = LayoutViewport()) {
     scrollable_area->SetScrollOffset(ScrollOffset(offset.x(), offset.y()),
                                      mojom::blink::ScrollType::kProgrammatic);
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.h b/third_party/blink/renderer/core/frame/web_local_frame_impl.h
index 7028eec..2a4ee67 100644
--- a/third_party/blink/renderer/core/frame/web_local_frame_impl.h
+++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.h
@@ -283,8 +283,8 @@
   std::unique_ptr<WebAssociatedURLLoader> CreateAssociatedURLLoader(
       const WebAssociatedURLLoaderOptions&) override;
   void DeprecatedStopLoading() override;
-  gfx::ScrollOffset GetScrollOffset() const override;
-  void SetScrollOffset(const gfx::ScrollOffset&) override;
+  gfx::Vector2dF GetScrollOffset() const override;
+  void SetScrollOffset(const gfx::Vector2dF&) override;
   gfx::Size DocumentSize() const override;
   bool HasVisibleContent() const override;
   gfx::Rect VisibleContentRect() const override;
diff --git a/third_party/blink/renderer/core/input/event_handler_test.cc b/third_party/blink/renderer/core/input/event_handler_test.cc
index 3dabd33..f98c072 100644
--- a/third_party/blink/renderer/core/input/event_handler_test.cc
+++ b/third_party/blink/renderer/core/input/event_handler_test.cc
@@ -2044,7 +2044,7 @@
   LocalFrameView* frame_view = GetDocument().View();
   frame_view->LayoutViewport()->DidCompositorScroll(FloatPoint(0, 500));
   WebView().MainFrameWidget()->ApplyViewportChangesForTesting(
-      {gfx::ScrollOffset(), gfx::Vector2dF(), 1.0f, false, 0, 0,
+      {gfx::Vector2dF(), gfx::Vector2dF(), 1.0f, false, 0, 0,
        cc::BrowserControlsState::kBoth, true});
   ASSERT_EQ(500, frame_view->LayoutViewport()->GetScrollOffset().Height());
   EXPECT_EQ("currently hovered", element1.InnerHTML().Utf8());
diff --git a/third_party/blink/renderer/core/input/scroll_manager.cc b/third_party/blink/renderer/core/input/scroll_manager.cc
index d7f6539..bedcf82 100644
--- a/third_party/blink/renderer/core/input/scroll_manager.cc
+++ b/third_party/blink/renderer/core/input/scroll_manager.cc
@@ -742,9 +742,9 @@
   FloatPoint current_position = scrollable_area->ScrollPosition();
   std::unique_ptr<cc::SnapSelectionStrategy> strategy =
       cc::SnapSelectionStrategy::CreateForDirection(
-          gfx::ScrollOffset(current_position.X(), current_position.Y()),
-          gfx::ScrollOffset(scroll_state_data->delta_x,
-                            scroll_state_data->delta_y),
+          gfx::Vector2dF(current_position.X(), current_position.Y()),
+          gfx::Vector2dF(scroll_state_data->delta_x,
+                         scroll_state_data->delta_y),
           RuntimeEnabledFeatures::FractionalScrollOffsetsEnabled());
 
   absl::optional<FloatPoint> snap_point =
@@ -907,8 +907,8 @@
   *out_initial_position = gfx::Vector2dF(current_position);
   std::unique_ptr<cc::SnapSelectionStrategy> strategy =
       cc::SnapSelectionStrategy::CreateForEndAndDirection(
-          gfx::ScrollOffset(*out_initial_position),
-          gfx::ScrollOffset(natural_displacement),
+          gfx::Vector2dF(*out_initial_position),
+          gfx::Vector2dF(natural_displacement),
           RuntimeEnabledFeatures::FractionalScrollOffsetsEnabled());
   absl::optional<FloatPoint> snap_end =
       scrollable_area->GetSnapPositionAndSetTarget(*strategy);
diff --git a/third_party/blink/renderer/core/inspector/dev_tools_emulator.cc b/third_party/blink/renderer/core/inspector/dev_tools_emulator.cc
index 439ee3c..6f3f8b163 100644
--- a/third_party/blink/renderer/core/inspector/dev_tools_emulator.cc
+++ b/third_party/blink/renderer/core/inspector/dev_tools_emulator.cc
@@ -446,10 +446,10 @@
 
   // Translate while taking into account current scroll offset.
   // TODO(lukasza): https://crbug.com/734201: Add OOPIF support.
-  gfx::ScrollOffset scroll_offset =
+  gfx::Vector2dF scroll_offset =
       web_view_->MainFrame()->IsWebLocalFrame()
           ? web_view_->MainFrame()->ToWebLocalFrame()->GetScrollOffset()
-          : gfx::ScrollOffset();
+          : gfx::Vector2dF();
   gfx::PointF visual_offset = web_view_->VisualViewportOffset();
   float scroll_x = scroll_offset.x() + visual_offset.x();
   float scroll_y = scroll_offset.y() + visual_offset.y();
diff --git a/third_party/blink/renderer/core/loader/programmatic_scroll_test.cc b/third_party/blink/renderer/core/loader/programmatic_scroll_test.cc
index 0338a74..982f180 100644
--- a/third_party/blink/renderer/core/loader/programmatic_scroll_test.cc
+++ b/third_party/blink/renderer/core/loader/programmatic_scroll_test.cc
@@ -58,7 +58,7 @@
   loader.GetDocumentLoader()->SetLoadType(WebFrameLoadType::kBackForward);
 
   web_view->SetPageScaleFactor(3.0f);
-  web_view->MainFrameImpl()->SetScrollOffset(gfx::ScrollOffset(0, 500));
+  web_view->MainFrameImpl()->SetScrollOffset(gfx::Vector2dF(0, 500));
   loader.GetDocumentLoader()->GetInitialScrollState().was_scrolled_by_user =
       false;
   loader.GetDocumentLoader()->GetHistoryItem()->SetPageScaleFactor(2);
@@ -93,7 +93,7 @@
   loader.GetDocumentLoader()->SetLoadType(WebFrameLoadType::kBackForward);
 
   web_view->SetPageScaleFactor(3.0f);
-  web_view->MainFrameImpl()->SetScrollOffset(gfx::ScrollOffset(0, 500));
+  web_view->MainFrameImpl()->SetScrollOffset(gfx::Vector2dF(0, 500));
   loader.GetDocumentLoader()->GetInitialScrollState().was_scrolled_by_user =
       false;
   loader.GetDocumentLoader()->GetHistoryItem()->SetPageScaleFactor(0);
@@ -124,13 +124,13 @@
   FrameLoader& loader = web_view->MainFrameImpl()->GetFrame()->Loader();
   loader.GetDocumentLoader()->SetLoadType(WebFrameLoadType::kBackForward);
 
-  web_view->MainFrameImpl()->SetScrollOffset(gfx::ScrollOffset(0, 500));
+  web_view->MainFrameImpl()->SetScrollOffset(gfx::Vector2dF(0, 500));
   loader.GetDocumentLoader()->GetInitialScrollState().was_scrolled_by_user =
       true;
   loader.SaveScrollState();
   loader.SaveScrollAnchor();
 
-  web_view->MainFrameImpl()->SetScrollOffset(gfx::ScrollOffset(0, 0));
+  web_view->MainFrameImpl()->SetScrollOffset(gfx::Vector2dF(0, 0));
   loader.SaveScrollState();
   loader.GetDocumentLoader()->GetInitialScrollState().was_scrolled_by_user =
       false;
diff --git a/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc b/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc
index 679e5ae..03d03dc 100644
--- a/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc
+++ b/third_party/blink/renderer/core/page/scrolling/root_scroller_test.cc
@@ -2835,7 +2835,7 @@
     ASSERT_EQ(1, GetBrowserControls().TopShownRatio());
     ASSERT_EQ(1, GetBrowserControls().BottomShownRatio());
     WebView().MainFrameWidget()->ApplyViewportChangesForTesting(
-        {gfx::ScrollOffset(), gfx::Vector2dF(), 1, false, -1, -1,
+        {gfx::Vector2dF(), gfx::Vector2dF(), 1, false, -1, -1,
          cc::BrowserControlsState::kBoth});
     ASSERT_EQ(0, GetBrowserControls().TopShownRatio());
     ASSERT_EQ(0, GetBrowserControls().BottomShownRatio());
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc
index 00d8c8c5..ba19867 100644
--- a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc
+++ b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc
@@ -92,7 +92,7 @@
 
 void ScrollingCoordinator::DidCompositorScroll(
     CompositorElementId element_id,
-    const gfx::ScrollOffset& offset,
+    const gfx::Vector2dF& offset,
     const absl::optional<cc::TargetSnapAreaElementIds>& snap_target_ids) {
   // Find the associated scrollable area using the element id and notify it of
   // the compositor-side scroll. We explicitly do not check the VisualViewport
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h
index a8fb4454..4ec379d 100644
--- a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h
+++ b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h
@@ -115,7 +115,7 @@
   // ScrollCallbacks implementation
   void DidCompositorScroll(
       CompositorElementId,
-      const gfx::ScrollOffset&,
+      const gfx::Vector2dF&,
       const absl::optional<cc::TargetSnapAreaElementIds>&) override;
   void DidChangeScrollbarsHidden(CompositorElementId, bool hidden) override;
 
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc b/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc
index c6a498f..2b3893a 100644
--- a/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc
+++ b/third_party/blink/renderer/core/page/scrolling/scrolling_test.cc
@@ -144,15 +144,14 @@
     return ScrollNodeForScrollableArea(ScrollableAreaByDOMElementId(dom_id));
   }
 
-  gfx::ScrollOffset CurrentScrollOffset(cc::ElementId element_id) const {
+  gfx::Vector2dF CurrentScrollOffset(cc::ElementId element_id) const {
     return RootCcLayer()
         ->layer_tree_host()
         ->property_trees()
         ->scroll_tree.current_scroll_offset(element_id);
   }
 
-  gfx::ScrollOffset CurrentScrollOffset(
-      const cc::ScrollNode* scroll_node) const {
+  gfx::Vector2dF CurrentScrollOffset(const cc::ScrollNode* scroll_node) const {
     return CurrentScrollOffset(scroll_node->element_id);
   }
 
@@ -1787,14 +1786,14 @@
   const auto* scroll_node = ScrollNodeForScrollableArea(scrollable_area);
 
   // Simulate 100px of scroll coming from the compositor thread during a commit.
-  gfx::ScrollOffset compositor_delta(0, 100.f);
+  gfx::Vector2dF compositor_delta(0, 100.f);
   cc::CompositorCommitData commit_data;
   commit_data.scrolls.push_back(
       {scrollable_area->GetScrollElementId(), compositor_delta, absl::nullopt});
   RootCcLayer()->layer_tree_host()->ApplyCompositorChanges(&commit_data);
   // The compositor offset is reflected in blink and cc scroll tree.
   EXPECT_EQ(compositor_delta,
-            gfx::ScrollOffset(scrollable_area->ScrollPosition()));
+            gfx::Vector2dF(scrollable_area->ScrollPosition()));
   EXPECT_EQ(compositor_delta, CurrentScrollOffset(scroll_node));
 
   // Before updating the lifecycle, set the scroll offset back to what it was
@@ -1806,7 +1805,7 @@
   // the main thread is concerned, it was unchanged since the last time we
   // pushed the scroll offset.
   ForceFullCompositingUpdate();
-  EXPECT_EQ(gfx::ScrollOffset(), CurrentScrollOffset(scroll_node));
+  EXPECT_EQ(gfx::Vector2dF(), CurrentScrollOffset(scroll_node));
 }
 
 TEST_P(ScrollingTest, UpdateVisualViewportScrollLayer) {
@@ -1830,12 +1829,12 @@
 
   page->GetVisualViewport().SetScale(2);
   ForceFullCompositingUpdate();
-  EXPECT_EQ(gfx::ScrollOffset(0, 0),
+  EXPECT_EQ(gfx::Vector2dF(0, 0),
             CurrentScrollOffset(inner_viewport_scroll_node));
 
   page->GetVisualViewport().SetLocation(FloatPoint(10, 20));
   ForceFullCompositingUpdate();
-  EXPECT_EQ(gfx::ScrollOffset(10, 20),
+  EXPECT_EQ(gfx::Vector2dF(10, 20),
             CurrentScrollOffset(inner_viewport_scroll_node));
 }
 
@@ -1985,21 +1984,21 @@
   auto* scrollable_area = scroller->GetLayoutBox()->GetScrollableArea();
   auto element_id = scrollable_area->GetScrollElementId();
 
-  EXPECT_EQ(gfx::ScrollOffset(), CurrentScrollOffset(element_id));
+  EXPECT_EQ(gfx::Vector2dF(), CurrentScrollOffset(element_id));
 
   // Simulate a direct scroll update out of document lifecycle update.
   scroller->scrollTo(0, 200);
   EXPECT_EQ(FloatPoint(0, 200), scrollable_area->ScrollPosition());
-  EXPECT_EQ(gfx::ScrollOffset(0, 200), CurrentScrollOffset(element_id));
+  EXPECT_EQ(gfx::Vector2dF(0, 200), CurrentScrollOffset(element_id));
 
   // Simulate the scroll update with scroll delta from impl-side at the
   // beginning of BeginMainFrame.
   cc::CompositorCommitData commit_data;
   commit_data.scrolls.push_back(cc::CompositorCommitData::ScrollUpdateInfo(
-      element_id, gfx::ScrollOffset(0, 10), absl::nullopt));
+      element_id, gfx::Vector2dF(0, 10), absl::nullopt));
   RootCcLayer()->layer_tree_host()->ApplyCompositorChanges(&commit_data);
   EXPECT_EQ(FloatPoint(0, 210), scrollable_area->ScrollPosition());
-  EXPECT_EQ(gfx::ScrollOffset(0, 210), CurrentScrollOffset(element_id));
+  EXPECT_EQ(gfx::Vector2dF(0, 210), CurrentScrollOffset(element_id));
 }
 
 TEST_P(ScrollingTest, ThumbInvalidatesLayer) {
diff --git a/third_party/blink/renderer/core/page/scrolling/snap_coordinator.cc b/third_party/blink/renderer/core/page/scrolling/snap_coordinator.cc
index eecde9e4..561579ee 100644
--- a/third_party/blink/renderer/core/page/scrolling/snap_coordinator.cc
+++ b/third_party/blink/renderer/core/page/scrolling/snap_coordinator.cc
@@ -266,7 +266,7 @@
     FloatPoint max_position = scrollable_area->ScrollOffsetToPosition(
         scrollable_area->MaximumScrollOffset());
     snap_container_data.set_max_position(
-        gfx::ScrollOffset(max_position.X(), max_position.Y()));
+        gfx::Vector2dF(max_position.X(), max_position.Y()));
 
     // Scroll-padding represents inward offsets from the corresponding edge of
     // the scrollport.
@@ -308,7 +308,7 @@
         cc::SnapStrictness::kProximity) {
       PhysicalSize size = container_rect.size;
       size.Scale(kProximityRatio);
-      gfx::ScrollOffset range(size.width.ToFloat(), size.height.ToFloat());
+      gfx::Vector2dF range(size.width.ToFloat(), size.height.ToFloat());
       snap_container_data.set_proximity_range(range);
     }
 
diff --git a/third_party/blink/renderer/core/page/scrolling/snap_coordinator_test.cc b/third_party/blink/renderer/core/page/scrolling/snap_coordinator_test.cc
index 5e29898..3e82ef3 100644
--- a/third_party/blink/renderer/core/page/scrolling/snap_coordinator_test.cc
+++ b/third_party/blink/renderer/core/page/scrolling/snap_coordinator_test.cc
@@ -406,7 +406,7 @@
       cc::ScrollSnapType(false, cc::SnapAxis::kBoth,
                          cc::SnapStrictness::kMandatory),
       gfx::RectF(10, 10, width - 20, height - 20),
-      gfx::ScrollOffset(max_position.X(), max_position.Y()));
+      gfx::Vector2dF(max_position.X(), max_position.Y()));
   cc::SnapAreaData expected_area(cc::ScrollSnapAlign(cc::SnapAlignment::kStart),
                                  gfx::RectF(192, 192, 116, 116), false,
                                  cc::ElementId(10));
@@ -440,7 +440,7 @@
       cc::ScrollSnapType(false, cc::SnapAxis::kBoth,
                          cc::SnapStrictness::kMandatory),
       gfx::RectF(10, 10, width - 20, height - 20),
-      gfx::ScrollOffset(max_position.X(), max_position.Y()));
+      gfx::Vector2dF(max_position.X(), max_position.Y()));
   cc::SnapAreaData expected_area(cc::ScrollSnapAlign(cc::SnapAlignment::kStart),
                                  gfx::RectF(192, 192, 116, 116), false,
                                  cc::ElementId(10));
@@ -500,7 +500,7 @@
       cc::ScrollSnapType(false, cc::SnapAxis::kBoth,
                          cc::SnapStrictness::kMandatory),
       gfx::RectF(0, 0, width, height),
-      gfx::ScrollOffset(max_position.X(), max_position.Y()));
+      gfx::Vector2dF(max_position.X(), max_position.Y()));
 
   cc::SnapAreaData expected_area(cc::ScrollSnapAlign(cc::SnapAlignment::kStart),
                                  gfx::RectF(200, 200, 100, 100), false,
@@ -539,7 +539,7 @@
       cc::ScrollSnapType(false, cc::SnapAxis::kBoth,
                          cc::SnapStrictness::kMandatory),
       gfx::RectF(20, 20, width - 20, height - 20),
-      gfx::ScrollOffset(max_position.X(), max_position.Y()));
+      gfx::Vector2dF(max_position.X(), max_position.Y()));
   // rect.x = scroller.border + scroller.padding + area.left + area.margin
   //          - area.scroll-margin
   // rect.y = scroller.border + scroller.padding + area.top + area.margin
@@ -581,7 +581,7 @@
       cc::ScrollSnapType(false, cc::SnapAxis::kBoth,
                          cc::SnapStrictness::kMandatory),
       gfx::RectF(10, 10, width - 20, height - 20),
-      gfx::ScrollOffset(max_position.X(), max_position.Y()));
+      gfx::Vector2dF(max_position.X(), max_position.Y()));
   cc::SnapAreaData expected_area(cc::ScrollSnapAlign(cc::SnapAlignment::kStart),
                                  gfx::RectF(208, 208, 84, 84), false,
                                  cc::ElementId(10));
@@ -628,7 +628,7 @@
       cc::ScrollSnapType(false, cc::SnapAxis::kBoth,
                          cc::SnapStrictness::kMandatory),
       gfx::RectF(16, 10, width - 28, height - 24),
-      gfx::ScrollOffset(max_position.X(), max_position.Y()));
+      gfx::Vector2dF(max_position.X(), max_position.Y()));
   cc::SnapAreaData expected_area(
       cc::ScrollSnapAlign(cc::SnapAlignment::kCenter),
       gfx::RectF(192, 198, 112, 108), false, cc::ElementId(10));
@@ -661,7 +661,7 @@
       cc::ScrollSnapType(false, cc::SnapAxis::kBoth,
                          cc::SnapStrictness::kMandatory),
       gfx::RectF(10, 10, width - 20, height - 20),
-      gfx::ScrollOffset(max_position.X(), max_position.Y()));
+      gfx::Vector2dF(max_position.X(), max_position.Y()));
 
   // The area is scaled from center, so it pushes the area's top-left corner to
   // (50, 50).
@@ -699,7 +699,7 @@
       cc::ScrollSnapType(false, cc::SnapAxis::kBoth,
                          cc::SnapStrictness::kMandatory),
       gfx::RectF(10, 10, width - 20, height - 20),
-      gfx::ScrollOffset(max_position.X(), max_position.Y()));
+      gfx::Vector2dF(max_position.X(), max_position.Y()));
   // Under vertical-rl writing mode, 'start' should align to the right
   // and 'end' should align to the left.
   cc::SnapAreaData expected_area(
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_test.cc b/third_party/blink/renderer/core/paint/compositing/compositing_test.cc
index 0e31613..5724463 100644
--- a/third_party/blink/renderer/core/paint/compositing/compositing_test.cc
+++ b/third_party/blink/renderer/core/paint/compositing/compositing_test.cc
@@ -166,7 +166,7 @@
   EXPECT_EQ(ScrollOffset(), scrollable_area->GetScrollOffset());
   cc::CompositorCommitData commit_data;
   commit_data.scrolls.push_back(
-      {scroll_element_id, gfx::ScrollOffset(0, 1), absl::nullopt});
+      {scroll_element_id, gfx::Vector2dF(0, 1), absl::nullopt});
   overflow_scroll_layer->layer_tree_host()->ApplyCompositorChanges(
       &commit_data);
   UpdateAllLifecyclePhases();
@@ -186,7 +186,7 @@
   // apply impl-side offsets without crashing.
   ASSERT_EQ(overflow_scroll_layer,
             CcLayerByCcElementId(RootCcLayer(), scroll_element_id));
-  commit_data.scrolls[0] = {scroll_element_id, gfx::ScrollOffset(0, 1),
+  commit_data.scrolls[0] = {scroll_element_id, gfx::Vector2dF(0, 1),
                             absl::nullopt};
   overflow_scroll_layer->layer_tree_host()->ApplyCompositorChanges(
       &commit_data);
@@ -223,7 +223,7 @@
   EXPECT_EQ(ScrollOffset(), scrollable_area->GetScrollOffset());
   cc::CompositorCommitData commit_data;
   commit_data.scrolls.push_back({scrollable_area->GetScrollElementId(),
-                                 gfx::ScrollOffset(0, 1), absl::nullopt});
+                                 gfx::Vector2dF(0, 1), absl::nullopt});
   RootCcLayer()->layer_tree_host()->ApplyCompositorChanges(&commit_data);
   UpdateAllLifecyclePhases();
   EXPECT_EQ(ScrollOffset(0, 1), scrollable_area->GetScrollOffset());
@@ -1718,10 +1718,10 @@
   // Simulate the scroll update with scroll delta from impl-side.
   cc::CompositorCommitData commit_data;
   commit_data.scrolls.emplace_back(cc::CompositorCommitData::ScrollUpdateInfo(
-      element_id, gfx::ScrollOffset(0, 10), absl::nullopt));
+      element_id, gfx::Vector2dF(0, 10), absl::nullopt));
   Compositor().LayerTreeHost()->ApplyCompositorChanges(&commit_data);
   EXPECT_EQ(FloatPoint(0, 10), scrollable_area->ScrollPosition());
-  EXPECT_EQ(gfx::ScrollOffset(0, 10),
+  EXPECT_EQ(gfx::Vector2dF(0, 10),
             GetPropertyTrees()->scroll_tree.current_scroll_offset(element_id));
 
   // Update just the blink lifecycle because a full frame would clear the bit
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
index 808ce32..260bb9d 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
@@ -1926,7 +1926,7 @@
   }
 
   cc::TargetSnapAreaElementIds snap_targets;
-  gfx::ScrollOffset snap_position;
+  gfx::Vector2dF snap_position;
   absl::optional<FloatPoint> snap_point;
   if (data.FindSnapPosition(strategy, &snap_position, &snap_targets,
                             active_element_id)) {
@@ -2395,8 +2395,8 @@
 
   FloatPoint end_point = ScrollOffsetToPosition(new_scroll_offset);
   std::unique_ptr<cc::SnapSelectionStrategy> strategy =
-      cc::SnapSelectionStrategy::CreateForEndPosition(
-          gfx::ScrollOffset(end_point), true, true);
+      cc::SnapSelectionStrategy::CreateForEndPosition(gfx::Vector2dF(end_point),
+                                                      true, true);
   end_point = GetSnapPositionAndSetTarget(*strategy).value_or(end_point);
   new_scroll_offset = ScrollPositionToOffset(end_point);
 
diff --git a/third_party/blink/renderer/core/scroll/scrollable_area.cc b/third_party/blink/renderer/core/scroll/scrollable_area.cc
index bb915f7..249d56d 100644
--- a/third_party/blink/renderer/core/scroll/scrollable_area.cc
+++ b/third_party/blink/renderer/core/scroll/scrollable_area.cc
@@ -959,7 +959,7 @@
   DCHECK(IsRootFrameViewport() || !GetLayoutBox()->IsGlobalRootScroller());
   std::unique_ptr<cc::SnapSelectionStrategy> strategy =
       cc::SnapSelectionStrategy::CreateForEndPosition(
-          gfx::ScrollOffset(end_position), scrolled_x, scrolled_y);
+          gfx::Vector2dF(end_position), scrolled_x, scrolled_y);
   return PerformSnapping(*strategy, mojom::blink::ScrollBehavior::kSmooth,
                          std::move(on_finish));
 }
@@ -970,8 +970,8 @@
   FloatPoint current_position = ScrollPosition();
   std::unique_ptr<cc::SnapSelectionStrategy> strategy =
       cc::SnapSelectionStrategy::CreateForDirection(
-          gfx::ScrollOffset(current_position),
-          gfx::ScrollOffset(delta.Width(), delta.Height()),
+          gfx::Vector2dF(current_position),
+          gfx::Vector2dF(delta.Width(), delta.Height()),
           RuntimeEnabledFeatures::FractionalScrollOffsetsEnabled());
   return PerformSnapping(*strategy, mojom::blink::ScrollBehavior::kSmooth,
                          std::move(on_finish));
@@ -982,8 +982,8 @@
   FloatPoint current_position = ScrollPosition();
   std::unique_ptr<cc::SnapSelectionStrategy> strategy =
       cc::SnapSelectionStrategy::CreateForEndAndDirection(
-          gfx::ScrollOffset(current_position),
-          gfx::ScrollOffset(delta.Width(), delta.Height()),
+          gfx::Vector2dF(current_position),
+          gfx::Vector2dF(delta.Width(), delta.Height()),
           RuntimeEnabledFeatures::FractionalScrollOffsetsEnabled());
   return PerformSnapping(*strategy);
 }
@@ -996,7 +996,7 @@
   FloatPoint current_position = ScrollPosition();
   std::unique_ptr<cc::SnapSelectionStrategy> strategy =
       cc::SnapSelectionStrategy::CreateForTargetElement(
-          gfx::ScrollOffset(current_position));
+          gfx::Vector2dF(current_position));
 
   PerformSnapping(*strategy, mojom::blink::ScrollBehavior::kInstant);
 }
diff --git a/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.cc b/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.cc
index 3d5296c..f1223597 100644
--- a/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.cc
+++ b/third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.cc
@@ -17,7 +17,7 @@
     FloatPoint target_value,
     ScrollType scroll_type)
     : curve_(cc::ScrollOffsetAnimationCurveFactory::CreateAnimation(
-          gfx::ScrollOffset(target_value.X(), target_value.Y()),
+          gfx::Vector2dF(target_value.X(), target_value.Y()),
           scroll_type)) {}
 
 CompositorScrollOffsetAnimationCurve::CompositorScrollOffsetAnimationCurve(
@@ -29,12 +29,11 @@
 
 void CompositorScrollOffsetAnimationCurve::SetInitialValue(
     FloatPoint initial_value) {
-  curve_->SetInitialValue(
-      gfx::ScrollOffset(initial_value.X(), initial_value.Y()));
+  curve_->SetInitialValue(gfx::Vector2dF(initial_value.X(), initial_value.Y()));
 }
 
 FloatPoint CompositorScrollOffsetAnimationCurve::GetValue(double time) const {
-  gfx::ScrollOffset value = curve_->GetValue(base::Seconds(time));
+  gfx::Vector2dF value = curve_->GetValue(base::Seconds(time));
   return FloatPoint(value.x(), value.y());
 }
 
@@ -48,13 +47,13 @@
 }
 
 FloatPoint CompositorScrollOffsetAnimationCurve::TargetValue() const {
-  gfx::ScrollOffset target = curve_->target_value();
+  gfx::Vector2dF target = curve_->target_value();
   return FloatPoint(target.x(), target.y());
 }
 
 void CompositorScrollOffsetAnimationCurve::UpdateTarget(base::TimeDelta time,
                                                         FloatPoint new_target) {
-  curve_->UpdateTarget(time, gfx::ScrollOffset(new_target.X(), new_target.Y()));
+  curve_->UpdateTarget(time, gfx::Vector2dF(new_target.X(), new_target.Y()));
 }
 
 std::unique_ptr<gfx::AnimationCurve>
diff --git a/third_party/blink/renderer/platform/geometry/float_point.h b/third_party/blink/renderer/platform/geometry/float_point.h
index ab84791..c84f247 100644
--- a/third_party/blink/renderer/platform/geometry/float_point.h
+++ b/third_party/blink/renderer/platform/geometry/float_point.h
@@ -38,7 +38,7 @@
 #include "third_party/skia/include/core/SkPoint.h"
 #include "ui/gfx/geometry/point3_f.h"
 #include "ui/gfx/geometry/point_f.h"
-#include "ui/gfx/geometry/scroll_offset.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 
 #if defined(OS_MAC)
 typedef struct CGPoint CGPoint;
@@ -136,9 +136,6 @@
     return gfx::Vector2dF(x_, y_);
   }
   explicit operator SkPoint() const { return SkPoint::Make(x_, y_); }
-  explicit operator gfx::ScrollOffset() const {
-    return gfx::ScrollOffset(x_, y_);
-  }
   operator gfx::Point3F() const { return gfx::Point3F(x_, y_, 0.f); }
 
   String ToString() const;
diff --git a/third_party/blink/renderer/platform/geometry/float_size.h b/third_party/blink/renderer/platform/geometry/float_size.h
index 1fdeffd..6ebec2f9 100644
--- a/third_party/blink/renderer/platform/geometry/float_size.h
+++ b/third_party/blink/renderer/platform/geometry/float_size.h
@@ -38,7 +38,6 @@
 #include "third_party/blink/renderer/platform/wtf/hash_traits.h"
 #include "third_party/blink/renderer/platform/wtf/math_extras.h"
 #include "third_party/skia/include/core/SkSize.h"
-#include "ui/gfx/geometry/scroll_offset.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/geometry/size_f.h"
 #include "ui/gfx/geometry/vector2d_f.h"
@@ -157,13 +156,6 @@
     return gfx::Vector2dF(width_, height_);
   }
 
-  // blink::ScrollOffset is typedef'd as FloatSize. When exposing outside blink
-  // it should probably be exposed as a gfx::ScrollOffset (as opposed to a
-  // Vector2dF).
-  constexpr explicit operator gfx::ScrollOffset() const {
-    return gfx::ScrollOffset(width_, height_);
-  }
-
   String ToString() const;
 
  private:
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
index 5476cab5..736e1029 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
+++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor.cc
@@ -1234,9 +1234,9 @@
   auto* property_trees = root_layer_->layer_tree_host()->property_trees();
   if (!property_trees->element_id_to_scroll_node_index.contains(element_id))
     return false;
-  PropertyTreeManager::DirectlySetScrollOffset(
-      *root_layer_->layer_tree_host(), element_id,
-      gfx::ScrollOffset(scroll_offset));
+  PropertyTreeManager::DirectlySetScrollOffset(*root_layer_->layer_tree_host(),
+                                               element_id,
+                                               gfx::Vector2dF(scroll_offset));
   return true;
 }
 
diff --git a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc
index 32baba1..86432717 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc
+++ b/third_party/blink/renderer/platform/graphics/compositing/paint_artifact_compositor_test.cc
@@ -64,7 +64,7 @@
  public:
   MOCK_METHOD3(DidCompositorScroll,
                void(CompositorElementId,
-                    const gfx::ScrollOffset&,
+                    const gfx::Vector2dF&,
                     const absl::optional<cc::TargetSnapAreaElementIds>&));
   MOCK_METHOD2(DidChangeScrollbarsHidden, void(CompositorElementId, bool));
 
@@ -1089,7 +1089,7 @@
   const cc::TransformNode& transform_node =
       *transform_tree.Node(scroll_node.transform_id);
   EXPECT_TRUE(transform_node.local.IsIdentity());
-  EXPECT_EQ(gfx::ScrollOffset(-7, -9), transform_node.scroll_offset);
+  EXPECT_EQ(gfx::Vector2dF(-7, -9), transform_node.scroll_offset);
   EXPECT_EQ(kNotScrollingOnMain, scroll_node.main_thread_scrolling_reasons);
 
   auto* layer = NonScrollableLayerAt(0);
@@ -1114,10 +1114,10 @@
 
   absl::optional<cc::TargetSnapAreaElementIds> targets;
   EXPECT_CALL(ScrollCallbacks(),
-              DidCompositorScroll(scroll_node.element_id,
-                                  gfx::ScrollOffset(1, 2), targets));
+              DidCompositorScroll(scroll_node.element_id, gfx::Vector2dF(1, 2),
+                                  targets));
   GetPropertyTrees().scroll_tree.NotifyDidCompositorScroll(
-      scroll_node.element_id, gfx::ScrollOffset(1, 2), targets);
+      scroll_node.element_id, gfx::Vector2dF(1, 2), targets);
 
   EXPECT_CALL(ScrollCallbacks(),
               DidChangeScrollbarsHidden(scroll_node.element_id, true));
@@ -1228,7 +1228,7 @@
   const cc::TransformNode& transform_node_a =
       *transform_tree.Node(scroll_node_a.transform_id);
   EXPECT_TRUE(transform_node_a.local.IsIdentity());
-  EXPECT_EQ(gfx::ScrollOffset(-11, -13), transform_node_a.scroll_offset);
+  EXPECT_EQ(gfx::Vector2dF(-11, -13), transform_node_a.scroll_offset);
 
   const cc::ScrollNode& scroll_node_b = *scroll_tree.Node(3);
   CheckCcScrollNode(*scroll_b, scroll_node_b);
@@ -1239,7 +1239,7 @@
   const cc::TransformNode& transform_node_b =
       *transform_tree.Node(scroll_node_b.transform_id);
   EXPECT_TRUE(transform_node_b.local.IsIdentity());
-  EXPECT_EQ(gfx::ScrollOffset(-37, -41), transform_node_b.scroll_offset);
+  EXPECT_EQ(gfx::Vector2dF(-37, -41), transform_node_b.scroll_offset);
 }
 
 TEST_P(PaintArtifactCompositorTest, ScrollHitTestLayerOrder) {
@@ -1377,7 +1377,7 @@
   const cc::TransformNode& transform_node_a =
       *transform_tree.Node(scroll_node_a.transform_id);
   EXPECT_TRUE(transform_node_a.local.IsIdentity());
-  EXPECT_EQ(gfx::ScrollOffset(-11, -13), transform_node_a.scroll_offset);
+  EXPECT_EQ(gfx::Vector2dF(-11, -13), transform_node_a.scroll_offset);
 }
 
 TEST_P(PaintArtifactCompositorTest, MergeSimpleChunks) {
@@ -3878,7 +3878,7 @@
   // The max scroll offset should be scaled by the page scale factor (see:
   // |ScrollTree::MaxScrollOffset|). This adjustment scales the contents from
   // 27x32 to 54x64 so the max scroll offset becomes (54-20)/2 x (64-10)/2.
-  EXPECT_EQ(gfx::ScrollOffset(17, 27), max_scroll_offset);
+  EXPECT_EQ(gfx::Vector2dF(17, 27), max_scroll_offset);
 }
 
 enum {
@@ -4513,9 +4513,9 @@
   EXPECT_EQ(scroll_element_id, scroll_node->element_id);
   EXPECT_EQ(scroll_element_id, scroll_layer->element_id());
   EXPECT_EQ(scroll_node->id, scroll_layer->scroll_tree_index());
-  EXPECT_EQ(gfx::ScrollOffset(-7, -9),
+  EXPECT_EQ(gfx::Vector2dF(-7, -9),
             scroll_tree.current_scroll_offset(scroll_element_id));
-  EXPECT_EQ(gfx::ScrollOffset(-7, -9), transform_node->scroll_offset);
+  EXPECT_EQ(gfx::Vector2dF(-7, -9), transform_node->scroll_offset);
 
   auto& host = GetLayerTreeHost();
   host.CompositeForTest(base::TimeTicks::Now(), true);
@@ -4527,10 +4527,10 @@
       scroll_element_id, FloatPoint(-10, -20)));
   EXPECT_TRUE(host.LayersThatShouldPushProperties().contains(scroll_layer));
   EXPECT_TRUE(host.proxy()->CommitRequested());
-  EXPECT_EQ(gfx::ScrollOffset(-10, -20),
+  EXPECT_EQ(gfx::Vector2dF(-10, -20),
             scroll_tree.current_scroll_offset(scroll_element_id));
   // DirectlySetScrollOffset doesn't update transform node.
-  EXPECT_EQ(gfx::ScrollOffset(-7, -9), transform_node->scroll_offset);
+  EXPECT_EQ(gfx::Vector2dF(-7, -9), transform_node->scroll_offset);
   EXPECT_FALSE(transform_tree.needs_update());
 }
 
diff --git a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
index f527c0c..4816413 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
+++ b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc
@@ -75,7 +75,7 @@
     if (transform_node.ScrollNode()) {
       // Blink creates a 2d transform node just for scroll offset whereas cc's
       // transform node has a special scroll offset field.
-      compositor_node.scroll_offset = gfx::ScrollOffset(-translation);
+      compositor_node.scroll_offset = gfx::Vector2dF(-translation);
       DCHECK(compositor_node.local.IsIdentity());
       DCHECK_EQ(gfx::Point3F(), compositor_node.origin);
     } else {
@@ -145,7 +145,7 @@
 
   DCHECK(!cc_transform->is_currently_animating);
 
-  gfx::ScrollOffset scroll_offset(-transform.Translation2D());
+  gfx::Vector2dF scroll_offset(-transform.Translation2D());
   DirectlySetScrollOffset(host, scroll_node->GetCompositorElementId(),
                           scroll_offset);
   if (cc_transform->scroll_offset != scroll_offset) {
@@ -206,7 +206,7 @@
 void PropertyTreeManager::DirectlySetScrollOffset(
     cc::LayerTreeHost& host,
     CompositorElementId element_id,
-    const gfx::ScrollOffset& scroll_offset) {
+    const gfx::Vector2dF& scroll_offset) {
   auto* property_trees = host.property_trees();
   if (property_trees->scroll_tree.SetScrollOffset(element_id, scroll_offset)) {
     // Scroll offset animations are clobbered via |Layer::PushPropertiesTo|.
diff --git a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.h b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.h
index 186ba66..1292742 100644
--- a/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.h
+++ b/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.h
@@ -25,7 +25,7 @@
 }
 
 namespace gfx {
-class ScrollOffset;
+class Vector2dF;
 }
 
 namespace blink {
@@ -149,7 +149,7 @@
   // update the cc transform node's scroll offset.
   static void DirectlySetScrollOffset(cc::LayerTreeHost&,
                                       CompositorElementId,
-                                      const gfx::ScrollOffset&);
+                                      const gfx::Vector2dF&);
 
   // Ensures a cc::ScrollNode for all scroll translations.
   void EnsureCompositorScrollNodes(
diff --git a/third_party/blink/renderer/platform/widget/input/elastic_overscroll_controller.cc b/third_party/blink/renderer/platform/widget/input/elastic_overscroll_controller.cc
index e01701de2..8b048ad 100644
--- a/third_party/blink/renderer/platform/widget/input/elastic_overscroll_controller.cc
+++ b/third_party/blink/renderer/platform/widget/input/elastic_overscroll_controller.cc
@@ -315,8 +315,8 @@
 }
 
 bool ElasticOverscrollController::PinnedHorizontally(float direction) const {
-  gfx::ScrollOffset scroll_offset = helper_->ScrollOffset();
-  gfx::ScrollOffset max_scroll_offset = helper_->MaxScrollOffset();
+  gfx::Vector2dF scroll_offset = helper_->ScrollOffset();
+  gfx::Vector2dF max_scroll_offset = helper_->MaxScrollOffset();
   if (direction < 0)
     return scroll_offset.x() <= 0;
   if (direction > 0)
@@ -325,8 +325,8 @@
 }
 
 bool ElasticOverscrollController::PinnedVertically(float direction) const {
-  gfx::ScrollOffset scroll_offset = helper_->ScrollOffset();
-  gfx::ScrollOffset max_scroll_offset = helper_->MaxScrollOffset();
+  gfx::Vector2dF scroll_offset = helper_->ScrollOffset();
+  gfx::Vector2dF max_scroll_offset = helper_->MaxScrollOffset();
   if (direction < 0)
     return scroll_offset.y() <= 0;
   if (direction > 0)
@@ -347,8 +347,8 @@
   if (stretch.IsZero())
     return;
 
-  gfx::ScrollOffset scroll_offset = helper_->ScrollOffset();
-  gfx::ScrollOffset max_scroll_offset = helper_->MaxScrollOffset();
+  gfx::Vector2dF scroll_offset = helper_->ScrollOffset();
+  gfx::Vector2dF max_scroll_offset = helper_->MaxScrollOffset();
 
   // Compute stretch_adjustment which will be added to |stretch| and subtracted
   // from the |scroll_offset|.
diff --git a/third_party/blink/renderer/platform/widget/input/elastic_overscroll_controller_bezier_unittest.cc b/third_party/blink/renderer/platform/widget/input/elastic_overscroll_controller_bezier_unittest.cc
index 9fdacbe..51ef0603 100644
--- a/third_party/blink/renderer/platform/widget/input/elastic_overscroll_controller_bezier_unittest.cc
+++ b/third_party/blink/renderer/platform/widget/input/elastic_overscroll_controller_bezier_unittest.cc
@@ -33,17 +33,15 @@
     stretch_amount_ = stretch_amount;
   }
   void ScrollBy(const Vector2dF& delta) override {
-    scroll_offset_ += gfx::ScrollOffset(delta);
+    scroll_offset_ += gfx::Vector2dF(delta);
   }
   void RequestOneBeginFrame() override {}
-  gfx::ScrollOffset ScrollOffset() const override { return scroll_offset_; }
-  gfx::ScrollOffset MaxScrollOffset() const override {
-    return max_scroll_offset_;
-  }
+  gfx::Vector2dF ScrollOffset() const override { return scroll_offset_; }
+  gfx::Vector2dF MaxScrollOffset() const override { return max_scroll_offset_; }
 
   void SetScrollOffsetAndMaxScrollOffset(
-      const gfx::ScrollOffset& scroll_offset,
-      const gfx::ScrollOffset& max_scroll_offset) {
+      const gfx::Vector2dF& scroll_offset,
+      const gfx::Vector2dF& max_scroll_offset) {
     scroll_offset_ = scroll_offset;
     max_scroll_offset_ = max_scroll_offset;
   }
@@ -51,7 +49,7 @@
  private:
   bool is_user_scrollable_ = true;
   Vector2dF stretch_amount_;
-  gfx::ScrollOffset scroll_offset_, max_scroll_offset_;
+  gfx::Vector2dF scroll_offset_, max_scroll_offset_;
 };
 
 class ElasticOverscrollControllerBezierTest : public testing::Test {
@@ -145,8 +143,8 @@
 TEST_F(ElasticOverscrollControllerBezierTest, ReconcileStretchAndScroll) {
   // Test vertical overscroll.
   SendGestureScrollBegin(PhaseState::kNonMomentum);
-  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(0, 0),
-                                            gfx::ScrollOffset(100, 100));
+  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::Vector2dF(0, 0),
+                                            gfx::Vector2dF(100, 100));
   SendGestureScrollUpdate(PhaseState::kNonMomentum, Vector2dF(0, -100));
   EXPECT_EQ(Vector2dF(0, -19), helper_.StretchAmount());
   helper_.ScrollBy(Vector2dF(0, 1));
@@ -159,8 +157,8 @@
 
   // Test horizontal overscroll.
   SendGestureScrollBegin(PhaseState::kNonMomentum);
-  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(0, 0),
-                                            gfx::ScrollOffset(100, 100));
+  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::Vector2dF(0, 0),
+                                            gfx::Vector2dF(100, 100));
   SendGestureScrollUpdate(PhaseState::kNonMomentum, Vector2dF(-100, 0));
   EXPECT_EQ(Vector2dF(-19, 0), helper_.StretchAmount());
   helper_.ScrollBy(Vector2dF(1, 0));
@@ -176,8 +174,8 @@
   controller_.state_ =
       ElasticOverscrollController::State::kStateMomentumAnimated;
   helper_.SetStretchAmount(Vector2dF(5, 10));
-  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(0, 20),
-                                            gfx::ScrollOffset(100, 100));
+  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::Vector2dF(0, 20),
+                                            gfx::Vector2dF(100, 100));
   controller_.ReconcileStretchAndScroll();
   controller_.bounce_forwards_duration_x_ = base::Milliseconds(1000);
   controller_.bounce_forwards_duration_y_ = base::Milliseconds(1000);
@@ -228,8 +226,8 @@
 // tick the animation as expected. When the stretch amount is near 0, the
 // scroller should treat the bounce as "completed".
 TEST_F(ElasticOverscrollControllerBezierTest, VerifyBackwardAnimationTick) {
-  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(0, 0),
-                                            gfx::ScrollOffset(100, 100));
+  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::Vector2dF(0, 0),
+                                            gfx::Vector2dF(100, 100));
 
   // Test vertical overscroll.
   EXPECT_EQ(controller_.state_, ElasticOverscrollController::kStateInactive);
@@ -282,8 +280,8 @@
 
 // Tests that the bounce forward animation ticks as expected.
 TEST_F(ElasticOverscrollControllerBezierTest, VerifyForwardAnimationTick) {
-  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(0, 0),
-                                            gfx::ScrollOffset(100, 100));
+  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::Vector2dF(0, 0),
+                                            gfx::Vector2dF(100, 100));
 
   // Test vertical forward bounce animations.
   EXPECT_EQ(controller_.state_, ElasticOverscrollController::kStateInactive);
@@ -359,8 +357,8 @@
 // Tests initiating a scroll when a bounce back animation is in progress works
 // as expected.
 TEST_F(ElasticOverscrollControllerBezierTest, VerifyScrollDuringBounceBack) {
-  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(0, 0),
-                                            gfx::ScrollOffset(100, 100));
+  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::Vector2dF(0, 0),
+                                            gfx::Vector2dF(100, 100));
 
   // Test vertical overscroll.
   SendGestureScrollBegin(PhaseState::kNonMomentum);
diff --git a/third_party/blink/renderer/platform/widget/input/elastic_overscroll_controller_exponential_unittest.cc b/third_party/blink/renderer/platform/widget/input/elastic_overscroll_controller_exponential_unittest.cc
index 69e08ca..77cfecf 100644
--- a/third_party/blink/renderer/platform/widget/input/elastic_overscroll_controller_exponential_unittest.cc
+++ b/third_party/blink/renderer/platform/widget/input/elastic_overscroll_controller_exponential_unittest.cc
@@ -53,12 +53,10 @@
   }
 
   Size ScrollBounds() const override { return Size(800, 600); }
-  gfx::ScrollOffset ScrollOffset() const override { return scroll_offset_; }
-  gfx::ScrollOffset MaxScrollOffset() const override {
-    return max_scroll_offset_;
-  }
+  gfx::Vector2dF ScrollOffset() const override { return scroll_offset_; }
+  gfx::Vector2dF MaxScrollOffset() const override { return max_scroll_offset_; }
   void ScrollBy(const Vector2dF& delta) override {
-    scroll_offset_ += gfx::ScrollOffset(delta);
+    scroll_offset_ += gfx::Vector2dF(delta);
   }
   void RequestOneBeginFrame() override { request_begin_frame_count_ += 1; }
 
@@ -67,8 +65,8 @@
   int set_stretch_amount_count() const { return set_stretch_amount_count_; }
 
   void SetScrollOffsetAndMaxScrollOffset(
-      const gfx::ScrollOffset& scroll_offset,
-      const gfx::ScrollOffset& max_scroll_offset) {
+      const gfx::Vector2dF& scroll_offset,
+      const gfx::Vector2dF& max_scroll_offset) {
     scroll_offset_ = scroll_offset;
     max_scroll_offset_ = max_scroll_offset;
   }
@@ -82,8 +80,8 @@
   int set_stretch_amount_count_;
   int request_begin_frame_count_;
 
-  gfx::ScrollOffset scroll_offset_;
-  gfx::ScrollOffset max_scroll_offset_;
+  gfx::Vector2dF scroll_offset_;
+  gfx::Vector2dF max_scroll_offset_;
 };
 
 class ElasticOverscrollControllerExponentialTest : public testing::Test {
@@ -156,8 +154,8 @@
 // Verify that stretching  occurs in one axis at a time, and that it
 // is biased to the Y axis.
 TEST_F(ElasticOverscrollControllerExponentialTest, Axis) {
-  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(10, 10),
-                                            gfx::ScrollOffset(10, 10));
+  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::Vector2dF(10, 10),
+                                            gfx::Vector2dF(10, 10));
 
   // If we push equally in the X and Y directions, we should see a stretch
   // in the Y direction.
@@ -175,8 +173,8 @@
   // If we push more in the X direction than the Y direction, we should see a
   // stretch  in the X direction. This decision should be based on the actual
   // overscroll delta.
-  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(0, 10),
-                                            gfx::ScrollOffset(10, 10));
+  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::Vector2dF(0, 10),
+                                            gfx::Vector2dF(10, 10));
   SendGestureScrollBegin(NonMomentumPhase);
   SendGestureScrollUpdate(NonMomentumPhase, Vector2dF(-25, 10),
                           Vector2dF(-25, 10));
@@ -195,8 +193,8 @@
   // We should not start stretching while we are not pinned in the direction
   // of the scroll (even if there is an overscroll delta). We have to wait for
   // the regular scroll to eat all of the events.
-  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(5, 5),
-                                            gfx::ScrollOffset(10, 10));
+  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::Vector2dF(5, 5),
+                                            gfx::Vector2dF(10, 10));
   SendGestureScrollBegin(NonMomentumPhase);
   SendGestureScrollUpdate(NonMomentumPhase, Vector2dF(0, 10), Vector2dF(0, 10));
   SendGestureScrollUpdate(NonMomentumPhase, Vector2dF(0, 10), Vector2dF(0, 10));
@@ -205,8 +203,8 @@
   // Now pin the -X and +Y direction. The first event will not generate a
   // stretch
   // because it is below the delta threshold of 10.
-  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(0, 10),
-                                            gfx::ScrollOffset(10, 10));
+  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::Vector2dF(0, 10),
+                                            gfx::Vector2dF(10, 10));
   SendGestureScrollUpdate(NonMomentumPhase, Vector2dF(0, 10), Vector2dF(0, 8));
   EXPECT_EQ(0, helper_.set_stretch_amount_count());
 
@@ -242,8 +240,8 @@
 TEST_F(ElasticOverscrollControllerExponentialTest, MomentumAnimate) {
   // Do an active scroll, then switch to the momentum phase and scroll for a
   // bit.
-  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(5, 5),
-                                            gfx::ScrollOffset(10, 10));
+  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::Vector2dF(5, 5),
+                                            gfx::Vector2dF(10, 10));
   SendGestureScrollBegin(NonMomentumPhase);
   SendGestureScrollUpdate(NonMomentumPhase, Vector2dF(0, -80), Vector2dF(0, 0));
   SendGestureScrollUpdate(NonMomentumPhase, Vector2dF(0, -80), Vector2dF(0, 0));
@@ -257,8 +255,8 @@
 
   // Hit the -Y edge and overscroll slightly, but not enough to go over the
   // threshold to cause a stretch.
-  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(5, 0),
-                                            gfx::ScrollOffset(10, 10));
+  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::Vector2dF(5, 0),
+                                            gfx::Vector2dF(10, 10));
   SendGestureScrollUpdate(MomentumPhase, Vector2dF(0, -80), Vector2dF(0, -8));
   EXPECT_EQ(0, helper_.set_stretch_amount_count());
   EXPECT_EQ(0, helper_.request_begin_frame_count());
@@ -327,43 +325,43 @@
   SendGestureScrollBegin(NonMomentumPhase);
 
   // Verify completely knocking out the scroll in the -Y direction.
-  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(5, 5),
-                                            gfx::ScrollOffset(10, 10));
+  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::Vector2dF(5, 5),
+                                            gfx::Vector2dF(10, 10));
   helper_.SetStretchAmount(Vector2dF(0, -10));
   controller_.ReconcileStretchAndScroll();
   EXPECT_EQ(helper_.StretchAmount(), Vector2dF(0, -5));
-  EXPECT_EQ(helper_.ScrollOffset(), gfx::ScrollOffset(5, 0));
+  EXPECT_EQ(helper_.ScrollOffset(), gfx::Vector2dF(5, 0));
 
   // Verify partially knocking out the scroll in the -Y direction.
-  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(5, 8),
-                                            gfx::ScrollOffset(10, 10));
+  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::Vector2dF(5, 8),
+                                            gfx::Vector2dF(10, 10));
   helper_.SetStretchAmount(Vector2dF(0, -5));
   controller_.ReconcileStretchAndScroll();
   EXPECT_EQ(helper_.StretchAmount(), Vector2dF(0, 0));
-  EXPECT_EQ(helper_.ScrollOffset(), gfx::ScrollOffset(5, 3));
+  EXPECT_EQ(helper_.ScrollOffset(), gfx::Vector2dF(5, 3));
 
   // Verify completely knocking out the scroll in the +X direction.
-  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(5, 5),
-                                            gfx::ScrollOffset(10, 10));
+  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::Vector2dF(5, 5),
+                                            gfx::Vector2dF(10, 10));
   helper_.SetStretchAmount(Vector2dF(10, 0));
   controller_.ReconcileStretchAndScroll();
   EXPECT_EQ(helper_.StretchAmount(), Vector2dF(5, 0));
-  EXPECT_EQ(helper_.ScrollOffset(), gfx::ScrollOffset(10, 5));
+  EXPECT_EQ(helper_.ScrollOffset(), gfx::Vector2dF(10, 5));
 
   // Verify partially knocking out the scroll in the +X and +Y directions.
-  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(2, 3),
-                                            gfx::ScrollOffset(10, 10));
+  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::Vector2dF(2, 3),
+                                            gfx::Vector2dF(10, 10));
   helper_.SetStretchAmount(Vector2dF(5, 5));
   controller_.ReconcileStretchAndScroll();
   EXPECT_EQ(helper_.StretchAmount(), Vector2dF(0, 0));
-  EXPECT_EQ(helper_.ScrollOffset(), gfx::ScrollOffset(7, 8));
+  EXPECT_EQ(helper_.ScrollOffset(), gfx::Vector2dF(7, 8));
 }
 
 // Verify that stretching  happens when the area is user scrollable.
 TEST_F(ElasticOverscrollControllerExponentialTest,
        UserScrollableRequiredForStretch) {
-  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(0, 0),
-                                            gfx::ScrollOffset(10, 10));
+  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::Vector2dF(0, 0),
+                                            gfx::Vector2dF(10, 10));
   Vector2dF delta(0, -15);
 
   // Do an active scroll, and ensure that the stretch amount doesn't change.
@@ -412,8 +410,8 @@
 // Verify that OverscrollBehaviorTypeNone disables the stretching on the
 // specified axis.
 TEST_F(ElasticOverscrollControllerExponentialTest, OverscrollBehavior) {
-  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(10, 10),
-                                            gfx::ScrollOffset(10, 10));
+  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::Vector2dF(10, 10),
+                                            gfx::Vector2dF(10, 10));
 
   // If we set OverscrollBehaviorTypeNone on x, we should not see a stretch
   // in the X direction.
@@ -481,8 +479,8 @@
        OverscrollBehaviorNonScrollable) {
   int expected_stretch_count = 0;
   // Set up a scroller which is vertically scrollable scrolled to the bottom.
-  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::ScrollOffset(0, 10),
-                                            gfx::ScrollOffset(0, 10));
+  helper_.SetScrollOffsetAndMaxScrollOffset(gfx::Vector2dF(0, 10),
+                                            gfx::Vector2dF(0, 10));
 
   SendGestureScrollBegin(NonMomentumPhase);
   SendGestureScrollUpdate(NonMomentumPhase, Vector2dF(25, 0), Vector2dF(25, 0));
diff --git a/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc b/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc
index 58ffa3b..062a085 100644
--- a/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc
+++ b/third_party/blink/renderer/platform/widget/input/input_handler_proxy.cc
@@ -1384,8 +1384,8 @@
 }
 
 void InputHandlerProxy::UpdateRootLayerStateForSynchronousInputHandler(
-    const gfx::ScrollOffset& total_scroll_offset,
-    const gfx::ScrollOffset& max_scroll_offset,
+    const gfx::Vector2dF& total_scroll_offset,
+    const gfx::Vector2dF& max_scroll_offset,
     const gfx::SizeF& scrollable_size,
     float page_scale_factor,
     float min_page_scale_factor,
@@ -1434,7 +1434,7 @@
 }
 
 void InputHandlerProxy::SynchronouslySetRootScrollOffset(
-    const gfx::ScrollOffset& root_offset) {
+    const gfx::Vector2dF& root_offset) {
   DCHECK(synchronous_input_handler_);
   input_handler_->SetSynchronousInputHandlerRootScrollOffset(root_offset);
 }
diff --git a/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc b/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc
index 084beab..af78d35 100644
--- a/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc
+++ b/third_party/blink/renderer/platform/widget/input/input_handler_proxy_unittest.cc
@@ -34,8 +34,8 @@
 #include "third_party/blink/renderer/platform/widget/input/event_with_callback.h"
 #include "third_party/blink/renderer/platform/widget/input/scroll_predictor.h"
 #include "ui/events/types/scroll_input_type.h"
-#include "ui/gfx/geometry/scroll_offset.h"
 #include "ui/gfx/geometry/size_f.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 #include "ui/latency/latency_info.h"
 
 using cc::InputHandler;
@@ -138,11 +138,11 @@
   void DestroyScrollElasticityHelper() override {}
 
   bool GetScrollOffsetForLayer(cc::ElementId element_id,
-                               gfx::ScrollOffset* offset) override {
+                               gfx::Vector2dF* offset) override {
     return false;
   }
   bool ScrollLayerTo(cc::ElementId element_id,
-                     const gfx::ScrollOffset& offset) override {
+                     const gfx::Vector2dF& offset) override {
     return false;
   }
 
@@ -168,7 +168,7 @@
 
   MOCK_METHOD0(RequestUpdateForSynchronousInputHandler, void());
   MOCK_METHOD1(SetSynchronousInputHandlerRootScrollOffset,
-               void(const gfx::ScrollOffset& root_offset));
+               void(const gfx::Vector2dF& root_offset));
 
   bool IsCurrentlyScrollingViewport() const override {
     return is_scrolling_root_;
@@ -192,8 +192,8 @@
 class MockSynchronousInputHandler : public SynchronousInputHandler {
  public:
   MOCK_METHOD6(UpdateRootLayerState,
-               void(const gfx::ScrollOffset& total_scroll_offset,
-                    const gfx::ScrollOffset& max_scroll_offset,
+               void(const gfx::Vector2dF& total_scroll_offset,
+                    const gfx::Vector2dF& max_scroll_offset,
                     const gfx::SizeF& scrollable_size,
                     float page_scale_factor,
                     float min_page_scale_factor,
@@ -618,7 +618,7 @@
 
   cc::InputHandlerPointerResult pointer_down_result;
   pointer_down_result.type = cc::PointerResultType::kScrollbarScroll;
-  pointer_down_result.scroll_offset = gfx::ScrollOffset(0, 1);
+  pointer_down_result.scroll_offset = gfx::Vector2dF(0, 1);
   EXPECT_CALL(mock_input_handler_, HitTest(_))
       .WillOnce(testing::Return(pointer_down_result.type));
   EXPECT_CALL(mock_input_handler_, MouseDown(_, _))
@@ -791,7 +791,7 @@
   mouse_event.button = WebMouseEvent::Button::kLeft;
   cc::InputHandlerPointerResult pointer_down_result;
   pointer_down_result.type = cc::PointerResultType::kScrollbarScroll;
-  pointer_down_result.scroll_offset = gfx::ScrollOffset(0, 1);
+  pointer_down_result.scroll_offset = gfx::Vector2dF(0, 1);
   EXPECT_CALL(mock_input_handler_, HitTest(_))
       .WillOnce(testing::Return(pointer_down_result.type));
   EXPECT_CALL(mock_input_handler_, MouseDown(_, _))
@@ -1473,7 +1473,7 @@
 
   cc::InputHandlerPointerResult pointer_down_result;
   pointer_down_result.type = cc::PointerResultType::kScrollbarScroll;
-  pointer_down_result.scroll_offset = gfx::ScrollOffset(0, 1);
+  pointer_down_result.scroll_offset = gfx::Vector2dF(0, 1);
   EXPECT_CALL(mock_input_handler_, HitTest(_))
       .WillOnce(testing::Return(pointer_down_result.type));
   EXPECT_CALL(mock_input_handler_, MouseDown(_, _))
@@ -2470,14 +2470,12 @@
 
   // When adding a SynchronousInputHandler, immediately request an
   // UpdateRootLayerStateForSynchronousInputHandler() call.
-  EXPECT_CALL(
-      mock_synchronous_input_handler,
-      UpdateRootLayerState(gfx::ScrollOffset(1, 2), gfx::ScrollOffset(3, 4),
-                           gfx::SizeF(5, 6), 7, 8, 9))
+  EXPECT_CALL(mock_synchronous_input_handler,
+              UpdateRootLayerState(gfx::Vector2dF(1, 2), gfx::Vector2dF(3, 4),
+                                   gfx::SizeF(5, 6), 7, 8, 9))
       .Times(1);
   proxy.UpdateRootLayerStateForSynchronousInputHandler(
-      gfx::ScrollOffset(1, 2), gfx::ScrollOffset(3, 4), gfx::SizeF(5, 6), 7, 8,
-      9);
+      gfx::Vector2dF(1, 2), gfx::Vector2dF(3, 4), gfx::SizeF(5, 6), 7, 8, 9);
 
   testing::Mock::VerifyAndClearExpectations(&mock_input_handler);
   testing::Mock::VerifyAndClearExpectations(&mock_client);
@@ -2493,9 +2491,9 @@
 
   proxy.SetSynchronousInputHandler(&mock_synchronous_input_handler);
 
-  EXPECT_CALL(mock_input_handler, SetSynchronousInputHandlerRootScrollOffset(
-                                      gfx::ScrollOffset(5, 6)));
-  proxy.SynchronouslySetRootScrollOffset(gfx::ScrollOffset(5, 6));
+  EXPECT_CALL(mock_input_handler,
+              SetSynchronousInputHandlerRootScrollOffset(gfx::Vector2dF(5, 6)));
+  proxy.SynchronouslySetRootScrollOffset(gfx::Vector2dF(5, 6));
 
   testing::Mock::VerifyAndClearExpectations(&mock_input_handler);
   testing::Mock::VerifyAndClearExpectations(&mock_client);
@@ -2512,7 +2510,7 @@
   // Test mousedown on the scrollbar. Expect to get GSB and GSU.
   cc::InputHandlerPointerResult pointer_down_result;
   pointer_down_result.type = cc::PointerResultType::kScrollbarScroll;
-  pointer_down_result.scroll_offset = gfx::ScrollOffset(0, 1);
+  pointer_down_result.scroll_offset = gfx::Vector2dF(0, 1);
   EXPECT_CALL(mock_input_handler_, HitTest(_))
       .WillOnce(testing::Return(pointer_down_result.type));
   EXPECT_CALL(mock_input_handler_, MouseDown(_, _))
@@ -3839,7 +3837,7 @@
   SetupEvents();
   cc::InputHandlerPointerResult pointer_down_result;
   pointer_down_result.type = cc::PointerResultType::kScrollbarScroll;
-  pointer_down_result.scroll_offset = gfx::ScrollOffset(0, 1);
+  pointer_down_result.scroll_offset = gfx::Vector2dF(0, 1);
   cc::InputHandlerPointerResult pointer_up_result;
   pointer_up_result.type = cc::PointerResultType::kScrollbarScroll;
 
diff --git a/third_party/blink/renderer/platform/widget/input/synchronous_compositor_proxy.cc b/third_party/blink/renderer/platform/widget/input/synchronous_compositor_proxy.cc
index bbca525..09db37f 100644
--- a/third_party/blink/renderer/platform/widget/input/synchronous_compositor_proxy.cc
+++ b/third_party/blink/renderer/platform/widget/input/synchronous_compositor_proxy.cc
@@ -62,8 +62,8 @@
 }
 
 void SynchronousCompositorProxy::UpdateRootLayerState(
-    const gfx::ScrollOffset& total_scroll_offset,
-    const gfx::ScrollOffset& max_scroll_offset,
+    const gfx::Vector2dF& total_scroll_offset,
+    const gfx::Vector2dF& max_scroll_offset,
     const gfx::SizeF& scrollable_size,
     float page_scale_factor,
     float min_page_scale_factor,
@@ -301,7 +301,7 @@
 }
 
 void SynchronousCompositorProxy::SetScroll(
-    const gfx::ScrollOffset& new_total_scroll_offset) {
+    const gfx::Vector2dF& new_total_scroll_offset) {
   if (total_scroll_offset_ == new_total_scroll_offset)
     return;
   total_scroll_offset_ = new_total_scroll_offset;
diff --git a/third_party/blink/renderer/platform/widget/input/synchronous_compositor_proxy.h b/third_party/blink/renderer/platform/widget/input/synchronous_compositor_proxy.h
index ccf8536..2c3580e 100644
--- a/third_party/blink/renderer/platform/widget/input/synchronous_compositor_proxy.h
+++ b/third_party/blink/renderer/platform/widget/input/synchronous_compositor_proxy.h
@@ -19,8 +19,8 @@
 #include "third_party/blink/public/mojom/input/synchronous_compositor.mojom-blink.h"
 #include "third_party/blink/public/platform/input/synchronous_input_handler_proxy.h"
 #include "third_party/blink/renderer/platform/widget/compositing/android_webview/synchronous_layer_tree_frame_sink.h"
-#include "ui/gfx/geometry/scroll_offset.h"
 #include "ui/gfx/geometry/size_f.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 
 namespace power_scheduler {
 class PowerModeVoter;
@@ -53,8 +53,8 @@
           compositor_request);
 
   // blink::SynchronousInputHandler overrides.
-  void UpdateRootLayerState(const gfx::ScrollOffset& total_scroll_offset,
-                            const gfx::ScrollOffset& max_scroll_offset,
+  void UpdateRootLayerState(const gfx::Vector2dF& total_scroll_offset,
+                            const gfx::Vector2dF& max_scroll_offset,
                             const gfx::SizeF& scrollable_size,
                             float page_scale_factor,
                             float min_page_scale_factor,
@@ -91,7 +91,7 @@
   void SetMemoryPolicy(uint32_t bytes_limit) final;
   void ReclaimResources(uint32_t layer_tree_frame_sink_id,
                         Vector<viz::ReturnedResource> resources) final;
-  void SetScroll(const gfx::ScrollOffset& total_scroll_offset) final;
+  void SetScroll(const gfx::Vector2dF& total_scroll_offset) final;
   void BeginFrame(const viz::BeginFrameArgs& args,
                   const WTF::HashMap<uint32_t, viz::FrameTimingDetails>&
                       timing_details) final;
@@ -142,8 +142,8 @@
   uint32_t version_ = 0;
   // |total_scroll_offset_| and |max_scroll_offset_| are in physical pixel when
   // use-zoom-for-dsf is enabled, otherwise in dip.
-  gfx::ScrollOffset total_scroll_offset_;  // Modified by both.
-  gfx::ScrollOffset max_scroll_offset_;
+  gfx::Vector2dF total_scroll_offset_;  // Modified by both.
+  gfx::Vector2dF max_scroll_offset_;
   gfx::SizeF scrollable_size_;
   float page_scale_factor_;
   float min_page_scale_factor_;
diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc
index a1cb8e9..ba2e79b 100644
--- a/ui/compositor/compositor.cc
+++ b/ui/compositor/compositor.cc
@@ -514,13 +514,13 @@
 // scroll_input_handler_ so that we don't have to keep a pointer to the
 // cc::InputHandler in this class.
 bool Compositor::ScrollLayerTo(cc::ElementId element_id,
-                               const gfx::ScrollOffset& offset) {
+                               const gfx::Vector2dF& offset) {
   return input_handler_weak_ &&
          input_handler_weak_->ScrollLayerTo(element_id, offset);
 }
 
 bool Compositor::GetScrollOffsetForLayer(cc::ElementId element_id,
-                                         gfx::ScrollOffset* offset) const {
+                                         gfx::Vector2dF* offset) const {
   return input_handler_weak_ &&
          input_handler_weak_->GetScrollOffsetForLayer(element_id, offset);
 }
diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h
index d484574..57dadd4 100644
--- a/ui/compositor/compositor.h
+++ b/ui/compositor/compositor.h
@@ -67,7 +67,6 @@
 }  // namespace mojom
 struct PresentationFeedback;
 class Rect;
-class ScrollOffset;
 class Size;
 }
 
@@ -256,8 +255,8 @@
   // Gets or sets the scroll offset for the given layer in step with the
   // cc::InputHandler. Returns true if the layer is active on the impl side.
   bool GetScrollOffsetForLayer(cc::ElementId element_id,
-                               gfx::ScrollOffset* offset) const;
-  bool ScrollLayerTo(cc::ElementId element_id, const gfx::ScrollOffset& offset);
+                               gfx::Vector2dF* offset) const;
+  bool ScrollLayerTo(cc::ElementId element_id, const gfx::Vector2dF& offset);
 
   // Mac path for transporting vsync parameters to the display. Other platforms
   // update it via the BrowserCompositorLayerTreeFrameSink directly.
diff --git a/ui/compositor/layer.cc b/ui/compositor/layer.cc
index ee9f8cd..cd0c8ed 100644
--- a/ui/compositor/layer.cc
+++ b/ui/compositor/layer.cc
@@ -1275,8 +1275,8 @@
 }
 
 void Layer::SetDidScrollCallback(
-    base::RepeatingCallback<void(const gfx::ScrollOffset&,
-                                 const cc::ElementId&)> callback) {
+    base::RepeatingCallback<void(const gfx::Vector2dF&, const cc::ElementId&)>
+        callback) {
   cc_layer_->SetDidScrollCallback(std::move(callback));
 }
 
@@ -1285,16 +1285,16 @@
   cc_layer_->SetUserScrollable(true, true);
 }
 
-gfx::ScrollOffset Layer::CurrentScrollOffset() const {
+gfx::Vector2dF Layer::CurrentScrollOffset() const {
   const Compositor* compositor = GetCompositor();
-  gfx::ScrollOffset offset;
+  gfx::Vector2dF offset;
   if (compositor &&
       compositor->GetScrollOffsetForLayer(cc_layer_->element_id(), &offset))
     return offset;
   return cc_layer_->scroll_offset();
 }
 
-void Layer::SetScrollOffset(const gfx::ScrollOffset& offset) {
+void Layer::SetScrollOffset(const gfx::Vector2dF& offset) {
   Compositor* compositor = GetCompositor();
   bool scrolled_on_impl_side =
       compositor && compositor->ScrollLayerTo(cc_layer_->element_id(), offset);
diff --git a/ui/compositor/layer.h b/ui/compositor/layer.h
index 3711fd7..1bcb8a7 100644
--- a/ui/compositor/layer.h
+++ b/ui/compositor/layer.h
@@ -447,8 +447,8 @@
   // Invoked when scrolling performed by the cc::InputHandler is committed. This
   // will only occur if the Layer has set scroll container bounds.
   void SetDidScrollCallback(
-      base::RepeatingCallback<void(const gfx::ScrollOffset&,
-                                   const cc::ElementId&)> callback);
+      base::RepeatingCallback<void(const gfx::Vector2dF&, const cc::ElementId&)>
+          callback);
 
   cc::ElementId element_id() const { return cc_layer_->element_id(); }
 
@@ -458,8 +458,8 @@
   void SetScrollable(const gfx::Size& container_bounds);
 
   // Gets and sets the current scroll offset of the layer.
-  gfx::ScrollOffset CurrentScrollOffset() const;
-  void SetScrollOffset(const gfx::ScrollOffset& offset);
+  gfx::Vector2dF CurrentScrollOffset() const;
+  void SetScrollOffset(const gfx::Vector2dF& offset);
 
   // ContentLayerClient implementation.
   gfx::Rect PaintableRegion() const override;
diff --git a/ui/compositor/overscroll/scroll_input_handler.cc b/ui/compositor/overscroll/scroll_input_handler.cc
index e5acb17..2e0cb1d 100644
--- a/ui/compositor/overscroll/scroll_input_handler.cc
+++ b/ui/compositor/overscroll/scroll_input_handler.cc
@@ -91,8 +91,8 @@
 void ScrollInputHandler::SetPrefersReducedMotion(bool prefers_reduced_motion) {}
 
 void ScrollInputHandler::UpdateRootLayerStateForSynchronousInputHandler(
-    const gfx::ScrollOffset& total_scroll_offset,
-    const gfx::ScrollOffset& max_scroll_offset,
+    const gfx::Vector2dF& total_scroll_offset,
+    const gfx::Vector2dF& max_scroll_offset,
     const gfx::SizeF& scrollable_size,
     float page_scale_factor,
     float min_page_scale_factor,
diff --git a/ui/compositor/overscroll/scroll_input_handler.h b/ui/compositor/overscroll/scroll_input_handler.h
index 8580f90c..cf5fe476 100644
--- a/ui/compositor/overscroll/scroll_input_handler.h
+++ b/ui/compositor/overscroll/scroll_input_handler.h
@@ -35,8 +35,8 @@
   void ReconcileElasticOverscrollAndRootScroll() override;
   void SetPrefersReducedMotion(bool prefers_reduced_motion) override;
   void UpdateRootLayerStateForSynchronousInputHandler(
-      const gfx::ScrollOffset& total_scroll_offset,
-      const gfx::ScrollOffset& max_scroll_offset,
+      const gfx::Vector2dF& total_scroll_offset,
+      const gfx::Vector2dF& max_scroll_offset,
       const gfx::SizeF& scrollable_size,
       float page_scale_factor,
       float min_page_scale_factor,
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn
index e592841..8f669880 100644
--- a/ui/gfx/BUILD.gn
+++ b/ui/gfx/BUILD.gn
@@ -802,7 +802,6 @@
       "geometry/rect_unittest.cc",
       "geometry/resize_utils_unittest.cc",
       "geometry/rounded_corners_f_unittest.cc",
-      "geometry/scroll_offset_unittest.cc",
       "geometry/size_unittest.cc",
       "geometry/vector2d_unittest.cc",
       "geometry/vector3d_unittest.cc",
diff --git a/ui/gfx/geometry/BUILD.gn b/ui/gfx/geometry/BUILD.gn
index 3f83f70..c277b335 100644
--- a/ui/gfx/geometry/BUILD.gn
+++ b/ui/gfx/geometry/BUILD.gn
@@ -45,8 +45,6 @@
     "resize_utils.h",
     "rounded_corners_f.cc",
     "rounded_corners_f.h",
-    "scroll_offset.cc",
-    "scroll_offset.h",
     "size.cc",
     "size.h",
     "size_conversions.cc",
diff --git a/ui/gfx/geometry/mojom/BUILD.gn b/ui/gfx/geometry/mojom/BUILD.gn
index 787c0aac..a5f18d7 100644
--- a/ui/gfx/geometry/mojom/BUILD.gn
+++ b/ui/gfx/geometry/mojom/BUILD.gn
@@ -66,10 +66,6 @@
         mojom = "gfx.mojom.Vector3dF"
         cpp = "::gfx::Vector3dF"
       },
-      {
-        mojom = "gfx.mojom.ScrollOffset"
-        cpp = "::gfx::ScrollOffset"
-      },
     ]
 
     traits_headers = [ "geometry_mojom_traits.h" ]
diff --git a/ui/gfx/geometry/mojom/geometry.mojom b/ui/gfx/geometry/mojom/geometry.mojom
index fad2a87..30be3e6 100644
--- a/ui/gfx/geometry/mojom/geometry.mojom
+++ b/ui/gfx/geometry/mojom/geometry.mojom
@@ -80,11 +80,6 @@
   float z;
 };
 
-struct ScrollOffset {
-  float x;
-  float y;
-};
-
 struct Quaternion {
   double x;
   double y;
diff --git a/ui/gfx/geometry/mojom/geometry_mojom_traits.h b/ui/gfx/geometry/mojom/geometry_mojom_traits.h
index 758dcdd..aa48273 100644
--- a/ui/gfx/geometry/mojom/geometry_mojom_traits.h
+++ b/ui/gfx/geometry/mojom/geometry_mojom_traits.h
@@ -14,7 +14,6 @@
 #include "ui/gfx/geometry/quaternion.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/rect_f.h"
-#include "ui/gfx/geometry/scroll_offset.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/geometry/size_f.h"
 #include "ui/gfx/geometry/vector2d.h"
@@ -170,18 +169,6 @@
 };
 
 template <>
-struct StructTraits<gfx::mojom::ScrollOffsetDataView, gfx::ScrollOffset> {
-  static float x(const gfx::ScrollOffset& v) { return v.x(); }
-  static float y(const gfx::ScrollOffset& v) { return v.y(); }
-  static bool Read(gfx::mojom::ScrollOffsetDataView data,
-                   gfx::ScrollOffset* out) {
-    out->set_x(data.x());
-    out->set_y(data.y());
-    return true;
-  }
-};
-
-template <>
 struct StructTraits<gfx::mojom::QuaternionDataView, gfx::Quaternion> {
   static double x(const gfx::Quaternion& q) { return q.x(); }
   static double y(const gfx::Quaternion& q) { return q.y(); }
diff --git a/ui/gfx/geometry/scroll_offset.cc b/ui/gfx/geometry/scroll_offset.cc
deleted file mode 100644
index 063b050..0000000
--- a/ui/gfx/geometry/scroll_offset.cc
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/gfx/geometry/scroll_offset.h"
-
-#include "base/strings/stringprintf.h"
-
-namespace gfx {
-
-std::string ScrollOffset::ToString() const {
-  return base::StringPrintf("[%f %f]", x_, y_);
-}
-
-}  // namespace gfx
diff --git a/ui/gfx/geometry/scroll_offset.h b/ui/gfx/geometry/scroll_offset.h
deleted file mode 100644
index a0e7e8e..0000000
--- a/ui/gfx/geometry/scroll_offset.h
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef UI_GFX_GEOMETRY_SCROLL_OFFSET_H_
-#define UI_GFX_GEOMETRY_SCROLL_OFFSET_H_
-
-#include <iosfwd>
-#include <string>
-
-#include "base/numerics/safe_conversions.h"
-#include "ui/gfx/geometry/geometry_export.h"
-#include "ui/gfx/geometry/vector2d.h"
-
-namespace gfx {
-
-// TODO(szager): Reconcile terminology with blink.  An 'offset' here corresponds
-// to a 'position' in blink.  In blink, 'offset' means something else.  See
-// third_party/WebKit/Source/core/layout/README.md for more information.
-
-class GEOMETRY_EXPORT ScrollOffset {
- public:
-  constexpr ScrollOffset() : x_(0), y_(0) {}
-  constexpr ScrollOffset(float x, float y) : x_(x), y_(y) {}
-  explicit ScrollOffset(const Vector2dF& v) : x_(v.x()), y_(v.y()) {}
-  explicit ScrollOffset(const Vector2d& v) : x_(v.x()), y_(v.y()) {}
-
-  float x() const { return x_; }
-  void set_x(float x) { x_ = x; }
-
-  float y() const { return y_; }
-  void set_y(float y) { y_ = y; }
-
-  // True if both components are 0.
-  bool IsZero() const {
-    return x_ == 0 && y_ == 0;
-  }
-
-  // Add the components of the |other| ScrollOffset to the current ScrollOffset.
-  void Add(const ScrollOffset& other) {
-    x_ += other.x_;
-    y_ += other.y_;
-  }
-
-  // Subtract the components of the |other| ScrollOffset from the current
-  // ScrollOffset.
-  void Subtract(const ScrollOffset& other) {
-    x_ -= other.x_;
-    y_ -= other.y_;
-  }
-
-  Vector2dF DeltaFrom(const ScrollOffset& v) const {
-    return Vector2dF(x_ - v.x(), y_ - v.y());
-  }
-
-  void operator+=(const ScrollOffset& other) { Add(other); }
-  void operator-=(const ScrollOffset& other) { Subtract(other); }
-
-  void SetToMin(const ScrollOffset& other) {
-    x_ = x_ <= other.x_ ? x_ : other.x_;
-    y_ = y_ <= other.y_ ? y_ : other.y_;
-  }
-
-  void SetToMax(const ScrollOffset& other) {
-    x_ = x_ >= other.x_ ? x_ : other.x_;
-    y_ = y_ >= other.y_ ? y_ : other.y_;
-  }
-
-  void Scale(float scale) { Scale(scale, scale); }
-  void Scale(float x_scale, float y_scale) {
-    x_ *= x_scale;
-    y_ *= y_scale;
-  }
-
-  std::string ToString() const;
-
- private:
-  float x_;
-  float y_;
-};
-
-inline bool operator==(const ScrollOffset& lhs, const ScrollOffset& rhs) {
-  return lhs.x() == rhs.x() && lhs.y() == rhs.y();
-}
-
-inline bool operator!=(const ScrollOffset& lhs, const ScrollOffset& rhs) {
-  return lhs.x() != rhs.x() || lhs.y() != rhs.y();
-}
-
-inline ScrollOffset operator-(const ScrollOffset& v) {
-  return ScrollOffset(-v.x(), -v.y());
-}
-
-inline ScrollOffset operator+(const ScrollOffset& lhs,
-                              const ScrollOffset& rhs) {
-  ScrollOffset result = lhs;
-  result.Add(rhs);
-  return result;
-}
-
-inline ScrollOffset operator-(const ScrollOffset& lhs,
-                              const ScrollOffset& rhs) {
-  ScrollOffset result = lhs;
-  result.Add(-rhs);
-  return result;
-}
-
-inline Vector2d ScrollOffsetToFlooredVector2d(const ScrollOffset& v) {
-  return Vector2d(base::ClampFloor(v.x()), base::ClampFloor(v.y()));
-}
-
-inline Vector2dF ScrollOffsetToVector2dF(const ScrollOffset& v) {
-  return Vector2dF(v.x(), v.y());
-}
-
-inline ScrollOffset ScrollOffsetWithDelta(const ScrollOffset& offset,
-                                          const Vector2dF& delta) {
-  return ScrollOffset(offset.x() + delta.x(),
-                      offset.y() + delta.y());
-}
-
-// This is declared here for use in gtest-based unit tests but is defined in
-// the //ui/gfx:test_support target. Depend on that to use this in your unit
-// test. This should not be used in production code - call ToString() instead.
-void PrintTo(const ScrollOffset& scroll_offset, ::std::ostream* os);
-
-}  // namespace gfx
-
-#endif  // UI_GFX_GEOMETRY_SCROLL_OFFSET_H_
diff --git a/ui/gfx/geometry/scroll_offset_unittest.cc b/ui/gfx/geometry/scroll_offset_unittest.cc
deleted file mode 100644
index 1aca07f..0000000
--- a/ui/gfx/geometry/scroll_offset_unittest.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <stddef.h>
-
-#include <cmath>
-#include <limits>
-
-#include "base/cxx17_backports.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/geometry/scroll_offset.h"
-
-namespace gfx {
-
-TEST(ScrollOffsetTest, IsZero) {
-  ScrollOffset zero(0, 0);
-  ScrollOffset nonzero(0.1f, -0.1f);
-
-  EXPECT_TRUE(zero.IsZero());
-  EXPECT_FALSE(nonzero.IsZero());
-}
-
-TEST(ScrollOffsetTest, Add) {
-  ScrollOffset f1(3.1f, 5.1f);
-  ScrollOffset f2(4.3f, -1.3f);
-
-  const struct {
-    ScrollOffset expected;
-    ScrollOffset actual;
-  } scroll_offset_tests[] = {
-    { ScrollOffset(3.1f, 5.1f), f1 + ScrollOffset() },
-    { ScrollOffset(3.1f + 4.3f, 5.1f - 1.3f), f1 + f2 },
-    { ScrollOffset(3.1f - 4.3f, 5.1f + 1.3f), f1 - f2 }
-  };
-
-  for (size_t i = 0; i < base::size(scroll_offset_tests); ++i)
-    EXPECT_EQ(scroll_offset_tests[i].expected.ToString(),
-              scroll_offset_tests[i].actual.ToString());
-}
-
-TEST(ScrollOffsetTest, Negative) {
-  const struct {
-    ScrollOffset expected;
-    ScrollOffset actual;
-  } scroll_offset_tests[] = {
-    { ScrollOffset(-0.3f, -0.3f), -ScrollOffset(0.3f, 0.3f) },
-    { ScrollOffset(0.3f, 0.3f), -ScrollOffset(-0.3f, -0.3f) },
-    { ScrollOffset(-0.3f, 0.3f), -ScrollOffset(0.3f, -0.3f) },
-    { ScrollOffset(0.3f, -0.3f), -ScrollOffset(-0.3f, 0.3f) }
-  };
-
-  for (size_t i = 0; i < base::size(scroll_offset_tests); ++i)
-    EXPECT_EQ(scroll_offset_tests[i].expected.ToString(),
-              scroll_offset_tests[i].actual.ToString());
-}
-
-TEST(ScrollOffsetTest, Scale) {
-  float float_values[][4] = {
-    { 4.5f, 1.2f, 3.3f, 5.6f },
-    { 4.5f, -1.2f, 3.3f, 5.6f },
-    { 4.5f, 1.2f, 3.3f, -5.6f },
-    { 4.5f, 1.2f, -3.3f, -5.6f },
-    { -4.5f, 1.2f, 3.3f, 5.6f },
-    { -4.5f, 1.2f, 0, 5.6f },
-    { -4.5f, 1.2f, 3.3f, 0 },
-    { 4.5f, 0, 3.3f, 5.6f },
-    { 0, 1.2f, 3.3f, 5.6f }
-  };
-
-  for (size_t i = 0; i < base::size(float_values); ++i) {
-    ScrollOffset v(float_values[i][0], float_values[i][1]);
-    v.Scale(float_values[i][2], float_values[i][3]);
-    EXPECT_EQ(v.x(), float_values[i][0] * float_values[i][2]);
-    EXPECT_EQ(v.y(), float_values[i][1] * float_values[i][3]);
-  }
-
-  float single_values[][3] = {
-    { 4.5f, 1.2f, 3.3f },
-    { 4.5f, -1.2f, 3.3f },
-    { 4.5f, 1.2f, 3.3f },
-    { 4.5f, 1.2f, -3.3f },
-    { -4.5f, 1.2f, 3.3f },
-    { -4.5f, 1.2f, 0 },
-    { -4.5f, 1.2f, 3.3f },
-    { 4.5f, 0, 3.3f },
-    { 0, 1.2f, 3.3f }
-  };
-
-  for (size_t i = 0; i < base::size(single_values); ++i) {
-    ScrollOffset v(single_values[i][0], single_values[i][1]);
-    v.Scale(single_values[i][2]);
-    EXPECT_EQ(v.x(), single_values[i][0] * single_values[i][2]);
-    EXPECT_EQ(v.y(), single_values[i][1] * single_values[i][2]);
-  }
-}
-
-TEST(ScrollOffsetTest, ClampScrollOffset) {
-  ScrollOffset a;
-
-  a = ScrollOffset(3.5, 5.5);
-  EXPECT_EQ(ScrollOffset(3.5, 5.5).ToString(), a.ToString());
-  a.SetToMax(ScrollOffset(2.5, 4.5));
-  EXPECT_EQ(ScrollOffset(3.5, 5.5).ToString(), a.ToString());
-  a.SetToMax(ScrollOffset(3.5, 5.5));
-  EXPECT_EQ(ScrollOffset(3.5, 5.5).ToString(), a.ToString());
-  a.SetToMax(ScrollOffset(4.5, 2.5));
-  EXPECT_EQ(ScrollOffset(4.5, 5.5).ToString(), a.ToString());
-  a.SetToMax(ScrollOffset(8.5, 10.5));
-  EXPECT_EQ(ScrollOffset(8.5, 10.5).ToString(), a.ToString());
-
-  a.SetToMin(ScrollOffset(9.5, 11.5));
-  EXPECT_EQ(ScrollOffset(8.5, 10.5).ToString(), a.ToString());
-  a.SetToMin(ScrollOffset(8.5, 10.5));
-  EXPECT_EQ(ScrollOffset(8.5, 10.5).ToString(), a.ToString());
-  a.SetToMin(ScrollOffset(11.5, 9.5));
-  EXPECT_EQ(ScrollOffset(8.5, 9.5).ToString(), a.ToString());
-  a.SetToMin(ScrollOffset(7.5, 11.5));
-  EXPECT_EQ(ScrollOffset(7.5, 9.5).ToString(), a.ToString());
-  a.SetToMin(ScrollOffset(3.5, 5.5));
-  EXPECT_EQ(ScrollOffset(3.5, 5.5).ToString(), a.ToString());
-}
-
-}  // namespace gfx
diff --git a/ui/gfx/ipc/geometry/gfx_param_traits.cc b/ui/gfx/ipc/geometry/gfx_param_traits.cc
index 6672a57..20bc088 100644
--- a/ui/gfx/ipc/geometry/gfx_param_traits.cc
+++ b/ui/gfx/ipc/geometry/gfx_param_traits.cc
@@ -13,7 +13,7 @@
 #include "ui/gfx/geometry/point3_f.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/rect_f.h"
-#include "ui/gfx/geometry/scroll_offset.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 
 namespace IPC {
 
@@ -214,32 +214,4 @@
                                p.height()));
 }
 
-void ParamTraits<gfx::ScrollOffset>::Write(base::Pickle* m,
-                                           const param_type& p) {
-  m->WriteDouble(p.x());
-  m->WriteDouble(p.y());
-}
-
-bool ParamTraits<gfx::ScrollOffset>::Read(const base::Pickle* m,
-                                          base::PickleIterator* iter,
-                                          param_type* r) {
-  double x = 0.f;
-  double y = 0.f;
-  if (!iter->ReadDouble(&x))
-    return false;
-  if (!iter->ReadDouble(&y))
-    return false;
-  r->set_x(x);
-  r->set_y(y);
-  return true;
-}
-
-void ParamTraits<gfx::ScrollOffset>::Log(const param_type& p, std::string* l) {
-  l->append("(");
-  LogParam(p.x(), l);
-  l->append(", ");
-  LogParam(p.y(), l);
-  l->append(")");
-}
-
 }  // namespace IPC
diff --git a/ui/gfx/ipc/geometry/gfx_param_traits.h b/ui/gfx/ipc/geometry/gfx_param_traits.h
index b29aed5..3020a097 100644
--- a/ui/gfx/ipc/geometry/gfx_param_traits.h
+++ b/ui/gfx/ipc/geometry/gfx_param_traits.h
@@ -17,7 +17,6 @@
 class Point3F;
 class Rect;
 class RectF;
-class ScrollOffset;
 class Size;
 class SizeF;
 class Vector2d;
@@ -116,16 +115,6 @@
   static void Log(const param_type& p, std::string* l);
 };
 
-template <>
-struct GFX_IPC_GEOMETRY_EXPORT ParamTraits<gfx::ScrollOffset> {
-  typedef gfx::ScrollOffset param_type;
-  static void Write(base::Pickle* m, const param_type& p);
-  static bool Read(const base::Pickle* m,
-                   base::PickleIterator* iter,
-                   param_type* r);
-  static void Log(const param_type& p, std::string* l);
-};
-
 }  // namespace IPC
 
 #endif  // UI_GFX_IPC_GEOMETRY_GFX_PARAM_TRAITS_H_
diff --git a/ui/gfx/test/gfx_util.cc b/ui/gfx/test/gfx_util.cc
index 17e6869f..56fa73a 100644
--- a/ui/gfx/test/gfx_util.cc
+++ b/ui/gfx/test/gfx_util.cc
@@ -18,7 +18,6 @@
 #include "ui/gfx/geometry/quad_f.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/rect_f.h"
-#include "ui/gfx/geometry/scroll_offset.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/geometry/size_f.h"
 #include "ui/gfx/geometry/vector2d.h"
@@ -176,10 +175,6 @@
   *os << rect.ToString();
 }
 
-void PrintTo(const ScrollOffset& offset, ::std::ostream* os) {
-  *os << offset.ToString();
-}
-
 void PrintTo(const Size& size, ::std::ostream* os) {
   *os << size.ToString();
 }
diff --git a/ui/views/controls/scroll_view.cc b/ui/views/controls/scroll_view.cc
index 51da1f7..99c1e91 100644
--- a/ui/views/controls/scroll_view.cc
+++ b/ui/views/controls/scroll_view.cc
@@ -102,15 +102,15 @@
     DCHECK_EQ(0, view->x());
     DCHECK_EQ(0, view->y());
   }
-  gfx::ScrollOffset offset = scrolls_with_layers
-                                 ? view->layer()->CurrentScrollOffset()
-                                 : gfx::ScrollOffset(-view->x(), -view->y());
+  gfx::Vector2dF offset = scrolls_with_layers
+                              ? view->layer()->CurrentScrollOffset()
+                              : gfx::Vector2dF(-view->x(), -view->y());
 
   int x = CheckScrollBounds(viewport->width(), view->width(), offset.x());
   int y = CheckScrollBounds(viewport->height(), view->height(), offset.y());
 
   if (scrolls_with_layers) {
-    view->layer()->SetScrollOffset(gfx::ScrollOffset(x, y));
+    view->layer()->SetScrollOffset(gfx::Vector2dF(x, y));
   } else {
     // This is no op if bounds are the same
     view->SetBounds(-x, -y, view->width(), view->height());
@@ -323,7 +323,7 @@
 gfx::Rect ScrollView::GetVisibleRect() const {
   if (!contents_)
     return gfx::Rect();
-  gfx::ScrollOffset offset = CurrentOffset();
+  gfx::Vector2dF offset = CurrentOffset();
   return gfx::Rect(offset.x(), offset.y(), contents_viewport_->width(),
                    contents_viewport_->height());
 }
@@ -652,8 +652,8 @@
     // Flip the viewport with layer transforms under RTL. Note the net effect is
     // to flip twice, so the text is not mirrored. This is necessary because
     // compositor scrolling is not RTL-aware. So although a toolkit-views layout
-    // will flip, increasing a horizontal gfx::ScrollOffset will move content to
-    // the left, regardless of RTL. A gfx::ScrollOffset must be positive, so to
+    // will flip, increasing a horizontal gfx::Vector2dF will move content to
+    // the left, regardless of RTL. A gfx::Vector2dF must be positive, so to
     // move (unscrolled) content to the right, we need to flip the viewport
     // layer. That would flip all the content as well, so flip (and translate)
     // the content layer. Compensating in this way allows the scrolling/offset
@@ -835,8 +835,8 @@
     case ax::mojom::Action::kScrollDown:
       return vert_sb_->ScrollByAmount(ScrollBar::ScrollAmount::kNextPage);
     case ax::mojom::Action::kSetScrollOffset:
-      ScrollToOffset(gfx::ScrollOffset(action_data.target_point.x(),
-                                       action_data.target_point.y()));
+      ScrollToOffset(gfx::Vector2dF(action_data.target_point.x(),
+                                    action_data.target_point.y()));
       return true;
     default:
       return View::HandleAccessibleAction(action_data);
@@ -847,7 +847,7 @@
   if (!contents_)
     return;
 
-  gfx::ScrollOffset offset = CurrentOffset();
+  gfx::Vector2dF offset = CurrentOffset();
   if (source == horiz_sb_ && IsHorizontalScrollEnabled()) {
     position = AdjustPosition(offset.x(), position, contents_->width(),
                               contents_viewport_->width());
@@ -957,7 +957,7 @@
                         ? y
                         : std::max(0, max_y - contents_viewport_->height());
 
-  ScrollToOffset(gfx::ScrollOffset(new_x, new_y));
+  ScrollToOffset(gfx::Vector2dF(new_x, new_y));
 }
 
 void ScrollView::ComputeScrollBarsVisibility(const gfx::Size& vp_size,
@@ -1019,7 +1019,7 @@
   if (!contents_)
     return;
 
-  const gfx::ScrollOffset offset = CurrentOffset();
+  const gfx::Vector2dF offset = CurrentOffset();
   if (IsHorizontalScrollEnabled()) {
     int vw = contents_viewport_->width();
     int cw = contents_->width();
@@ -1032,13 +1032,12 @@
   }
 }
 
-gfx::ScrollOffset ScrollView::CurrentOffset() const {
-  return ScrollsWithLayers()
-             ? contents_->layer()->CurrentScrollOffset()
-             : gfx::ScrollOffset(-contents_->x(), -contents_->y());
+gfx::Vector2dF ScrollView::CurrentOffset() const {
+  return ScrollsWithLayers() ? contents_->layer()->CurrentScrollOffset()
+                             : gfx::Vector2dF(-contents_->x(), -contents_->y());
 }
 
-void ScrollView::ScrollToOffset(const gfx::ScrollOffset& offset) {
+void ScrollView::ScrollToOffset(const gfx::Vector2dF& offset) {
   if (ScrollsWithLayers()) {
     contents_->layer()->SetScrollOffset(offset);
   } else {
@@ -1080,12 +1079,12 @@
   UpdateBackground();
 }
 
-void ScrollView::OnLayerScrolled(const gfx::ScrollOffset& current_offset,
+void ScrollView::OnLayerScrolled(const gfx::Vector2dF& current_offset,
                                  const cc::ElementId&) {
   OnScrolled(current_offset);
 }
 
-void ScrollView::OnScrolled(const gfx::ScrollOffset& offset) {
+void ScrollView::OnScrolled(const gfx::Vector2dF& offset) {
   UpdateOverflowIndicatorVisibility(offset);
   UpdateScrollBarPositions();
   ScrollHeader();
@@ -1183,7 +1182,7 @@
 }
 
 void ScrollView::UpdateOverflowIndicatorVisibility(
-    const gfx::ScrollOffset& offset) {
+    const gfx::Vector2dF& offset) {
   SetControlVisibility(more_content_top_.get(),
                        !draw_border_ && !header_ && IsVerticalScrollEnabled() &&
                            offset.y() > vert_sb_->GetMinPosition() &&
diff --git a/ui/views/controls/scroll_view.h b/ui/views/controls/scroll_view.h
index 9bb7567..541ad6dc 100644
--- a/ui/views/controls/scroll_view.h
+++ b/ui/views/controls/scroll_view.h
@@ -23,7 +23,7 @@
 }
 
 namespace gfx {
-class ScrollOffset;
+class Vector2dF;
 }
 
 namespace views {
@@ -285,17 +285,17 @@
 
   // Helpers to get and set the current scroll offset (either from the ui::Layer
   // or from the |contents_| origin offset).
-  gfx::ScrollOffset CurrentOffset() const;
-  void ScrollToOffset(const gfx::ScrollOffset& offset);
+  gfx::Vector2dF CurrentOffset() const;
+  void ScrollToOffset(const gfx::Vector2dF& offset);
 
   // Whether the ScrollView scrolls using ui::Layer APIs.
   bool ScrollsWithLayers() const;
 
   // Callback entrypoint when hosted Layers are scrolled by the Compositor.
-  void OnLayerScrolled(const gfx::ScrollOffset&, const cc::ElementId&);
+  void OnLayerScrolled(const gfx::Vector2dF&, const cc::ElementId&);
 
   // Updates accessory elements when |contents_| is scrolled.
-  void OnScrolled(const gfx::ScrollOffset& offset);
+  void OnScrolled(const gfx::Vector2dF& offset);
 
   // Horizontally scrolls the header (if any) to match the contents.
   void ScrollHeader();
@@ -310,7 +310,7 @@
 
   // Shows/hides the overflow indicators depending on the position of the
   // scrolling content within the viewport.
-  void UpdateOverflowIndicatorVisibility(const gfx::ScrollOffset& offset);
+  void UpdateOverflowIndicatorVisibility(const gfx::Vector2dF& offset);
 
   // The current contents and its viewport. |contents_| is contained in
   // |contents_viewport_|.
diff --git a/ui/views/controls/scroll_view_unittest.cc b/ui/views/controls/scroll_view_unittest.cc
index 84c6d50..c9886fa 100644
--- a/ui/views/controls/scroll_view_unittest.cc
+++ b/ui/views/controls/scroll_view_unittest.cc
@@ -26,7 +26,7 @@
 #include "ui/events/keycodes/keyboard_codes.h"
 #include "ui/events/test/event_generator.h"
 #include "ui/events/types/event_type.h"
-#include "ui/gfx/geometry/scroll_offset.h"
+#include "ui/gfx/geometry/vector2d_f.h"
 #include "ui/views/border.h"
 #include "ui/views/controls/scrollbar/base_scroll_bar_thumb.h"
 #include "ui/views/controls/scrollbar/overlay_scroll_bar.h"
@@ -71,12 +71,10 @@
   }
 
   gfx::Point IntegralViewOffset() {
-    return gfx::Point() - gfx::ScrollOffsetToFlooredVector2d(CurrentOffset());
+    return gfx::Point() - gfx::ToFlooredVector2d(CurrentOffset());
   }
 
-  gfx::ScrollOffset CurrentOffset() const {
-    return scroll_view_->CurrentOffset();
-  }
+  gfx::Vector2dF CurrentOffset() const { return scroll_view_->CurrentOffset(); }
 
   base::RetainingOneShotTimer* GetScrollBarHideTimer(
       ScrollBarOrientation orientation) {
@@ -894,7 +892,7 @@
   // Expect there to be a horizontal scrollbar, making the viewport shorter.
   EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutHeight(), viewport_height);
 
-  gfx::ScrollOffset offset = test_api.CurrentOffset();
+  gfx::Vector2dF offset = test_api.CurrentOffset();
   EXPECT_EQ(415 - viewport_height, offset.y());
 
   // Scroll to the current y-location and 10x10; should do nothing.
@@ -924,7 +922,7 @@
   // Expect there to be a vertical scrollbar, making the viewport shorter.
   EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutWidth(), viewport_width);
 
-  gfx::ScrollOffset offset = test_api.CurrentOffset();
+  gfx::Vector2dF offset = test_api.CurrentOffset();
   EXPECT_EQ(315 - viewport_width, offset.x());
 
   // Scroll to the current x-location and 10x10; should do nothing.
@@ -954,7 +952,7 @@
   // Expect there to be a vertical scrollbar, making the viewport shorter.
   EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutHeight(), viewport_height);
 
-  gfx::ScrollOffset offset = test_api.CurrentOffset();
+  gfx::Vector2dF offset = test_api.CurrentOffset();
   EXPECT_EQ(315 - viewport_height, offset.y());
 
   // Scroll to the current x-location and 10x10; should do nothing.
@@ -986,7 +984,7 @@
   // Expect there to be a horizontal scrollbar, making the viewport shorter.
   EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutHeight(), viewport_height);
 
-  gfx::ScrollOffset offset = test_api.CurrentOffset();
+  gfx::Vector2dF offset = test_api.CurrentOffset();
   EXPECT_EQ(415 - viewport_height, offset.y());
 }
 
@@ -1022,9 +1020,9 @@
   inner_contents_ptr->ScrollRectToVisible(gfx::Rect(0, 405, 10, 10));
   const int inner_viewport_height =
       inner_test_api.contents_viewport()->height();
-  gfx::ScrollOffset inner_offset = inner_test_api.CurrentOffset();
+  gfx::Vector2dF inner_offset = inner_test_api.CurrentOffset();
   EXPECT_EQ(415 - inner_viewport_height, inner_offset.y());
-  gfx::ScrollOffset outer_offset = outer_test_api.CurrentOffset();
+  gfx::Vector2dF outer_offset = outer_test_api.CurrentOffset();
   EXPECT_EQ(0, outer_offset.y());
 
   // Set focus to the inner scroll view's contents root. This should cause the
@@ -1388,7 +1386,7 @@
   EXPECT_TRUE(hide_timer[VERTICAL]->IsRunning());
 
   // Scrolling should have occurred.
-  EXPECT_EQ(gfx::ScrollOffset(0, y_offset), test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(0, y_offset), test_api.CurrentOffset());
 
   // Then, scrolling horizontally should show the horizontal scroller. The
   // vertical scroller should still be visible, running its hide timer.
@@ -1403,7 +1401,7 @@
   }
 
   // Now scrolling has occurred in both directions.
-  EXPECT_EQ(gfx::ScrollOffset(x_offset, y_offset), test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(x_offset, y_offset), test_api.CurrentOffset());
 }
 
 #endif  // OS_MAC
@@ -1417,12 +1415,12 @@
   contents->SetBoundsRect(gfx::Rect(0, 0, 300, 300));
   scroll_view_->Layout();
 
-  EXPECT_EQ(gfx::ScrollOffset(), test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(), test_api.CurrentOffset());
 
   // Scroll as far as it goes and query location to discount scroll bars.
   contents->ScrollRectToVisible(gfx::Rect(300, 300, 1, 1));
-  const gfx::ScrollOffset fully_scrolled = test_api.CurrentOffset();
-  EXPECT_NE(gfx::ScrollOffset(), fully_scrolled);
+  const gfx::Vector2dF fully_scrolled = test_api.CurrentOffset();
+  EXPECT_NE(gfx::Vector2dF(), fully_scrolled);
 
   // Making the viewport 55 pixels taller should scroll up the same amount.
   scroll_view_->SetBoundsRect(gfx::Rect(0, 0, 100, 155));
@@ -1532,7 +1530,7 @@
       kWidth + test_api.GetScrollBar(VERTICAL)->GetThickness(), kMaxHeight));
 
   // Make sure the initial origin is 0,0
-  EXPECT_EQ(gfx::ScrollOffset(0, 0), test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(0, 0), test_api.CurrentOffset());
 
   // The vertical scroll bar should be visible and the horizontal scroll bar
   // should not.
@@ -1552,7 +1550,7 @@
   // Now scroll the view to someplace in the middle of the scrollable region.
   int offset = kMaxHeight * 2;
   scroll_view_->ScrollToPosition(test_api.GetScrollBar(VERTICAL), offset);
-  EXPECT_EQ(gfx::ScrollOffset(0, offset), test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(0, offset), test_api.CurrentOffset());
 
   // At this point, both overflow indicators on the top and bottom should be
   // visible.
@@ -1566,7 +1564,7 @@
   // Finally scroll the view to end of the scrollable region.
   offset = kMaxHeight * 4;
   scroll_view_->ScrollToPosition(test_api.GetScrollBar(VERTICAL), offset);
-  EXPECT_EQ(gfx::ScrollOffset(0, offset), test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(0, offset), test_api.CurrentOffset());
 
   // The overflow indicator on the bottom should not be visible.
   EXPECT_FALSE(test_api.more_content_bottom()->GetVisible());
@@ -1595,7 +1593,7 @@
   contents->SetBounds(0, 0, kWidth * 5, kHeight);
 
   // Make sure the initial origin is 0,0
-  EXPECT_EQ(gfx::ScrollOffset(0, 0), test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(0, 0), test_api.CurrentOffset());
 
   // The horizontal scroll bar should be visible and the vertical scroll bar
   // should not.
@@ -1615,7 +1613,7 @@
   // Now scroll the view to someplace in the middle of the scrollable region.
   int offset = kWidth * 2;
   scroll_view_->ScrollToPosition(test_api.GetScrollBar(HORIZONTAL), offset);
-  EXPECT_EQ(gfx::ScrollOffset(offset, 0), test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(offset, 0), test_api.CurrentOffset());
 
   // At this point, both overflow indicators on the left and right should be
   // visible.
@@ -1629,7 +1627,7 @@
   // Finally scroll the view to end of the scrollable region.
   offset = kWidth * 4;
   scroll_view_->ScrollToPosition(test_api.GetScrollBar(HORIZONTAL), offset);
-  EXPECT_EQ(gfx::ScrollOffset(offset, 0), test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(offset, 0), test_api.CurrentOffset());
 
   // The overflow indicator on the right should not be visible.
   EXPECT_FALSE(test_api.more_content_right()->GetVisible());
@@ -1656,7 +1654,7 @@
   scroll_view_->SetSize(gfx::Size(kWidth, kHeight));
 
   // Make sure the initial origin is 0,0
-  EXPECT_EQ(gfx::ScrollOffset(0, 0), test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(0, 0), test_api.CurrentOffset());
 
   // The horizontal and vertical scroll bars should be visible.
   CheckScrollbarVisibility(scroll_view_.get(), HORIZONTAL, true);
@@ -1675,7 +1673,7 @@
   // region.
   int offset_x = kWidth * 2;
   scroll_view_->ScrollToPosition(test_api.GetScrollBar(HORIZONTAL), offset_x);
-  EXPECT_EQ(gfx::ScrollOffset(offset_x, 0), test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(offset_x, 0), test_api.CurrentOffset());
 
   // Since there is a vertical scrollbar only the overflow indicator on the left
   // should be visible and the one on the right should still not be visible.
@@ -1689,7 +1687,7 @@
   // Next, scroll the view to end of the scrollable region.
   offset_x = kWidth * 4;
   scroll_view_->ScrollToPosition(test_api.GetScrollBar(HORIZONTAL), offset_x);
-  EXPECT_EQ(gfx::ScrollOffset(offset_x, 0), test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(offset_x, 0), test_api.CurrentOffset());
 
   // The overflow indicator on the right should still not be visible.
   EXPECT_FALSE(test_api.more_content_right()->GetVisible());
@@ -1705,7 +1703,7 @@
 
   // Return the view back to the horizontal origin.
   scroll_view_->ScrollToPosition(test_api.GetScrollBar(HORIZONTAL), 0);
-  EXPECT_EQ(gfx::ScrollOffset(0, 0), test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(0, 0), test_api.CurrentOffset());
 
   // The overflow indicators on the right and bottom should not be visible since
   // they are against the scrollbars.
@@ -1721,7 +1719,7 @@
   // region.
   int offset_y = kHeight * 2;
   scroll_view_->ScrollToPosition(test_api.GetScrollBar(VERTICAL), offset_y);
-  EXPECT_EQ(gfx::ScrollOffset(0, offset_y), test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(0, offset_y), test_api.CurrentOffset());
 
   // Similar to the above, since there is a horizontal scrollbar only the
   // overflow indicator on the top should be visible and the one on the bottom
@@ -1736,7 +1734,7 @@
   // Finally, for the vertical test scroll the region all the way to the end.
   offset_y = kHeight * 4;
   scroll_view_->ScrollToPosition(test_api.GetScrollBar(VERTICAL), offset_y);
-  EXPECT_EQ(gfx::ScrollOffset(0, offset_y), test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(0, offset_y), test_api.CurrentOffset());
 
   // The overflow indicator on the bottom should still not be visible.
   EXPECT_FALSE(test_api.more_content_bottom()->GetVisible());
@@ -1754,7 +1752,7 @@
   // direction.
   offset_x = kWidth * 4;
   scroll_view_->ScrollToPosition(test_api.GetScrollBar(HORIZONTAL), offset_x);
-  EXPECT_EQ(gfx::ScrollOffset(offset_x, offset_y), test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(offset_x, offset_y), test_api.CurrentOffset());
 
   // The overflow indicator on the bottom and right should still not be visible.
   EXPECT_FALSE(test_api.more_content_bottom()->GetVisible());
@@ -1783,7 +1781,7 @@
                 kMaxHeight + header_ptr->height()));
 
   // Make sure the initial origin is 0,0
-  EXPECT_EQ(gfx::ScrollOffset(0, 0), test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(0, 0), test_api.CurrentOffset());
 
   // The vertical scroll bar should be visible and the horizontal scroll bar
   // should not.
@@ -1803,7 +1801,7 @@
   // Now scroll the view to someplace in the middle of the scrollable region.
   int offset = kMaxHeight * 2;
   scroll_view_->ScrollToPosition(test_api.GetScrollBar(VERTICAL), offset);
-  EXPECT_EQ(gfx::ScrollOffset(0, offset), test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(0, offset), test_api.CurrentOffset());
 
   // At this point, only the overflow indicator on the bottom should be visible
   // because the top indicator never comes on because of the presence of the
@@ -1818,7 +1816,7 @@
   // Finally scroll the view to end of the scrollable region.
   offset = test_api.GetScrollBar(VERTICAL)->GetMaxPosition();
   scroll_view_->ScrollToPosition(test_api.GetScrollBar(VERTICAL), offset);
-  EXPECT_EQ(gfx::ScrollOffset(0, offset), test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(0, offset), test_api.CurrentOffset());
 
   // The overflow indicator on the bottom should not be visible now.
   EXPECT_FALSE(test_api.more_content_bottom()->GetVisible());
@@ -1856,14 +1854,14 @@
   CheckScrollbarVisibility(scroll_view_.get(), VERTICAL, false);
 
   // Make sure the initial origin is 0,0
-  EXPECT_EQ(gfx::ScrollOffset(0, 0), test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(0, 0), test_api.CurrentOffset());
 
   // Now scroll the view to someplace in the middle of the scrollable region.
   int offset_x = kWidth * 2;
   scroll_view_->ScrollToPosition(test_api.GetScrollBar(HORIZONTAL), offset_x);
   int offset_y = kHeight * 2;
   scroll_view_->ScrollToPosition(test_api.GetScrollBar(VERTICAL), offset_y);
-  EXPECT_EQ(gfx::ScrollOffset(offset_x, offset_y), test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(offset_x, offset_y), test_api.CurrentOffset());
 
   // All overflow indicators should be visible.
   ASSERT_TRUE(test_api.more_content_right()->GetVisible());
@@ -2106,7 +2104,7 @@
                                    kCellHeight * kNesting);
   ScrollView* scroll_view = AddScrollViewWithContentSize(kContentSize, false);
   ScrollViewTestApi test_api(scroll_view);
-  EXPECT_EQ(gfx::ScrollOffset(0, 0), test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(0, 0), test_api.CurrentOffset());
 
   // Sanity check that the contents has a layer iff testing layers.
   EXPECT_EQ(IsTestingLayers(), !!scroll_view->contents()->layer());
@@ -2130,7 +2128,7 @@
   // Test vertical scrolling using coordinates on the contents canvas.
   gfx::Rect offset(0, kCellHeight * 2, kCellWidth, kCellHeight);
   scroll_view->contents()->ScrollRectToVisible(offset);
-  EXPECT_EQ(gfx::ScrollOffset(0, offset.y()), test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(0, offset.y()), test_api.CurrentOffset());
 
   // Rely on auto-flipping for this and future HitTestInCorner() calls.
   EXPECT_EQ(gfx::Point(1, kCellHeight * 2 + 1),
@@ -2139,8 +2137,7 @@
   // Test horizontal scrolling.
   offset.set_x(kCellWidth * 2);
   scroll_view->contents()->ScrollRectToVisible(offset);
-  EXPECT_EQ(gfx::ScrollOffset(offset.x(), offset.y()),
-            test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(offset.x(), offset.y()), test_api.CurrentOffset());
   EXPECT_EQ(gfx::Point(kCellWidth * 2 + 1, kCellHeight * 2 + 1),
             HitTestInCorner(scroll_view->contents()));
 
@@ -2172,13 +2169,13 @@
     int y_offset_in_cell = kCellHeight - partial_view->height();
     if (!scroll_view->vertical_scroll_bar()->OverlapsContent())
       y_offset_in_cell -= scroll_view->vertical_scroll_bar()->GetThickness();
-    EXPECT_EQ(gfx::ScrollOffset(kCellWidth * i - x_offset_in_cell,
-                                kCellHeight * i - y_offset_in_cell),
+    EXPECT_EQ(gfx::Vector2dF(kCellWidth * i - x_offset_in_cell,
+                             kCellHeight * i - y_offset_in_cell),
               test_api.CurrentOffset());
 
     // Now scroll the rest.
     deepest_view->ScrollViewToVisible();
-    EXPECT_EQ(gfx::ScrollOffset(kCellWidth * i, kCellHeight * i),
+    EXPECT_EQ(gfx::Vector2dF(kCellWidth * i, kCellHeight * i),
               test_api.CurrentOffset());
 
     // The partial view should now be at the top-left of the viewport (top-right
@@ -2193,9 +2190,9 @@
 
   // Scrolling to the deepest view should have moved the viewport so that the
   // (kNesting - 1) parent views are all off-screen.
-  EXPECT_EQ(gfx::ScrollOffset(kCellWidth * (kNesting - 1),
-                              kCellHeight * (kNesting - 1)),
-            test_api.CurrentOffset());
+  EXPECT_EQ(
+      gfx::Vector2dF(kCellWidth * (kNesting - 1), kCellHeight * (kNesting - 1)),
+      test_api.CurrentOffset());
 }
 
 // Test that views scroll offsets are in sync with the layer scroll offsets.
@@ -2205,12 +2202,12 @@
       gfx::Size(kDefaultWidth * 5, kDefaultHeight * 5), false);
   ScrollViewTestApi test_api(scroll_view);
 
-  EXPECT_EQ(gfx::ScrollOffset(0, 0), test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(0, 0), test_api.CurrentOffset());
 
   // UI code may request a scroll before layer changes are committed.
   gfx::Rect offset(0, kDefaultHeight * 2, kDefaultWidth, kDefaultHeight);
   scroll_view->contents()->ScrollRectToVisible(offset);
-  EXPECT_EQ(gfx::ScrollOffset(0, offset.y()), test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(0, offset.y()), test_api.CurrentOffset());
 
   // The following only makes sense when layered scrolling is enabled.
   View* container = scroll_view->contents();
@@ -2229,39 +2226,38 @@
   // But setting on the impl side should fail since the layer isn't committed.
   cc::ElementId element_id =
       container->layer()->cc_layer_for_testing()->element_id();
-  EXPECT_FALSE(compositor->ScrollLayerTo(element_id, gfx::ScrollOffset(0, 0)));
-  EXPECT_EQ(gfx::ScrollOffset(0, offset.y()), test_api.CurrentOffset());
+  EXPECT_FALSE(compositor->ScrollLayerTo(element_id, gfx::Vector2dF(0, 0)));
+  EXPECT_EQ(gfx::Vector2dF(0, offset.y()), test_api.CurrentOffset());
 
   WaitForCommit();
-  EXPECT_EQ(gfx::ScrollOffset(0, offset.y()), test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(0, offset.y()), test_api.CurrentOffset());
 
   // Upon commit, the impl side should report the same value too.
-  gfx::ScrollOffset impl_offset;
+  gfx::Vector2dF impl_offset;
   EXPECT_TRUE(compositor->GetScrollOffsetForLayer(element_id, &impl_offset));
-  EXPECT_EQ(gfx::ScrollOffset(0, offset.y()), impl_offset);
+  EXPECT_EQ(gfx::Vector2dF(0, offset.y()), impl_offset);
 
   // Now impl-side scrolling should work, and also update the ScrollView.
   offset.set_y(kDefaultHeight * 3);
   EXPECT_TRUE(
-      compositor->ScrollLayerTo(element_id, gfx::ScrollOffset(0, offset.y())));
-  EXPECT_EQ(gfx::ScrollOffset(0, offset.y()), test_api.CurrentOffset());
+      compositor->ScrollLayerTo(element_id, gfx::Vector2dF(0, offset.y())));
+  EXPECT_EQ(gfx::Vector2dF(0, offset.y()), test_api.CurrentOffset());
 
   // Scroll via ScrollView API. Should be reflected on the impl side.
   offset.set_y(kDefaultHeight * 4);
   scroll_view->contents()->ScrollRectToVisible(offset);
-  EXPECT_EQ(gfx::ScrollOffset(0, offset.y()), test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(0, offset.y()), test_api.CurrentOffset());
 
   EXPECT_TRUE(compositor->GetScrollOffsetForLayer(element_id, &impl_offset));
-  EXPECT_EQ(gfx::ScrollOffset(0, offset.y()), impl_offset);
+  EXPECT_EQ(gfx::Vector2dF(0, offset.y()), impl_offset);
 
   // Test horizontal scrolling.
   offset.set_x(kDefaultWidth * 2);
   scroll_view->contents()->ScrollRectToVisible(offset);
-  EXPECT_EQ(gfx::ScrollOffset(offset.x(), offset.y()),
-            test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(offset.x(), offset.y()), test_api.CurrentOffset());
 
   EXPECT_TRUE(compositor->GetScrollOffsetForLayer(element_id, &impl_offset));
-  EXPECT_EQ(gfx::ScrollOffset(offset.x(), offset.y()), impl_offset);
+  EXPECT_EQ(gfx::Vector2dF(offset.x(), offset.y()), impl_offset);
 }
 
 namespace {
@@ -2287,7 +2283,7 @@
     // and dispatch again. Simulate that.
     EXPECT_FALSE(scroll_event.handled());
     EXPECT_FALSE(scroll_event.stopped_propagation());
-    EXPECT_EQ(gfx::ScrollOffset(), test_api.CurrentOffset());
+    EXPECT_EQ(gfx::Vector2dF(), test_api.CurrentOffset());
 
     ui::MouseWheelEvent wheel(scroll_event);
     scroll_view->OnMouseEvent(&wheel);
@@ -2310,7 +2306,7 @@
   ApplyScrollEvent(test_api, scroll_view, scroll);
 
   // Check if the scroll view has been offset.
-  EXPECT_EQ(gfx::ScrollOffset(0, 10), test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(0, 10), test_api.CurrentOffset());
 }
 
 // Tests to see that transposed (treat-as-horizontal) scroll events are handled
@@ -2330,7 +2326,7 @@
   ApplyScrollEvent(test_api, scroll_view, scroll);
 
   // Check if the scroll view has been offset.
-  EXPECT_EQ(gfx::ScrollOffset(10, 0), test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(10, 0), test_api.CurrentOffset());
 }
 
 // Tests to see that transposed (treat-as-horizontal) scroll events are handled
@@ -2354,7 +2350,7 @@
   ApplyScrollEvent(test_api, scroll_view, scroll);
 
   // Check if the scroll view has been offset.
-  EXPECT_EQ(gfx::ScrollOffset(10, 0), test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(10, 0), test_api.CurrentOffset());
 }
 
 // Tests to see that transposed (treat-as-horizontal) scroll events are handled
@@ -2378,7 +2374,7 @@
   ApplyScrollEvent(test_api, scroll_view, scroll);
 
   // Check if the scroll view has been offset.
-  EXPECT_EQ(gfx::ScrollOffset(10, 0), test_api.CurrentOffset());
+  EXPECT_EQ(gfx::Vector2dF(10, 0), test_api.CurrentOffset());
 }
 
 TEST_F(WidgetScrollViewTest, UnboundedScrollViewUsesContentPreferredSize) {
diff --git a/ui/views/view.cc b/ui/views/view.cc
index 54a01e2..39a73376 100644
--- a/ui/views/view.cc
+++ b/ui/views/view.cc
@@ -643,7 +643,7 @@
     return gfx::Transform();
 
   gfx::Transform transform = layer()->transform();
-  gfx::ScrollOffset scroll_offset = layer()->CurrentScrollOffset();
+  gfx::Vector2dF scroll_offset = layer()->CurrentScrollOffset();
   // Offsets for layer-based scrolling are never negative, but the horizontal
   // scroll direction is reversed in RTL via canvas flipping.
   transform.Translate((GetMirrored() ? 1 : -1) * scroll_offset.x(),