[go: nahoru, domu]

Add about:flags plumbing for OOP-R

Currently, out of process rasterization (oop-r) is controlled by a
single command line flag (--enable-oop-rasterization) and default off.
Many places in the code check this.

This patch centralizes the enabling logic into gpu_util.cc and
GpuFeatureList as the definitive source for whether oop-r is enabled.

First, command line entries are forwarded via GpuPreferences to the gpu
process.  Then, GpuInfo decides whether or not oop-r can be supported.
Then the gpu preferenes (enable and disable), blacklist, and finch entry
(default off now) are used to set the GpuFeatureInfo status value.  This
status value is passed to gles2::FeatureInfo to enable/disable
chromium_raster_transport in the raster decoder if needed for oop
raster.

The command line flags no longer need to be piped to the renderer or the
gpu process.  The renderer also uses the GpuFeatureInfo to figure out
whether to use oop-r.  If it says it is supported, then it should be
used.

Bug: 847684
Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel;master.tryserver.blink:linux_trusty_blink_rel
Change-Id: Ifecda890216e573745ae1c823294b9bbc1962cab
Reviewed-on: https://chromium-review.googlesource.com/1083115
Commit-Queue: enne <enne@chromium.org>
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
Reviewed-by: Steven Bennetts <stevenjb@chromium.org>
Reviewed-by: Chris Palmer <palmer@chromium.org>
Reviewed-by: Antoine Labour <piman@chromium.org>
Reviewed-by: Jonathan Backer <backer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#565061}
diff --git a/cc/BUILD.gn b/cc/BUILD.gn
index 28bd06c6..99acdd1e 100644
--- a/cc/BUILD.gn
+++ b/cc/BUILD.gn
@@ -787,6 +787,7 @@
     "//gpu:test_support",
     "//gpu/command_buffer/client:gles2_implementation",
     "//gpu/command_buffer/client:raster",
+    "//gpu/ipc:gl_in_process_context",
     "//gpu/ipc/common:struct_traits",
     "//media",
     "//mojo/edk",
diff --git a/cc/test/DEPS b/cc/test/DEPS
index 06419d31..29765c44 100644
--- a/cc/test/DEPS
+++ b/cc/test/DEPS
@@ -15,4 +15,7 @@
   "run_all_(perf|unit)tests\.cc": [
     "+mojo/edk/embedder/embedder.h",
   ],
+  "cc_test_suite\.cc": [
+    "+gpu/config",
+  ],
 }
diff --git a/cc/test/cc_test_suite.cc b/cc/test/cc_test_suite.cc
index d29c84b6d..ee7ae53f 100644
--- a/cc/test/cc_test_suite.cc
+++ b/cc/test/cc_test_suite.cc
@@ -4,9 +4,14 @@
 
 #include "cc/test/cc_test_suite.h"
 
+#include "base/command_line.h"
 #include "base/message_loop/message_loop.h"
 #include "base/threading/thread_id_name_manager.h"
 #include "components/viz/test/paths.h"
+#include "gpu/config/gpu_info_collector.h"
+#include "gpu/config/gpu_preferences.h"
+#include "gpu/config/gpu_util.h"
+#include "gpu/ipc/in_process_command_buffer.h"
 #include "ui/gl/test/gl_surface_test_support.h"
 
 namespace cc {
@@ -19,7 +24,21 @@
 void CCTestSuite::Initialize() {
   base::TestSuite::Initialize();
   message_loop_ = std::make_unique<base::MessageLoop>();
+
   gl::GLSurfaceTestSupport::InitializeOneOff();
+  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+  gpu::GPUInfo gpu_info;
+  gpu::CollectGraphicsInfoForTesting(&gpu_info);
+  gpu::GpuFeatureInfo gpu_feature_info = gpu::ComputeGpuFeatureInfo(
+      gpu_info, gpu::GpuPreferences(), command_line, nullptr);
+  // Always enable gpu and oop raster, regardless of platform and blacklist.
+  gpu_feature_info.status_values[gpu::GPU_FEATURE_TYPE_GPU_RASTERIZATION] =
+      gpu::kGpuFeatureStatusEnabled;
+  gpu_feature_info.status_values[gpu::GPU_FEATURE_TYPE_OOP_RASTERIZATION] =
+      gpu::kGpuFeatureStatusEnabled;
+  gpu::InProcessCommandBuffer::InitializeDefaultServiceForTesting(
+      gpu_feature_info);
+
   viz::Paths::RegisterPathProvider();
 
   base::ThreadIdNameManager::GetInstance()->SetName("Main");
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 6bebc3a..7023e0b 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -3069,17 +3069,12 @@
       GetTaskRunner(), ResourcePool::kDefaultExpirationDelay,
       settings_.disallow_non_exact_resource_reuse);
 
-  // TODO(piman): Make oop raster always supported: http://crbug.com/786591
-  use_oop_rasterization_ = settings_.enable_oop_rasterization;
-  if (use_oop_rasterization_) {
-    auto* context = layer_tree_frame_sink_->worker_context_provider();
-    if (context) {
-      viz::RasterContextProvider::ScopedRasterContextLock hold(context);
-      use_oop_rasterization_ &=
-          context->ContextCapabilities().supports_oop_raster;
-    } else {
-      use_oop_rasterization_ = false;
-    }
+  auto* context = layer_tree_frame_sink_->worker_context_provider();
+  if (context) {
+    viz::RasterContextProvider::ScopedRasterContextLock hold(context);
+    use_oop_rasterization_ = context->ContextCapabilities().supports_oop_raster;
+  } else {
+    use_oop_rasterization_ = false;
   }
 
   // Since the new context may be capable of MSAA, update status here. We don't
diff --git a/cc/trees/layer_tree_settings.h b/cc/trees/layer_tree_settings.h
index eb02ef49..736df815 100644
--- a/cc/trees/layer_tree_settings.h
+++ b/cc/trees/layer_tree_settings.h
@@ -138,10 +138,6 @@
   // produces the active tree as its 'sync tree'.
   bool commit_to_active_tree = true;
 
-  // Whether to use out of process raster.  If true, whenever gpu raster
-  // would have been used, out of process gpu raster will be used instead.
-  bool enable_oop_rasterization = false;
-
   // Whether image animations can be reset to the beginning to avoid skipping
   // many frames.
   bool enable_image_animation_resync = true;
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index e984419..e38739f9 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -444,6 +444,14 @@
      switches::kForceGpuRasterization, ""},
 };
 
