[go: nahoru, domu]

cc: Enable MSAA only for layers with slow paths.

Currently MSAA is controlled using a global switch for all layers which
is enabled based on whether currently painted content on any layer has
slow paths. Switching this state tears down all tile resources, both on
pending and active tree. As such this switching can be quite expensive
since we need to re-raster the entire visible viewport and causes jank,
because the active tree can not be redrawn until its tiles are ready.

For a long scrolling page where only some content of a layer has slow
paths, this switching can occur each time this content scrolls in and
out of the interest rect.

Avoid the above by allow MSAA to be applied on a per layer basis. Since
the decision changes only when the painted content of a layer is
updated, which should already be invalidated in that case, this avoids
any unnecessary raster invalidation.

R=ericrk@chromium.org

Bug: 1013758
Change-Id: I00678d21abb09b00c1246246076ee1a4e50d1822
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1891746
Auto-Submit: Khushal <khushalsagar@chromium.org>
Reviewed-by: Ilya Sherman <isherman@chromium.org>
Reviewed-by: Eric Karl <ericrk@chromium.org>
Commit-Queue: Khushal <khushalsagar@chromium.org>
Cr-Commit-Position: refs/heads/master@{#712297}
diff --git a/cc/layers/heads_up_display_layer_impl.cc b/cc/layers/heads_up_display_layer_impl.cc
index fb48799..5f16900 100644
--- a/cc/layers/heads_up_display_layer_impl.cc
+++ b/cc/layers/heads_up_display_layer_impl.cc
@@ -884,10 +884,6 @@
       status = "off (device)";
       color = SK_ColorRED;
       break;
-    case GpuRasterizationStatus::MSAA_CONTENT:
-      status = "MSAA (content)";
-      color = SK_ColorCYAN;
-      break;
   }
 
   if (status.empty())
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc
index 5aa9981..f64c500 100644
--- a/cc/layers/layer.cc
+++ b/cc/layers/layer.cc
@@ -1436,14 +1436,6 @@
   return false;
 }
 
-bool Layer::HasSlowPaths() const {
-  return false;
-}
-
-bool Layer::HasNonAAPaint() const {
-  return false;
-}
-
 void Layer::UpdateDebugInfo() {
   DCHECK(frame_viewer_instrumentation::IsTracingLayerTreeSnapshots());
   if (inputs_.client)
diff --git a/cc/layers/layer.h b/cc/layers/layer.h
index 3e1a5e5c..57458be 100644
--- a/cc/layers/layer.h
+++ b/cc/layers/layer.h
@@ -576,23 +576,6 @@
   // if there is anything new to commit. If all layers return false, the commit
   // may be aborted.
   virtual bool Update();
-  // Internal method to be overriden by Layer subclasses that override Update()
-  // and require rasterization. After Update() is called, this is immediately
-  // called, and should return whether the layer will require rasterization of
-  // paths that will be difficult/slow to raster. Only layers that do
-  // rasterization via TileManager need to override this, other layers that have
-  // content generated in other ways may leave it as the default.
-  virtual bool HasSlowPaths() const;
-  // Internal method to be overriden by Layer subclasses that override Update()
-  // and require rasterization. After Update() is called, this is immediately
-  // called, and should return whether the layer will require rasterization of a
-  // drawing operation that must not be anti-aliased. In this case using MSAA to
-  // antialias the entire layer's content would produce an incorrect result.
-  // This result is considered sticky, once a layer returns true, so false
-  // positives should be avoided. Only layers that do rasterization via
-  // TileManager need to override this, other layers that have content generated
-  // in other ways may leave it as the default.
-  virtual bool HasNonAAPaint() const;
 
   // Internal to property tree construction. This allows a layer to request that
   // its transform should be snapped such that the layer aligns with the pixel
diff --git a/cc/layers/picture_layer.cc b/cc/layers/picture_layer.cc
index d6c2c09..d13ed64 100644
--- a/cc/layers/picture_layer.cc
+++ b/cc/layers/picture_layer.cc
@@ -17,8 +17,6 @@
 #include "cc/trees/transform_node.h"
 #include "ui/gfx/geometry/rect_conversions.h"
 
-static constexpr int kMaxNumberOfSlowPathsBeforeReporting = 5;
-
 namespace cc {
 
 PictureLayer::PictureLayerInputs::PictureLayerInputs() = default;
@@ -189,22 +187,6 @@
   return raster_source->GetFlattenedPicture();
 }
 
-bool PictureLayer::HasSlowPaths() const {
-  // The display list needs to be created (see: UpdateAndExpandInvalidation)
-  // before checking for slow paths. There are cases where an update will not
-  // create a display list (e.g., if the size is empty). We return false in
-  // these cases because the slow paths bit sticks true.
-  return picture_layer_inputs_.display_list &&
-         picture_layer_inputs_.display_list->NumSlowPaths() >
-             kMaxNumberOfSlowPathsBeforeReporting;
-}
-
-bool PictureLayer::HasNonAAPaint() const {
-  // We return false by default, as this bit sticks true.
-  return picture_layer_inputs_.display_list &&
-         picture_layer_inputs_.display_list->HasNonAAPaint();
-}
-
 void PictureLayer::ClearClient() {
   picture_layer_inputs_.client = nullptr;
   UpdateDrawsContent(HasDrawableContent());
diff --git a/cc/layers/picture_layer.h b/cc/layers/picture_layer.h
index 8150e151..05e41d7 100644
--- a/cc/layers/picture_layer.h
+++ b/cc/layers/picture_layer.h
@@ -49,8 +49,6 @@
   void SetNeedsDisplayRect(const gfx::Rect& layer_rect) override;
   sk_sp<SkPicture> GetPicture() const override;
   bool Update() override;
-  bool HasSlowPaths() const override;
-  bool HasNonAAPaint() const override;
   void RunMicroBenchmark(MicroBenchmark* benchmark) override;
   void CaptureContent(const gfx::Rect& rect,
                       std::vector<NodeId>* content) override;
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
index 2369a661..e88484b 100644
--- a/cc/layers/picture_layer_impl.cc
+++ b/cc/layers/picture_layer_impl.cc
@@ -680,6 +680,17 @@
         SetPaintWorkletInputs({});
       }
     }
+
+    // If the MSAA sample count has changed, we need to re-raster the complete
+    // layer.
+    if (raster_source_ && raster_source_->GetDisplayItemList() &&
+        raster_source->GetDisplayItemList() &&
+        layer_tree_impl()->GetMSAASampleCountForRaster(
+            raster_source_->GetDisplayItemList()) !=
+            layer_tree_impl()->GetMSAASampleCountForRaster(
+                raster_source->GetDisplayItemList())) {
+      new_invalidation->Union(gfx::Rect(raster_source->GetSize()));
+    }
   }
 
   // The |raster_source_| is initially null, so have to check for that for the
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc
index 77fb247..67e1df6 100644
--- a/cc/layers/picture_layer_impl_unittest.cc
+++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -2491,73 +2491,6 @@
   EXPECT_NE(active_tiling->TileAt(0, 0), pending_tiling->TileAt(0, 0));
 }
 
-class MSAAEnabledPictureLayerImplTest : public PictureLayerImplTest {
- public:
-  LayerTreeSettings CreateSettings() override {
-    LayerTreeSettings settings = PictureLayerImplTest::CreateSettings();
-    settings.gpu_rasterization_msaa_sample_count = 1;
-    return settings;
-  }
-};
-
-TEST_F(MSAAEnabledPictureLayerImplTest, SyncTilingAfterMSAAToggles) {
-  host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
-
-  gfx::Size layer_bounds(10, 10);
-
-  scoped_refptr<FakeRasterSource> pending_raster_source =
-      FakeRasterSource::CreateFilled(layer_bounds);
-  scoped_refptr<FakeRasterSource> active_raster_source =
-      FakeRasterSource::CreateFilled(layer_bounds);
-
-  SetupTrees(pending_raster_source, active_raster_source);
-
-  EXPECT_TRUE(pending_layer()->tilings()->FindTilingWithScaleKey(1.f));
-  EXPECT_TRUE(active_layer()->tilings()->FindTilingWithScaleKey(1.f));
-
-  // MSAA is disabled by default.
-  EXPECT_FALSE(host_impl()->use_msaa());
-  EXPECT_EQ(0u, pending_layer()->release_tile_resources_count());
-  EXPECT_EQ(0u, active_layer()->release_tile_resources_count());
-  EXPECT_EQ(0u, pending_layer()->release_resources_count());
-  EXPECT_EQ(0u, active_layer()->release_resources_count());
-  // Toggling MSAA clears all tilings on both trees.
-  host_impl()->SetContentHasSlowPaths(true);
-  host_impl()->CommitComplete();
-  EXPECT_TRUE(host_impl()->use_msaa());
-  EXPECT_EQ(1u, pending_layer()->release_tile_resources_count());
-  EXPECT_EQ(1u, active_layer()->release_tile_resources_count());
-  EXPECT_EQ(1u, pending_layer()->release_resources_count());
-  EXPECT_EQ(1u, active_layer()->release_resources_count());
-
-  // But the pending layer gets a tiling back, and can activate it.
-  EXPECT_TRUE(pending_layer()->tilings()->FindTilingWithScaleKey(1.f));
-  EXPECT_EQ(0u, active_layer()->tilings()->num_tilings());
-
-  host_impl()->NotifyReadyToActivate();
-  ActivateTree();
-  EXPECT_TRUE(active_layer()->tilings()->FindTilingWithScaleKey(1.f));
-
-  SetupPendingTree(pending_raster_source);
-  EXPECT_TRUE(pending_layer()->tilings()->FindTilingWithScaleKey(1.f));
-
-  // Toggling msaa clears all tilings on both trees.
-  host_impl()->SetContentHasSlowPaths(false);
-  EXPECT_TRUE(host_impl()->use_msaa());
-  host_impl()->CommitComplete();
-  EXPECT_EQ(GpuRasterizationStatus::ON,
-            host_impl()->gpu_rasterization_status());
-  EXPECT_EQ(2u, pending_layer()->release_tile_resources_count());
-  EXPECT_EQ(2u, active_layer()->release_tile_resources_count());
-  EXPECT_EQ(2u, pending_layer()->release_resources_count());
-  EXPECT_EQ(2u, active_layer()->release_resources_count());
-  host_impl()->NotifyReadyToActivate();
-
-  host_impl()->CommitComplete();
-  EXPECT_EQ(GpuRasterizationStatus::ON,
-            host_impl()->gpu_rasterization_status());
-}
-
 TEST_F(LegacySWPictureLayerImplTest, HighResCreatedWhenBoundsShrink) {
   // Put 0.5 as high res.
   SetInitialDeviceScaleFactor(0.5f);
diff --git a/cc/layers/picture_layer_unittest.cc b/cc/layers/picture_layer_unittest.cc
index 9f8feab..daf3676 100644
--- a/cc/layers/picture_layer_unittest.cc
+++ b/cc/layers/picture_layer_unittest.cc
@@ -227,76 +227,6 @@
   host_impl.active_tree()->root_layer()->DidDraw(nullptr);
 }
 
