diff --git a/android_webview/browser/surfaces_instance.cc b/android_webview/browser/surfaces_instance.cc
index cde8ba380a6fc..2423715784c0f 100644
--- a/android_webview/browser/surfaces_instance.cc
+++ b/android_webview/browser/surfaces_instance.cc
@@ -142,8 +142,9 @@ void SurfacesInstance::DrawAndSwap(const gfx::Size& viewport,
   viz::SurfaceDrawQuad* surface_quad =
       render_pass->CreateAndAppendDrawQuad<viz::SurfaceDrawQuad>();
   surface_quad->SetNew(quad_state, gfx::Rect(quad_state->quad_layer_rect),
-                       gfx::Rect(quad_state->quad_layer_rect), child_id,
-                       base::nullopt, SK_ColorWHITE, false);
+                       gfx::Rect(quad_state->quad_layer_rect),
+                       viz::SurfaceRange(base::nullopt, child_id),
+                       SK_ColorWHITE, false);
 
   viz::CompositorFrame frame;
   // We draw synchronously, so acknowledge a manual BeginFrame.
diff --git a/cc/layers/surface_layer_impl.cc b/cc/layers/surface_layer_impl.cc
index b525536856b81..ea94f4fe56677 100644
--- a/cc/layers/surface_layer_impl.cc
+++ b/cc/layers/surface_layer_impl.cc
@@ -116,8 +116,7 @@ void SurfaceLayerImpl::AppendQuads(viz::RenderPass* render_pass,
   if (!surface_range_.IsValid())
     return;
 
-  auto* primary = CreateSurfaceDrawQuad(render_pass, surface_range_.end(),
-                                        surface_range_.start());
+  auto* primary = CreateSurfaceDrawQuad(render_pass, surface_range_);
   if (primary && surface_range_.end() != surface_range_.start()) {
     // Add the primary surface ID as a dependency.
     append_quads_data->activation_dependencies.push_back(surface_range_.end());
@@ -141,9 +140,8 @@ bool SurfaceLayerImpl::is_surface_layer() const {
 
 viz::SurfaceDrawQuad* SurfaceLayerImpl::CreateSurfaceDrawQuad(
     viz::RenderPass* render_pass,
-    const viz::SurfaceId& primary_surface_id,
-    const base::Optional<viz::SurfaceId>& fallback_surface_id) {
-  DCHECK(primary_surface_id.is_valid());
+    const viz::SurfaceRange& surface_range) {
+  DCHECK(surface_range.end().is_valid());
 
   float device_scale_factor = layer_tree_impl()->device_scale_factor();
 
@@ -168,9 +166,9 @@ viz::SurfaceDrawQuad* SurfaceLayerImpl::CreateSurfaceDrawQuad(
 
   auto* surface_draw_quad =
       render_pass->CreateAndAppendDrawQuad<viz::SurfaceDrawQuad>();
-  surface_draw_quad->SetNew(
-      shared_quad_state, quad_rect, visible_quad_rect, primary_surface_id,
-      fallback_surface_id, background_color(), stretch_content_to_fill_bounds_);
+  surface_draw_quad->SetNew(shared_quad_state, quad_rect, visible_quad_rect,
+                            surface_range, background_color(),
+                            stretch_content_to_fill_bounds_);
 
   return surface_draw_quad;
 }
diff --git a/cc/layers/surface_layer_impl.h b/cc/layers/surface_layer_impl.h
index 8addaaa42fb05..e09d63140b890 100644
--- a/cc/layers/surface_layer_impl.h
+++ b/cc/layers/surface_layer_impl.h
@@ -71,8 +71,7 @@ class CC_EXPORT SurfaceLayerImpl : public LayerImpl {
  private:
   viz::SurfaceDrawQuad* CreateSurfaceDrawQuad(
       viz::RenderPass* render_pass,
-      const viz::SurfaceId& surface_id,
-      const base::Optional<viz::SurfaceId>& fallback_surface_id);
+      const viz::SurfaceRange& surface_range);
 
   void GetDebugBorderProperties(SkColor* color, float* width) const override;
   void AppendRainbowDebugBorder(viz::RenderPass* render_pass);
diff --git a/cc/layers/surface_layer_impl_unittest.cc b/cc/layers/surface_layer_impl_unittest.cc
index c51be4be392cb..c0fc9e7ef8bee 100644
--- a/cc/layers/surface_layer_impl_unittest.cc
+++ b/cc/layers/surface_layer_impl_unittest.cc
@@ -157,17 +157,17 @@ TEST(SurfaceLayerImplTest, SurfaceLayerImplWithTwoDifferentSurfaces) {
       viz::SurfaceDrawQuad::MaterialCast(render_pass->quad_list.ElementAt(2));
   ASSERT_TRUE(surface_draw_quad3);
 
-  EXPECT_EQ(surface_id1, surface_draw_quad1->primary_surface_id);
+  EXPECT_EQ(surface_id1, surface_draw_quad1->surface_range.end());
   EXPECT_EQ(SK_ColorBLUE, surface_draw_quad1->default_background_color);
-  EXPECT_EQ(surface_id2, surface_draw_quad1->fallback_surface_id);
+  EXPECT_EQ(surface_id2, surface_draw_quad1->surface_range.start());
 
-  EXPECT_EQ(surface_id1, surface_draw_quad2->primary_surface_id);
+  EXPECT_EQ(surface_id1, surface_draw_quad2->surface_range.end());
   EXPECT_EQ(SK_ColorBLUE, surface_draw_quad2->default_background_color);
-  EXPECT_EQ(base::nullopt, surface_draw_quad2->fallback_surface_id);
+  EXPECT_EQ(base::nullopt, surface_draw_quad2->surface_range.start());
 
-  EXPECT_EQ(surface_id1, surface_draw_quad3->primary_surface_id);
+  EXPECT_EQ(surface_id1, surface_draw_quad3->surface_range.end());
   EXPECT_EQ(SK_ColorBLUE, surface_draw_quad3->default_background_color);
-  EXPECT_EQ(surface_id2, surface_draw_quad3->fallback_surface_id);
+  EXPECT_EQ(surface_id2, surface_draw_quad3->surface_range.start());
 }
 
 // This test verifies that if one SurfaceLayerImpl has a deadline
@@ -256,8 +256,8 @@ TEST(SurfaceLayerImplTest, SurfaceLayerImplWithMatchingPrimaryAndFallback) {
       viz::SurfaceDrawQuad::MaterialCast(render_pass->quad_list.ElementAt(0));
   ASSERT_TRUE(surface_draw_quad1);
 
-  EXPECT_EQ(surface_id1, surface_draw_quad1->primary_surface_id);
-  EXPECT_EQ(surface_id1, surface_draw_quad1->fallback_surface_id);
+  EXPECT_EQ(surface_id1, surface_draw_quad1->surface_range.end());
+  EXPECT_EQ(surface_id1, surface_draw_quad1->surface_range.start());
   EXPECT_EQ(SK_ColorBLUE, surface_draw_quad1->default_background_color);
 }
 
diff --git a/components/viz/client/hit_test_data_provider_draw_quad.cc b/components/viz/client/hit_test_data_provider_draw_quad.cc
index a9352520ddfd5..5d9947b82b73a 100644
--- a/components/viz/client/hit_test_data_provider_draw_quad.cc
+++ b/components/viz/client/hit_test_data_provider_draw_quad.cc
@@ -41,9 +41,9 @@ base::Optional<HitTestRegionList> HitTestDataProviderDrawQuad::GetHitTestData(
         // Skip the quad if the FrameSinkId between fallback and primary is not
         // the same, because we don't know which FrameSinkId would be used to
         // draw this quad.
-        if (surface_quad->fallback_surface_id.has_value() &&
-            surface_quad->fallback_surface_id->frame_sink_id() !=
-                surface_quad->primary_surface_id.frame_sink_id()) {
+        if (surface_quad->surface_range.start() &&
+            surface_quad->surface_range.start()->frame_sink_id() !=
+                surface_quad->surface_range.end().frame_sink_id()) {
           continue;
         }
 
@@ -58,7 +58,7 @@ base::Optional<HitTestRegionList> HitTestDataProviderDrawQuad::GetHitTestData(
         hit_test_region_list->regions.emplace_back();
         HitTestRegion& hit_test_region = hit_test_region_list->regions.back();
         hit_test_region.frame_sink_id =
-            surface_quad->primary_surface_id.frame_sink_id();
+            surface_quad->surface_range.end().frame_sink_id();
         hit_test_region.flags = HitTestRegionFlags::kHitTestMouse |
                                 HitTestRegionFlags::kHitTestTouch |
                                 HitTestRegionFlags::kHitTestChildSurface;
diff --git a/components/viz/client/hit_test_data_provider_draw_quad_unittest.cc b/components/viz/client/hit_test_data_provider_draw_quad_unittest.cc
index e67bbd4476abe..0b6ba4715ba40 100644
--- a/components/viz/client/hit_test_data_provider_draw_quad_unittest.cc
+++ b/components/viz/client/hit_test_data_provider_draw_quad_unittest.cc
@@ -47,9 +47,10 @@ std::unique_ptr<RenderPass> CreateRenderPassWithChildSurface(
                        1, SkBlendMode::kSrcOver, 0);
 
   auto* surface_quad = pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
-  surface_quad->SetNew(pass->shared_quad_state_list.back(), child_rect,
-                       child_rect, child_surface_id, fallback_child_surface_id,
-                       SK_ColorWHITE, false);
+  surface_quad->SetNew(
+      pass->shared_quad_state_list.back(), child_rect, child_rect,
+      SurfaceRange(fallback_child_surface_id, child_surface_id), SK_ColorWHITE,
+      false);
 
   return pass;
 }
diff --git a/components/viz/common/quads/draw_quad_unittest.cc b/components/viz/common/quads/draw_quad_unittest.cc
index 479a1b89dbf5c..82b9c82e1b5a0 100644
--- a/components/viz/common/quads/draw_quad_unittest.cc
+++ b/components/viz/common/quads/draw_quad_unittest.cc
@@ -283,19 +283,21 @@ TEST(DrawQuadTest, CopySurfaceDrawQuad) {
       LocalSurfaceId(5678, base::UnguessableToken::Create()));
   CREATE_SHARED_STATE();
 
-  CREATE_QUAD_NEW(SurfaceDrawQuad, visible_rect, primary_surface_id,
-                  fallback_surface_id, SK_ColorWHITE, true);
+  CREATE_QUAD_NEW(SurfaceDrawQuad, visible_rect,
+                  SurfaceRange(fallback_surface_id, primary_surface_id),
+                  SK_ColorWHITE, true);
   EXPECT_EQ(DrawQuad::SURFACE_CONTENT, copy_quad->material);
   EXPECT_EQ(visible_rect, copy_quad->visible_rect);
-  EXPECT_EQ(primary_surface_id, copy_quad->primary_surface_id);
-  EXPECT_EQ(fallback_surface_id, copy_quad->fallback_surface_id);
+  EXPECT_EQ(primary_surface_id, copy_quad->surface_range.end());
+  EXPECT_EQ(fallback_surface_id, *copy_quad->surface_range.start());
   EXPECT_TRUE(copy_quad->stretch_content_to_fill_bounds);
 
-  CREATE_QUAD_ALL(SurfaceDrawQuad, primary_surface_id, fallback_surface_id,
+  CREATE_QUAD_ALL(SurfaceDrawQuad,
+                  SurfaceRange(fallback_surface_id, primary_surface_id),
                   SK_ColorWHITE, false);
   EXPECT_EQ(DrawQuad::SURFACE_CONTENT, copy_quad->material);
-  EXPECT_EQ(primary_surface_id, copy_quad->primary_surface_id);
-  EXPECT_EQ(fallback_surface_id, copy_quad->fallback_surface_id);
+  EXPECT_EQ(primary_surface_id, copy_quad->surface_range.end());
+  EXPECT_EQ(fallback_surface_id, *copy_quad->surface_range.start());
   EXPECT_FALSE(copy_quad->stretch_content_to_fill_bounds);
 }
 
@@ -573,8 +575,9 @@ TEST_F(DrawQuadIteratorTest, SurfaceDrawQuad) {
                        LocalSurfaceId(4321, base::UnguessableToken::Create()));
 
   CREATE_SHARED_STATE();
-  CREATE_QUAD_NEW(SurfaceDrawQuad, visible_rect, surface_id, base::nullopt,
-                  SK_ColorWHITE, false);
+  CREATE_QUAD_NEW(SurfaceDrawQuad, visible_rect,
+                  SurfaceRange(base::nullopt, surface_id), SK_ColorWHITE,
+                  false);
   EXPECT_EQ(0, IterateAndCount(quad_new));
 }
 
diff --git a/components/viz/common/quads/surface_draw_quad.cc b/components/viz/common/quads/surface_draw_quad.cc
index 4489167189ba9..3edad1aa15576 100644
--- a/components/viz/common/quads/surface_draw_quad.cc
+++ b/components/viz/common/quads/surface_draw_quad.cc
@@ -20,36 +20,30 @@ SurfaceDrawQuad::~SurfaceDrawQuad() = default;
 SurfaceDrawQuad& SurfaceDrawQuad::operator=(const SurfaceDrawQuad& other) =
     default;
 
-void SurfaceDrawQuad::SetNew(
-    const SharedQuadState* shared_quad_state,
-    const gfx::Rect& rect,
-    const gfx::Rect& visible_rect,
-    const SurfaceId& primary_surface_id,
-    const base::Optional<SurfaceId>& fallback_surface_id,
-    SkColor default_background_color,
-    bool stretch_content_to_fill_bounds) {
+void SurfaceDrawQuad::SetNew(const SharedQuadState* shared_quad_state,
+                             const gfx::Rect& rect,
+                             const gfx::Rect& visible_rect,
+                             const SurfaceRange& surface_range,
+                             SkColor default_background_color,
+                             bool stretch_content_to_fill_bounds) {
   bool needs_blending = true;
   DrawQuad::SetAll(shared_quad_state, DrawQuad::SURFACE_CONTENT, rect,
                    visible_rect, needs_blending);
-  this->primary_surface_id = primary_surface_id;
-  this->fallback_surface_id = fallback_surface_id;
+  this->surface_range = surface_range;
   this->default_background_color = default_background_color;
   this->stretch_content_to_fill_bounds = stretch_content_to_fill_bounds;
 }
 
-void SurfaceDrawQuad::SetAll(
-    const SharedQuadState* shared_quad_state,
-    const gfx::Rect& rect,
-    const gfx::Rect& visible_rect,
-    bool needs_blending,
-    const SurfaceId& primary_surface_id,
-    const base::Optional<SurfaceId>& fallback_surface_id,
-    SkColor default_background_color,
-    bool stretch_content_to_fill_bounds) {
+void SurfaceDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
+                             const gfx::Rect& rect,
+                             const gfx::Rect& visible_rect,
+                             bool needs_blending,
+                             const SurfaceRange& surface_range,
+                             SkColor default_background_color,
+                             bool stretch_content_to_fill_bounds) {
   DrawQuad::SetAll(shared_quad_state, DrawQuad::SURFACE_CONTENT, rect,
                    visible_rect, needs_blending);
-  this->primary_surface_id = primary_surface_id;
-  this->fallback_surface_id = fallback_surface_id;
+  this->surface_range = surface_range;
   this->default_background_color = default_background_color;
   this->stretch_content_to_fill_bounds = stretch_content_to_fill_bounds;
 }
@@ -60,9 +54,7 @@ const SurfaceDrawQuad* SurfaceDrawQuad::MaterialCast(const DrawQuad* quad) {
 }
 
 void SurfaceDrawQuad::ExtendValue(base::trace_event::TracedValue* value) const {
-  value->SetString("primary_surface_id", primary_surface_id.ToString());
-  if (fallback_surface_id.has_value())
-    value->SetString("fallback_surface_id", fallback_surface_id->ToString());
+  value->SetString("surface_range", surface_range.ToString());
 }
 
 }  // namespace viz
diff --git a/components/viz/common/quads/surface_draw_quad.h b/components/viz/common/quads/surface_draw_quad.h
index c3ee5160c1a0d..d63abc1a6ad52 100644
--- a/components/viz/common/quads/surface_draw_quad.h
+++ b/components/viz/common/quads/surface_draw_quad.h
@@ -9,7 +9,7 @@
 
 #include "base/optional.h"
 #include "components/viz/common/quads/draw_quad.h"
-#include "components/viz/common/surfaces/surface_id.h"
+#include "components/viz/common/surfaces/surface_range.h"
 #include "components/viz/common/viz_common_export.h"
 #include "third_party/skia/include/core/SkColor.h"
 
@@ -26,8 +26,7 @@ class VIZ_COMMON_EXPORT SurfaceDrawQuad : public DrawQuad {
   void SetNew(const SharedQuadState* shared_quad_state,
               const gfx::Rect& rect,
               const gfx::Rect& visible_rect,
-              const SurfaceId& primary_surface_id,
-              const base::Optional<SurfaceId>& fallback_surface_id,
+              const SurfaceRange& surface_range,
               SkColor default_background_color,
               bool stretch_content_to_fill_bounds);
 
@@ -35,13 +34,11 @@ class VIZ_COMMON_EXPORT SurfaceDrawQuad : public DrawQuad {
               const gfx::Rect& rect,
               const gfx::Rect& visible_rect,
               bool needs_blending,
-              const SurfaceId& primary_surface_id,
-              const base::Optional<SurfaceId>& fallback_surface_id,
+              const SurfaceRange& surface_range,
               SkColor default_background_color,
               bool stretch_content_to_fill_bounds);
 
-  SurfaceId primary_surface_id;
-  base::Optional<SurfaceId> fallback_surface_id;
+  SurfaceRange surface_range;
   SkColor default_background_color = SK_ColorWHITE;
   bool stretch_content_to_fill_bounds = false;
 
diff --git a/components/viz/service/display/display_unittest.cc b/components/viz/service/display/display_unittest.cc
index 327e77f82ca19..deacc82fd9080 100644
--- a/components/viz/service/display/display_unittest.cc
+++ b/components/viz/service/display/display_unittest.cc
@@ -3277,9 +3277,8 @@ TEST_F(DisplayTest, CompositorFrameWithPresentationToken) {
     auto* quad2 = pass->quad_list.AllocateAndConstruct<SurfaceDrawQuad>();
     quad2->SetNew(shared_quad_state2, rect2 /* rect */,
                   rect2 /* visible_rect */,
-                  sub_surface_id /* primary_surface_id */,
-                  base::Optional<SurfaceId>() /* fallback_surface_id */,
-                  SK_ColorBLACK, false /* stretch_content_to_fill_bounds */);
+                  SurfaceRange(base::nullopt, sub_surface_id), SK_ColorBLACK,
+                  false /* stretch_content_to_fill_bounds */);
 
     pass_list.push_back(std::move(pass));
     SubmitCompositorFrame(&pass_list, local_surface_id);
diff --git a/components/viz/service/display/surface_aggregator.cc b/components/viz/service/display/surface_aggregator.cc
index 11aa65e1af8b0..60b32ff60b9cd 100644
--- a/components/viz/service/display/surface_aggregator.cc
+++ b/components/viz/service/display/surface_aggregator.cc
@@ -24,6 +24,7 @@
 #include "components/viz/common/quads/solid_color_draw_quad.h"
 #include "components/viz/common/quads/surface_draw_quad.h"
 #include "components/viz/common/quads/texture_draw_quad.h"
+#include "components/viz/common/surfaces/surface_range.h"
 #include "components/viz/service/display/display_resource_provider.h"
 #include "components/viz/service/surfaces/surface.h"
 #include "components/viz/service/surfaces/surface_client.h"
@@ -197,7 +198,7 @@ void SurfaceAggregator::HandleSurfaceQuad(
     bool ignore_undamaged,
     gfx::Rect* damage_rect_in_quad_space,
     bool* damage_rect_in_quad_space_valid) {
-  SurfaceId primary_surface_id = surface_quad->primary_surface_id;
+  SurfaceId primary_surface_id = surface_quad->surface_range.end();
   Surface* primary_surface = manager_->GetSurfaceForId(primary_surface_id);
   if (primary_surface && primary_surface->HasActiveFrame()) {
     EmitSurfaceContent(primary_surface, parent_device_scale_factor,
@@ -211,19 +212,19 @@ void SurfaceAggregator::HandleSurfaceQuad(
 
   // If there's no fallback surface ID provided, then simply emit a
   // SolidColorDrawQuad with the provided default background color.
-  if (!surface_quad->fallback_surface_id) {
+  if (!surface_quad->surface_range.start()) {
     EmitDefaultBackgroundColorQuad(surface_quad, target_transform, clip_rect,
                                    dest_pass);
     return;
   }
 
   Surface* fallback_surface = manager_->GetLatestInFlightSurface(
-      primary_surface_id, *surface_quad->fallback_surface_id);
+      primary_surface_id, *surface_quad->surface_range.start());
 
   // If the fallback is specified and missing then that's an error. Report the
   // error to console, and log the UMA.
   if (!fallback_surface || !fallback_surface->HasActiveFrame()) {
-    ReportMissingFallbackSurface(*surface_quad->fallback_surface_id,
+    ReportMissingFallbackSurface(*surface_quad->surface_range.start(),
                                  fallback_surface);
     EmitDefaultBackgroundColorQuad(surface_quad, target_transform, clip_rect,
                                    dest_pass);
@@ -477,8 +478,8 @@ void SurfaceAggregator::EmitDefaultBackgroundColorQuad(
   // If a fallback surface is specified but unavaialble then pick a very bright
   // and obvious color for the SolidColorDrawQuad so developers notice there's
   // an error when debugging.
-  if (surface_quad->fallback_surface_id.has_value() &&
-      surface_quad->fallback_surface_id->is_valid()) {
+  if (surface_quad->surface_range.start() &&
+      surface_quad->surface_range.start()->is_valid()) {
     background_color = SK_ColorMAGENTA;
   }
 #endif
@@ -679,7 +680,7 @@ void SurfaceAggregator::CopyQuadsToPass(
       // current data.
       last_copied_source_shared_quad_state = nullptr;
 
-      if (!surface_quad->primary_surface_id.is_valid())
+      if (!surface_quad->surface_range.end().is_valid())
         continue;
 
       HandleSurfaceQuad(surface_quad, parent_device_scale_factor,
@@ -876,23 +877,20 @@ gfx::Rect SurfaceAggregator::PrewalkTree(Surface* surface,
     render_pass_dependencies_[parent_pass_id].insert(remapped_pass_id);
 
   struct SurfaceInfo {
-    SurfaceInfo(const SurfaceId& primary_id,
-                const base::Optional<SurfaceId>& fallback_id,
+    SurfaceInfo(const SurfaceRange& surface_range,
                 bool has_moved_pixels,
                 RenderPassId parent_pass_id,
                 const gfx::Transform& target_to_surface_transform,
                 const gfx::Rect& quad_rect,
                 bool stretch_content_to_fill_bounds)
-        : primary_id(primary_id),
-          fallback_id(fallback_id),
+        : surface_range(surface_range),
           has_moved_pixels(has_moved_pixels),
           parent_pass_id(parent_pass_id),
           target_to_surface_transform(target_to_surface_transform),
           quad_rect(quad_rect),
           stretch_content_to_fill_bounds(stretch_content_to_fill_bounds) {}
 
-    SurfaceId primary_id;
-    base::Optional<SurfaceId> fallback_id;
+    SurfaceRange surface_range;
     bool has_moved_pixels;
     RenderPassId parent_pass_id;
     gfx::Transform target_to_surface_transform;
@@ -937,9 +935,9 @@ gfx::Rect SurfaceAggregator::PrewalkTree(Surface* surface,
             render_pass->transform_to_root_target,
             surface_quad->shared_quad_state->quad_to_target_transform);
         child_surfaces.emplace_back(
-            surface_quad->primary_surface_id, surface_quad->fallback_surface_id,
-            in_moved_pixel_pass, remapped_pass_id, target_to_surface_transform,
-            surface_quad->rect, surface_quad->stretch_content_to_fill_bounds);
+            surface_quad->surface_range, in_moved_pixel_pass, remapped_pass_id,
+            target_to_surface_transform, surface_quad->rect,
+            surface_quad->stretch_content_to_fill_bounds);
       } else if (quad->material == DrawQuad::RENDER_PASS) {
         const auto* render_pass_quad = RenderPassDrawQuad::MaterialCast(quad);
         if (in_moved_pixel_pass) {
@@ -991,32 +989,39 @@ gfx::Rect SurfaceAggregator::PrewalkTree(Surface* surface,
       // are provided and they have the same FrameSinkId and embed token,
       // otherwise the only Surface other than fallback that can be shown is the
       // primary.
-      if (!surface_info.fallback_id ||
-          surface_info.fallback_id->frame_sink_id() !=
-              surface_info.primary_id.frame_sink_id() ||
-          surface_info.fallback_id->local_surface_id().embed_token() !=
-              surface_info.primary_id.local_surface_id().embed_token()) {
-        damage_ranges_[surface_info.primary_id.frame_sink_id()] =
-            std::make_pair(surface_info.primary_id.local_surface_id(),
-                           surface_info.primary_id.local_surface_id());
-      } else if (surface_info.fallback_id != surface_info.primary_id) {
-        damage_ranges_[surface_info.primary_id.frame_sink_id()] =
-            std::make_pair(surface_info.fallback_id->local_surface_id(),
-                           surface_info.primary_id.local_surface_id());
+      if (!surface_info.surface_range.start() ||
+          surface_info.surface_range.start()->frame_sink_id() !=
+              surface_info.surface_range.end().frame_sink_id() ||
+          surface_info.surface_range.start()
+                  ->local_surface_id()
+                  .embed_token() != surface_info.surface_range.end()
+                                        .local_surface_id()
+                                        .embed_token()) {
+        damage_ranges_[surface_info.surface_range.end().frame_sink_id()] =
+            std::make_pair(surface_info.surface_range.end().local_surface_id(),
+                           surface_info.surface_range.end().local_surface_id());
+      } else if (surface_info.surface_range.start() !=
+                 surface_info.surface_range.end()) {
+        damage_ranges_[surface_info.surface_range.end().frame_sink_id()] =
+            std::make_pair(
+                surface_info.surface_range.start()->local_surface_id(),
+                surface_info.surface_range.end().local_surface_id());
       }
     }
-    Surface* child_surface = manager_->GetSurfaceForId(surface_info.primary_id);
+    Surface* child_surface =
+        manager_->GetSurfaceForId(surface_info.surface_range.end());
     gfx::Rect surface_damage;
     if (!child_surface || !child_surface->HasActiveFrame()) {
       // If the primary surface is not available then we assume the damage is
       // the full size of the SurfaceDrawQuad because we might need to introduce
       // gutter.
       surface_damage = surface_info.quad_rect;
-      if (surface_info.fallback_id) {
+      if (surface_info.surface_range.start()) {
         // TODO(fsamuel): Consider caching this value somewhere so that
         // HandleSurfaceQuad doesn't need to call it again.
         Surface* fallback_surface = manager_->GetLatestInFlightSurface(
-            surface_info.primary_id, *surface_info.fallback_id);
+            surface_info.surface_range.end(),
+            *surface_info.surface_range.start());
         if (fallback_surface && fallback_surface->HasActiveFrame())
           child_surface = fallback_surface;
       }
diff --git a/components/viz/service/display/surface_aggregator_perftest.cc b/components/viz/service/display/surface_aggregator_perftest.cc
index 4b815d1e06050..9aa1b37c71655 100644
--- a/components/viz/service/display/surface_aggregator_perftest.cc
+++ b/components/viz/service/display/surface_aggregator_perftest.cc
@@ -93,8 +93,10 @@ class SurfaceAggregatorPerfTest : public testing::Test {
         auto* surface_quad = pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
         surface_quad->SetNew(
             sqs, gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1),
-            SurfaceId(FrameSinkId(1, i), LocalSurfaceId(i, kArbitraryToken)),
-            base::nullopt, SK_ColorWHITE, false);
+            SurfaceRange(base::nullopt,
+                         SurfaceId(FrameSinkId(1, i),
+                                   LocalSurfaceId(i, kArbitraryToken))),
+            SK_ColorWHITE, false);
       }
 
       frame_builder.AddRenderPass(std::move(pass));
@@ -115,9 +117,11 @@ class SurfaceAggregatorPerfTest : public testing::Test {
       auto* surface_quad = pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
       surface_quad->SetNew(
           sqs, gfx::Rect(0, 0, 100, 100), gfx::Rect(0, 0, 100, 100),
-          SurfaceId(FrameSinkId(1, num_surfaces),
-                    LocalSurfaceId(num_surfaces, kArbitraryToken)),
-          base::nullopt, SK_ColorWHITE, false);
+          SurfaceRange(
+              base::nullopt,
+              SurfaceId(FrameSinkId(1, num_surfaces),
+                        LocalSurfaceId(num_surfaces, kArbitraryToken))),
+          SK_ColorWHITE, false);
 
       pass->output_rect = gfx::Rect(0, 0, 100, 100);
 
diff --git a/components/viz/service/display/surface_aggregator_pixeltest.cc b/components/viz/service/display/surface_aggregator_pixeltest.cc
index 493ba4987a0a3..46aa050d0d50b 100644
--- a/components/viz/service/display/surface_aggregator_pixeltest.cc
+++ b/components/viz/service/display/surface_aggregator_pixeltest.cc
@@ -138,7 +138,8 @@ TEST_F(SurfaceAggregatorPixelTest, DrawSimpleAggregatedFrame) {
     auto* surface_quad = pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
     surface_quad->SetNew(pass->shared_quad_state_list.back(),
                          gfx::Rect(child_size), gfx::Rect(child_size),
-                         child_surface_id, base::nullopt, SK_ColorWHITE, false);
+                         SurfaceRange(base::nullopt, child_surface_id),
+                         SK_ColorWHITE, false);
 
     auto* color_quad = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
     bool force_anti_aliasing_off = false;
@@ -224,8 +225,8 @@ TEST_F(SurfaceAggregatorPixelTest, DrawAggregatedFrameWithSurfaceTransforms) {
     auto* left_surface_quad = pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
     left_surface_quad->SetNew(pass->shared_quad_state_list.back(),
                               gfx::Rect(child_size), gfx::Rect(child_size),
-                              left_child_id, base::nullopt, SK_ColorWHITE,
-                              false);
+                              SurfaceRange(base::nullopt, left_child_id),
+                              SK_ColorWHITE, false);
 
     surface_transform.Translate(100, 0);
     CreateAndAppendTestSharedQuadState(pass.get(), surface_transform,
@@ -234,8 +235,8 @@ TEST_F(SurfaceAggregatorPixelTest, DrawAggregatedFrameWithSurfaceTransforms) {
     auto* right_surface_quad = pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
     right_surface_quad->SetNew(pass->shared_quad_state_list.back(),
                                gfx::Rect(child_size), gfx::Rect(child_size),
-                               right_child_id, base::nullopt, SK_ColorWHITE,
-                               false);
+                               SurfaceRange(base::nullopt, right_child_id),
+                               SK_ColorWHITE, false);
 
     auto root_frame =
         CompositorFrameBuilder().AddRenderPass(std::move(pass)).Build();
diff --git a/components/viz/service/display/surface_aggregator_unittest.cc b/components/viz/service/display/surface_aggregator_unittest.cc
index a6ebb854c8c3a..ebbcce2a6cb9e 100644
--- a/components/viz/service/display/surface_aggregator_unittest.cc
+++ b/components/viz/service/display/surface_aggregator_unittest.cc
@@ -333,10 +333,11 @@ class SurfaceAggregatorTest : public testing::Test, public DisplayTimeSource {
         pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
     surface_quad->SetNew(
         pass->shared_quad_state_list.back(), primary_surface_rect,
-        primary_surface_rect, primary_surface_id,
-        fallback_surface_id.is_valid()
-            ? base::Optional<SurfaceId>(fallback_surface_id)
-            : base::nullopt,
+        primary_surface_rect,
+        SurfaceRange(fallback_surface_id.is_valid()
+                         ? base::Optional<SurfaceId>(fallback_surface_id)
+                         : base::nullopt,
+                     primary_surface_id),
         default_background_color, stretch_content_to_fill_bounds);
   }
 
@@ -1903,8 +1904,8 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateSharedQuadStateProperties) {
       child_one_pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
   grandchild_surface_quad->SetNew(
       child_one_pass->shared_quad_state_list.back(), gfx::Rect(SurfaceSize()),
-      gfx::Rect(SurfaceSize()), grandchild_surface_id, base::nullopt,
-      SK_ColorWHITE, false);
+      gfx::Rect(SurfaceSize()),
+      SurfaceRange(base::nullopt, grandchild_surface_id), SK_ColorWHITE, false);
   AddSolidColorQuadWithBlendMode(SurfaceSize(), child_one_pass.get(),
                                  blend_modes[3]);
   QueuePassAsFrame(std::move(child_one_pass), child_one_local_surface_id,
@@ -1930,18 +1931,18 @@ TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateSharedQuadStateProperties) {
                                  blend_modes[0]);
   auto* child_one_surface_quad =
       root_pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
-  child_one_surface_quad->SetNew(root_pass->shared_quad_state_list.back(),
-                                 gfx::Rect(SurfaceSize()),
-                                 gfx::Rect(SurfaceSize()), child_one_surface_id,
-                                 base::nullopt, SK_ColorWHITE, false);
+  child_one_surface_quad->SetNew(
+      root_pass->shared_quad_state_list.back(), gfx::Rect(SurfaceSize()),
+      gfx::Rect(SurfaceSize()),
+      SurfaceRange(base::nullopt, child_one_surface_id), SK_ColorWHITE, false);
   AddSolidColorQuadWithBlendMode(SurfaceSize(), root_pass.get(),
                                  blend_modes[4]);
   auto* child_two_surface_quad =
       root_pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
-  child_two_surface_quad->SetNew(root_pass->shared_quad_state_list.back(),
-                                 gfx::Rect(SurfaceSize()),
-                                 gfx::Rect(SurfaceSize()), child_two_surface_id,
-                                 base::nullopt, SK_ColorWHITE, false);
+  child_two_surface_quad->SetNew(
+      root_pass->shared_quad_state_list.back(), gfx::Rect(SurfaceSize()),
+      gfx::Rect(SurfaceSize()),
+      SurfaceRange(base::nullopt, child_two_surface_id), SK_ColorWHITE, false);
   AddSolidColorQuadWithBlendMode(SurfaceSize(), root_pass.get(),
                                  blend_modes[6]);
 
@@ -3212,7 +3213,8 @@ void SubmitCompositorFrameWithResources(ResourceId* resource_ids,
   if (child_id.is_valid()) {
     auto* surface_quad = pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
     surface_quad->SetNew(sqs, gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1),
-                         child_id, base::nullopt, SK_ColorWHITE, false);
+                         SurfaceRange(base::nullopt, child_id), SK_ColorWHITE,
+                         false);
   }
 
   for (size_t i = 0u; i < num_resource_ids; ++i) {
@@ -3480,7 +3482,8 @@ TEST_F(SurfaceAggregatorWithResourcesTest, SecureOutputTexture) {
     auto* surface_quad = pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
 
     surface_quad->SetNew(sqs, gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1),
-                         surface1_id, base::nullopt, SK_ColorWHITE, false);
+                         SurfaceRange(base::nullopt, surface1_id),
+                         SK_ColorWHITE, false);
     pass->copy_requests.push_back(CopyOutputRequest::CreateStubForTesting());
 
     CompositorFrame frame =
diff --git a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc
index f5578eef306a0..a555d9a953012 100644
--- a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc
+++ b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc
@@ -110,9 +110,9 @@ static HitTestRegionList CreateHitTestData(const CompositorFrame& frame) {
         // Skip the quad if the FrameSinkId between fallback and primary is not
         // the same, because we don't know which FrameSinkId would be used to
         // draw this quad.
-        if (surface_quad->fallback_surface_id.has_value() &&
-            surface_quad->fallback_surface_id->frame_sink_id() !=
-                surface_quad->primary_surface_id.frame_sink_id()) {
+        if (surface_quad->surface_range.start() &&
+            surface_quad->surface_range.start()->frame_sink_id() !=
+                surface_quad->surface_range.end().frame_sink_id()) {
           continue;
         }
 
@@ -127,7 +127,7 @@ static HitTestRegionList CreateHitTestData(const CompositorFrame& frame) {
         hit_test_region_list.regions.emplace_back();
         HitTestRegion* hit_test_region = &hit_test_region_list.regions.back();
         hit_test_region->frame_sink_id =
-            surface_quad->primary_surface_id.frame_sink_id();
+            surface_quad->surface_range.end().frame_sink_id();
         hit_test_region->flags = HitTestRegionFlags::kHitTestMouse |
                                  HitTestRegionFlags::kHitTestTouch |
                                  HitTestRegionFlags::kHitTestChildSurface;
diff --git a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink_unittest.cc b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink_unittest.cc
index d807033e4da4e..c4c52773605d2 100644
--- a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink_unittest.cc
+++ b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink_unittest.cc
@@ -210,9 +210,8 @@ TEST_F(DirectLayerTreeFrameSinkTest, HitTestRegionList) {
       0.5f /* opacity */, SkBlendMode::kSrcOver, 0 /* sorting_context_id */);
   auto* quad2 = pass2->quad_list.AllocateAndConstruct<SurfaceDrawQuad>();
   quad2->SetNew(shared_quad_state2, rect2 /* rect */, rect2 /* visible_rect */,
-                child_surface_id /* primary_surface_id */,
-                base::Optional<SurfaceId>() /* fallback_surface_id */,
-                SK_ColorBLACK, false /* stretch_content_to_fill_bounds */);
+                SurfaceRange(base::nullopt, child_surface_id), SK_ColorBLACK,
+                false /* stretch_content_to_fill_bounds */);
   pass_list.push_back(std::move(pass2));
 
   auto pass3 = RenderPass::Create();
@@ -252,9 +251,8 @@ TEST_F(DirectLayerTreeFrameSinkTest, HitTestRegionList) {
       0.5f /* opacity */, SkBlendMode::kSrcOver, 0 /* sorting_context_id */);
   auto* quad4 = pass4->quad_list.AllocateAndConstruct<SurfaceDrawQuad>();
   quad4->SetNew(shared_quad_state4, rect4 /* rect */, rect4 /* visible_rect */,
-                child_surface_id4 /* primary_surface_id */,
-                base::Optional<SurfaceId>() /* fallback_surface_id */,
-                SK_ColorBLACK, false /* stretch_content_to_fill_bounds */);
+                SurfaceRange(base::nullopt, child_surface_id4), SK_ColorBLACK,
+                false /* stretch_content_to_fill_bounds */);
   pass_list.push_back(std::move(pass4));
 
   const auto* hit_test_region_list1 =
diff --git a/components/viz/service/frame_sinks/video_detector_unittest.cc b/components/viz/service/frame_sinks/video_detector_unittest.cc
index d7f76b72c88a5..977931a75337f 100644
--- a/components/viz/service/frame_sinks/video_detector_unittest.cc
+++ b/components/viz/service/frame_sinks/video_detector_unittest.cc
@@ -133,10 +133,10 @@ class VideoDetectorTest : public testing::Test {
     for (CompositorFrameSinkSupport* frame_sink : embedded_clients_) {
       SurfaceDrawQuad* quad =
           render_pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
-      quad->SetNew(shared_quad_state, gfx::Rect(0, 0, 10, 10),
-                   gfx::Rect(0, 0, 5, 5),
-                   frame_sink->last_activated_surface_id(), base::nullopt,
-                   SK_ColorMAGENTA, false);
+      quad->SetNew(
+          shared_quad_state, gfx::Rect(0, 0, 10, 10), gfx::Rect(0, 0, 5, 5),
+          SurfaceRange(base::nullopt, frame_sink->last_activated_surface_id()),
+          SK_ColorMAGENTA, false);
     }
     root_frame_sink_->SubmitCompositorFrame(
         root_frame_sink_->last_activated_local_surface_id(), std::move(frame));
diff --git a/components/viz/service/surfaces/surface_hittest.cc b/components/viz/service/surfaces/surface_hittest.cc
index 14c50d37f84ea..83d97e9ca9bfa 100644
--- a/components/viz/service/surfaces/surface_hittest.cc
+++ b/components/viz/service/surfaces/surface_hittest.cc
@@ -147,7 +147,7 @@ bool SurfaceHittest::GetTargetSurfaceAtPointInternal(
 
         gfx::Transform transform_to_child_space;
         if (GetTargetSurfaceAtPointInternal(
-                surface_quad->primary_surface_id, 0, point_in_quad_space,
+                surface_quad->surface_range.end(), 0, point_in_quad_space,
                 referenced_passes, out_surface_id, &transform_to_child_space,
                 out_query_renderer)) {
           *out_transform = transform_to_child_space * target_to_quad_transform *
@@ -155,7 +155,7 @@ bool SurfaceHittest::GetTargetSurfaceAtPointInternal(
           return true;
         } else if (delegate_ && delegate_->AcceptHitTarget(
                                     surface_quad, point_in_quad_space)) {
-          *out_surface_id = surface_quad->primary_surface_id;
+          *out_surface_id = surface_quad->surface_range.end();
           *out_transform = transform_to_child_space * target_to_quad_transform *
                            transform_from_root_target;
           return true;
@@ -251,7 +251,7 @@ bool SurfaceHittest::GetTransformToTargetSurfaceInternal(
       }
 
       const SurfaceDrawQuad* surface_quad = SurfaceDrawQuad::MaterialCast(quad);
-      if (surface_quad->primary_surface_id == target_surface_id) {
+      if (surface_quad->surface_range.end() == target_surface_id) {
         *out_transform = target_to_quad_transform * transform_from_root_target;
         return true;
       }
@@ -260,7 +260,7 @@ bool SurfaceHittest::GetTransformToTargetSurfaceInternal(
       // find the |target_surface_id| there.
       gfx::Transform transform_to_child_space;
       if (GetTransformToTargetSurfaceInternal(
-              surface_quad->primary_surface_id, target_surface_id, 0,
+              surface_quad->surface_range.end(), target_surface_id, 0,
               referenced_passes, &transform_to_child_space)) {
         *out_transform = transform_to_child_space * target_to_quad_transform *
                          transform_from_root_target;
diff --git a/components/viz/test/surface_hittest_test_helpers.cc b/components/viz/test/surface_hittest_test_helpers.cc
index 8db686fefcc45..8f2d32b5073a0 100644
--- a/components/viz/test/surface_hittest_test_helpers.cc
+++ b/components/viz/test/surface_hittest_test_helpers.cc
@@ -56,8 +56,8 @@ void CreateSurfaceDrawQuad(RenderPass* pass,
   SurfaceDrawQuad* surface_quad =
       pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
   surface_quad->SetNew(pass->shared_quad_state_list.back(), quad_rect,
-                       quad_rect, surface_id, SurfaceId(), SK_ColorWHITE,
-                       false);
+                       quad_rect, SurfaceRange(base::nullopt, surface_id),
+                       SK_ColorWHITE, false);
 }
 
 void CreateRenderPass(int render_pass_id,
@@ -99,10 +99,10 @@ void TestSurfaceHittestDelegate::AddInsetsForAcceptSurface(
 bool TestSurfaceHittestDelegate::RejectHitTarget(
     const SurfaceDrawQuad* surface_quad,
     const gfx::Point& point_in_quad_space) {
-  if (!insets_for_reject_.count(surface_quad->primary_surface_id))
+  if (!insets_for_reject_.count(surface_quad->surface_range.end()))
     return false;
   gfx::Rect bounds(surface_quad->rect);
-  bounds.Inset(insets_for_reject_[surface_quad->primary_surface_id]);
+  bounds.Inset(insets_for_reject_[surface_quad->surface_range.end()]);
   // If the point provided falls outside the inset, then we skip this surface.
   if (!bounds.Contains(point_in_quad_space)) {
     if (surface_quad->rect.Contains(point_in_quad_space))
@@ -115,10 +115,10 @@ bool TestSurfaceHittestDelegate::RejectHitTarget(
 bool TestSurfaceHittestDelegate::AcceptHitTarget(
     const SurfaceDrawQuad* surface_quad,
     const gfx::Point& point_in_quad_space) {
-  if (!insets_for_accept_.count(surface_quad->primary_surface_id))
+  if (!insets_for_accept_.count(surface_quad->surface_range.end()))
     return false;
   gfx::Rect bounds(surface_quad->rect);
-  bounds.Inset(insets_for_accept_[surface_quad->primary_surface_id]);
+  bounds.Inset(insets_for_accept_[surface_quad->surface_range.end()]);
   // If the point provided falls outside the inset, then we accept this surface.
   if (!bounds.Contains(point_in_quad_space)) {
     ++accept_target_overrides_;
diff --git a/content/browser/renderer_host/render_widget_host_input_event_router.cc b/content/browser/renderer_host/render_widget_host_input_event_router.cc
index 48dd2935ef844..8317c806adb37 100644
--- a/content/browser/renderer_host/render_widget_host_input_event_router.cc
+++ b/content/browser/renderer_host/render_widget_host_input_event_router.cc
@@ -170,7 +170,7 @@ RenderWidgetHostInputEventRouter::HittestDelegate::HittestDelegate(
 bool RenderWidgetHostInputEventRouter::HittestDelegate::RejectHitTarget(
     const viz::SurfaceDrawQuad* surface_quad,
     const gfx::Point& point_in_quad_space) {
-  auto it = hittest_data_.find(surface_quad->primary_surface_id);
+  auto it = hittest_data_.find(surface_quad->surface_range.end());
   if (it != hittest_data_.end() && it->second.ignored_for_hittest)
     return true;
   return false;
@@ -179,7 +179,7 @@ bool RenderWidgetHostInputEventRouter::HittestDelegate::RejectHitTarget(
 bool RenderWidgetHostInputEventRouter::HittestDelegate::AcceptHitTarget(
     const viz::SurfaceDrawQuad* surface_quad,
     const gfx::Point& point_in_quad_space) {
-  auto it = hittest_data_.find(surface_quad->primary_surface_id);
+  auto it = hittest_data_.find(surface_quad->surface_range.end());
   if (it != hittest_data_.end() && !it->second.ignored_for_hittest)
     return true;
   return false;
diff --git a/content/renderer/android/synchronous_layer_tree_frame_sink.cc b/content/renderer/android/synchronous_layer_tree_frame_sink.cc
index 24c569eea6572..558e0ff4fd3cb 100644
--- a/content/renderer/android/synchronous_layer_tree_frame_sink.cc
+++ b/content/renderer/android/synchronous_layer_tree_frame_sink.cc
@@ -313,8 +313,10 @@ void SynchronousLayerTreeFrameSink::SubmitCompositorFrame(
         SkBlendMode::kSrcOver, 0 /* sorting_context_id */);
     surface_quad->SetNew(
         shared_quad_state, gfx::Rect(child_size), gfx::Rect(child_size),
-        viz::SurfaceId(kChildFrameSinkId, child_local_surface_id_),
-        base::nullopt, SK_ColorWHITE, false);
+        viz::SurfaceRange(
+            base::nullopt,
+            viz::SurfaceId(kChildFrameSinkId, child_local_surface_id_)),
+        SK_ColorWHITE, false);
 
     child_support_->SubmitCompositorFrame(child_local_surface_id_,
                                           std::move(frame));
diff --git a/services/ui/ws/frame_generator.cc b/services/ui/ws/frame_generator.cc
index 5c73aa0b588d1..bf0bee4f5d716 100644
--- a/services/ui/ws/frame_generator.cc
+++ b/services/ui/ws/frame_generator.cc
@@ -233,8 +233,7 @@ void FrameGenerator::DrawWindow(viz::RenderPass* pass) {
   auto* quad = pass->CreateAndAppendDrawQuad<viz::SurfaceDrawQuad>();
   quad->SetAll(sqs, bounds_at_origin /* rect */,
                bounds_at_origin /* visible_rect */, true /* needs_blending*/,
-               window_manager_surface_info_.id(),
-               window_manager_surface_info_.id(),
+               viz::SurfaceRange(window_manager_surface_info_.id()),
                SK_ColorWHITE /* default_background_color */,
                false /* stretch_content_to_fill_bounds */);
 }
diff --git a/services/viz/public/cpp/compositing/quads_struct_traits.cc b/services/viz/public/cpp/compositing/quads_struct_traits.cc
index 5f7acfec5b024..47121a2087da7 100644
--- a/services/viz/public/cpp/compositing/quads_struct_traits.cc
+++ b/services/viz/public/cpp/compositing/quads_struct_traits.cc
@@ -112,8 +112,7 @@ bool StructTraits<viz::mojom::SurfaceQuadStateDataView, viz::DrawQuad>::Read(
   viz::SurfaceDrawQuad* quad = static_cast<viz::SurfaceDrawQuad*>(out);
   quad->default_background_color = data.default_background_color();
   quad->stretch_content_to_fill_bounds = data.stretch_content_to_fill_bounds();
-  return data.ReadPrimarySurfaceId(&quad->primary_surface_id) &&
-         data.ReadFallbackSurfaceId(&quad->fallback_surface_id);
+  return data.ReadSurfaceRange(&quad->surface_range);
 }
 
 // static
diff --git a/services/viz/public/cpp/compositing/quads_struct_traits.h b/services/viz/public/cpp/compositing/quads_struct_traits.h
index 93f16a02d3b31..ac28fea34ebff 100644
--- a/services/viz/public/cpp/compositing/quads_struct_traits.h
+++ b/services/viz/public/cpp/compositing/quads_struct_traits.h
@@ -19,7 +19,7 @@
 #include "services/viz/public/cpp/compositing/filter_operation_struct_traits.h"
 #include "services/viz/public/cpp/compositing/filter_operations_struct_traits.h"
 #include "services/viz/public/cpp/compositing/shared_quad_state_struct_traits.h"
-#include "services/viz/public/cpp/compositing/surface_id_struct_traits.h"
+#include "services/viz/public/cpp/compositing/surface_range_struct_traits.h"
 #include "services/viz/public/interfaces/compositing/quads.mojom-shared.h"
 #include "ui/gfx/geometry/mojo/geometry_struct_traits.h"
 #include "ui/gfx/ipc/color/gfx_param_traits.h"
@@ -238,17 +238,10 @@ struct StructTraits<viz::mojom::StreamVideoQuadStateDataView, viz::DrawQuad> {
 
 template <>
 struct StructTraits<viz::mojom::SurfaceQuadStateDataView, viz::DrawQuad> {
-  static const viz::SurfaceId& primary_surface_id(const viz::DrawQuad& input) {
+  static const viz::SurfaceRange& surface_range(const viz::DrawQuad& input) {
     const viz::SurfaceDrawQuad* quad =
         viz::SurfaceDrawQuad::MaterialCast(&input);
-    return quad->primary_surface_id;
-  }
-
-  static const base::Optional<viz::SurfaceId>& fallback_surface_id(
-      const viz::DrawQuad& input) {
-    const viz::SurfaceDrawQuad* quad =
-        viz::SurfaceDrawQuad::MaterialCast(&input);
-    return quad->fallback_surface_id;
+    return quad->surface_range;
   }
 
   static uint32_t default_background_color(const viz::DrawQuad& input) {
diff --git a/services/viz/public/cpp/compositing/struct_traits_unittest.cc b/services/viz/public/cpp/compositing/struct_traits_unittest.cc
index 3ee54c2df3e4f..2d0f620f893b9 100644
--- a/services/viz/public/cpp/compositing/struct_traits_unittest.cc
+++ b/services/viz/public/cpp/compositing/struct_traits_unittest.cc
@@ -776,9 +776,11 @@ TEST_F(StructTraitsTest, RenderPass) {
   const gfx::Rect surface_quad_rect(1337, 2448, 1234, 5678);
   surface_quad->SetNew(
       shared_state_2, surface_quad_rect, surface_quad_rect,
-      SurfaceId(FrameSinkId(1337, 1234),
-                LocalSurfaceId(1234, base::UnguessableToken::Create())),
-      base::nullopt, SK_ColorYELLOW, false);
+      SurfaceRange(
+          base::nullopt,
+          SurfaceId(FrameSinkId(1337, 1234),
+                    LocalSurfaceId(1234, base::UnguessableToken::Create()))),
+      SK_ColorYELLOW, false);
 
   std::unique_ptr<RenderPass> output;
   SerializeAndDeserialize<mojom::RenderPass>(input, &output);
@@ -847,10 +849,7 @@ TEST_F(StructTraitsTest, RenderPass) {
   EXPECT_EQ(out_surface_quad->shared_quad_state, out_sqs2);
   EXPECT_EQ(surface_quad->rect, out_surface_quad->rect);
   EXPECT_EQ(surface_quad->visible_rect, out_surface_quad->visible_rect);
-  EXPECT_EQ(surface_quad->primary_surface_id,
-            out_surface_quad->primary_surface_id);
-  EXPECT_EQ(surface_quad->fallback_surface_id,
-            out_surface_quad->fallback_surface_id);
+  EXPECT_EQ(surface_quad->surface_range, out_surface_quad->surface_range);
   EXPECT_EQ(surface_quad->default_background_color,
             out_surface_quad->default_background_color);
   EXPECT_EQ(surface_quad->stretch_content_to_fill_bounds,
@@ -921,9 +920,9 @@ TEST_F(StructTraitsTest, QuadListBasic) {
       LocalSurfaceId(1234, base::UnguessableToken::Create()));
   SurfaceDrawQuad* primary_surface_quad =
       render_pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
-  primary_surface_quad->SetNew(sqs, rect3, rect3, primary_surface_id,
-                               base::Optional<SurfaceId>(fallback_surface_id),
-                               SK_ColorBLUE, false);
+  primary_surface_quad->SetNew(
+      sqs, rect3, rect3, SurfaceRange(fallback_surface_id, primary_surface_id),
+      SK_ColorBLUE, false);
 
   const gfx::Rect rect4(1234, 5678, 9101112, 13141516);
   const ResourceId resource_id4(1337);
@@ -1000,11 +999,11 @@ TEST_F(StructTraitsTest, QuadListBasic) {
   EXPECT_EQ(rect3, out_primary_surface_draw_quad->visible_rect);
   EXPECT_TRUE(out_primary_surface_draw_quad->needs_blending);
   EXPECT_EQ(primary_surface_id,
-            out_primary_surface_draw_quad->primary_surface_id);
+            out_primary_surface_draw_quad->surface_range.end());
   EXPECT_EQ(SK_ColorBLUE,
             out_primary_surface_draw_quad->default_background_color);
   EXPECT_EQ(fallback_surface_id,
-            out_primary_surface_draw_quad->fallback_surface_id);
+            out_primary_surface_draw_quad->surface_range.start());
 
   const RenderPassDrawQuad* out_render_pass_draw_quad =
       RenderPassDrawQuad::MaterialCast(output->quad_list.ElementAt(3));
diff --git a/services/viz/public/interfaces/compositing/quads.mojom b/services/viz/public/interfaces/compositing/quads.mojom
index c3184f8d34dcc..b1eaad0ab05fe 100644
--- a/services/viz/public/interfaces/compositing/quads.mojom
+++ b/services/viz/public/interfaces/compositing/quads.mojom
@@ -4,7 +4,7 @@
 
 module viz.mojom;
 
-import "services/viz/public/interfaces/compositing/surface_id.mojom";
+import "services/viz/public/interfaces/compositing/surface_range.mojom";
 import "services/viz/public/interfaces/compositing/shared_quad_state.mojom";
 import "ui/gfx/geometry/mojo/geometry.mojom";
 import "ui/gfx/mojo/color_space.mojom";
@@ -55,8 +55,7 @@ struct StreamVideoQuadState {
 };
 
 struct SurfaceQuadState {
-  SurfaceId primary_surface_id;
-  SurfaceId? fallback_surface_id;
+  SurfaceRange surface_range;
   uint32 default_background_color;
   bool stretch_content_to_fill_bounds;
 };