+const FeatureEntry::Choice kEnableOopRasterizationChoices[] = {
+    {flags_ui::kGenericExperimentChoiceDefault, "", ""},
+    {flags_ui::kGenericExperimentChoiceEnabled,
+     switches::kEnableOopRasterization, ""},
+    {flags_ui::kGenericExperimentChoiceDisabled,
+     switches::kDisableOopRasterization, ""},
+};
+
 #if defined(OS_CHROMEOS)
 const FeatureEntry::Choice kMemoryPressureThresholdChoices[] = {
     {flags_ui::kGenericExperimentChoiceDefault, "", ""},
@@ -1376,6 +1384,9 @@
     {"enable-gpu-rasterization", flag_descriptions::kGpuRasterizationName,
      flag_descriptions::kGpuRasterizationDescription, kOsAll,
      MULTI_VALUE_TYPE(kEnableGpuRasterizationChoices)},
+    {"enable-oop-rasterization", flag_descriptions::kOopRasterizationName,
+     flag_descriptions::kOopRasterizationDescription, kOsAll,
+     MULTI_VALUE_TYPE(kEnableOopRasterizationChoices)},
     {"gpu-rasterization-msaa-sample-count",
      flag_descriptions::kGpuRasterizationMsaaSampleCountName,
      flag_descriptions::kGpuRasterizationMsaaSampleCountDescription, kOsAll,
diff --git a/chrome/browser/chromeos/login/chrome_restart_request.cc b/chrome/browser/chromeos/login/chrome_restart_request.cc
index ec567a7..cd9f870 100644
--- a/chrome/browser/chromeos/login/chrome_restart_request.cc
+++ b/chrome/browser/chromeos/login/chrome_restart_request.cc
@@ -97,6 +97,8 @@
     ::switches::kDisableGpuCompositing,
     ::switches::kDisableGpuRasterization,
     ::switches::kDisableLowResTiling,
+    ::switches::kDisableOopRasterization,
+    ::switches::kDisablePartialRaster,
     ::switches::kDisablePepper3DImageChromium,
     ::switches::kDisablePreferCompositingToLCDText,
     ::switches::kDisablePanelFitting,
@@ -110,8 +112,7 @@
     ::switches::kEnableLogging,
     ::switches::kEnableLowResTiling,
     ::switches::kEnableNativeGpuMemoryBuffers,
-    ::switches::kEnableOOPRasterization,
-    ::switches::kDisablePartialRaster,
+    ::switches::kEnableOopRasterization,
     ::switches::kEnablePartialRaster,
     ::switches::kEnablePinch,
     ::switches::kEnablePreferCompositingToLCDText,
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index d90f940..9e7ef9f 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -1166,6 +1166,11 @@
     "Always displays voice search icon in focused omnibox as long as voice "
     "search is possible";
 
+const char kOopRasterizationName[] = "Out of process rasterization";
+const char kOopRasterizationDescription[] =
+    "Perform Ganesh raster in the GPU Process instead of the renderer.  "
+    "Must also enable GPU rasterization";
+
 const char kOriginTrialsName[] = "Origin Trials";
 const char kOriginTrialsDescription[] =
     "Enables origin trials for controlling access to feature/API experiments.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 37f0f28..5e397326 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -729,6 +729,9 @@
 extern const char kOmniboxVoiceSearchAlwaysVisibleName[];
 extern const char kOmniboxVoiceSearchAlwaysVisibleDescription[];
 
+extern const char kOopRasterizationName[];
+extern const char kOopRasterizationDescription[];
+
 extern const char kOverflowIconsForMediaControlsName[];
 extern const char kOverflowIconsForMediaControlsDescription[];
 
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc
index 51e76d38..28464e9 100644
--- a/content/browser/gpu/gpu_process_host.cc
+++ b/content/browser/gpu/gpu_process_host.cc
@@ -204,7 +204,6 @@
 #endif
     switches::kEnableGpuRasterization,
     switches::kEnableLogging,
-    switches::kEnableOOPRasterization,
     switches::kEnableVizDevTools,
     switches::kHeadless,
     switches::kLoggingLevel,
diff --git a/content/browser/oop_browsertest.cc b/content/browser/oop_browsertest.cc
index d66d54e..7f38f92 100644
--- a/content/browser/oop_browsertest.cc
+++ b/content/browser/oop_browsertest.cc
@@ -13,6 +13,7 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
+#include "content/public/common/content_switches.h"
 #include "content/public/test/browser_test_utils.h"
 #include "content/public/test/content_browser_test.h"
 #include "content/public/test/content_browser_test_utils.h"
@@ -35,7 +36,7 @@
     ContentBrowserTest::SetUpCommandLine(command_line);
     command_line->AppendSwitch(switches::kEnableGpuRasterization);
     command_line->AppendSwitch(switches::kEnablePixelOutputInTests);
-    command_line->AppendSwitch(switches::kEnableOOPRasterization);
+    command_line->AppendSwitch(switches::kEnableOopRasterization);
 
     const bool use_gpu_in_tests = !features::IsMashEnabled();
     if (use_gpu_in_tests)
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index fa286f3..5c752f2a 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -2724,7 +2724,6 @@
     switches::kEnableLCDText,
     switches::kEnableLogging,
     switches::kEnableNetworkInformationDownlinkMax,
-    switches::kEnableOOPRasterization,
     switches::kEnablePluginPlaceholderTesting,
     switches::kEnablePreciseMemoryInfo,
     switches::kEnablePrintBrowser,
diff --git a/content/public/browser/gpu_utils.cc b/content/public/browser/gpu_utils.cc
index 52db493..6de9eb0 100644
--- a/content/public/browser/gpu_utils.cc
+++ b/content/public/browser/gpu_utils.cc
@@ -88,6 +88,12 @@
       (gpu_preferences.single_process || gpu_preferences.in_process_gpu);
   gpu_preferences.gpu_sandbox_start_early =
       command_line->HasSwitch(switches::kGpuSandboxStartEarly);
+
+  gpu_preferences.enable_oop_rasterization =
+      command_line->HasSwitch(switches::kEnableOopRasterization);
+  gpu_preferences.disable_oop_rasterization =
+      command_line->HasSwitch(switches::kDisableOopRasterization);
+
   // Some of these preferences are set or adjusted in
   // GpuDataManagerImplPrivate::AppendGpuCommandLine.
   return gpu_preferences;
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc
index 4982b8880..aecf483 100644
--- a/content/public/common/content_switches.cc
+++ b/content/public/common/content_switches.cc
@@ -480,7 +480,14 @@
 // Always use the Skia GPU backend for drawing layer tiles. Only valid with GPU
 // accelerated compositing + impl-side painting. Overrides the
 // kEnableGpuRasterization flag.
-const char kForceGpuRasterization[]        = "force-gpu-rasterization";
+const char kForceGpuRasterization[] = "force-gpu-rasterization";
+
+// Disables OOP rasterization.  Takes precedence over the enable flag.
+const char kDisableOopRasterization[] = "disable-oop-rasterization";
+
+// Turns on out of process raster for the renderer whenever gpu raster
+// would have been used.  Enables the chromium_raster_transport extension.
+const char kEnableOopRasterization[] = "enable-oop-rasterization";
 
 // The number of multisample antialiasing samples for GPU rasterization.
 // Requires MSAA support on GPU to have an effect. 0 disables MSAA.
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h
index 639826eff..245de08 100644
--- a/content/public/common/content_switches.h
+++ b/content/public/common/content_switches.h
@@ -150,6 +150,8 @@
 CONTENT_EXPORT extern const char kFieldTrialHandle[];
 CONTENT_EXPORT extern const char kForceDisplayList2dCanvas[];
 CONTENT_EXPORT extern const char kForceGpuRasterization[];
+CONTENT_EXPORT extern const char kDisableOopRasterization[];
+CONTENT_EXPORT extern const char kEnableOopRasterization[];
 CONTENT_EXPORT extern const char kForceOverlayFullscreenVideo[];
 CONTENT_EXPORT extern const char kForcePresentationReceiverForTesting[];
 CONTENT_EXPORT extern const char kForceRendererAccessibility[];
diff --git a/content/renderer/gpu/render_widget_compositor.cc b/content/renderer/gpu/render_widget_compositor.cc
index 612213c..52cf1da8 100644
--- a/content/renderer/gpu/render_widget_compositor.cc
+++ b/content/renderer/gpu/render_widget_compositor.cc
@@ -405,8 +405,6 @@
       compositor_deps->IsElasticOverscrollEnabled();
   settings.resource_settings.use_gpu_memory_buffer_resources =
       compositor_deps->IsGpuMemoryBufferCompositorResourcesEnabled();
-  settings.enable_oop_rasterization =
-      cmd.HasSwitch(switches::kEnableOOPRasterization);
 
   // Build LayerTreeSettings from command line args.
   if (cmd.HasSwitch(cc::switches::kBrowserControlsShowThreshold)) {
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index 1642c620..204a300 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -2387,12 +2387,10 @@
   }
 
   bool support_locking = true;
-  // TODO(backer): Remove checking the command line. GpuInfo is coming
-  // from a trusted source so the command line check is unnecessary.
   bool support_oop_rasterization =
-      gpu_channel_host->gpu_info().oop_rasterization_supported &&
-      base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kEnableOOPRasterization);
+      gpu_channel_host->gpu_feature_info()
+          .status_values[gpu::GPU_FEATURE_TYPE_OOP_RASTERIZATION] ==
+      gpu::kGpuFeatureStatusEnabled;
   bool support_gles2_interface = !support_oop_rasterization;
   bool support_raster_interface = true;
   bool support_grcontext = !support_oop_rasterization;
diff --git a/gpu/command_buffer/service/buffer_manager_unittest.cc b/gpu/command_buffer/service/buffer_manager_unittest.cc
index 2d4e6c0..40afa37 100644
--- a/gpu/command_buffer/service/buffer_manager_unittest.cc
+++ b/gpu/command_buffer/service/buffer_manager_unittest.cc
@@ -13,7 +13,6 @@
 #include "gpu/command_buffer/service/gpu_service_test.h"
 #include "gpu/command_buffer/service/mocks.h"
 #include "gpu/command_buffer/service/test_helper.h"
-#include "gpu/config/gpu_preferences.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gl/gl_mock.h"
 
@@ -250,8 +249,9 @@
   void SetUp() override {
     GpuDriverBugWorkarounds gpu_driver_bug_workarounds;
     gpu_driver_bug_workarounds.use_client_side_arrays_for_stream_buffers = true;
+    GpuFeatureInfo gpu_feature_info;
     feature_info_ =
-        new FeatureInfo(gpu_driver_bug_workarounds, GpuPreferences());
+        new FeatureInfo(gpu_driver_bug_workarounds, gpu_feature_info);
     SetUpBase(NULL, feature_info_.get(), "");
   }
 
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc
index 72b2fd7d..0ab4b02 100644
--- a/gpu/command_buffer/service/feature_info.cc
+++ b/gpu/command_buffer/service/feature_info.cc
@@ -16,7 +16,6 @@
 #include "build/build_config.h"
 #include "gpu/command_buffer/service/gpu_switches.h"
 #include "gpu/command_buffer/service/texture_definition.h"
-#include "gpu/config/gpu_preferences.h"
 #include "gpu/config/gpu_switches.h"
 #include "ui/gl/gl_bindings.h"
 #include "ui/gl/gl_fence.h"
@@ -219,13 +218,14 @@
 
 FeatureInfo::FeatureInfo(
     const GpuDriverBugWorkarounds& gpu_driver_bug_workarounds,
-    const GpuPreferences& gpu_preferences)
+    const GpuFeatureInfo& gpu_feature_info)
     : workarounds_(gpu_driver_bug_workarounds) {
   InitializeBasicState(base::CommandLine::InitializedForCurrentProcess()
                            ? base::CommandLine::ForCurrentProcess()
                            : nullptr);
   feature_flags_.chromium_raster_transport =
-      gpu_preferences.enable_oop_rasterization;
+      gpu_feature_info.status_values[GPU_FEATURE_TYPE_OOP_RASTERIZATION] ==
+      gpu::kGpuFeatureStatusEnabled;
 }
 
 void FeatureInfo::InitializeBasicState(const base::CommandLine* command_line) {
diff --git a/gpu/command_buffer/service/feature_info.h b/gpu/command_buffer/service/feature_info.h
index 4b3e307..41a2e1a 100644
--- a/gpu/command_buffer/service/feature_info.h
+++ b/gpu/command_buffer/service/feature_info.h
@@ -14,6 +14,7 @@
 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
 #include "gpu/command_buffer/service/gles2_cmd_validation.h"
 #include "gpu/config/gpu_driver_bug_workarounds.h"
+#include "gpu/config/gpu_feature_info.h"
 #include "gpu/gpu_gles2_export.h"
 #include "ui/gl/extension_set.h"
 
@@ -26,7 +27,6 @@
 }
 
 namespace gpu {
-struct GpuPreferences;
 namespace gles2 {
 
 // FeatureInfo records the features that are available for a ContextGroup.
@@ -135,7 +135,7 @@
 
   // Constructor with workarounds taken from the current process's CommandLine
   FeatureInfo(const GpuDriverBugWorkarounds& gpu_driver_bug_workarounds,
-              const GpuPreferences& gpu_preferences);
+              const GpuFeatureInfo& gpu_feature_info);
 
   // Initializes the feature information. Needs a current GL context.
   void Initialize(ContextType context_type,
diff --git a/gpu/command_buffer/service/feature_info_unittest.cc b/gpu/command_buffer/service/feature_info_unittest.cc
index 136ee637..7db95ae2 100644
--- a/gpu/command_buffer/service/feature_info_unittest.cc
+++ b/gpu/command_buffer/service/feature_info_unittest.cc
@@ -13,7 +13,6 @@
 #include "gpu/command_buffer/service/test_helper.h"
 #include "gpu/command_buffer/service/texture_manager.h"
 #include "gpu/config/gpu_driver_bug_workarounds.h"
-#include "gpu/config/gpu_preferences.h"
 #include "gpu/config/gpu_switches.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gl/gl_fence.h"
@@ -135,7 +134,7 @@
 
   void SetupWithWorkarounds(const gpu::GpuDriverBugWorkarounds& workarounds) {
     GpuServiceTest::SetUp();
-    info_ = new FeatureInfo(workarounds, GpuPreferences());
+    info_ = new FeatureInfo(workarounds, GpuFeatureInfo());
   }
 
   void SetupInitExpectationsWithWorkarounds(
@@ -144,7 +143,7 @@
     GpuServiceTest::SetUpWithGLVersion("2.0", extensions);
     TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion(
         gl_.get(), extensions, "", "", GetContextType());
-    info_ = new FeatureInfo(workarounds, GpuPreferences());
+    info_ = new FeatureInfo(workarounds, GpuFeatureInfo());
     info_->Initialize(GetContextType(), IsPassthroughCmdDecoder(),
                       DisallowedFeatures());
   }
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 1b77041..c3fb8b1 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -16089,7 +16089,7 @@
           cmd_data);
   Bucket* bucket = CreateBucket(c.bucket_id);
   scoped_refptr<FeatureInfo> info(
-      new FeatureInfo(workarounds(), group_->gpu_preferences()));
+      new FeatureInfo(workarounds(), group_->gpu_feature_info()));
   DisallowedFeatures disallowed_features = feature_info_->disallowed_features();
   disallowed_features.AllowExtensions();
   info->Initialize(feature_info_->context_type(),
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
index 6ee7927..2f99513 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
@@ -454,7 +454,7 @@
       offscreen_(false),
       group_(group),
       feature_info_(new FeatureInfo(group->feature_info()->workarounds(),
-                                    group->gpu_preferences())),
+                                    group->gpu_feature_info())),
       emulated_back_buffer_(nullptr),
       offscreen_single_buffer_(false),
       offscreen_target_buffer_preserved_(false),
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
index fdaccfa..fd41286 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
@@ -26,7 +26,6 @@
 #include "gpu/command_buffer/service/service_utils.h"
 #include "gpu/command_buffer/service/test_helper.h"
 #include "gpu/command_buffer/service/vertex_attrib_manager.h"