-TEST(PictureLayerTest, HasSlowPaths) {
-  std::unique_ptr<FakeRecordingSource> recording_source_owned(
-      new FakeRecordingSource);
-  FakeRecordingSource* recording_source = recording_source_owned.get();
-
-  gfx::Size layer_bounds(200, 200);
-  gfx::Rect layer_rect(layer_bounds);
-  Region invalidation(layer_rect);
-
-  FakeContentLayerClient client;
-  client.set_bounds(layer_bounds);
-  scoped_refptr<FakePictureLayer> layer =
-      FakePictureLayer::CreateWithRecordingSource(
-          &client, std::move(recording_source_owned));
-
-  FakeLayerTreeHostClient host_client;
-  TestTaskGraphRunner task_graph_runner;
-  auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
-  std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(
-      &host_client, &task_graph_runner, animation_host.get());
-  host->SetRootLayer(layer);
-
-  recording_source->SetNeedsDisplayRect(layer_rect);
-  layer->Update();
-
-  // Layer does not have slow paths by default.
-  EXPECT_FALSE(layer->HasSlowPaths());
-
-  // Add slow-path content to the client.
-  client.set_contains_slow_paths(true);
-  recording_source->SetNeedsDisplayRect(layer_rect);
-  layer->Update();
-  EXPECT_TRUE(layer->HasSlowPaths());
-}
-
-TEST(PictureLayerTest, HasNonAAPaint) {
-  std::unique_ptr<FakeRecordingSource> recording_source_owned(
-      new FakeRecordingSource);
-  FakeRecordingSource* recording_source = recording_source_owned.get();
-
-  gfx::Size layer_bounds(200, 200);
-  gfx::Rect layer_rect(layer_bounds);
-  Region invalidation(layer_rect);
-
-  FakeContentLayerClient client;
-  client.set_bounds(layer_bounds);
-  scoped_refptr<FakePictureLayer> layer =
-      FakePictureLayer::CreateWithRecordingSource(
-          &client, std::move(recording_source_owned));
-
-  FakeLayerTreeHostClient host_client;
-  TestTaskGraphRunner task_graph_runner;
-  auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
-  std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create(
-      &host_client, &task_graph_runner, animation_host.get());
-  host->SetRootLayer(layer);
-
-  recording_source->SetNeedsDisplayRect(layer_rect);
-  layer->Update();
-
-  // Layer does not have non-aa paint by default.
-  EXPECT_FALSE(layer->HasNonAAPaint());
-
-  // Add non-aa content to the client.
-  client.add_draw_rect(layer_rect, PaintFlags());
-  recording_source->SetNeedsDisplayRect(layer_rect);
-  layer->Update();
-  EXPECT_TRUE(layer->HasNonAAPaint());
-}
-
 // PicturePile uses the source frame number as a unit for measuring invalidation
 // frequency. When a pile moves between compositors, the frame number increases
 // non-monotonically. This executes that code path under this scenario allowing
diff --git a/cc/layers/texture_layer_impl_unittest.cc b/cc/layers/texture_layer_impl_unittest.cc
index dad5205..0e46ca0 100644
--- a/cc/layers/texture_layer_impl_unittest.cc
+++ b/cc/layers/texture_layer_impl_unittest.cc
@@ -102,41 +102,5 @@
   }
 }
 
-TEST(TextureLayerImplTest, ResourceNotFreedOnMSAAToggle) {
-  bool released = false;
-  LayerTreeImplTestBase impl(
-      FakeLayerTreeFrameSink::Create3dForGpuRasterization());
-  impl.host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
-
-  gfx::Size layer_size(1000, 1000);
-  gfx::Size viewport_size(1000, 1000);
-
-  viz::TransferableResource resource;
-  resource.is_software = false;
-  resource.mailbox_holder.mailbox = gpu::Mailbox::Generate();
-  resource.mailbox_holder.sync_token =
-      gpu::SyncToken(gpu::CommandBufferNamespace::GPU_IO,
-                     gpu::CommandBufferId::FromUnsafeValue(0x234), 0x456);
-  resource.mailbox_holder.texture_target = GL_TEXTURE_2D;
-
-  TextureLayerImpl* texture_layer_impl = impl.AddLayer<TextureLayerImpl>();
-  texture_layer_impl->SetBounds(layer_size);
-  texture_layer_impl->SetDrawsContent(true);
-  texture_layer_impl->SetTransferableResource(
-      resource, viz::SingleReleaseCallback::Create(base::BindOnce(
-                    [](bool* released, const gpu::SyncToken& sync_token,
-                       bool lost) { *released = true; },
-                    base::Unretained(&released))));
-  CopyProperties(impl.root_layer(), texture_layer_impl);
-
-  impl.CalcDrawProps(viewport_size);
-
-  EXPECT_FALSE(released);
-  // Toggling MSAA clears all tilings on both trees.
-  impl.host_impl()->SetContentHasSlowPaths(true);
-  impl.host_impl()->CommitComplete();
-  EXPECT_FALSE(released);
-}
-
 }  // namespace
 }  // namespace cc
diff --git a/cc/raster/gpu_raster_buffer_provider.cc b/cc/raster/gpu_raster_buffer_provider.cc
index cbe878b..481e7be9 100644
--- a/cc/raster/gpu_raster_buffer_provider.cc
+++ b/cc/raster/gpu_raster_buffer_provider.cc
@@ -128,8 +128,7 @@
     const gfx::Rect& playback_rect,
     const gfx::AxisTransform2d& transform,
     const RasterSource::PlaybackSettings& playback_settings,
-    viz::RasterContextProvider* context_provider,
-    int msaa_sample_count) {
+    viz::RasterContextProvider* context_provider) {
   gpu::raster::RasterInterface* ri = context_provider->RasterInterface();
   if (mailbox->IsZero()) {
     DCHECK(!sync_token.HasData());
@@ -146,9 +145,9 @@
     ri->WaitSyncTokenCHROMIUM(sync_token.GetConstData());
   }
 
-  ri->BeginRasterCHROMIUM(raster_source->background_color(), msaa_sample_count,
-                          playback_settings.use_lcd_text, color_space,
-                          mailbox->name);
+  ri->BeginRasterCHROMIUM(
+      raster_source->background_color(), playback_settings.msaa_sample_count,
+      playback_settings.use_lcd_text, color_space, mailbox->name);
   float recording_to_raster_scale =
       transform.scale() / raster_source->recording_scale_factor();
   gfx::Size content_size = raster_source->GetContentSize(transform.scale());
@@ -183,7 +182,6 @@
     const gfx::AxisTransform2d& transform,
     const RasterSource::PlaybackSettings& playback_settings,
     viz::RasterContextProvider* context_provider,
-    int msaa_sample_count,
     bool unpremultiply_and_dither,
     const gfx::Size& max_tile_size) {
   gpu::raster::RasterInterface* ri = context_provider->RasterInterface();
@@ -215,13 +213,13 @@
       scoped_surface.emplace(context_provider->GrContext(), sk_color_space,
                              texture_id, texture_target, resource_size,
                              resource_format, playback_settings.use_lcd_text,
-                             msaa_sample_count);
+                             playback_settings.msaa_sample_count);
       surface = scoped_surface->surface();
     } else {
       scoped_dither_surface.emplace(
           context_provider, sk_color_space, playback_rect, raster_full_rect,
           max_tile_size, texture_id, resource_size,
-          playback_settings.use_lcd_text, msaa_sample_count);
+          playback_settings.use_lcd_text, playback_settings.msaa_sample_count);
       surface = scoped_dither_surface->surface();
     }
 
@@ -346,7 +344,6 @@
     viz::ContextProvider* compositor_context_provider,
     viz::RasterContextProvider* worker_context_provider,
     bool use_gpu_memory_buffer_resources,
-    int gpu_rasterization_msaa_sample_count,
     viz::ResourceFormat tile_format,
     const gfx::Size& max_tile_size,
     bool unpremultiply_and_dither_low_bit_depth_tiles,
@@ -355,7 +352,6 @@
     : compositor_context_provider_(compositor_context_provider),
       worker_context_provider_(worker_context_provider),
       use_gpu_memory_buffer_resources_(use_gpu_memory_buffer_resources),
-      msaa_sample_count_(gpu_rasterization_msaa_sample_count),
       tile_format_(tile_format),
       max_tile_size_(max_tile_size),
       unpremultiply_and_dither_low_bit_depth_tiles_(
@@ -402,13 +398,6 @@
   return !ShouldUnpremultiplyAndDitherResource(GetResourceFormat());
 }
 
-bool GpuRasterBufferProvider::CanPartialRasterIntoProvidedResource() const {
-  // Partial raster doesn't support MSAA, as the MSAA resolve is unaware of clip
-  // rects.
-  // TODO(crbug.com/629683): See if we can work around this limitation.
-  return msaa_sample_count_ == 0;
-}
-
 bool GpuRasterBufferProvider::IsResourceReadyToDraw(
     const ResourcePool::InUsePoolResource& resource) const {
   const gpu::SyncToken& sync_token = resource.gpu_backing()->mailbox_sync_token;
@@ -421,6 +410,10 @@
       sync_token);
 }
 
+bool GpuRasterBufferProvider::CanPartialRasterIntoProvidedResource() const {
+  return true;
+}
+
 uint64_t GpuRasterBufferProvider::SetReadyToDrawCallback(
     const std::vector<const ResourcePool::InUsePoolResource*>& resources,
     base::OnceClosure callback,
@@ -566,19 +559,17 @@
     if (measure_raster_metric)
       timer.emplace();
     if (enable_oop_rasterization_) {
-      RasterizeSourceOOP(raster_source, resource_has_previous_content, mailbox,
-                         sync_token, texture_target,
-                         texture_is_overlay_candidate, resource_size,
-                         resource_format, color_space, raster_full_rect,
-                         playback_rect, transform, playback_settings,
-                         worker_context_provider_, msaa_sample_count_);
+      RasterizeSourceOOP(
+          raster_source, resource_has_previous_content, mailbox, sync_token,
+          texture_target, texture_is_overlay_candidate, resource_size,
+          resource_format, color_space, raster_full_rect, playback_rect,
+          transform, playback_settings, worker_context_provider_);
     } else {
       RasterizeSource(raster_source, resource_has_previous_content, mailbox,
                       sync_token, texture_target, texture_is_overlay_candidate,
                       resource_size, resource_format, color_space,
                       raster_full_rect, playback_rect, transform,
                       playback_settings, worker_context_provider_,
-                      msaa_sample_count_,
                       ShouldUnpremultiplyAndDitherResource(resource_format),
                       max_tile_size_);
     }
diff --git a/cc/raster/gpu_raster_buffer_provider.h b/cc/raster/gpu_raster_buffer_provider.h
index 2f54037b..101d5b5e 100644
--- a/cc/raster/gpu_raster_buffer_provider.h
+++ b/cc/raster/gpu_raster_buffer_provider.h
@@ -32,7 +32,6 @@
       viz::ContextProvider* compositor_context_provider,
       viz::RasterContextProvider* worker_context_provider,
       bool use_gpu_memory_buffer_resources,
-      int gpu_rasterization_msaa_sample_count,
       viz::ResourceFormat tile_format,
       const gfx::Size& max_tile_size,
       bool unpremultiply_and_dither_low_bit_depth_tiles,
@@ -161,7 +160,6 @@
   viz::ContextProvider* const compositor_context_provider_;
   viz::RasterContextProvider* const worker_context_provider_;
   const bool use_gpu_memory_buffer_resources_;
-  const int msaa_sample_count_;
   const viz::ResourceFormat tile_format_;
   const gfx::Size max_tile_size_;
   const bool unpremultiply_and_dither_low_bit_depth_tiles_;
diff --git a/cc/raster/raster_buffer_provider_perftest.cc b/cc/raster/raster_buffer_provider_perftest.cc
index 66391be..5567363 100644
--- a/cc/raster/raster_buffer_provider_perftest.cc
+++ b/cc/raster/raster_buffer_provider_perftest.cc
@@ -371,7 +371,7 @@
         Create3dResourceProvider();
         raster_buffer_provider_ = std::make_unique<GpuRasterBufferProvider>(
             compositor_context_provider_.get(), worker_context_provider_.get(),
-            false, 0, viz::RGBA_8888, gfx::Size(), true, false);
+            false, viz::RGBA_8888, gfx::Size(), true, false);
         break;
       case RASTER_BUFFER_PROVIDER_TYPE_BITMAP:
         CreateSoftwareResourceProvider();
diff --git a/cc/raster/raster_buffer_provider_unittest.cc b/cc/raster/raster_buffer_provider_unittest.cc
index 391ee0eb..53e05cf 100644
--- a/cc/raster/raster_buffer_provider_unittest.cc
+++ b/cc/raster/raster_buffer_provider_unittest.cc
@@ -225,13 +225,13 @@
       case RASTER_BUFFER_PROVIDER_TYPE_GPU:
         Create3dResourceProvider();
         raster_buffer_provider_ = std::make_unique<GpuRasterBufferProvider>(
-            context_provider_.get(), worker_context_provider_.get(), false, 0,
+            context_provider_.get(), worker_context_provider_.get(), false,
             viz::RGBA_8888, gfx::Size(), true, false, 1);
         break;
       case RASTER_BUFFER_PROVIDER_TYPE_GPU_OOPR:
         Create3dResourceProvider();
         raster_buffer_provider_ = std::make_unique<GpuRasterBufferProvider>(
-            context_provider_.get(), worker_context_provider_.get(), false, 0,
+            context_provider_.get(), worker_context_provider_.get(), false,
             viz::RGBA_8888, gfx::Size(), true, true, 1);
         break;
       case RASTER_BUFFER_PROVIDER_TYPE_BITMAP:
diff --git a/cc/raster/raster_source.h b/cc/raster/raster_source.h
index bbf9f14..33b3564 100644
--- a/cc/raster/raster_source.h
+++ b/cc/raster/raster_source.h
@@ -38,6 +38,9 @@
     // If set to true, we should use LCD text.
     bool use_lcd_text = true;
 
+    // Specifies the sample count if MSAA is enabled for this tile.
+    int msaa_sample_count = 0;
+
     ImageProvider* image_provider = nullptr;
   };
 
diff --git a/cc/test/fake_content_layer_client.cc b/cc/test/fake_content_layer_client.cc
index 99c2183..685cf22c 100644
--- a/cc/test/fake_content_layer_client.cc
+++ b/cc/test/fake_content_layer_client.cc
@@ -26,13 +26,7 @@
 
 FakeContentLayerClient::ImageData::~ImageData() = default;
 
-FakeContentLayerClient::FakeContentLayerClient()
-    : fill_with_nonsolid_color_(false),
-      last_canvas_(nullptr),
-      last_painting_control_(PAINTING_BEHAVIOR_NORMAL),
-      reported_memory_usage_(0),
-      bounds_set_(false),
-      contains_slow_paths_(false) {}
+FakeContentLayerClient::FakeContentLayerClient() = default;
 
 FakeContentLayerClient::~FakeContentLayerClient() = default;
 
@@ -108,6 +102,14 @@
     display_list->EndPaintOfUnpaired(PaintableRegion());
   }
 
+  if (has_non_aa_paint_) {
+    PaintFlags flags;
+    flags.setAntiAlias(false);
+    display_list->StartPaint();
+    display_list->push<DrawRectOp>(SkRect::MakeWH(10, 10), flags);
+    display_list->EndPaintOfUnpaired(PaintableRegion());
+  }
+
   display_list->Finalize();
   return display_list;
 }
diff --git a/cc/test/fake_content_layer_client.h b/cc/test/fake_content_layer_client.h
index acb16f4..91d43e9 100644
--- a/cc/test/fake_content_layer_client.h
+++ b/cc/test/fake_content_layer_client.h
@@ -56,6 +56,10 @@
     contains_slow_paths_ = contains_slow_paths;
   }
 
+  void set_has_non_aa_paint(bool has_non_aa_paint) {
+    has_non_aa_paint_ = has_non_aa_paint;
+  }
+
   void add_draw_rect(const gfx::Rect& rect, const PaintFlags& flags) {
     draw_rects_.push_back(std::make_pair(gfx::RectF(rect), flags));
   }
@@ -107,15 +111,16 @@
   using RectPaintVector = std::vector<std::pair<gfx::RectF, PaintFlags>>;
   using ImageVector = std::vector<ImageData>;
 
-  bool fill_with_nonsolid_color_;
+  bool fill_with_nonsolid_color_ = false;
   RectPaintVector draw_rects_;
   ImageVector draw_images_;
-  SkCanvas* last_canvas_;
-  PaintingControlSetting last_painting_control_;
-  size_t reported_memory_usage_;
+  SkCanvas* last_canvas_ = nullptr;
+  PaintingControlSetting last_painting_control_ = PAINTING_BEHAVIOR_NORMAL;
+  size_t reported_memory_usage_ = 0;
   gfx::Size bounds_;
-  bool bounds_set_;
-  bool contains_slow_paths_;
+  bool bounds_set_ = false;
+  bool contains_slow_paths_ = false;
+  bool has_non_aa_paint_ = false;
 };
 
 }  // namespace cc
diff --git a/cc/test/fake_picture_layer.cc b/cc/test/fake_picture_layer.cc
index c7afffe..5550c05 100644
--- a/cc/test/fake_picture_layer.cc
+++ b/cc/test/fake_picture_layer.cc
@@ -39,16 +39,4 @@
   return updated || always_update_resources_;
 }
 
-bool FakePictureLayer::HasSlowPaths() const {
-  if (force_content_has_slow_paths_)
-    return true;
-  return PictureLayer::HasSlowPaths();
-}
-
-bool FakePictureLayer::HasNonAAPaint() const {
-  if (force_content_has_non_aa_paint_)
-    return true;
-  return PictureLayer::HasNonAAPaint();
-}
-
 }  // namespace cc