-#include "gpu/config/gpu_preferences.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gl/gl_mock.h"
 #include "ui/gl/init/gl_factory.h"
@@ -209,15 +208,16 @@
 
   SetupMockGLBehaviors();
 
+  GpuFeatureInfo gpu_feature_info;
   scoped_refptr<FeatureInfo> feature_info =
-      new FeatureInfo(workarounds, GpuPreferences());
+      new FeatureInfo(workarounds, gpu_feature_info);
 
   group_ = scoped_refptr<ContextGroup>(new ContextGroup(
       gpu_preferences_, false, &mailbox_manager_, memory_tracker_,
       &shader_translator_cache_, &framebuffer_completeness_cache_, feature_info,
       normalized_init.bind_generates_resource, &image_manager_,
       nullptr /* image_factory */, nullptr /* progress_reporter */,
-      GpuFeatureInfo(), &discardable_manager_));
+      gpu_feature_info, &discardable_manager_));
   bool use_default_textures = normalized_init.bind_generates_resource;
 
   InSequence sequence;
diff --git a/gpu/command_buffer/service/gpu_fence_manager_unittest.cc b/gpu/command_buffer/service/gpu_fence_manager_unittest.cc
index 3bdab917..cc96195 100644
--- a/gpu/command_buffer/service/gpu_fence_manager_unittest.cc
+++ b/gpu/command_buffer/service/gpu_fence_manager_unittest.cc
@@ -11,7 +11,6 @@
 #include "gpu/command_buffer/service/feature_info.h"
 #include "gpu/command_buffer/service/gpu_service_test.h"
 #include "gpu/command_buffer/service/test_helper.h"