diff --git a/cc/test/fake_picture_layer.h b/cc/test/fake_picture_layer.h
index ad56115..34e860a 100644
--- a/cc/test/fake_picture_layer.h
+++ b/cc/test/fake_picture_layer.h
@@ -30,8 +30,6 @@
   // Layer implementation.
   std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
   bool Update() override;
-  bool HasSlowPaths() const override;
-  bool HasNonAAPaint() const override;
 
   int update_count() const { return update_count_; }
   void reset_update_count() { update_count_ = 0; }
@@ -40,14 +38,6 @@
     always_update_resources_ = always_update_resources;
   }
 
-  void set_force_content_has_slow_paths(bool flag) {
-    force_content_has_slow_paths_ = flag;
-  }
-
-  void set_force_content_has_non_aa_paint(bool flag) {
-    force_content_has_non_aa_paint_ = flag;
-  }
-
   void set_fixed_tile_size(gfx::Size fixed_tile_size) {
     fixed_tile_size_ = fixed_tile_size;
   }
@@ -61,8 +51,6 @@
   int update_count_ = 0;
   bool always_update_resources_ = false;
 
-  bool force_content_has_slow_paths_ = false;
-  bool force_content_has_non_aa_paint_ = false;
   gfx::Size fixed_tile_size_;
 };
 
diff --git a/cc/test/fake_recording_source.h b/cc/test/fake_recording_source.h
index a09e430..cf53877 100644
--- a/cc/test/fake_recording_source.h
+++ b/cc/test/fake_recording_source.h
@@ -68,6 +68,14 @@
     client_.set_fill_with_nonsolid_color(nonsolid);
   }
 
+  void set_has_non_aa_paint(bool has_non_aa_paint) {
+    client_.set_has_non_aa_paint(has_non_aa_paint);
+  }
+
+  void set_has_slow_paths(bool slow_paths) {
+    client_.set_contains_slow_paths(slow_paths);
+  }
+
   void Rerecord() {
     SetNeedsDisplayRect(recorded_viewport_);
     Region invalidation;
@@ -143,6 +151,10 @@
     recording_scale_factor_ = recording_scale_factor;
   }
 
+  const scoped_refptr<DisplayItemList> GetDisplayItemList() const {
+    return display_list_;
+  }
+
  private:
   FakeContentLayerClient client_;
   PaintFlags default_flags_;
diff --git a/cc/test/fake_tile_manager_client.cc b/cc/test/fake_tile_manager_client.cc
index 8411d78..032400bd 100644
--- a/cc/test/fake_tile_manager_client.cc
+++ b/cc/test/fake_tile_manager_client.cc
@@ -33,4 +33,9 @@
   return PaintImage::kDefaultFrameIndex;
 }
 
+int FakeTileManagerClient::GetMSAASampleCountForRaster(
+    const scoped_refptr<DisplayItemList>& display_list) {
+  return 0;
+}
+
 }  // namespace cc
diff --git a/cc/test/fake_tile_manager_client.h b/cc/test/fake_tile_manager_client.h
index 791beb93..43527eb 100644
--- a/cc/test/fake_tile_manager_client.h
+++ b/cc/test/fake_tile_manager_client.h
@@ -31,6 +31,8 @@
   void RequestImplSideInvalidationForCheckerImagedTiles() override {}
   size_t GetFrameIndexForImage(const PaintImage& paint_image,
                                WhichTree tree) const override;
+  int GetMSAASampleCountForRaster(
+      const scoped_refptr<DisplayItemList>& display_list) override;
 
  private:
   gfx::ColorSpace color_space_;
diff --git a/cc/test/layer_tree_pixel_resource_test.cc b/cc/test/layer_tree_pixel_resource_test.cc
index d813b248..dd9e71b 100644
--- a/cc/test/layer_tree_pixel_resource_test.cc
+++ b/cc/test/layer_tree_pixel_resource_test.cc
@@ -99,7 +99,7 @@
       EXPECT_NE(RENDERER_SOFTWARE, renderer_type());
       bool enable_oopr = renderer_type() == RENDERER_SKIA_VK;
       return std::make_unique<GpuRasterBufferProvider>(
-          compositor_context_provider, worker_context_provider, false, 0,
+          compositor_context_provider, worker_context_provider, false,
           gpu_raster_format, gfx::Size(), true, enable_oopr);
     }
     case ZERO_COPY:
diff --git a/cc/tiles/tile_manager.cc b/cc/tiles/tile_manager.cc
index f1d6625..4e0cd9a 100644
--- a/cc/tiles/tile_manager.cc
+++ b/cc/tiles/tile_manager.cc
@@ -1129,11 +1129,14 @@
   TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
                "TileManager::CreateRasterTask", "Tile", tile->id());
 
+  const int msaa_sample_count = client_->GetMSAASampleCountForRaster(
+      prioritized_tile.raster_source()->GetDisplayItemList());
+
   // Get the resource.
   ResourcePool::InUsePoolResource resource;
   uint64_t resource_content_id = 0;
   gfx::Rect invalidated_rect = tile->invalidated_content_rect();
-  if (UsePartialRaster() && tile->invalidated_id()) {
+  if (UsePartialRaster(msaa_sample_count) && tile->invalidated_id()) {
     resource = resource_pool_->TryAcquireResourceForPartialRaster(
         tile->id(), tile->invalidated_content_rect(), tile->invalidated_id(),
         &invalidated_rect);
@@ -1156,6 +1159,7 @@
   const bool skip_images =
       prioritized_tile.priority().resolution == LOW_RESOLUTION;
   playback_settings.use_lcd_text = tile->can_use_lcd_text();
+  playback_settings.msaa_sample_count = msaa_sample_count;
 
   // Create and queue all image decode tasks that this tile depends on. Note
   // that we need to store the images for decode tasks in
@@ -1605,9 +1609,13 @@
   return std::move(state);
 }
 
-bool TileManager::UsePartialRaster() const {
+bool TileManager::UsePartialRaster(int msaa_sample_count) const {
+  // Partial raster doesn't support MSAA, as the MSAA resolve is unaware of clip
+  // rects.
+  // TODO(crbug.com/629683): See if we can work around this limitation.
   return tile_manager_settings_.use_partial_raster &&
-         raster_buffer_provider_->CanPartialRasterIntoProvidedResource();
+         raster_buffer_provider_->CanPartialRasterIntoProvidedResource() &&
+         msaa_sample_count == 0;
 }
 
 void TileManager::CheckPendingGpuWorkAndIssueSignals() {
diff --git a/cc/tiles/tile_manager.h b/cc/tiles/tile_manager.h
index afa7d42..b92d4e8 100644
--- a/cc/tiles/tile_manager.h
+++ b/cc/tiles/tile_manager.h
@@ -87,9 +87,14 @@
   // rasterized with missing images need to be invalidated.
   virtual void RequestImplSideInvalidationForCheckerImagedTiles() = 0;
 
+  // Returns the frame index to display for the given image on the given tree.
   virtual size_t GetFrameIndexForImage(const PaintImage& paint_image,
                                        WhichTree tree) const = 0;
 
+  // Returns the sample count to use if MSAA is enabled for a tile.
+  virtual int GetMSAASampleCountForRaster(
+      const scoped_refptr<DisplayItemList>& display_list) = 0;
+
  protected:
   virtual ~TileManagerClient() {}
 };
@@ -399,7 +404,7 @@
   std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
   ScheduledTasksStateAsValue() const;
 
-  bool UsePartialRaster() const;
+  bool UsePartialRaster(int msaa_sample_count) const;
 
   void FlushAndIssueSignals();
   void CheckPendingGpuWorkAndIssueSignals();
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc
index dfc42e30..0eca5ea7 100644
--- a/cc/trees/layer_tree_host.cc
+++ b/cc/trees/layer_tree_host.cc
@@ -557,8 +557,6 @@
     ukm_recorder_factory_.reset();
   }
 
-  host_impl->SetContentHasSlowPaths(content_has_slow_paths_);
-  host_impl->SetContentHasNonAAPaint(content_has_non_aa_paint_);
   task_graph_runner_ = nullptr;
   input_handler_weak_ptr_ = host_impl->AsWeakPtr();
   return host_impl;
@@ -778,13 +776,6 @@
   // mostly used for debugging purposes.
   UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationEnabled",
                         gpu_rasterization_enabled);
-  if (gpu_rasterization_enabled) {
-    UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationSuitableContent",
-                          !content_has_slow_paths_);
-    UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationSlowPathsWithNonAAPaint",
-                          content_has_slow_paths_ && content_has_non_aa_paint_);
-  }
-
   gpu_rasterization_histogram_recorded_ = true;
 }
 
@@ -862,31 +853,7 @@
 
   LayerList update_layer_list;
   draw_property_utils::FindLayersThatNeedUpdates(this, &update_layer_list);
-
-  bool painted_content_has_slow_paths = false;
-  bool painted_content_has_non_aa_paint = false;
-  bool did_paint_content =
-      PaintContent(update_layer_list, &painted_content_has_slow_paths,
-                   &painted_content_has_non_aa_paint);
-
-  // |painted_content_has_non_aa_paint| is a correctness (not performance)
-  // modifier, if it changes we immediately update. To prevent churn, this flag
-  // is sticky.
-  content_has_non_aa_paint_ |= painted_content_has_non_aa_paint;
-
-  // If no slow-path content has appeared for a required number of frames,
-  // update the flag.
-  if (!painted_content_has_slow_paths) {
-    ++num_consecutive_frames_without_slow_paths_;
-    if (num_consecutive_frames_without_slow_paths_ >=
-        kNumFramesToConsiderBeforeRemovingSlowPathFlag) {
-      content_has_slow_paths_ = false;
-    }
-  } else {
-    num_consecutive_frames_without_slow_paths_ = 0;
-    content_has_slow_paths_ = true;
-  }
-
+  bool did_paint_content = PaintContent(update_layer_list);
   return did_paint_content;
 }
 
@@ -1095,8 +1062,6 @@
 
   // Reset gpu rasterization tracking.
   // This flag is sticky until a new tree comes along.
-  content_has_slow_paths_ = false;
-  content_has_non_aa_paint_ = false;
   gpu_rasterization_histogram_recorded_ = false;
 
   force_use_property_tree_builder_ = false;
@@ -1442,15 +1407,11 @@
   return iter != layer_id_map_.end() ? iter->second : nullptr;
 }
 
-bool LayerTreeHost::PaintContent(const LayerList& update_layer_list,
-                                 bool* content_has_slow_paths,
-                                 bool* content_has_non_aa_paint) {
+bool LayerTreeHost::PaintContent(const LayerList& update_layer_list) {
   base::AutoReset<bool> painting(&in_paint_layer_contents_, true);
   bool did_paint_content = false;
   for (const auto& layer : update_layer_list) {
     did_paint_content |= layer->Update();
-    *content_has_slow_paths |= layer->HasSlowPaths();
-    *content_has_non_aa_paint |= layer->HasNonAAPaint();
   }
   return did_paint_content;
 }
@@ -1624,8 +1585,6 @@
 
 void LayerTreeHost::PushLayerTreeHostPropertiesTo(
     LayerTreeHostImpl* host_impl) {
-  host_impl->SetContentHasSlowPaths(content_has_slow_paths_);
-  host_impl->SetContentHasNonAAPaint(content_has_non_aa_paint_);
   host_impl->set_external_pinch_gesture_active(
       is_external_pinch_gesture_active_);
   RecordGpuRasterizationHistogram(host_impl);
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h
index 0f9d1ed..d4e9352 100644
--- a/cc/trees/layer_tree_host.h
+++ b/cc/trees/layer_tree_host.h
@@ -478,9 +478,7 @@
   void UnregisterLayer(Layer* layer);
   Layer* LayerById(int id) const;
 
-  bool PaintContent(const LayerList& update_layer_list,
-                    bool* content_has_slow_paths,
-                    bool* content_has_non_aa_paint);
+  bool PaintContent(const LayerList& update_layer_list);
   bool in_paint_layer_contents() const { return in_paint_layer_contents_; }
 
   void SetHasCopyRequest(bool has_copy_request);
@@ -751,8 +749,6 @@
 
   bool visible_ = false;
 
-  bool content_has_slow_paths_ = false;
-  bool content_has_non_aa_paint_ = false;
   bool gpu_rasterization_histogram_recorded_ = false;
 
   // If set, then page scale animation has completed, but the client hasn't been
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index b5fc8437..7446dd4 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -1862,6 +1862,21 @@
       paint_image.stable_id(), tree);
 }
 
+int LayerTreeHostImpl::GetMSAASampleCountForRaster(
+    const scoped_refptr<DisplayItemList>& display_list) {
+  constexpr int kMinNumberOfSlowPathsForMSAA = 6;
+  if (display_list->NumSlowPaths() < kMinNumberOfSlowPathsForMSAA)
+    return 0;
+
+  if (!can_use_msaa_)
+    return 0;
+
+  if (display_list->HasNonAAPaint() && !supports_disable_msaa_)
+    return 0;
+
+  return RequestedMSAASampleCount();
+}
+
 void LayerTreeHostImpl::NotifyReadyToActivate() {
   // The TileManager may call this method while the pending tree is still being
   // painted, as it isn't aware of the ongoing paint. We shouldn't tell the
@@ -2432,20 +2447,6 @@
   return settings_.gpu_rasterization_msaa_sample_count;
 }
 
-void LayerTreeHostImpl::SetContentHasSlowPaths(bool flag) {
-  if (content_has_slow_paths_ != flag) {
-    content_has_slow_paths_ = flag;
-    need_update_gpu_rasterization_status_ = true;
-  }
-}
-
-void LayerTreeHostImpl::SetContentHasNonAAPaint(bool flag) {
-  if (content_has_non_aa_paint_ != flag) {
-    content_has_non_aa_paint_ = flag;
-    need_update_gpu_rasterization_status_ = true;
-  }
-}
-
 void LayerTreeHostImpl::GetGpuRasterizationCapabilities(
     bool* gpu_rasterization_enabled,
     bool* gpu_rasterization_supported,
@@ -2536,23 +2537,14 @@
                                   &max_msaa_samples, &supports_disable_msaa);
 
   bool use_gpu = false;
-  bool use_msaa = false;
-  bool using_msaa_for_slow_paths =
-      requested_msaa_samples > 0 &&
-      max_msaa_samples >= requested_msaa_samples &&
-      (!content_has_non_aa_paint_ || supports_disable_msaa);
+  bool can_use_msaa =
+      requested_msaa_samples > 0 && max_msaa_samples >= requested_msaa_samples;
+
   if (settings_.gpu_rasterization_forced) {
     use_gpu = true;
     gpu_rasterization_status_ = GpuRasterizationStatus::ON_FORCED;
-    use_msaa = content_has_slow_paths_ && using_msaa_for_slow_paths;
-    if (use_msaa) {
-      gpu_rasterization_status_ = GpuRasterizationStatus::MSAA_CONTENT;
-    }
   } else if (!gpu_rasterization_enabled) {
     gpu_rasterization_status_ = GpuRasterizationStatus::OFF_DEVICE;
-  } else if (content_has_slow_paths_ && using_msaa_for_slow_paths) {
-    use_gpu = use_msaa = true;
-    gpu_rasterization_status_ = GpuRasterizationStatus::MSAA_CONTENT;
   } else {
     use_gpu = true;
     gpu_rasterization_status_ = GpuRasterizationStatus::ON;
@@ -2564,18 +2556,24 @@
       // be created due to losing the GL context, force use of software
       // raster.
       use_gpu = false;
-      use_msaa = false;
+      can_use_msaa_ = false;
+      supports_disable_msaa_ = false;
       gpu_rasterization_status_ = GpuRasterizationStatus::OFF_DEVICE;
     }
   }
 
-  if (use_gpu == use_gpu_rasterization_ && use_msaa == use_msaa_)
+  // Changes in MSAA settings require that we re-raster resources for the
+  // settings to take effect. But we don't need to trigger any raster
+  // invalidation in this case since these settings change only if the context
+  // changed. In this case we already re-allocate and re-raster all resources.
+  if (use_gpu == use_gpu_rasterization_ && can_use_msaa == can_use_msaa_ &&
+      supports_disable_msaa == supports_disable_msaa_) {
     return false;
+  }
 
-  // Note that this must happen first, in case the rest of the calls want to
-  // query the new state of |use_gpu_rasterization_|.
   use_gpu_rasterization_ = use_gpu;
-  use_msaa_ = use_msaa;
+  can_use_msaa_ = can_use_msaa;
+  supports_disable_msaa_ = supports_disable_msaa;
   return true;
 }
 
@@ -3243,11 +3241,10 @@
   if (use_gpu_rasterization_) {
     DCHECK(worker_context_provider);
 
-    int msaa_sample_count = use_msaa_ ? RequestedMSAASampleCount() : 0;
     return std::make_unique<GpuRasterBufferProvider>(
         compositor_context_provider, worker_context_provider,
         settings_.resource_settings.use_gpu_memory_buffer_resources,
-        msaa_sample_count, tile_format, settings_.max_gpu_raster_tile_size,
+        tile_format, settings_.max_gpu_raster_tile_size,
         settings_.unpremultiply_and_dither_low_bit_depth_tiles,
         use_oop_rasterization_);
   }
@@ -3478,9 +3475,9 @@
     use_oop_rasterization_ = false;
   }
 
-  // Since the new context may be capable of MSAA, update status here. We don't
-  // need to check the return value since we are recreating all resources
-  // already.
+  // Since the new context may support GPU raster or be capable of MSAA, update
+  // status here. We don't need to check the return value since we are
+  // recreating all resources already.
   SetNeedUpdateGpuRasterizationStatus();
   UpdateGpuRasterizationStatus();
 
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index 2c74597..73f79db8 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -106,7 +106,6 @@
   ON,
   ON_FORCED,
   OFF_DEVICE,