-#include "gpu/config/gpu_preferences.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/gpu_fence.h"
 #include "ui/gfx/gpu_fence_handle.h"
@@ -35,7 +34,7 @@
   GpuFenceManagerTest() {
     GpuDriverBugWorkarounds gpu_driver_bug_workaround;
     feature_info_ =
-        new FeatureInfo(gpu_driver_bug_workaround, GpuPreferences());
+        new FeatureInfo(gpu_driver_bug_workaround, GpuFeatureInfo());
   }
 
   ~GpuFenceManagerTest() override {}
diff --git a/gpu/command_buffer/service/raster_decoder_unittest_base.cc b/gpu/command_buffer/service/raster_decoder_unittest_base.cc
index 03f569cc..ece501a 100644
--- a/gpu/command_buffer/service/raster_decoder_unittest_base.cc
+++ b/gpu/command_buffer/service/raster_decoder_unittest_base.cc
@@ -26,7 +26,6 @@
 #include "gpu/command_buffer/service/service_utils.h"
 #include "gpu/command_buffer/service/test_helper.h"
 #include "gpu/command_buffer/service/vertex_attrib_manager.h"
-#include "gpu/config/gpu_preferences.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gl/gl_mock.h"
 #include "ui/gl/init/gl_factory.h"
@@ -185,14 +184,15 @@
   gl_.reset(new StrictMock<MockGLInterface>());
   ::gl::MockGLInterface::SetGLInterface(gl_.get());
 
+  GpuFeatureInfo gpu_feature_info;
   scoped_refptr<FeatureInfo> feature_info =
-      new FeatureInfo(init.workarounds, GpuPreferences());
+      new FeatureInfo(init.workarounds, gpu_feature_info);
 
   group_ = scoped_refptr<ContextGroup>(new ContextGroup(
       gpu_preferences_, false, &mailbox_manager_, memory_tracker_,
       &shader_translator_cache_, &framebuffer_completeness_cache_, feature_info,
       bind_generates_resource, &image_manager_, nullptr /* image_factory */,
-      nullptr /* progress_reporter */, GpuFeatureInfo(),
+      nullptr /* progress_reporter */, gpu_feature_info,
       &discardable_manager_));
 
   InSequence sequence;
diff --git a/gpu/command_buffer/service/service_utils.cc b/gpu/command_buffer/service/service_utils.cc
index 11d2c71..431a6bd2 100644
--- a/gpu/command_buffer/service/service_utils.cc
+++ b/gpu/command_buffer/service/service_utils.cc
@@ -156,8 +156,6 @@
       command_line->HasSwitch(switches::kDisableGpuDriverBugWorkarounds);
   gpu_preferences.ignore_gpu_blacklist =
       command_line->HasSwitch(switches::kIgnoreGpuBlacklist);
-  gpu_preferences.enable_oop_rasterization =
-      command_line->HasSwitch(switches::kEnableOOPRasterization);
   gpu_preferences.use_gpu_fences_for_overlay_planes =
       command_line->HasSwitch(switches::kUseGpuFencesForOverlayPlanes);
   return gpu_preferences;
diff --git a/gpu/command_buffer/service/texture_manager_unittest.cc b/gpu/command_buffer/service/texture_manager_unittest.cc
index a621357..34cabe7 100644
--- a/gpu/command_buffer/service/texture_manager_unittest.cc
+++ b/gpu/command_buffer/service/texture_manager_unittest.cc
@@ -26,7 +26,6 @@
 #include "gpu/command_buffer/service/mocks.h"
 #include "gpu/command_buffer/service/service_discardable_manager.h"
 #include "gpu/command_buffer/service/test_helper.h"
-#include "gpu/config/gpu_preferences.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gl/gl_image_stub.h"
 #include "ui/gl/gl_mock.h"
@@ -75,7 +74,7 @@
   TextureManagerTest() {
     GpuDriverBugWorkarounds gpu_driver_bug_workaround;
     feature_info_ =
-        new FeatureInfo(gpu_driver_bug_workaround, GpuPreferences());
+        new FeatureInfo(gpu_driver_bug_workaround, GpuFeatureInfo());
   }
 
   ~TextureManagerTest() override = default;