-  MSAA_CONTENT,
 };
 
 enum class ImplThreadPhase {
@@ -474,6 +473,8 @@
   void RequestImplSideInvalidationForCheckerImagedTiles() override;
   size_t GetFrameIndexForImage(const PaintImage& paint_image,
                                WhichTree tree) const override;
+  int GetMSAASampleCountForRaster(
+      const scoped_refptr<DisplayItemList>& display_list) override;
 
   // ScrollbarAnimationControllerClient implementation.
   void PostDelayedScrollbarAnimationTask(base::OnceClosure task,
@@ -524,15 +525,12 @@
   virtual bool InitializeFrameSink(LayerTreeFrameSink* layer_tree_frame_sink);
   TileManager* tile_manager() { return &tile_manager_; }
 
-  void SetContentHasSlowPaths(bool flag);
-  void SetContentHasNonAAPaint(bool flag);
   void GetGpuRasterizationCapabilities(bool* gpu_rasterization_enabled,
                                        bool* gpu_rasterization_supported,
                                        int* max_msaa_samples,
                                        bool* supports_disable_msaa);
   bool use_gpu_rasterization() const { return use_gpu_rasterization_; }
   bool use_oop_rasterization() const { return use_oop_rasterization_; }
-  bool use_msaa() const { return use_msaa_; }
 
   GpuRasterizationStatus gpu_rasterization_status() const {
     return gpu_rasterization_status_;
@@ -811,6 +809,8 @@
     return did_lock_scrolling_layer_;
   }
 
+  bool can_use_msaa() const { return can_use_msaa_; }
+
  protected:
   LayerTreeHostImpl(
       const LayerTreeSettings& settings,
@@ -1049,12 +1049,12 @@
   std::unique_ptr<viz::ContextCacheController::ScopedVisibility>
       worker_context_visibility_;
 
+  bool can_use_msaa_ = false;
+  bool supports_disable_msaa_ = false;
+
   bool need_update_gpu_rasterization_status_ = false;
-  bool content_has_slow_paths_ = false;
-  bool content_has_non_aa_paint_ = false;
   bool use_gpu_rasterization_ = false;
   bool use_oop_rasterization_ = false;
-  bool use_msaa_ = false;
   GpuRasterizationStatus gpu_rasterization_status_ =
       GpuRasterizationStatus::OFF_DEVICE;
   std::unique_ptr<RasterBufferProvider> raster_buffer_provider_;
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index 6648989..809fec7 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -9166,44 +9166,6 @@
   EXPECT_SCOPED(ExpectFullDamageAndDraw(host_impl_.get()));
 }
 
-TEST_F(LayerTreeHostImplTest, RequireHighResAfterMSAAToggles) {
-  // Create a host impl with MSAA support and a forced sample count of 4.
-  LayerTreeSettings msaaSettings = DefaultSettings();
-  msaaSettings.gpu_rasterization_msaa_sample_count = 4;
-  EXPECT_TRUE(CreateHostImpl(
-      msaaSettings, FakeLayerTreeFrameSink::Create3dForGpuRasterization(
-                        msaaSettings.gpu_rasterization_msaa_sample_count)));
-
-  ASSERT_TRUE(host_impl_->active_tree());
-  EXPECT_FALSE(host_impl_->use_msaa());
-
-  // RequiresHighResToDraw is set when new output surface is used.
-  EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
-
-  host_impl_->ResetRequiresHighResToDraw();
-
-  host_impl_->SetContentHasSlowPaths(false);
-  host_impl_->CommitComplete();
-  EXPECT_FALSE(host_impl_->RequiresHighResToDraw());
-  host_impl_->NotifyReadyToActivate();
-  host_impl_->SetContentHasSlowPaths(true);
-  host_impl_->CommitComplete();
-  EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
-  host_impl_->NotifyReadyToActivate();
-  host_impl_->SetContentHasSlowPaths(false);
-  host_impl_->CommitComplete();
-  EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
-  host_impl_->NotifyReadyToActivate();
-
-  host_impl_->ResetRequiresHighResToDraw();
-
-  EXPECT_FALSE(host_impl_->RequiresHighResToDraw());
-  host_impl_->SetContentHasSlowPaths(true);
-  host_impl_->CommitComplete();
-  EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
-  host_impl_->NotifyReadyToActivate();
-}
-
 class LayerTreeHostImplTestPrepareTiles : public LayerTreeHostImplTest {
  public:
   void SetUp() override {
@@ -9295,41 +9257,6 @@
   EXPECT_NE(0u, id1);
 }
 
-TEST_F(LayerTreeHostImplTest,
-       GpuRasterizationStatusChangeDoesNotEvictUIResources) {
-  // Create a host impl with MSAA support and a forced sample count of 4.
-  LayerTreeSettings msaaSettings = DefaultSettings();
-  msaaSettings.gpu_rasterization_msaa_sample_count = 4;
-  EXPECT_TRUE(CreateHostImpl(
-      msaaSettings, FakeLayerTreeFrameSink::Create3dForGpuRasterization(
-                        msaaSettings.gpu_rasterization_msaa_sample_count)));
-
-  host_impl_->SetContentHasSlowPaths(false);
-  host_impl_->CommitComplete();
-  EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status());
-  EXPECT_TRUE(host_impl_->use_gpu_rasterization());
-  EXPECT_FALSE(host_impl_->use_msaa());
-
-  UIResourceId ui_resource_id = 1;
-  UIResourceBitmap bitmap(gfx::Size(1, 1), false /* is_opaque */);
-  host_impl_->CreateUIResource(ui_resource_id, bitmap);
-  viz::ResourceId resource_id =
-      host_impl_->ResourceIdForUIResource(ui_resource_id);
-  EXPECT_NE(viz::kInvalidResourceId, resource_id);
-  EXPECT_FALSE(host_impl_->EvictedUIResourcesExist());
-
-  host_impl_->SetContentHasSlowPaths(true);
-  host_impl_->CommitComplete();
-  EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT,
-            host_impl_->gpu_rasterization_status());
-  EXPECT_TRUE(host_impl_->use_gpu_rasterization());
-  EXPECT_TRUE(host_impl_->use_msaa());
-
-  resource_id = host_impl_->ResourceIdForUIResource(ui_resource_id);
-  EXPECT_NE(viz::kInvalidResourceId, resource_id);
-  EXPECT_FALSE(host_impl_->EvictedUIResourcesExist());
-}
-
 TEST_F(LayerTreeHostImplTest, ObeyMSAACaps) {
   LayerTreeSettings msaaSettings = DefaultSettings();
   msaaSettings.gpu_rasterization_msaa_sample_count = 4;
@@ -9341,15 +9268,7 @@
         msaaSettings,
         FakeLayerTreeFrameSink::Create3dForGpuRasterization(
             msaaSettings.gpu_rasterization_msaa_sample_count, msaa_is_slow)));
-
-    host_impl_->SetContentHasSlowPaths(true);
-    host_impl_->CommitComplete();
-
-    EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT,
-              host_impl_->gpu_rasterization_status());
-    EXPECT_TRUE(host_impl_->use_gpu_rasterization());
-    EXPECT_FALSE(host_impl_->use_oop_rasterization());
-    EXPECT_TRUE(host_impl_->use_msaa());
+    EXPECT_TRUE(host_impl_->can_use_msaa());
   }
 
   // gpu raster, msaa off
@@ -9359,15 +9278,7 @@
         msaaSettings,
         FakeLayerTreeFrameSink::Create3dForGpuRasterization(
             msaaSettings.gpu_rasterization_msaa_sample_count, msaa_is_slow)));
-
-    host_impl_->SetContentHasSlowPaths(true);
-    host_impl_->CommitComplete();
-
-    EXPECT_EQ(GpuRasterizationStatus::ON,
-              host_impl_->gpu_rasterization_status());
-    EXPECT_TRUE(host_impl_->use_gpu_rasterization());
-    EXPECT_FALSE(host_impl_->use_oop_rasterization());
-    EXPECT_FALSE(host_impl_->use_msaa());
+    EXPECT_FALSE(host_impl_->can_use_msaa());
   }
 
   // oop raster, msaa on
@@ -9377,15 +9288,7 @@
         msaaSettings,
         FakeLayerTreeFrameSink::Create3dForOopRasterization(
             msaaSettings.gpu_rasterization_msaa_sample_count, msaa_is_slow)));
-
-    host_impl_->SetContentHasSlowPaths(true);
-    host_impl_->CommitComplete();
-
-    EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT,
-              host_impl_->gpu_rasterization_status());
-    EXPECT_TRUE(host_impl_->use_gpu_rasterization());
-    EXPECT_TRUE(host_impl_->use_oop_rasterization());
-    EXPECT_TRUE(host_impl_->use_msaa());
+    EXPECT_TRUE(host_impl_->can_use_msaa());
   }
 
   // oop raster, msaa off
@@ -9395,15 +9298,7 @@
         msaaSettings,
         FakeLayerTreeFrameSink::Create3dForOopRasterization(
             msaaSettings.gpu_rasterization_msaa_sample_count, msaa_is_slow)));
-
-    host_impl_->SetContentHasSlowPaths(true);
-    host_impl_->CommitComplete();
-
-    EXPECT_EQ(GpuRasterizationStatus::ON,
-              host_impl_->gpu_rasterization_status());
-    EXPECT_TRUE(host_impl_->use_gpu_rasterization());
-    EXPECT_TRUE(host_impl_->use_oop_rasterization());
-    EXPECT_FALSE(host_impl_->use_msaa());
+    EXPECT_FALSE(host_impl_->can_use_msaa());
   }
 }
 
@@ -11917,40 +11812,6 @@
   EXPECT_FALSE(controller.did_draw_frame());
 }
 
-// Tests that SetContentHasSlowPaths behaves as expected.
-TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusSlowPaths) {
-  LayerTreeSettings msaaSettings = DefaultSettings();
-  msaaSettings.gpu_rasterization_msaa_sample_count = 4;
-  EXPECT_TRUE(CreateHostImpl(
-      msaaSettings, FakeLayerTreeFrameSink::Create3dForGpuRasterization(
-                        msaaSettings.gpu_rasterization_msaa_sample_count)));
-
-  // Set initial state, with slow paths on.
-  host_impl_->SetContentHasSlowPaths(true);
-  host_impl_->CommitComplete();
-  EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT,
-            host_impl_->gpu_rasterization_status());
-  EXPECT_TRUE(host_impl_->use_msaa());
-  host_impl_->NotifyReadyToActivate();
-
-  // Toggle slow paths off.
-  host_impl_->SetContentHasSlowPaths(false);
-  host_impl_->CommitComplete();
-  EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status());
-  EXPECT_TRUE(host_impl_->use_gpu_rasterization());
-  EXPECT_FALSE(host_impl_->use_msaa());
-  host_impl_->NotifyReadyToActivate();
-
-  // And on.
-  host_impl_->SetContentHasSlowPaths(true);
-  host_impl_->CommitComplete();
-  EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT,
-            host_impl_->gpu_rasterization_status());
-  EXPECT_TRUE(host_impl_->use_gpu_rasterization());
-  EXPECT_TRUE(host_impl_->use_msaa());
-  host_impl_->NotifyReadyToActivate();
-}
-
 // Tests that SetDeviceScaleFactor correctly impacts GPU rasterization.
 TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusDeviceScaleFactor) {
   // Create a host impl with MSAA support (4 samples).
@@ -11960,7 +11821,6 @@
       msaaSettings, FakeLayerTreeFrameSink::Create3dForGpuRasterization(4)));
 
   // Set initial state, before varying scale factor.
-  host_impl_->SetContentHasSlowPaths(true);
   host_impl_->CommitComplete();
   EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status());
   EXPECT_TRUE(host_impl_->use_gpu_rasterization());
@@ -11970,18 +11830,15 @@
   // 8 to 4.
   host_impl_->active_tree()->SetDeviceScaleFactor(2.0f);
   host_impl_->CommitComplete();
-  EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT,
-            host_impl_->gpu_rasterization_status());
+  EXPECT_TRUE(host_impl_->can_use_msaa());
   EXPECT_TRUE(host_impl_->use_gpu_rasterization());
-  EXPECT_TRUE(host_impl_->use_msaa());
   host_impl_->NotifyReadyToActivate();
 
   // Set device scale factor back to 1.
   host_impl_->active_tree()->SetDeviceScaleFactor(1.0f);
   host_impl_->CommitComplete();
-  EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status());
+  EXPECT_FALSE(host_impl_->can_use_msaa());
   EXPECT_TRUE(host_impl_->use_gpu_rasterization());
-  EXPECT_FALSE(host_impl_->use_msaa());
   host_impl_->NotifyReadyToActivate();
 }
 
@@ -11994,12 +11851,9 @@
       msaaSettings, FakeLayerTreeFrameSink::Create3dForGpuRasterization(
                         msaaSettings.gpu_rasterization_msaa_sample_count)));
 
-  host_impl_->SetContentHasSlowPaths(true);
   host_impl_->CommitComplete();
-  EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT,
-            host_impl_->gpu_rasterization_status());
+  EXPECT_TRUE(host_impl_->can_use_msaa());
   EXPECT_TRUE(host_impl_->use_gpu_rasterization());
-  EXPECT_TRUE(host_impl_->use_msaa());
 }
 
 class GpuRasterizationDisabledLayerTreeHostImplTest
@@ -12010,28 +11864,6 @@
   }
 };
 
-// Tests that GPU rasterization overrides work as expected.
-TEST_F(GpuRasterizationDisabledLayerTreeHostImplTest,
-       GpuRasterizationStatusOverrides) {
-  LayerTreeSettings settings = DefaultSettings();
-  EXPECT_TRUE(CreateHostImpl(settings, FakeLayerTreeFrameSink::Create3d()));
-  host_impl_->SetContentHasSlowPaths(false);
-  host_impl_->CommitComplete();
-  EXPECT_EQ(GpuRasterizationStatus::OFF_DEVICE,
-            host_impl_->gpu_rasterization_status());
-  EXPECT_FALSE(host_impl_->use_gpu_rasterization());
-
-  // GPU rasterization explicitly forced.
-  settings.gpu_rasterization_forced = true;
-  EXPECT_TRUE(CreateHostImpl(settings, FakeLayerTreeFrameSink::Create3d()));
-
-  host_impl_->SetContentHasSlowPaths(true);
-  host_impl_->CommitComplete();
-  EXPECT_EQ(GpuRasterizationStatus::ON_FORCED,
-            host_impl_->gpu_rasterization_status());
-  EXPECT_TRUE(host_impl_->use_gpu_rasterization());
-}
-
 class MsaaIsSlowLayerTreeHostImplTest : public LayerTreeHostImplTest {
  public:
   void CreateHostImplWithCaps(bool msaa_is_slow, bool avoid_stencil_buffers) {
@@ -12055,37 +11887,29 @@
   // Ensure that without the msaa_is_slow or avoid_stencil_buffers caps
   // we raster slow paths with msaa.
   CreateHostImplWithCaps(false, false);
-  host_impl_->SetContentHasSlowPaths(true);
   host_impl_->CommitComplete();
-  EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT,
-            host_impl_->gpu_rasterization_status());
+  EXPECT_TRUE(host_impl_->can_use_msaa());
   EXPECT_TRUE(host_impl_->use_gpu_rasterization());
 
   // Ensure that with either msaa_is_slow or avoid_stencil_buffers caps
   // we don't raster slow paths with msaa (we'll still use GPU raster, though).
   // msaa_is_slow = true, avoid_stencil_buffers = false
   CreateHostImplWithCaps(true, false);
-  host_impl_->SetContentHasSlowPaths(true);
   host_impl_->CommitComplete();
-  EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status());
+  EXPECT_FALSE(host_impl_->can_use_msaa());
   EXPECT_TRUE(host_impl_->use_gpu_rasterization());
-  EXPECT_FALSE(host_impl_->use_msaa());
 
   // msaa_is_slow = false, avoid_stencil_buffers = true
   CreateHostImplWithCaps(false, true);
-  host_impl_->SetContentHasSlowPaths(true);
   host_impl_->CommitComplete();
-  EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status());
   EXPECT_TRUE(host_impl_->use_gpu_rasterization());
-  EXPECT_FALSE(host_impl_->use_msaa());
+  EXPECT_FALSE(host_impl_->can_use_msaa());
 
   // msaa_is_slow = true, avoid_stencil_buffers = true
   CreateHostImplWithCaps(true, true);
-  host_impl_->SetContentHasSlowPaths(true);
   host_impl_->CommitComplete();
-  EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status());
   EXPECT_TRUE(host_impl_->use_gpu_rasterization());
-  EXPECT_FALSE(host_impl_->use_msaa());
+  EXPECT_FALSE(host_impl_->can_use_msaa());
 }
 
 class MsaaCompatibilityLayerTreeHostImplTest : public LayerTreeHostImplTest {
@@ -12109,44 +11933,51 @@
 
 TEST_F(MsaaCompatibilityLayerTreeHostImplTest,
        GpuRasterizationStatusNonAAPaint) {
+  // Always use a recording with slow paths so the toggle is dependent on non aa
+  // paint.
+  auto recording_source = FakeRecordingSource::CreateRecordingSource(
+      gfx::Rect(100, 100), gfx::Size(100, 100));
+  recording_source->set_has_slow_paths(true);
+
   // Ensure that without non-aa paint and without multisample compatibility, we
   // raster slow paths with msaa.
   CreateHostImplWithMultisampleCompatibility(false);
-  host_impl_->SetContentHasSlowPaths(true);
-  host_impl_->SetContentHasNonAAPaint(false);
-  host_impl_->CommitComplete();
-  EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT,
-            host_impl_->gpu_rasterization_status());
-  EXPECT_TRUE(host_impl_->use_gpu_rasterization());
+  recording_source->set_has_non_aa_paint(false);
+  recording_source->Rerecord();
+  EXPECT_TRUE(host_impl_->can_use_msaa());
+  EXPECT_GT(host_impl_->GetMSAASampleCountForRaster(
+                recording_source->GetDisplayItemList()),
+            0);
 
   // Ensure that without non-aa paint and with multisample compatibility, we
   // raster slow paths with msaa.
   CreateHostImplWithMultisampleCompatibility(true);
-  host_impl_->SetContentHasSlowPaths(true);
-  host_impl_->SetContentHasNonAAPaint(false);
-  host_impl_->CommitComplete();
-  EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT,
-            host_impl_->gpu_rasterization_status());
-  EXPECT_TRUE(host_impl_->use_gpu_rasterization());
+  recording_source->set_has_non_aa_paint(false);
+  recording_source->Rerecord();
+  EXPECT_TRUE(host_impl_->can_use_msaa());
+  EXPECT_GT(host_impl_->GetMSAASampleCountForRaster(
+                recording_source->GetDisplayItemList()),
+            0);
 
   // Ensure that with non-aa paint and without multisample compatibility, we do
   // not raster slow paths with msaa.
   CreateHostImplWithMultisampleCompatibility(false);
-  host_impl_->SetContentHasSlowPaths(true);
-  host_impl_->SetContentHasNonAAPaint(true);
-  host_impl_->CommitComplete();
-  EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status());
-  EXPECT_TRUE(host_impl_->use_gpu_rasterization());
+  recording_source->set_has_non_aa_paint(true);
+  recording_source->Rerecord();
+  EXPECT_TRUE(host_impl_->can_use_msaa());
+  EXPECT_EQ(host_impl_->GetMSAASampleCountForRaster(
+                recording_source->GetDisplayItemList()),
+            0);
 
   // Ensure that with non-aa paint and with multisample compatibility, we raster
   // slow paths with msaa.
   CreateHostImplWithMultisampleCompatibility(true);
-  host_impl_->SetContentHasSlowPaths(true);
-  host_impl_->SetContentHasNonAAPaint(true);
-  host_impl_->CommitComplete();
-  EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT,
-            host_impl_->gpu_rasterization_status());
-  EXPECT_TRUE(host_impl_->use_gpu_rasterization());
+  recording_source->set_has_non_aa_paint(true);
+  recording_source->Rerecord();
+  EXPECT_TRUE(host_impl_->can_use_msaa());
+  EXPECT_GT(host_impl_->GetMSAASampleCountForRaster(
+                recording_source->GetDisplayItemList()),
+            0);
 }
 
 TEST_F(LayerTreeHostImplTest, UpdatePageScaleFactorOnActiveTree) {
@@ -12729,20 +12560,6 @@
   EXPECT_GT(layer->tilings()->num_tilings(), 0u);
 }
 