diff --git a/gpu/command_buffer/tests/fuzzer_main.cc b/gpu/command_buffer/tests/fuzzer_main.cc
index 754f4c8..0125db8 100644
--- a/gpu/command_buffer/tests/fuzzer_main.cc
+++ b/gpu/command_buffer/tests/fuzzer_main.cc
@@ -298,12 +298,6 @@
     auto* command_line = base::CommandLine::ForCurrentProcess();
     ALLOW_UNUSED_LOCAL(command_line);
 
-#if defined(GPU_FUZZER_USE_RASTER_DECODER)
-    // TODO(backer): Remove this. Currently used to set
-    // |chromium_raster_transport| features flag (https://crbug.com/786591).
-    command_line->AppendSwitch(switches::kEnableOOPRasterization);
-#endif
-
 #if defined(GPU_FUZZER_USE_ANGLE)
     command_line->AppendSwitchASCII(switches::kUseGL,
                                     gl::kGLImplementationANGLEName);
@@ -341,18 +335,25 @@
     }
 
     context_->MakeCurrent(surface_.get());
+    GpuFeatureInfo gpu_feature_info;
+#if defined(GPU_FUZZER_USE_RASTER_DECODER)
+    // Cause feature_info's |chromium_raster_transport| to be enabled.
+    gpu_feature_info.status_values[GPU_FEATURE_TYPE_OOP_RASTERIZATION] =
+        kGpuFeatureStatusEnabled;
+#endif
     scoped_refptr<gles2::FeatureInfo> feature_info =
-        new gles2::FeatureInfo(config_.workarounds, gpu_preferences_);
+        new gles2::FeatureInfo(config_.workarounds, gpu_feature_info);
     scoped_refptr<gles2::ContextGroup> context_group = new gles2::ContextGroup(
         gpu_preferences_, true, &mailbox_manager_, nullptr /* memory_tracker */,
         &translator_cache_, &completeness_cache_, feature_info,
         config_.attrib_helper.bind_generates_resource, &image_manager_,
         nullptr /* image_factory */, nullptr /* progress_reporter */,
-        GpuFeatureInfo(), discardable_manager_.get());
+        gpu_feature_info, discardable_manager_.get());
     command_buffer_.reset(new CommandBufferDirect(
         context_group->transfer_buffer_manager(), &sync_point_manager_));
 
 #if defined(GPU_FUZZER_USE_RASTER_DECODER)
+    CHECK(feature_info->feature_flags().chromium_raster_transport);
     decoder_.reset(raster::RasterDecoder::Create(
         command_buffer_.get(), command_buffer_->service(), &outputter_,
         context_group.get()));
diff --git a/gpu/command_buffer/tests/gl_manager.cc b/gpu/command_buffer/tests/gl_manager.cc
index 65b9c66..972ff41d 100644
--- a/gpu/command_buffer/tests/gl_manager.cc
+++ b/gpu/command_buffer/tests/gl_manager.cc
@@ -36,7 +36,6 @@
 #include "gpu/command_buffer/service/memory_tracking.h"
 #include "gpu/command_buffer/service/service_utils.h"
 #include "gpu/command_buffer/service/transfer_buffer_manager.h"
-#include "gpu/config/gpu_preferences.h"
 #include "gpu/ipc/in_process_command_buffer.h"
 #include "gpu/ipc/service/gpu_memory_buffer_factory.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -327,15 +326,16 @@
       std::make_unique<gles2::ShaderTranslatorCache>(gpu_preferences_);
 
   if (!context_group) {
+    GpuFeatureInfo gpu_feature_info;
     scoped_refptr<gles2::FeatureInfo> feature_info =
-        new gles2::FeatureInfo(workarounds, GpuPreferences());
+        new gles2::FeatureInfo(workarounds, gpu_feature_info);
     // Always mark the passthrough command decoder as supported so that tests do
     // not unexpectedly use the wrong command decoder
     context_group = new gles2::ContextGroup(
         gpu_preferences_, true, mailbox_manager_, nullptr /* memory_tracker */,
         translator_cache_.get(), &completeness_cache_, feature_info,
         options.bind_generates_resource, &image_manager_, options.image_factory,
-        nullptr /* progress_reporter */, GpuFeatureInfo(),
+        nullptr /* progress_reporter */, gpu_feature_info,
         &discardable_manager_);
   }
 
diff --git a/gpu/command_buffer/tests/gl_tests_main.cc b/gpu/command_buffer/tests/gl_tests_main.cc
index 021ac07..9d2dbfd 100644
--- a/gpu/command_buffer/tests/gl_tests_main.cc
+++ b/gpu/command_buffer/tests/gl_tests_main.cc
@@ -4,6 +4,7 @@
 
 #include "base/at_exit.h"
 #include "base/bind.h"
+#include "base/command_line.h"
 #include "base/feature_list.h"
 #include "base/message_loop/message_loop.h"
 #if defined(OS_MACOSX)
@@ -13,6 +14,10 @@
 #include "base/test/test_suite.h"
 #include "gpu/command_buffer/client/gles2_lib.h"
 #include "gpu/command_buffer/tests/gl_test_utils.h"
+#include "gpu/config/gpu_info_collector.h"
+#include "gpu/config/gpu_preferences.h"
+#include "gpu/config/gpu_util.h"
+#include "gpu/ipc/in_process_command_buffer.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
 namespace {
@@ -25,6 +30,20 @@
 #endif
   base::FeatureList::InitializeInstance(std::string(), std::string());
   gpu::GLTestHelper::InitializeGLDefault();
+
+  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+  gpu::GPUInfo gpu_info;
+  gpu::CollectGraphicsInfoForTesting(&gpu_info);
+  gpu::GpuFeatureInfo gpu_feature_info = gpu::ComputeGpuFeatureInfo(
+      gpu_info, gpu::GpuPreferences(), command_line, nullptr);
+  // Always enable gpu and oop raster, regardless of platform and blacklist.
+  gpu_feature_info.status_values[gpu::GPU_FEATURE_TYPE_GPU_RASTERIZATION] =
+      gpu::kGpuFeatureStatusEnabled;
+  gpu_feature_info.status_values[gpu::GPU_FEATURE_TYPE_OOP_RASTERIZATION] =
+      gpu::kGpuFeatureStatusEnabled;
+  gpu::InProcessCommandBuffer::InitializeDefaultServiceForTesting(
+      gpu_feature_info);
+
   ::gles2::Initialize();
   return testSuite->Run();
 }
diff --git a/gpu/command_buffer/tests/gl_unittest.cc b/gpu/command_buffer/tests/gl_unittest.cc
index bae4060..3aefbe4 100644
--- a/gpu/command_buffer/tests/gl_unittest.cc
+++ b/gpu/command_buffer/tests/gl_unittest.cc
@@ -11,7 +11,6 @@
 #include "gpu/command_buffer/service/feature_info.h"
 #include "gpu/command_buffer/tests/gl_manager.h"
 #include "gpu/command_buffer/tests/gl_test_utils.h"