-TEST_F(LayerTreeHostImplTest, NeedUpdateGpuRasterization) {
-  EXPECT_FALSE(host_impl_->NeedUpdateGpuRasterizationStatusForTesting());
-
-  host_impl_->SetContentHasSlowPaths(true);
-  EXPECT_TRUE(host_impl_->NeedUpdateGpuRasterizationStatusForTesting());
-  host_impl_->CommitComplete();
-  EXPECT_FALSE(host_impl_->NeedUpdateGpuRasterizationStatusForTesting());
-
-  host_impl_->SetContentHasNonAAPaint(true);
-  EXPECT_TRUE(host_impl_->NeedUpdateGpuRasterizationStatusForTesting());
-  host_impl_->CommitComplete();
-  EXPECT_FALSE(host_impl_->NeedUpdateGpuRasterizationStatusForTesting());
-}
-
 TEST_F(LayerTreeHostImplTest, WhiteListedTouchActionTest1) {
   WhiteListedTouchActionTestHelper(1.0f, 1.0f);
 }
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc
index 7c6b334..6c9d0b6 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -6159,19 +6159,13 @@
   }
 
   void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
-    EXPECT_FALSE(layer_->HasSlowPaths());
-
     EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization());
     EXPECT_FALSE(host_impl->use_gpu_rasterization());
-    EXPECT_FALSE(host_impl->use_msaa());
   }
 
   void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
-    EXPECT_FALSE(layer_->HasSlowPaths());
-
     EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization());
     EXPECT_FALSE(host_impl->use_gpu_rasterization());
-    EXPECT_FALSE(host_impl->use_msaa());
     EndTest();
   }
 
@@ -6237,17 +6231,19 @@
   void BeginTest() override { PostSetNeedsCommitToMainThread(); }
 
   void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
-    EXPECT_FALSE(layer_->HasSlowPaths());
+    auto* raster_source = static_cast<PictureLayerImpl*>(
+                              host_impl->sync_tree()->LayerById(layer_->id()))
+                              ->GetRasterSource();
+    EXPECT_EQ(host_impl->GetMSAASampleCountForRaster(
+                  raster_source->GetDisplayItemList()),
+              0);
     EXPECT_TRUE(host_impl->pending_tree()->use_gpu_rasterization());
     EXPECT_TRUE(host_impl->use_gpu_rasterization());
-    EXPECT_FALSE(host_impl->use_msaa());
   }
 
   void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
-    EXPECT_FALSE(layer_->HasSlowPaths());
     EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization());
     EXPECT_TRUE(host_impl->use_gpu_rasterization());
-    EXPECT_FALSE(host_impl->use_msaa());
     EndTest();
   }
 };
@@ -6259,7 +6255,7 @@
  protected:
   void BeginTest() override {
     // Content-based MSAA trigger.
-    layer_->set_force_content_has_slow_paths(true);
+    layer_client_.set_contains_slow_paths(true);
 
     // MSAA trigger will take effect when layers are updated.
     // The results will be verified after commit is completed below.
@@ -6270,125 +6266,20 @@
   }
 
   void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
-    // Ensure the slow path bit sticks.
-    EXPECT_TRUE(layer_->HasSlowPaths());
-
+    auto* raster_source = static_cast<PictureLayerImpl*>(
+                              host_impl->sync_tree()->LayerById(layer_->id()))
+                              ->GetRasterSource();
+    EXPECT_GT(host_impl->GetMSAASampleCountForRaster(
+                  raster_source->GetDisplayItemList()),
+              0);
     EXPECT_TRUE(host_impl->pending_tree()->use_gpu_rasterization());
     EXPECT_TRUE(host_impl->use_gpu_rasterization());
-    EXPECT_TRUE(host_impl->use_msaa());
-  }
-
-  void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
-    EXPECT_TRUE(layer_->HasSlowPaths());
-
-    EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization());
-    EXPECT_TRUE(host_impl->use_gpu_rasterization());
-    EXPECT_TRUE(host_impl->use_msaa());
     EndTest();
   }
 };
 
 MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabledWithMSAA);
 
-class LayerTreeHostTestGpuRasterizationMSAAReenabled
-    : public LayerTreeHostWithGpuRasterizationSupportedTest {
- protected:
-  void InitializeSettings(LayerTreeSettings* settings) override {
-    settings->gpu_rasterization_msaa_sample_count = 4;
-  }
-
-  void BeginTest() override {
-    // Content-based MSAA trigger is relevant.
-    layer_->set_force_content_has_slow_paths(true);
-
-    // MSAA trigger will take effect when layers are updated.
-    // The results will be verified after commit is completed below.
-    // Since we are manually marking the source as containing slow paths,
-    // make sure that the layer gets a chance to update.
-    layer_->SetNeedsDisplay();
-    PostSetNeedsCommitToMainThread();
-  }
-
-  void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
-    SCOPED_TRACE(base::StringPrintf("commit %d", num_commits_));
-    if (expected_use_msaa_) {
-      EXPECT_TRUE(host_impl->use_msaa());
-    } else {
-      EXPECT_FALSE(host_impl->use_msaa());
-    }
-
-    ++num_commits_;
-    switch (num_commits_) {
-      case 1:
-        layer_->set_force_content_has_slow_paths(false);
-        break;
-      case 30:
-        layer_->set_force_content_has_slow_paths(true);
-        break;
-      case 31:
-        layer_->set_force_content_has_slow_paths(false);
-        break;
-      case 90:
-        expected_use_msaa_ = false;
-        break;
-    }
-    PostSetNeedsCommitToMainThread();
-    if (num_commits_ > 100)
-      EndTest();
-  }
-
-  int num_commits_ = 0;
-  bool expected_use_msaa_ = true;
-};
-
-MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationMSAAReenabled);
-
-class LayerTreeHostTestGpuRasterizationNonAASticky
-    : public LayerTreeHostWithGpuRasterizationSupportedTest {
- protected:
-  void InitializeSettings(LayerTreeSettings* settings) override {
-    settings->gpu_rasterization_msaa_sample_count = 4;
-  }
-
-  void BeginTest() override {
-    // Start without slow paths, but no non-aa paint.
-    layer_->set_force_content_has_slow_paths(true);
-    layer_->set_force_content_has_non_aa_paint(false);
-
-    // The results will be verified after commit is completed below.
-    layer_->SetNeedsDisplay();
-    PostSetNeedsCommitToMainThread();
-  }
-
-  void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
-    SCOPED_TRACE(base::StringPrintf("commit %d", num_commits_));
-    if (expected_use_msaa_) {
-      EXPECT_TRUE(host_impl->use_msaa());
-    } else {
-      EXPECT_FALSE(host_impl->use_msaa());
-    }
-
-    ++num_commits_;
-    switch (num_commits_) {
-      case 30:
-        layer_->set_force_content_has_non_aa_paint(true);
-        expected_use_msaa_ = false;
-        break;
-      case 31:
-        layer_->set_force_content_has_non_aa_paint(false);
-        break;
-    }
-    PostSetNeedsCommitToMainThread();
-    if (num_commits_ > 100)
-      EndTest();
-  }
-
-  int num_commits_ = 0;
-  bool expected_use_msaa_ = true;
-};
-
-MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationNonAASticky);
-
 class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest {
  protected:
   void InitializeSettings(LayerTreeSettings* settings) override {
@@ -6415,9 +6306,6 @@
   }
 
   void BeginTest() override {
-    // Content-based MSAA trigger is irrelevant as well.
-    layer_->set_force_content_has_slow_paths(true);
-
     // Veto will take effect when layers are updated.
     // The results will be verified after commit is completed below.
     // Since we are manually marking the source as containing slow paths,
@@ -6427,16 +6315,11 @@
   }
 
   void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
-    // Ensure the slow-paths bit sticks.
-    EXPECT_TRUE(layer_->HasSlowPaths());
-
     EXPECT_TRUE(host_impl->sync_tree()->use_gpu_rasterization());
     EXPECT_TRUE(host_impl->use_gpu_rasterization());
   }
 
   void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
-    EXPECT_TRUE(layer_->HasSlowPaths());
-
     EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization());
     EXPECT_TRUE(host_impl->use_gpu_rasterization());
     EndTest();
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index ec7fbb3..9ea2e70 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -2369,6 +2369,11 @@
   return host_impl_->IsActivelyScrolling();
 }
 
+int LayerTreeImpl::GetMSAASampleCountForRaster(
+    const scoped_refptr<DisplayItemList>& display_list) {
+  return host_impl_->GetMSAASampleCountForRaster(display_list);
+}
+
 void LayerTreeImpl::SetPendingPageScaleAnimation(
     std::unique_ptr<PendingPageScaleAnimation> pending_animation) {
   pending_page_scale_animation_ = std::move(pending_animation);
diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h
index c9faf90..efe9c9c 100644
--- a/cc/trees/layer_tree_impl.h
+++ b/cc/trees/layer_tree_impl.h
@@ -151,6 +151,8 @@
       base::flat_map<PaintImage::Id, PaintImage::DecodingMode>
           decoding_mode_map);
   bool IsActivelyScrolling() const;
+  int GetMSAASampleCountForRaster(
+      const scoped_refptr<DisplayItemList>& display_list);
 
   // Tree specific methods exposed to layer-impl tree.
   // ---------------------------------------------------------------------------
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index e1fcc4b..be3facbb 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -118445,6 +118445,9 @@
 
 <histogram name="Renderer4.GpuRasterizationSlowPathsWithNonAAPaint"
     enum="BooleanHasSlowPathsWithNonAAPaint" expires_after="M78">
+  <obsolete>
+    Deprecated 10/2019.
+  </obsolete>
   <owner>ericrk@chromium.org</owner>
   <owner>enne@chromium.org</owner>
   <summary>
@@ -118456,7 +118459,11 @@
 </histogram>
 
 <histogram name="Renderer4.GpuRasterizationSuitableContent"
-    enum="BooleanEnabled">
+    enum="BooleanEnabled" expires_after="M79">
+  <obsolete>
+    Deprecated 10/2019. Gpu rasterization is no longer dynamically triggerd by
+    content.
+  </obsolete>
   <owner>ericrk@chromium.org</owner>
   <owner>enne@chromium.org</owner>
   <summary>