-#include "gpu/config/gpu_preferences.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -104,7 +103,7 @@
 
 TEST_F(GLTest, FeatureFlagsMatchCapabilities) {
   scoped_refptr<gles2::FeatureInfo> features =
-      new gles2::FeatureInfo(gl_.workarounds(), GpuPreferences());
+      new gles2::FeatureInfo(gl_.workarounds(), GpuFeatureInfo());
   features->InitializeForTesting();
   const auto& caps = gl_.GetCapabilities();
   const auto& flags = features->feature_flags();
diff --git a/gpu/config/gpu_blacklist.cc b/gpu/config/gpu_blacklist.cc
index e6a3f6d..553d1c1 100644
--- a/gpu/config/gpu_blacklist.cc
+++ b/gpu/config/gpu_blacklist.cc
@@ -43,6 +43,8 @@
                             GPU_FEATURE_TYPE_ACCELERATED_WEBGL2);
   list->AddSupportedFeature("protected_video_decode",
                             GPU_FEATURE_TYPE_PROTECTED_VIDEO_DECODE);
+  list->AddSupportedFeature("oop_rasterization",
+                            GPU_FEATURE_TYPE_OOP_RASTERIZATION);
   return list;
 }
 
diff --git a/gpu/config/gpu_feature_type.h b/gpu/config/gpu_feature_type.h
index 52e0233..3587f075 100644
--- a/gpu/config/gpu_feature_type.h
+++ b/gpu/config/gpu_feature_type.h
@@ -21,6 +21,7 @@
   GPU_FEATURE_TYPE_GPU_RASTERIZATION,
   GPU_FEATURE_TYPE_ACCELERATED_WEBGL2,
   GPU_FEATURE_TYPE_PROTECTED_VIDEO_DECODE,
+  GPU_FEATURE_TYPE_OOP_RASTERIZATION,
   NUMBER_OF_GPU_FEATURE_TYPES
 };
 
diff --git a/gpu/config/gpu_finch_features.cc b/gpu/config/gpu_finch_features.cc
index b8926d11..6b9f27d 100644
--- a/gpu/config/gpu_finch_features.cc
+++ b/gpu/config/gpu_finch_features.cc
@@ -20,6 +20,11 @@
     "DefaultEnableGpuRasterization", base::FEATURE_DISABLED_BY_DEFAULT};
 #endif
 
+// Enable out of process rasterization by default.  This can still be overridden
+// by --enable-oop-rasterization or --disable-oop-rasterization.
+const base::Feature kDefaultEnableOopRasterization{
+    "DefaultEnableOopRasterization", base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Use the passthrough command decoder by default.  This can be overridden with
 // the --use-cmd-decoder=passthrough or --use-cmd-decoder=validating flags.
 const base::Feature kDefaultPassthroughCommandDecoder{
diff --git a/gpu/config/gpu_finch_features.h b/gpu/config/gpu_finch_features.h
index 6aec6b35..8573fcef 100644
--- a/gpu/config/gpu_finch_features.h
+++ b/gpu/config/gpu_finch_features.h
@@ -17,6 +17,8 @@
 // alongside the definition of their values in the .cc file.
 GPU_EXPORT extern const base::Feature kDefaultEnableGpuRasterization;
 
+GPU_EXPORT extern const base::Feature kDefaultEnableOopRasterization;
+
 GPU_EXPORT extern const base::Feature kDefaultPassthroughCommandDecoder;
 
 GPU_EXPORT extern const base::Feature kDirectCompositionOverlays;
diff --git a/gpu/config/gpu_preferences.h b/gpu/config/gpu_preferences.h
index 22a17a3..6916fa8 100644
--- a/gpu/config/gpu_preferences.h
+++ b/gpu/config/gpu_preferences.h
@@ -181,8 +181,10 @@
   // Ignores GPU blacklist.
   bool ignore_gpu_blacklist = false;
 
-  // Enable GPU rasterization in the GPU process.
+  // Oop rasterization preferences in the GPU process.  disable wins over
+  // enable, and neither means use defaults from GpuFeatureInfo.
   bool enable_oop_rasterization = false;
+  bool disable_oop_rasterization = false;
 
   // Use GpuFence objects to synchronize display of overlay planes.
   bool use_gpu_fences_for_overlay_planes = false;
diff --git a/gpu/config/gpu_preferences_unittest.cc b/gpu/config/gpu_preferences_unittest.cc
index 81842aa..67e9ff7 100644
--- a/gpu/config/gpu_preferences_unittest.cc
+++ b/gpu/config/gpu_preferences_unittest.cc
@@ -69,6 +69,7 @@
             right.disable_gpu_driver_bug_workarounds);
   EXPECT_EQ(left.ignore_gpu_blacklist, right.ignore_gpu_blacklist);
   EXPECT_EQ(left.enable_oop_rasterization, right.enable_oop_rasterization);
+  EXPECT_EQ(left.disable_oop_rasterization, right.disable_oop_rasterization);
   EXPECT_EQ(left.use_gpu_fences_for_overlay_planes,
             right.use_gpu_fences_for_overlay_planes);
   EXPECT_EQ(left.watchdog_starts_backgrounded,
@@ -146,6 +147,7 @@
     GPU_PREFERENCES_FIELD(disable_gpu_driver_bug_workarounds, true)
     GPU_PREFERENCES_FIELD(ignore_gpu_blacklist, true)
     GPU_PREFERENCES_FIELD(enable_oop_rasterization, true)
+    GPU_PREFERENCES_FIELD(disable_oop_rasterization, true)
     GPU_PREFERENCES_FIELD(use_gpu_fences_for_overlay_planes, true)
     GPU_PREFERENCES_FIELD(watchdog_starts_backgrounded, true)
 
diff --git a/gpu/config/gpu_switches.cc b/gpu/config/gpu_switches.cc
index ab9fb786..79002ed 100644
--- a/gpu/config/gpu_switches.cc
+++ b/gpu/config/gpu_switches.cc
@@ -19,10 +19,6 @@
 // impl-side painting.
 const char kEnableGpuRasterization[] = "enable-gpu-rasterization";
 
-// Turns on out of process raster for the renderer whenever gpu raster
-// would have been used.  Enables the chromium_raster_transport extension.
-const char kEnableOOPRasterization[] = "enable-oop-rasterization";
-
 // Passes encoded GpuPreferences to GPU process.
 const char kGpuPreferences[] = "gpu-preferences";
 
diff --git a/gpu/config/gpu_switches.h b/gpu/config/gpu_switches.h
index 0f88c6e..0dddd1e9 100644
--- a/gpu/config/gpu_switches.h
+++ b/gpu/config/gpu_switches.h
@@ -12,7 +12,6 @@
 GPU_EXPORT extern const char kDisableGpuDriverBugWorkarounds[];
 GPU_EXPORT extern const char kDisableGpuRasterization[];
 GPU_EXPORT extern const char kEnableGpuRasterization[];
-GPU_EXPORT extern const char kEnableOOPRasterization[];
 GPU_EXPORT extern const char kGpuPreferences[];
 GPU_EXPORT extern const char kIgnoreGpuBlacklist[];
 GPU_EXPORT extern const char kGpuBlacklistTestGroup[];
diff --git a/gpu/config/gpu_util.cc b/gpu/config/gpu_util.cc
index 769d82d6..464c5d84 100644
--- a/gpu/config/gpu_util.cc
+++ b/gpu/config/gpu_util.cc
@@ -56,6 +56,39 @@
   return kGpuFeatureStatusEnabled;
 }
 
+GpuFeatureStatus GetOopRasterizationFeatureStatus(
+    const std::set<int>& blacklisted_features,
+    const base::CommandLine& command_line,
+    const GpuPreferences& gpu_preferences,
+    const GPUInfo& gpu_info) {
+  // OOP rasterization requires GPU rasterization, so if blacklisted or
+  // disabled, report the same.
+  auto status =
+      GetGpuRasterizationFeatureStatus(blacklisted_features, command_line);
+  if (status != kGpuFeatureStatusEnabled)
+    return status;
+
+  // If we can't create a GrContext for whatever reason, don't enable oop
+  // rasterization.
+  if (!gpu_info.oop_rasterization_supported)
+    return kGpuFeatureStatusDisabled;
+
+  if (gpu_preferences.disable_oop_rasterization)
+    return kGpuFeatureStatusDisabled;
+  else if (gpu_preferences.enable_oop_rasterization)
+    return kGpuFeatureStatusEnabled;
+
+  if (blacklisted_features.count(GPU_FEATURE_TYPE_OOP_RASTERIZATION))
+    return kGpuFeatureStatusBlacklisted;
+
+  // OOP Rasterization on platforms that are not fully enabled is controlled by
+  // a finch experiment.
+  if (!base::FeatureList::IsEnabled(features::kDefaultEnableOopRasterization))
+    return kGpuFeatureStatusDisabled;
+
+  return kGpuFeatureStatusEnabled;
+}
+
 GpuFeatureStatus GetWebGLFeatureStatus(
     const std::set<int>& blacklisted_features,
     bool use_swift_shader) {
@@ -212,6 +245,8 @@
       kGpuFeatureStatusSoftware;
   gpu_feature_info.status_values[GPU_FEATURE_TYPE_PROTECTED_VIDEO_DECODE] =
       kGpuFeatureStatusDisabled;
+  gpu_feature_info.status_values[GPU_FEATURE_TYPE_OOP_RASTERIZATION] =
+      kGpuFeatureStatusDisabled;
 #if DCHECK_IS_ON()
   for (int ii = 0; ii < NUMBER_OF_GPU_FEATURE_TYPES; ++ii) {
     DCHECK_NE(kGpuFeatureStatusUndefined, gpu_feature_info.status_values[ii]);
@@ -242,6 +277,8 @@
       kGpuFeatureStatusDisabled;
   gpu_feature_info.status_values[GPU_FEATURE_TYPE_PROTECTED_VIDEO_DECODE] =
       kGpuFeatureStatusDisabled;
+  gpu_feature_info.status_values[GPU_FEATURE_TYPE_OOP_RASTERIZATION] =
+      kGpuFeatureStatusDisabled;
 #if DCHECK_IS_ON()
   for (int ii = 0; ii < NUMBER_OF_GPU_FEATURE_TYPES; ++ii) {
     DCHECK_NE(kGpuFeatureStatusUndefined, gpu_feature_info.status_values[ii]);
@@ -272,6 +309,8 @@
       kGpuFeatureStatusSoftware;
   gpu_feature_info.status_values[GPU_FEATURE_TYPE_PROTECTED_VIDEO_DECODE] =
       kGpuFeatureStatusDisabled;
+  gpu_feature_info.status_values[GPU_FEATURE_TYPE_OOP_RASTERIZATION] =
+      kGpuFeatureStatusDisabled;
 #if DCHECK_IS_ON()
   for (int ii = 0; ii < NUMBER_OF_GPU_FEATURE_TYPES; ++ii) {
     DCHECK_NE(kGpuFeatureStatusUndefined, gpu_feature_info.status_values[ii]);
@@ -342,6 +381,9 @@
   gpu_feature_info.status_values[GPU_FEATURE_TYPE_PROTECTED_VIDEO_DECODE] =
       GetProtectedVideoDecodeFeatureStatus(blacklisted_features, gpu_info,
                                            use_swift_shader);
+  gpu_feature_info.status_values[GPU_FEATURE_TYPE_OOP_RASTERIZATION] =
+      GetOopRasterizationFeatureStatus(blacklisted_features, *command_line,
+                                       gpu_preferences, gpu_info);
 #if DCHECK_IS_ON()
   for (int ii = 0; ii < NUMBER_OF_GPU_FEATURE_TYPES; ++ii) {
     DCHECK_NE(kGpuFeatureStatusUndefined, gpu_feature_info.status_values[ii]);
diff --git a/gpu/gles2_conform_support/egl/context.cc b/gpu/gles2_conform_support/egl/context.cc
index 00e7114..db5f39e 100644
--- a/gpu/gles2_conform_support/egl/context.cc
+++ b/gpu/gles2_conform_support/egl/context.cc
@@ -257,14 +257,15 @@
 bool Context::CreateService(gl::GLSurface* gl_surface) {
   gpu::SharedMemoryLimits limits;
   gpu::GpuPreferences gpu_preferences;
+  gpu::GpuFeatureInfo gpu_feature_info;
   scoped_refptr<gpu::gles2::FeatureInfo> feature_info(
       new gpu::gles2::FeatureInfo(gpu_driver_bug_workarounds_,
-                                  gpu_preferences));
+                                  gpu_feature_info));
   scoped_refptr<gpu::gles2::ContextGroup> group(new gpu::gles2::ContextGroup(
       gpu_preferences, true, &mailbox_manager_, nullptr /* memory_tracker */,
       &translator_cache_, &completeness_cache_, feature_info, true,
       &image_manager_, nullptr /* image_factory */,
-      nullptr /* progress_reporter */, gpu::GpuFeatureInfo(),
+      nullptr /* progress_reporter */, gpu_feature_info,
       &discardable_manager_));
 
   transfer_buffer_manager_ =
diff --git a/gpu/ipc/common/gpu_preferences.mojom b/gpu/ipc/common/gpu_preferences.mojom
index c239789..7173447b 100644
--- a/gpu/ipc/common/gpu_preferences.mojom
+++ b/gpu/ipc/common/gpu_preferences.mojom
@@ -60,6 +60,7 @@
   bool disable_gpu_driver_bug_workarounds;
   bool ignore_gpu_blacklist;
   bool enable_oop_rasterization;
+  bool disable_oop_rasterization;
   bool use_gpu_fences_for_overlay_planes;
   bool watchdog_starts_backgrounded;
 };
diff --git a/gpu/ipc/common/gpu_preferences_struct_traits.h b/gpu/ipc/common/gpu_preferences_struct_traits.h
index 432234d..219ca8e 100644
--- a/gpu/ipc/common/gpu_preferences_struct_traits.h
+++ b/gpu/ipc/common/gpu_preferences_struct_traits.h
@@ -116,6 +116,7 @@
         prefs.disable_gpu_driver_bug_workarounds();
     out->ignore_gpu_blacklist = prefs.ignore_gpu_blacklist();
     out->enable_oop_rasterization = prefs.enable_oop_rasterization();
+    out->disable_oop_rasterization = prefs.disable_oop_rasterization();
     out->use_gpu_fences_for_overlay_planes =
         prefs.use_gpu_fences_for_overlay_planes();
     out->watchdog_starts_backgrounded = prefs.watchdog_starts_backgrounded();
@@ -246,6 +247,9 @@
   static bool enable_oop_rasterization(const gpu::GpuPreferences& prefs) {
     return prefs.enable_oop_rasterization;
   }
+  static bool disable_oop_rasterization(const gpu::GpuPreferences& prefs) {
+    return prefs.disable_oop_rasterization;
+  }
   static bool use_gpu_fences_for_overlay_planes(
       const gpu::GpuPreferences& prefs) {
     return prefs.use_gpu_fences_for_overlay_planes;
diff --git a/gpu/ipc/in_process_command_buffer.cc b/gpu/ipc/in_process_command_buffer.cc
index a8c7f94..91dee108 100644
--- a/gpu/ipc/in_process_command_buffer.cc
+++ b/gpu/ipc/in_process_command_buffer.cc
@@ -327,7 +327,7 @@
     GpuDriverBugWorkarounds workarounds(
         service_->gpu_feature_info().enabled_gpu_driver_bug_workarounds);
     auto feature_info = base::MakeRefCounted<gles2::FeatureInfo>(
-        workarounds, service_->gpu_preferences());
+        workarounds, service_->gpu_feature_info());
 
     context_group_ = base::MakeRefCounted<gles2::ContextGroup>(
         service_->gpu_preferences(),
@@ -359,11 +359,11 @@
   command_buffer_ = std::make_unique<CommandBufferService>(
       this, transfer_buffer_manager_.get());
 
-  // Check gpu_preferences() as well as attribs.enable_oop_rasterization to
-  // prevent compromised renderer from unilaterally enabling RasterDecoder until
-  // we have fuzzed it (https://crbug.com/829469).
-  if (service_->gpu_preferences().enable_oop_rasterization &&
-      params.attribs.enable_oop_rasterization &&
+  bool supports_oop_rasterization =
+      service_->gpu_feature_info()
+          .status_values[GPU_FEATURE_TYPE_OOP_RASTERIZATION] ==
+      kGpuFeatureStatusEnabled;
+  if (supports_oop_rasterization && params.attribs.enable_oop_rasterization &&
       params.attribs.enable_raster_interface &&
       !params.attribs.enable_gles2_interface) {
     decoder_.reset(raster::RasterDecoder::Create(this, command_buffer_.get(),
diff --git a/gpu/ipc/raster_in_process_context.cc b/gpu/ipc/raster_in_process_context.cc
index a9c307c..7cf18ef 100644
--- a/gpu/ipc/raster_in_process_context.cc
+++ b/gpu/ipc/raster_in_process_context.cc
@@ -57,16 +57,6 @@
     return ContextResult::kFatalFailure;
   }
 
-  // TODO(backer): Remove this. Currently used to set
-  // |chromium_raster_transport| features flag (https://crbug.com/786591) and
-  // enable_oop_rasterization in GpuPreferences (https://crbug.com/829469).
-  if (attribs.enable_oop_rasterization &&
-      !base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kEnableOOPRasterization)) {
-    base::CommandLine::ForCurrentProcess()->AppendSwitch(
-        switches::kEnableOOPRasterization);
-  }
-
   command_buffer_ = std::make_unique<InProcessCommandBuffer>(service);
   auto result = command_buffer_->Initialize(
       nullptr /* surface */, true /* is_offscreen */, kNullSurfaceHandle,
diff --git a/gpu/ipc/service/gles2_command_buffer_stub.cc b/gpu/ipc/service/gles2_command_buffer_stub.cc
index c3f9e69a..da6fc29 100644
--- a/gpu/ipc/service/gles2_command_buffer_stub.cc
+++ b/gpu/ipc/service/gles2_command_buffer_stub.cc
@@ -94,7 +94,7 @@
            init_params.attribs.bind_generates_resource);
   } else {
     scoped_refptr<gles2::FeatureInfo> feature_info = new gles2::FeatureInfo(
-        manager->gpu_driver_bug_workarounds(), manager->gpu_preferences());
+        manager->gpu_driver_bug_workarounds(), manager->gpu_feature_info());
     gpu::GpuMemoryBufferFactory* gmb_factory =
         manager->gpu_memory_buffer_factory();
     context_group_ = new gles2::ContextGroup(
diff --git a/gpu/ipc/service/gpu_channel.cc b/gpu/ipc/service/gpu_channel.cc
index fcf39fb..b7cbf4d 100644
--- a/gpu/ipc/service/gpu_channel.cc
+++ b/gpu/ipc/service/gpu_channel.cc
@@ -614,10 +614,11 @@
 
   std::unique_ptr<CommandBufferStub> stub;
 
-  // Check gpu_preferences() as well as attribs.enable_oop_rasterization to
-  // preventcompromised renderer from unilaterally enabling RasterDecoder until
-  // we have fuzzed it (https://crbug.com/829469).
-  if (gpu_channel_manager_->gpu_preferences().enable_oop_rasterization &&
+  bool supports_oop_rasterization =
+      gpu_channel_manager_->gpu_feature_info()
+          .status_values[GPU_FEATURE_TYPE_GPU_RASTERIZATION] ==
+      kGpuFeatureStatusEnabled;
+  if (supports_oop_rasterization &&
       init_params.attribs.enable_oop_rasterization &&
       init_params.attribs.enable_raster_interface &&
       !init_params.attribs.enable_gles2_interface) {
diff --git a/gpu/ipc/service/raster_command_buffer_stub.cc b/gpu/ipc/service/raster_command_buffer_stub.cc
index e21fb49..abab626 100644
--- a/gpu/ipc/service/raster_command_buffer_stub.cc
+++ b/gpu/ipc/service/raster_command_buffer_stub.cc
@@ -89,7 +89,7 @@
            init_params.attribs.bind_generates_resource);
   } else {
     scoped_refptr<gles2::FeatureInfo> feature_info = new gles2::FeatureInfo(
-        manager->gpu_driver_bug_workarounds(), manager->gpu_preferences());
+        manager->gpu_driver_bug_workarounds(), manager->gpu_feature_info());
     gpu::GpuMemoryBufferFactory* gmb_factory =
         manager->gpu_memory_buffer_factory();
     context_group_ = new gles2::ContextGroup(
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 4354ce9..3e3bf70 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -27195,6 +27195,7 @@
   <int value="-1151766565" label="enable-fullscreen-tab-detaching"/>
   <int value="-1145702446" label="ChromeHomeInactivitySheetExpansion:enabled"/>
   <int value="-1145246849" label="ThirdPartyDoodles:enabled"/>
+  <int value="-1143496217" label="enable-oop-rasterization"/>
   <int value="-1137442543" label="enable-slimming-paint"/>
   <int value="-1136627751" label="ignore-autocomplete-off-autofill"/>
   <int value="-1136509631" label="ssl-interstitial-v1"/>
@@ -28510,6 +28511,7 @@
   <int value="1845131710" label="Newblue:enabled"/>
   <int value="1847024354" label="enable-hotword-hardware"/>
   <int value="1849379463" label="OfflinePagesCTV2:enabled"/>
+  <int value="1849580433" label="disable-oop-rasterization"/>
   <int value="1851358497" label="enable-ash-sidebar"/>
   <int value="1852630189" label="NTPBookmarkSuggestions:disabled"/>
   <int value="1855524566" label="allow-insecure-websocket-from-https-origin"/>