Revert "Share one GLContext for all RasterDecoder when virtual context is used."

This reverts commit 1808a743048d147521eaffb386dc9f29b4ecae0e.

Reason for revert: Null-dereference READ in gpu::gles2::ContextState::api
https://crbug.com/912981

Original change's description:
> Share one GLContext for all RasterDecoder when virtual context is used.
> 
> With this CL, we will create a GLContextVirtual in RasterDecoderContextState,
> and share it with all raster decoders, display compositoer, etc. It is a
> temporary solution. In follow up CLs, we will share the one GLContext with
> GLES2 as well. In that case, we will use GLContext directly instead of
> GLContextVirtual.
> 
> Change-Id: If9b8d1f32e58b32a9d9f8cd07aa10c30432e3183
> Bug: 902904
> Reviewed-on: https://chromium-review.googlesource.com/c/1357463
> Commit-Queue: Peng Huang <penghuang@chromium.org>
> Reviewed-by: Antoine Labour <piman@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#614694}

TBR=penghuang@chromium.org,piman@chromium.org

Change-Id: I2eb66f211d408988f30bfb870425da80e0eb7a4b
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: 902904
Reviewed-on: https://chromium-review.googlesource.com/c/1368284
Reviewed-by: Peng Huang <penghuang@chromium.org>
Commit-Queue: Peng Huang <penghuang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#614738}
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
index 4501800..64b4e99 100644
--- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
+++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
@@ -140,7 +140,7 @@
   bool MakeCurrent();
 
   GrContext* gr_context() { return context_state_->gr_context; }
-  gl::GLContext* gl_context() { return context_state_->context(); }
+  gl::GLContext* gl_context() { return context_state_->context.get(); }
 
   const gpu::CommandBufferId command_buffer_id_;
   GpuServiceImpl* const gpu_service_;
diff --git a/components/viz/service/gl/gpu_service_impl.cc b/components/viz/service/gl/gpu_service_impl.cc
index 9ce7beb..eec9603 100644
--- a/components/viz/service/gl/gpu_service_impl.cc
+++ b/components/viz/service/gl/gpu_service_impl.cc
@@ -298,7 +298,7 @@
   // TODO(penghuang): https://crbug.com/899740 Support GLSurface which is not
   // compatible.
   DCHECK_EQ(surface->GetCompatibilityKey(),
-            context_state->surface()->GetCompatibilityKey());
+            context_state->surface->GetCompatibilityKey());
   DCHECK(!context_state->use_virtualized_gl_contexts);
   return context_state;
 }
diff --git a/gpu/command_buffer/service/decoder_context.h b/gpu/command_buffer/service/decoder_context.h
index 523bf03..abc53a0 100644
--- a/gpu/command_buffer/service/decoder_context.h
+++ b/gpu/command_buffer/service/decoder_context.h
@@ -213,12 +213,6 @@
   // Methods required by GpuTracer
   //
   virtual gles2::Outputter* outputter() const = 0;
-
-  // Restores all attributs in the gl context state.
-  virtual void RestoreAllAttributes() const = 0;
-
-  // Restores texture states for a given service id.
-  virtual void RestoreTextureState(unsigned service_id) const = 0;
 };
 
 }  // namespace gpu
diff --git a/gpu/command_buffer/service/gl_context_virtual_delegate.h b/gpu/command_buffer/service/gl_context_virtual_delegate.h
index 0db2f14..1b2ffc57 100644
--- a/gpu/command_buffer/service/gl_context_virtual_delegate.h
+++ b/gpu/command_buffer/service/gl_context_virtual_delegate.h
@@ -32,6 +32,7 @@
   // Restore States.
   virtual void RestoreGlobalState() const = 0;
   virtual void ClearAllAttributes() const = 0;
+  virtual void RestoreAllAttributes() const = 0;
   virtual void RestoreActiveTexture() const = 0;
   virtual void RestoreAllTextureUnitAndSamplerBindings(
       const gles2::ContextState* prev_state) const = 0;
@@ -41,6 +42,7 @@
   virtual void RestoreFramebufferBindings() const = 0;
   virtual void RestoreRenderbufferBindings() = 0;
   virtual void RestoreProgramBindings() const = 0;
+  virtual void RestoreTextureState(unsigned service_id) const = 0;
   virtual void RestoreTextureUnitBindings(unsigned unit) const = 0;
   virtual void RestoreVertexAttribArray(unsigned index) = 0;
   virtual void RestoreAllExternalTextureBindingsIfNeeded() = 0;
diff --git a/gpu/command_buffer/service/gl_state_restorer_impl.cc b/gpu/command_buffer/service/gl_state_restorer_impl.cc
index 0d20724..d47a8d4 100644
--- a/gpu/command_buffer/service/gl_state_restorer_impl.cc
+++ b/gpu/command_buffer/service/gl_state_restorer_impl.cc
@@ -71,14 +71,12 @@
 
 void GLStateRestorerImpl::PauseQueries() {
   DCHECK(delegate_.get());
-  if (auto* query_manager = delegate_->GetQueryManager())
-    query_manager->PauseQueries();
+  delegate_->GetQueryManager()->PauseQueries();
 }
 
 void GLStateRestorerImpl::ResumeQueries() {
   DCHECK(delegate_.get());
-  if (auto* query_manager = delegate_->GetQueryManager())
-    query_manager->ResumeQueries();
+  delegate_->GetQueryManager()->ResumeQueries();
 }
 
 const gles2::ContextState* GLStateRestorerImpl::GetContextState() const {
diff --git a/gpu/command_buffer/service/gr_cache_controller.cc b/gpu/command_buffer/service/gr_cache_controller.cc
index 787ef40..4bb1cc1 100644
--- a/gpu/command_buffer/service/gr_cache_controller.cc
+++ b/gpu/command_buffer/service/gr_cache_controller.cc
@@ -21,7 +21,7 @@
 
 void GrCacheController::ScheduleGrContextCleanup() {
   DCHECK(task_runner_->BelongsToCurrentThread());
-  DCHECK(context_state_->IsCurrent(nullptr));
+  DCHECK(context_state_->context->IsCurrent(nullptr));
 
   if (!context_state_->gr_context)
     return;
@@ -35,6 +35,7 @@
   // a long while even if it is under budget. Below we set a call back to
   // purge all possible GrContext resources if the context itself is not being
   // used.
+  context_state_->context->DirtyVirtualContextState();
   context_state_->need_context_state_reset = true;
   context_state_->gr_context->performDeferredCleanup(
       std::chrono::seconds(kOldResourceCleanupDelaySeconds));
@@ -63,6 +64,7 @@
     return;
   }
 
+  context_state_->context->DirtyVirtualContextState();
   context_state_->need_context_state_reset = true;
   context_state_->gr_context->freeGpuResources();
 }
diff --git a/gpu/command_buffer/service/raster_decoder.cc b/gpu/command_buffer/service/raster_decoder.cc
index e34d92f..7b9f9d8 100644
--- a/gpu/command_buffer/service/raster_decoder.cc
+++ b/gpu/command_buffer/service/raster_decoder.cc
@@ -72,16 +72,16 @@
 
 // Local versions of the SET_GL_ERROR macros
 #define LOCAL_SET_GL_ERROR(error, function_name, msg) \
-  ERRORSTATE_SET_GL_ERROR(error_state_.get(), error, function_name, msg)
-#define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label)      \
-  ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(error_state_.get(), function_name, \
+  ERRORSTATE_SET_GL_ERROR(GetErrorState(), error, function_name, msg)
+#define LOCAL_SET_GL_ERROR_INVALID_ENUM(function_name, value, label)   \
+  ERRORSTATE_SET_GL_ERROR_INVALID_ENUM(GetErrorState(), function_name, \
                                        static_cast<uint32_t>(value), label)
 #define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name) \
-  ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state_.get(), function_name)
+  ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(GetErrorState(), function_name)
 #define LOCAL_PEEK_GL_ERROR(function_name) \
-  ERRORSTATE_PEEK_GL_ERROR(error_state_.get(), function_name)
+  ERRORSTATE_PEEK_GL_ERROR(GetErrorState(), function_name)
 #define LOCAL_CLEAR_REAL_GL_ERRORS(function_name) \
-  ERRORSTATE_CLEAR_REAL_GL_ERRORS(error_state_.get(), function_name)
+  ERRORSTATE_CLEAR_REAL_GL_ERRORS(GetErrorState(), function_name)
 #define LOCAL_PERFORMANCE_WARNING(msg) \
   PerformanceWarning(__FILE__, __LINE__, msg)
 #define LOCAL_RENDER_WARNING(msg) RenderWarning(__FILE__, __LINE__, msg)
@@ -284,8 +284,6 @@
   }
   Capabilities GetCapabilities() override;
   const gles2::ContextState* GetContextState() override;
-
-  // TODO(penghuang): Remove unused context state related methods.
   void RestoreGlobalState() const override;
   void ClearAllAttributes() const override;
   void RestoreAllAttributes() const override;
@@ -304,7 +302,6 @@
   void RestoreVertexAttribArray(unsigned index) override;
   void RestoreAllExternalTextureBindingsIfNeeded() override;
   QueryManager* GetQueryManager() override;
-
   void SetQueryCallback(unsigned int query_client_id,
                         base::OnceClosure callback) override;
   gles2::GpuFenceManager* GetGpuFenceManager() override;
@@ -407,10 +404,7 @@
     return &it->second;
   }
 
-  gles2::ContextState* state() const {
-    return raster_decoder_context_state_->context_state();
-  }
-  gl::GLApi* api() const { return state()->api(); }
+  gl::GLApi* api() const { return state_.api(); }
   GrContext* gr_context() const {
     return raster_decoder_context_state_->gr_context;
   }
@@ -428,8 +422,7 @@
 
   bool IsRobustnessSupported() {
     return has_robustness_extension_ &&
-           raster_decoder_context_state_->context()
-               ->WasAllocatedUsingRobustnessExtension();
+           context_->WasAllocatedUsingRobustnessExtension();
   }
 
   const gl::GLVersionInfo& gl_version_info() {
@@ -605,6 +598,7 @@
   // only if not returning an error.
   error::Error current_decoder_error_ = error::kNoError;
 
+  scoped_refptr<gl::GLSurface> surface_;
   scoped_refptr<gl::GLContext> context_;
 
   DecoderClient* client_;
@@ -612,7 +606,6 @@
   gles2::DebugMarkerManager debug_marker_manager_;
   gles2::Logger logger_;
   std::unique_ptr<gles2::ErrorState> error_state_;
-  bool context_lost_ = false;
 
   // The ContextGroup for this decoder uses to track resources.
   scoped_refptr<gles2::ContextGroup> group_;
@@ -622,6 +615,9 @@
 
   std::unique_ptr<QueryManager> query_manager_;
 
+  // All the state for this context.
+  gles2::ContextState state_;
+
   gles2::GLES2Util util_;
 
   // An optional behaviour to lose the context and group when OOM.
@@ -741,6 +737,8 @@
       raster_decoder_context_state_(std::move(raster_decoder_context_state)),
       validators_(new Validators),
       feature_info_(group_->feature_info()),
+      state_(group_->feature_info(),
+             false /* track_texture_and_sampler_units */),
       service_logging_(
           group_->gpu_preferences().enable_gpu_service_logging_gpu),
       gpu_decoder_category_(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
@@ -769,6 +767,8 @@
   DCHECK(context->IsCurrent(surface.get()));
   DCHECK(!context_.get());
 
+  state_.set_api(gl::g_current_gl_context);
+
   set_initialized();
 
   if (!offscreen) {
@@ -781,8 +781,7 @@
   if (group_->gpu_preferences().enable_gpu_command_logging)
     SetLogCommands(true);
 
-  DCHECK_EQ(surface.get(), raster_decoder_context_state_->surface());
-  DCHECK_EQ(context.get(), raster_decoder_context_state_->context());
+  surface_ = surface;
   context_ = context;
 
   // Create GPU Tracer for timing values.
@@ -800,15 +799,22 @@
     Destroy(true);
     return result;
   }
-
   CHECK_GL_ERROR();
 
-  query_manager_ = std::make_unique<QueryManager>();
+  state_.InitGenericAttribs(group_->max_vertex_attribs());
+
+  query_manager_.reset(new QueryManager());
 
   has_robustness_extension_ = features().arb_robustness ||
                               features().khr_robustness ||
                               features().ext_robustness;
 
+  // Set all the default state because some GL drivers get it wrong.
+  // TODO(backer): Not all of this state needs to be initialized. Reduce the set
+  // if perf becomes a problem.
+  state_.InitCapabilities(nullptr);
+  state_.InitState(nullptr);
+
   if (attrib_helper.enable_oop_rasterization) {
     if (!features().chromium_raster_transport) {
       LOG(ERROR) << "ContextResult::kFatalFailure: "
@@ -830,8 +836,7 @@
   if (!initialized())
     return;
 
-  DCHECK(!have_context ||
-         raster_decoder_context_state_->context()->IsCurrent(nullptr));
+  DCHECK(!have_context || context_->IsCurrent(nullptr));
 
   if (have_context) {
     if (copy_tex_image_blit_.get()) {
@@ -856,8 +861,14 @@
     if (group_ && group_->texture_manager()) {
       group_->texture_manager()->MarkContextLost();
     }
+
+    state_.MarkContextLost();
   }
 
+  // Unbind everything.
+  state_.bound_pixel_pack_buffer = nullptr;
+  state_.bound_pixel_unpack_buffer = nullptr;
+
   copy_tex_image_blit_.reset();
   copy_texture_chromium_.reset();
 
@@ -873,6 +884,8 @@
 
   // Destroy the surface before the context, some surface destructors make GL
   // calls.
+  surface_ = nullptr;
+
   if (context_.get()) {
     context_->ReleaseCurrent(nullptr);
     context_ = nullptr;
@@ -884,22 +897,23 @@
 
 // Make this decoder's GL context current.
 bool RasterDecoderImpl::MakeCurrent() {
+  DCHECK(surface_);
   if (!context_.get())
     return false;
 
-  if (context_lost_) {
+  if (WasContextLost()) {
     LOG(ERROR) << "  RasterDecoderImpl: Trying to make lost context current.";
     return false;
   }
 
-  if (raster_decoder_context_state_->context_lost() ||
-      !raster_decoder_context_state_->MakeCurrent(nullptr)) {
+  // TODO(https://crbug.com/902904): Switch to
+  // raster_decoder_context_state_->MakeCurrent(nullptr).
+  if (!context_->MakeCurrent(surface_.get())) {
     LOG(ERROR) << "  RasterDecoderImpl: Context lost during MakeCurrent.";
     MarkContextLost(error::kMakeCurrentFailed);
     group_->LoseContexts(error::kUnknown);
     return false;
   }
-
   DCHECK_EQ(api(), gl::g_current_gl_context);
 
   if (CheckResetStatus()) {
@@ -920,7 +934,7 @@
 }
 
 gl::GLSurface* RasterDecoderImpl::GetGLSurface() {
-  return raster_decoder_context_state_->surface();
+  return surface_.get();
 }
 
 Capabilities RasterDecoderImpl::GetCapabilities() {
@@ -952,12 +966,18 @@
 }
 
 const gles2::ContextState* RasterDecoderImpl::GetContextState() {
-  NOTREACHED();
-  return nullptr;
+  if (raster_decoder_context_state_->need_context_state_reset) {
+    // Returning nullptr to force full state restoration by the caller.  We do
+    // this because GrContext changes to GL state are untracked in our state_.
+    return nullptr;
+  }
+
+  return &state_;
 }
 
 void RasterDecoderImpl::RestoreGlobalState() const {
   raster_decoder_context_state_->PessimisticallyResetGrContext();
+  state_.RestoreGlobalState(nullptr);
 }
 
 void RasterDecoderImpl::ClearAllAttributes() const {}
@@ -967,6 +987,10 @@
 }
 
 void RasterDecoderImpl::RestoreState(const gles2::ContextState* prev_state) {
+  TRACE_EVENT1("gpu", "RasterDecoderImpl::RestoreState", "context",
+               logger_.GetLogPrefix());
+  state_.RestoreState(prev_state);
+  raster_decoder_context_state_->need_context_state_reset = false;
   raster_decoder_context_state_->PessimisticallyResetGrContext();
 }
 
@@ -986,22 +1010,36 @@
 
 void RasterDecoderImpl::RestoreBufferBinding(unsigned int target) {
   raster_decoder_context_state_->PessimisticallyResetGrContext();
+  if (target == GL_PIXEL_PACK_BUFFER) {
+    state_.UpdatePackParameters();
+  } else if (target == GL_PIXEL_UNPACK_BUFFER) {
+    state_.UpdateUnpackParameters();
+  }
+  api()->glBindBufferFn(target, 0);
 }
 
 void RasterDecoderImpl::RestoreBufferBindings() const {
   raster_decoder_context_state_->PessimisticallyResetGrContext();
+  state_.RestoreBufferBindings();
 }
 
 void RasterDecoderImpl::RestoreFramebufferBindings() const {
   raster_decoder_context_state_->PessimisticallyResetGrContext();
+  state_.fbo_binding_for_scissor_workaround_dirty = true;
+  state_.stencil_state_changed_since_validation = true;
+
+  if (workarounds().flush_on_framebuffer_change)
+    api()->glFlushFn();
 }
 
 void RasterDecoderImpl::RestoreRenderbufferBindings() {
   raster_decoder_context_state_->PessimisticallyResetGrContext();
+  state_.RestoreRenderbufferBindings();
 }
 
 void RasterDecoderImpl::RestoreProgramBindings() const {
   raster_decoder_context_state_->PessimisticallyResetGrContext();
+  state_.RestoreProgramSettings(nullptr, false);
 }
 
 void RasterDecoderImpl::RestoreTextureState(unsigned service_id) const {
@@ -1029,7 +1067,7 @@
 }
 
 void RasterDecoderImpl::RestoreVertexAttribArray(unsigned index) {
-  raster_decoder_context_state_->PessimisticallyResetGrContext();
+  NOTIMPLEMENTED();
 }
 
 void RasterDecoderImpl::RestoreAllExternalTextureBindingsIfNeeded() {
@@ -1058,12 +1096,13 @@
 }
 
 bool RasterDecoderImpl::HasPendingQueries() const {
-  return query_manager_ && query_manager_->HavePendingQueries();
+  return query_manager_.get() && query_manager_->HavePendingQueries();
 }
 
 void RasterDecoderImpl::ProcessPendingQueries(bool did_finish) {
-  if (query_manager_)
-    query_manager_->ProcessPendingQueries(did_finish);
+  if (!query_manager_.get())
+    return;
+  query_manager_->ProcessPendingQueries(did_finish);
 }
 
 bool RasterDecoderImpl::HasMoreIdleWork() const {
@@ -1098,7 +1137,7 @@
 }
 
 bool RasterDecoderImpl::WasContextLost() const {
-  return context_lost_;
+  return raster_decoder_context_state_->context_lost;
 }
 
 bool RasterDecoderImpl::WasContextLostByRobustnessExtension() const {
@@ -1111,14 +1150,16 @@
     return;
 
   // Don't make GL calls in here, the context might not be current.
-  context_lost_ = true;
   command_buffer_service()->SetContextLostReason(reason);
   current_decoder_error_ = error::kLostContext;
+
+  state_.MarkContextLost();
+  raster_decoder_context_state_->MarkContextLost();
 }
 
 bool RasterDecoderImpl::CheckResetStatus() {
   DCHECK(!WasContextLost());
-  DCHECK(raster_decoder_context_state_->context()->IsCurrent(nullptr));
+  DCHECK(context_->IsCurrent(nullptr));
 
   if (IsRobustnessSupported()) {
     // If the reason for the call was a GL error, we can try to determine the
@@ -1160,7 +1201,7 @@
 }
 
 void RasterDecoderImpl::SetIgnoreCachedStateForTest(bool ignore) {
-  state()->SetIgnoreCachedStateForTest(ignore);
+  state_.SetIgnoreCachedStateForTest(ignore);
 }
 
 gles2::ImageManager* RasterDecoderImpl::GetImageManagerForTest() {
@@ -1399,12 +1440,12 @@
   {
     const bool state_is_dirty =
         raster_decoder_context_state_->need_context_state_reset;
-    ScopedTextureBinder binder(state(), texture->target(),
+    ScopedTextureBinder binder(&state_, texture->target(),
                                texture->service_id(), gr_context(),
                                state_is_dirty);
     base::Optional<ScopedPixelUnpackState> pixel_unpack_state;
     if (raster_decoder_context_state_->need_context_state_reset) {
-      pixel_unpack_state.emplace(state(), gr_context(), group_->feature_info());
+      pixel_unpack_state.emplace(&state_, gr_context(), group_->feature_info());
     }
     // Add extra scope to destroy zero and the object it owns right
     // after its usage.
@@ -1841,7 +1882,7 @@
   GLint dest_level = 0;
 
   ScopedTextureBinder binder(
-      state(), texture_manager(), dest_texture_ref, dest_target, gr_context(),
+      &state_, texture_manager(), dest_texture_ref, dest_target, gr_context(),
       raster_decoder_context_state_->need_context_state_reset);
   base::Optional<ScopedPixelUnpackState> pixel_unpack_state;
 
@@ -1880,7 +1921,7 @@
       // If the image is in shared memory, we may need upload the pixel data
       // with SubTexImage2D, so we need reset pixel unpack state if gl context
       // state has been touched by skia.
-      pixel_unpack_state.emplace(state(), gr_context(), group_->feature_info());
+      pixel_unpack_state.emplace(&state_, gr_context(), group_->feature_info());
     }
   } else {
     if (!source_texture->GetLevelSize(source_target, 0 /* level */,
@@ -1941,7 +1982,7 @@
             source_internal_format) == GL_SRGB ||
         gles2::GLES2Util::GetColorEncodingFromInternalFormat(
             dest_internal_format) == GL_SRGB;
-    state()->EnableDisableFramebufferSRGB(enable_framebuffer_srgb);
+    state_.EnableDisableFramebufferSRGB(enable_framebuffer_srgb);
   }
 
   // Clear the source texture if necessary.
@@ -2054,8 +2095,7 @@
     gl::GLImage* image = texture->GetLevelImage(textarget, 0, &image_state);
     if (image && image_state == gles2::Texture::UNBOUND) {
       ScopedGLErrorSuppressor suppressor(
-          "RasterDecoderImpl::DoBindOrCopyTexImageIfNeeded",
-          error_state_.get());
+          "RasterDecoderImpl::DoBindOrCopyTexImageIfNeeded", GetErrorState());
       api()->glBindTextureFn(textarget, texture->service_id());
       if (!image->BindTexImage(textarget)) {
         // Note: We update the state to COPIED prior to calling CopyTexImage()
diff --git a/gpu/command_buffer/service/raster_decoder_context_state.cc b/gpu/command_buffer/service/raster_decoder_context_state.cc
index 9dc7b51..5ebefe8 100644
--- a/gpu/command_buffer/service/raster_decoder_context_state.cc
+++ b/gpu/command_buffer/service/raster_decoder_context_state.cc
@@ -7,8 +7,6 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/trace_event/memory_dump_manager.h"
 #include "gpu/command_buffer/common/activity_flags.h"
-#include "gpu/command_buffer/service/context_state.h"
-#include "gpu/command_buffer/service/gl_context_virtual.h"
 #include "gpu/command_buffer/service/service_transfer_cache.h"
 #include "gpu/config/gpu_driver_bug_workarounds.h"
 #include "gpu/vulkan/buildflags.h"
@@ -32,19 +30,17 @@
     bool use_virtualized_gl_contexts,
     base::OnceClosure context_lost_callback,
     viz::VulkanContextProvider* vulkan_context_provider)
-    : use_virtualized_gl_contexts(use_virtualized_gl_contexts),
+    : share_group(std::move(share_group)),
+      surface(std::move(surface)),
+      context(std::move(context)),
+      use_virtualized_gl_contexts(use_virtualized_gl_contexts),
       context_lost_callback(std::move(context_lost_callback)),
       vk_context_provider(vulkan_context_provider),
 #if BUILDFLAG(ENABLE_VULKAN)
       gr_context(vk_context_provider ? vk_context_provider->GetGrContext()
                                      : nullptr),
 #endif
-      use_vulkan_gr_context(!!gr_context),
-      share_group_(std::move(share_group)),
-      context_(context),
-      real_context_(std::move(context)),
-      surface_(std::move(surface)),
-      weak_ptr_factory_(this) {
+      use_vulkan_gr_context(!!gr_context) {
   if (base::ThreadTaskRunnerHandle::IsSet()) {
     base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
         this, "RasterDecoderContextState", base::ThreadTaskRunnerHandle::Get());
@@ -64,10 +60,10 @@
     GpuProcessActivityFlags* activity_flags,
     gl::ProgressReporter* progress_reporter) {
   if (!use_vulkan_gr_context) {
-    DCHECK(context_->IsCurrent(surface()));
+    DCHECK(context->IsCurrent(surface.get()));
 
     sk_sp<GrGLInterface> interface(gl::init::CreateGrGLInterface(
-        *context_->GetVersionInfo(), workarounds.use_es2_for_oopr,
+        *context->GetVersionInfo(), workarounds.use_es2_for_oopr,
         progress_reporter));
     if (!interface) {
       LOG(ERROR) << "OOP raster support disabled: GrGLInterface creation "
@@ -115,77 +111,6 @@
   transfer_cache = std::make_unique<ServiceTransferCache>();
 }
 
-bool RasterDecoderContextState::InitializeGL(
-    const GpuDriverBugWorkarounds& gpu_driver_bug_workarounds,
-    const GpuFeatureInfo& gpu_feature_info) {
-  if (use_vulkan_gr_context)
-    return true;
-  DCHECK(!context_state_);
-
-  feature_info_ = base::MakeRefCounted<gles2::FeatureInfo>(
-      gpu_driver_bug_workarounds, gpu_feature_info);
-
-  feature_info_->Initialize(gpu::CONTEXT_TYPE_OPENGLES2,
-                            false /* is_passthrough_cmd_decoder */,
-                            gles2::DisallowedFeatures());
-
-  auto* api = gl::g_current_gl_context;
-  const GLint kGLES2RequiredMinimumVertexAttribs = 8u;
-  GLint max_vertex_attribs = 0;
-  api->glGetIntegervFn(GL_MAX_VERTEX_ATTRIBS, &max_vertex_attribs);
-  if (max_vertex_attribs < kGLES2RequiredMinimumVertexAttribs)
-    return false;
-
-  context_state_ = std::make_unique<gles2::ContextState>(
-      feature_info_.get(), false /* track_texture_and_sampler_units */);
-
-  context_state_->set_api(api);
-  context_state_->InitGenericAttribs(max_vertex_attribs);
-
-  // Set all the default state because some GL drivers get it wrong.
-  // TODO(backer): Not all of this state needs to be initialized. Reduce the set
-  // if perf becomes a problem.
-  context_state_->InitCapabilities(nullptr);
-  context_state_->InitState(nullptr);
-
-  if (use_virtualized_gl_contexts) {
-    auto virtual_context = base::MakeRefCounted<GLContextVirtual>(
-        share_group_.get(), real_context_.get(),
-        weak_ptr_factory_.GetWeakPtr());
-    if (!virtual_context->Initialize(surface_.get(), gl::GLContextAttribs()))
-      return false;
-    context_ = std::move(virtual_context);
-    MakeCurrent(nullptr);
-  }
-  return true;
-}
-
-bool RasterDecoderContextState::MakeCurrent(gl::GLSurface* surface) {
-  if (context_lost_)
-    return false;
-
-  if (!context_->MakeCurrent(surface ? surface : surface_.get())) {
-    MarkContextLost();
-    return false;
-  }
-  return true;
-}
-
-void RasterDecoderContextState::MarkContextLost() {
-  if (!context_lost_) {
-    context_lost_ = true;
-    context_state_->MarkContextLost();
-    if (gr_context)
-      gr_context->abandonContext();
-    std::move(context_lost_callback).Run();
-  }
-  // TODO notify gpu channel manager.
-}
-
-bool RasterDecoderContextState::IsCurrent(gl::GLSurface* surface) {
-  return context_->IsCurrent(surface);
-}
-
 bool RasterDecoderContextState::OnMemoryDump(
     const base::trace_event::MemoryDumpArgs& args,
     base::trace_event::ProcessMemoryDump* pmd) {
@@ -202,7 +127,7 @@
   }
 
   // Ensure the context is current before doing any GPU cleanup.
-  MakeCurrent(nullptr);
+  context->MakeCurrent(surface.get());
 
   switch (memory_pressure_level) {
     case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE:
@@ -230,93 +155,29 @@
     gr_context->resetContext();
 }
 
-bool RasterDecoderContextState::initialized() const {
+void RasterDecoderContextState::MarkContextLost() {
+  if (!context_lost) {
+    context_lost = true;
+    if (gr_context)
+      gr_context->abandonContext();
+    std::move(context_lost_callback).Run();
+  }
+}
+
+bool RasterDecoderContextState::MakeCurrent(gl::GLSurface* current_surface) {
+  if (context_lost)
+    return false;
+
+  if (context->IsCurrent(current_surface))
+    return true;
+
+  if (!context->MakeCurrent(current_surface ? current_surface
+                                            : surface.get())) {
+    MarkContextLost();
+    return false;
+  }
   return true;
 }
 
-const gles2::ContextState* RasterDecoderContextState::GetContextState() {
-  if (need_context_state_reset) {
-    // Returning nullptr to force full state restoration by the caller.  We do
-    // this because GrContext changes to GL state are untracked in our
-    // context_state_.
-    return nullptr;
-  }
-  return context_state_.get();
-}
-
-void RasterDecoderContextState::RestoreState(
-    const gles2::ContextState* prev_state) {
-  PessimisticallyResetGrContext();
-  context_state_->RestoreState(prev_state);
-}
-
-void RasterDecoderContextState::RestoreGlobalState() const {
-  PessimisticallyResetGrContext();
-  context_state_->RestoreGlobalState(nullptr);
-}
-void RasterDecoderContextState::ClearAllAttributes() const {}
-
-void RasterDecoderContextState::RestoreActiveTexture() const {
-  PessimisticallyResetGrContext();
-}
-
-void RasterDecoderContextState::RestoreAllTextureUnitAndSamplerBindings(
-    const gles2::ContextState* prev_state) const {
-  PessimisticallyResetGrContext();
-}
-
-void RasterDecoderContextState::RestoreActiveTextureUnitBinding(
-    unsigned int target) const {
-  PessimisticallyResetGrContext();
-}
-
-void RasterDecoderContextState::RestoreBufferBinding(unsigned int target) {
-  PessimisticallyResetGrContext();
-  if (target == GL_PIXEL_PACK_BUFFER) {
-    context_state_->UpdatePackParameters();
-  } else if (target == GL_PIXEL_UNPACK_BUFFER) {
-    context_state_->UpdateUnpackParameters();
-  }
-  context_state_->api()->glBindBufferFn(target, 0);
-}
-
-void RasterDecoderContextState::RestoreBufferBindings() const {
-  PessimisticallyResetGrContext();
-  context_state_->RestoreBufferBindings();
-}
-
-void RasterDecoderContextState::RestoreFramebufferBindings() const {
-  PessimisticallyResetGrContext();
-  context_state_->fbo_binding_for_scissor_workaround_dirty = true;
-  context_state_->stencil_state_changed_since_validation = true;
-}
-
-void RasterDecoderContextState::RestoreRenderbufferBindings() {
-  PessimisticallyResetGrContext();
-  context_state_->RestoreRenderbufferBindings();
-}
-
-void RasterDecoderContextState::RestoreProgramBindings() const {
-  PessimisticallyResetGrContext();
-  context_state_->RestoreProgramSettings(nullptr, false);
-}
-
-void RasterDecoderContextState::RestoreTextureUnitBindings(
-    unsigned unit) const {
-  PessimisticallyResetGrContext();
-}
-
-void RasterDecoderContextState::RestoreVertexAttribArray(unsigned index) {
-  NOTIMPLEMENTED();
-}
-
-void RasterDecoderContextState::RestoreAllExternalTextureBindingsIfNeeded() {
-  PessimisticallyResetGrContext();
-}
-
-QueryManager* RasterDecoderContextState::GetQueryManager() {
-  return nullptr;
-}
-
 }  // namespace raster
 }  // namespace gpu
diff --git a/gpu/command_buffer/service/raster_decoder_context_state.h b/gpu/command_buffer/service/raster_decoder_context_state.h
index d34c622..84bed6c 100644
--- a/gpu/command_buffer/service/raster_decoder_context_state.h
+++ b/gpu/command_buffer/service/raster_decoder_context_state.h
@@ -7,10 +7,8 @@
 
 #include "base/memory/memory_pressure_listener.h"
 #include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
 #include "base/trace_event/memory_dump_provider.h"
 #include "gpu/command_buffer/common/skia_utils.h"
-#include "gpu/command_buffer/service/gl_context_virtual_delegate.h"
 #include "gpu/gpu_gles2_export.h"
 #include "third_party/skia/include/gpu/GrContext.h"
 #include "ui/gl/progress_reporter.h"
@@ -27,21 +25,14 @@
 
 namespace gpu {
 class GpuDriverBugWorkarounds;
-struct GpuFeatureInfo;
 class GpuProcessActivityFlags;
 class ServiceTransferCache;
-namespace gles2 {
-class FeatureInfo;
-struct ContextState;
-}  // namespace gles2
 
 namespace raster {
 
-// TODO(penghuang): Make RasterDecoderContextState a class.
 struct GPU_GLES2_EXPORT RasterDecoderContextState
-    : public base::trace_event::MemoryDumpProvider,
-      public gpu::GLContextVirtualDelegate,
-      public base::RefCounted<RasterDecoderContextState> {
+    : public base::RefCounted<RasterDecoderContextState>,
+      public base::trace_event::MemoryDumpProvider {
  public:
   // TODO: Refactor code to have seperate constructor for GL and Vulkan and not
   // initialize/use GL related info for vulkan and vice-versa.
@@ -57,27 +48,20 @@
                            GrContextOptions::PersistentCache* cache,
                            GpuProcessActivityFlags* activity_flags = nullptr,
                            gl::ProgressReporter* progress_reporter = nullptr);
-
-  // TODO(penghuang) do not depend on ContextGroup.
-  bool InitializeGL(const GpuDriverBugWorkarounds& gpu_driver_bug_workarounds,
-                    const GpuFeatureInfo& gpu_feature_info);
-
-  bool MakeCurrent(gl::GLSurface* surface);
-  void MarkContextLost();
-  bool IsCurrent(gl::GLSurface* surface);
-
   void PurgeMemory(
       base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level);
 
   void PessimisticallyResetGrContext() const;
 
-  gl::GLShareGroup* share_group() { return share_group_.get(); }
-  gl::GLContext* context() { return context_.get(); }
-  gl::GLContext* real_context() { return real_context_.get(); }
-  gl::GLSurface* surface() { return surface_.get(); }
-  gles2::ContextState* context_state() const { return context_state_.get(); }
-  bool context_lost() const { return context_lost_; }
+  void MarkContextLost();
 
+  // surface == nullptr indicates that caller doesn't care what surface is
+  // current with the context.
+  bool MakeCurrent(gl::GLSurface* current_surface);
+
+  scoped_refptr<gl::GLShareGroup> share_group;
+  scoped_refptr<gl::GLSurface> surface;
+  scoped_refptr<gl::GLContext> context;
   sk_sp<GrContext> owned_gr_context;
   std::unique_ptr<ServiceTransferCache> transfer_cache;
   const bool use_virtualized_gl_contexts = false;
@@ -85,6 +69,7 @@
   viz::VulkanContextProvider* vk_context_provider = nullptr;
   GrContext* gr_context = nullptr;
   const bool use_vulkan_gr_context = false;
+  bool context_lost = false;
   size_t glyph_cache_max_texture_bytes = 0u;
 
   // |need_context_state_reset| is set whenever Skia may have altered the
@@ -99,43 +84,7 @@
 
  private:
   friend class base::RefCounted<RasterDecoderContextState>;
-
   ~RasterDecoderContextState() override;
-
-  // gpu::GLContextVirtualDelegate implementation.
-  bool initialized() const override;
-  const gles2::ContextState* GetContextState() override;
-  void RestoreState(const gles2::ContextState* prev_state) override;
-  void RestoreGlobalState() const override;
-  void ClearAllAttributes() const override;
-  void RestoreActiveTexture() const override;
-  void RestoreAllTextureUnitAndSamplerBindings(
-      const gles2::ContextState* prev_state) const override;
-  void RestoreActiveTextureUnitBinding(unsigned int target) const override;
-  void RestoreBufferBinding(unsigned int target) override;
-  void RestoreBufferBindings() const override;
-  void RestoreFramebufferBindings() const override;
-  void RestoreRenderbufferBindings() override;
-  void RestoreProgramBindings() const override;
-  void RestoreTextureUnitBindings(unsigned unit) const override;
-  void RestoreVertexAttribArray(unsigned index) override;
-  void RestoreAllExternalTextureBindingsIfNeeded() override;
-  QueryManager* GetQueryManager() override;
-
-  scoped_refptr<gl::GLShareGroup> share_group_;
-  scoped_refptr<gl::GLContext> context_;
-  scoped_refptr<gl::GLContext> real_context_;
-  scoped_refptr<gl::GLSurface> surface_;
-  scoped_refptr<gles2::FeatureInfo> feature_info_;
-
-  // raster decoders and display compositor share this context_state_.
-  std::unique_ptr<gles2::ContextState> context_state_;
-
-  bool context_lost_ = false;
-
-  base::WeakPtrFactory<RasterDecoderContextState> weak_ptr_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(RasterDecoderContextState);
 };
 
 }  // namespace raster
diff --git a/gpu/command_buffer/service/raster_decoder_unittest.cc b/gpu/command_buffer/service/raster_decoder_unittest.cc
index efce9b9..89d2836 100644
--- a/gpu/command_buffer/service/raster_decoder_unittest.cc
+++ b/gpu/command_buffer/service/raster_decoder_unittest.cc
@@ -214,10 +214,6 @@
     gl::GLSurfaceTestSupport::InitializeOneOff();
     gpu::GpuDriverBugWorkarounds workarounds;
 
-    GpuFeatureInfo gpu_feature_info;
-    gpu_feature_info.status_values[GPU_FEATURE_TYPE_OOP_RASTERIZATION] =
-        kGpuFeatureStatusEnabled;
-
     scoped_refptr<gl::GLShareGroup> share_group = new gl::GLShareGroup();
     scoped_refptr<gl::GLSurface> surface =
         gl::init::CreateOffscreenGLSurface(gfx::Size());
@@ -229,8 +225,10 @@
         std::move(share_group), std::move(surface), std::move(context),
         false /* use_virtualized_gl_contexts */, base::DoNothing());
     context_state_->InitializeGrContext(workarounds, nullptr);
-    context_state_->InitializeGL(workarounds, gpu_feature_info);
 
+    GpuFeatureInfo gpu_feature_info;
+    gpu_feature_info.status_values[GPU_FEATURE_TYPE_OOP_RASTERIZATION] =
+        kGpuFeatureStatusEnabled;
     scoped_refptr<gles2::FeatureInfo> feature_info =
         new gles2::FeatureInfo(workarounds, gpu_feature_info);
     group_ = new gles2::ContextGroup(
@@ -265,10 +263,10 @@
     ContextCreationAttribs attribs;
     attribs.enable_oop_rasterization = true;
     attribs.enable_raster_interface = true;
-    CHECK_EQ(decoder->Initialize(context_state_->surface(),
-                                 context_state_->context(), true,
-                                 gles2::DisallowedFeatures(), attribs),
-             ContextResult::kSuccess);
+    CHECK_EQ(
+        decoder->Initialize(context_state_->surface, context_state_->context,
+                            true, gles2::DisallowedFeatures(), attribs),
+        ContextResult::kSuccess);
     return decoder;
   }
 
@@ -315,7 +313,7 @@
   EXPECT_TRUE(context_state_->need_context_state_reset);
 
   decoder1->Destroy(true);
-  context_state_->MakeCurrent(nullptr);
+  context_state_->context->MakeCurrent(context_state_->surface.get());
   decoder2->Destroy(true);
 
   // Make sure the context is preserved across decoders.
diff --git a/gpu/command_buffer/service/raster_decoder_unittest_base.cc b/gpu/command_buffer/service/raster_decoder_unittest_base.cc
index af44348..0c9eddd 100644
--- a/gpu/command_buffer/service/raster_decoder_unittest_base.cc
+++ b/gpu/command_buffer/service/raster_decoder_unittest_base.cc
@@ -230,10 +230,7 @@
   // we can use the ContextGroup to figure out how the real RasterDecoder
   // will initialize itself.
   command_buffer_service_.reset(new FakeCommandBufferServiceBase());
-  command_buffer_service_for_mock_decoder_.reset(
-      new FakeCommandBufferServiceBase());
-  mock_decoder_.reset(
-      new MockRasterDecoder(command_buffer_service_for_mock_decoder_.get()));
+  mock_decoder_.reset(new MockRasterDecoder(command_buffer_service_.get()));
 
   EXPECT_EQ(group_->Initialize(mock_decoder_.get(), context_type,
                                gles2::DisallowedFeatures()),
@@ -253,14 +250,6 @@
       init.lose_context_when_out_of_memory;
   attribs.context_type = context_type;
 
-  // Setup expections for RasterDecoderContextState::InitializeGL()
-  // It will initialize a FeatureInfo and
-  gles2::TestHelper::SetupFeatureInfoInitExpectationsWithGLVersion(
-      gl_.get(), all_extensions.c_str(), "" /* gl_renderer */,
-      init.gl_version.c_str(), CONTEXT_TYPE_OPENGLES2);
-  EXPECT_CALL(*gl_, GetIntegerv(GL_MAX_VERTEX_ATTRIBS, _))
-      .WillOnce(SetArgPointee<1>(8u))
-      .RetiresOnSaturation();
   SetupInitCapabilitiesExpectations(group_->feature_info()->IsES3Capable());
   SetupInitStateExpectations(group_->feature_info()->IsES3Capable());
 
@@ -268,10 +257,6 @@
       new gl::GLShareGroup(), surface_, context_,
       feature_info->workarounds().use_virtualized_gl_contexts,
       base::DoNothing());
-
-  raster_decoder_context_state_->InitializeGL(init.workarounds,
-                                              gpu_feature_info);
-
   decoder_.reset(RasterDecoder::Create(this, command_buffer_service_.get(),
                                        &outputter_, group_.get(),
                                        raster_decoder_context_state_));
@@ -281,10 +266,9 @@
   copy_texture_manager_ = new gles2::MockCopyTextureResourceManager();
   decoder_->SetCopyTextureResourceManagerForTest(copy_texture_manager_);
 
-  ASSERT_EQ(
-      decoder_->Initialize(surface_, raster_decoder_context_state_->context(),
-                           true, gles2::DisallowedFeatures(), attribs),
-      gpu::ContextResult::kSuccess);
+  ASSERT_EQ(decoder_->Initialize(surface_, context_, true,
+                                 gles2::DisallowedFeatures(), attribs),
+            gpu::ContextResult::kSuccess);
 
   EXPECT_CALL(*context_, MakeCurrent(surface_.get())).WillOnce(Return(true));
   if (context_->WasAllocatedUsingRobustnessExtension()) {
@@ -318,7 +302,6 @@
   decoder_.reset();
   group_->Destroy(mock_decoder_.get(), false);
   command_buffer_service_.reset();
-  command_buffer_service_for_mock_decoder_.reset();
   ::gl::MockGLInterface::SetGLInterface(nullptr);
   gl_.reset();
   gl::init::ShutdownGL(false);
diff --git a/gpu/command_buffer/service/raster_decoder_unittest_base.h b/gpu/command_buffer/service/raster_decoder_unittest_base.h
index 84e84f9..1eae7d8 100644
--- a/gpu/command_buffer/service/raster_decoder_unittest_base.h
+++ b/gpu/command_buffer/service/raster_decoder_unittest_base.h
@@ -250,8 +250,6 @@
   std::unique_ptr<FakeCommandBufferServiceBase> command_buffer_service_;
   gles2::TraceOutputter outputter_;
   std::unique_ptr<MockRasterDecoder> mock_decoder_;
-  std::unique_ptr<FakeCommandBufferServiceBase>
-      command_buffer_service_for_mock_decoder_;
   std::unique_ptr<RasterDecoder> decoder_;
 
   GLuint client_texture_id_;
diff --git a/gpu/command_buffer/service/raster_decoder_unittest_context_lost.cc b/gpu/command_buffer/service/raster_decoder_unittest_context_lost.cc
index 57bd17f..be57e397a 100644
--- a/gpu/command_buffer/service/raster_decoder_unittest_context_lost.cc
+++ b/gpu/command_buffer/service/raster_decoder_unittest_context_lost.cc
@@ -145,7 +145,6 @@
   EXPECT_CALL(*context_, MakeCurrent(surface_.get())).WillOnce(Return(false));
   // Expect the group to be lost.
   EXPECT_CALL(*mock_decoder_, MarkContextLost(error::kUnknown)).Times(1);
-  EXPECT_FALSE(decoder_->WasContextLost());
   decoder_->MakeCurrent();
   EXPECT_TRUE(decoder_->WasContextLost());
   EXPECT_EQ(error::kMakeCurrentFailed, GetContextLostReason());
@@ -286,6 +285,18 @@
   EXPECT_EQ(error::kInnocent, GetContextLostReason());
 }
 
+TEST_P(RasterDecoderLostContextTest, LoseVirtualContextWithRobustness) {
+  InitWithVirtualContextsAndRobustness();
+  EXPECT_CALL(*mock_decoder_, MarkContextLost(error::kUnknown)).Times(1);
+  // Signal guilty....
+  DoGetErrorWithContextLost(GL_GUILTY_CONTEXT_RESET_KHR);
+  EXPECT_TRUE(decoder_->WasContextLost());
+  EXPECT_TRUE(decoder_->WasContextLostByRobustnessExtension());
+  // ...but make sure we don't pretend, since for virtual contexts we don't
+  // know if this was really the guilty client.
+  EXPECT_EQ(error::kUnknown, GetContextLostReason());
+}
+
 TEST_P(RasterDecoderLostContextTest, LoseGroupFromRobustness) {
   // If one context in a group is lost through robustness,
   // the other ones should also get lost and query the reset status.
diff --git a/gpu/command_buffer/service/wrapped_sk_image.cc b/gpu/command_buffer/service/wrapped_sk_image.cc
index ae7940f..911e917 100644
--- a/gpu/command_buffer/service/wrapped_sk_image.cc
+++ b/gpu/command_buffer/service/wrapped_sk_image.cc
@@ -30,9 +30,9 @@
 class WrappedSkImage : public SharedImageBacking {
  public:
   ~WrappedSkImage() override {
-    DCHECK(context_state_->context_lost() ||
-           context_state_->context()->IsCurrent(nullptr));
-    if (!context_state_->context_lost())
+    DCHECK(context_state_->context_lost ||
+           context_state_->context->IsCurrent(nullptr));
+    if (!context_state_->context_lost)
       context_state_->need_context_state_reset = true;
   }
 
@@ -70,9 +70,9 @@
   sk_sp<SkSurface> GetSkSurface(int final_msaa_count,
                                 SkColorType color_type,
                                 const SkSurfaceProps& surface_props) {
-    if (context_state_->context_lost())
+    if (context_state_->context_lost)
       return nullptr;
-    DCHECK(context_state_->context()->IsCurrent(nullptr));
+    DCHECK(context_state_->context->IsCurrent(nullptr));
     GrBackendTexture gr_texture =
         image_->getBackendTexture(/*flushPendingGrContextIO=*/true);
     DCHECK(gr_texture.isValid());
@@ -113,9 +113,9 @@
   }
 
   bool Initialize(const SkImageInfo& info) {
-    if (context_state_->context_lost())
+    if (context_state_->context_lost)
       return false;
-    DCHECK(context_state_->context()->IsCurrent(nullptr));
+    DCHECK(context_state_->context->IsCurrent(nullptr));
 
     context_state_->need_context_state_reset = true;
 
diff --git a/gpu/ipc/in_process_command_buffer.cc b/gpu/ipc/in_process_command_buffer.cc
index 9cd4152..827a1f5 100644
--- a/gpu/ipc/in_process_command_buffer.cc
+++ b/gpu/ipc/in_process_command_buffer.cc
@@ -563,8 +563,6 @@
       context_state_ = base::MakeRefCounted<raster::RasterDecoderContextState>(
           gl_share_group_, surface_, real_context, use_virtualized_gl_context_,
           base::DoNothing());
-      context_state_->InitializeGL(workarounds,
-                                   task_executor_->gpu_feature_info());
       gr_shader_cache_ = params.gr_shader_cache;
       context_state_->InitializeGrContext(workarounds, params.gr_shader_cache,
                                           params.activity_flags);
@@ -584,22 +582,18 @@
     }
 
     if (use_virtualized_gl_context_) {
-      if (context_state_) {
-        context_ = context_state_->context();
-      } else {
-        context_ = base::MakeRefCounted<GLContextVirtual>(
-            gl_share_group_.get(), real_context.get(), decoder_->AsWeakPtr());
-        if (!context_->Initialize(surface_.get(),
-                                  GenerateGLContextAttribs(
-                                      params.attribs, context_group_.get()))) {
-          // TODO(piman): This might not be fatal, we could recurse into
-          // CreateGLContext to get more info, tho it should be exceedingly
-          // rare and may not be recoverable anyway.
-          DestroyOnGpuThread();
-          LOG(ERROR) << "ContextResult::kFatalFailure: "
-                        "Failed to initialize virtual GL context.";
-          return gpu::ContextResult::kFatalFailure;
-        }
+      context_ = base::MakeRefCounted<GLContextVirtual>(
+          gl_share_group_.get(), real_context.get(), decoder_->AsWeakPtr());
+      if (!context_->Initialize(
+              surface_.get(),
+              GenerateGLContextAttribs(params.attribs, context_group_.get()))) {
+        // TODO(piman): This might not be fatal, we could recurse into
+        // CreateGLContext to get more info, tho it should be exceedingly
+        // rare and may not be recoverable anyway.
+        DestroyOnGpuThread();
+        LOG(ERROR) << "ContextResult::kFatalFailure: "
+                      "Failed to initialize virtual GL context.";
+        return gpu::ContextResult::kFatalFailure;
       }
 
       if (!context_->MakeCurrent(surface_.get())) {
diff --git a/gpu/ipc/service/gpu_channel_manager.cc b/gpu/ipc/service/gpu_channel_manager.cc
index 124f686..e72dc59 100644
--- a/gpu/ipc/service/gpu_channel_manager.cc
+++ b/gpu/ipc/service/gpu_channel_manager.cc
@@ -319,7 +319,7 @@
 
   if (raster_decoder_context_state_) {
     gr_cache_controller_.reset();
-    raster_decoder_context_state_->MarkContextLost();
+    raster_decoder_context_state_->context_lost = true;
     raster_decoder_context_state_.reset();
   }
 
@@ -353,7 +353,7 @@
 scoped_refptr<raster::RasterDecoderContextState>
 GpuChannelManager::GetRasterDecoderContextState(ContextResult* result) {
   if (raster_decoder_context_state_ &&
-      !raster_decoder_context_state_->context_lost()) {
+      !raster_decoder_context_state_->context_lost) {
     *result = ContextResult::kSuccess;
     return raster_decoder_context_state_;
   }
@@ -442,14 +442,6 @@
                      /*synthetic_loss=*/false),
       vulkan_context_provider_);
 
-  if (!vulkan_context_provider_) {
-    if (!raster_decoder_context_state_->InitializeGL(
-            gpu_driver_bug_workarounds(), gpu_feature_info())) {
-      raster_decoder_context_state_ = nullptr;
-      return nullptr;
-    }
-  }
-
   const bool enable_raster_transport =
       gpu_feature_info_.status_values[GPU_FEATURE_TYPE_OOP_RASTERIZATION] ==
       gpu::kGpuFeatureStatusEnabled;
diff --git a/gpu/ipc/service/raster_command_buffer_stub.cc b/gpu/ipc/service/raster_command_buffer_stub.cc
index 1751107..78adb55 100644
--- a/gpu/ipc/service/raster_command_buffer_stub.cc
+++ b/gpu/ipc/service/raster_command_buffer_stub.cc
@@ -119,8 +119,8 @@
     return result;
   }
 
-  surface_ = raster_decoder_context_state->surface();
-  share_group_ = raster_decoder_context_state->share_group();
+  surface_ = raster_decoder_context_state->surface;
+  share_group_ = raster_decoder_context_state->share_group;
   use_virtualized_gl_context_ =
       raster_decoder_context_state->use_virtualized_gl_contexts;
 
@@ -138,9 +138,26 @@
   crash_keys::gpu_gl_context_is_virtual.Set(use_virtualized_gl_context_ ? "1"
                                                                         : "0");
 
-  scoped_refptr<gl::GLContext> context =
-      raster_decoder_context_state->context();
-  if (!raster_decoder_context_state->MakeCurrent(nullptr)) {
+  scoped_refptr<gl::GLContext> context = raster_decoder_context_state->context;
+  if (use_virtualized_gl_context_) {
+    context = base::MakeRefCounted<GLContextVirtual>(
+        share_group_.get(), context.get(), decoder->AsWeakPtr());
+    if (!context->Initialize(surface_.get(),
+                             GenerateGLContextAttribs(init_params.attribs,
+                                                      context_group_.get()))) {
+      // The real context created above for the default offscreen surface
+      // might not be compatible with this surface.
+      context = nullptr;
+      // TODO(piman): This might not be fatal, we could recurse into
+      // CreateGLContext to get more info, tho it should be exceedingly
+      // rare and may not be recoverable anyway.
+      LOG(ERROR) << "ContextResult::kFatalFailure: "
+                    "Failed to initialize virtual GL context.";
+      return gpu::ContextResult::kFatalFailure;
+    }
+  }
+
+  if (!context->MakeCurrent(surface_.get())) {
     LOG(ERROR) << "ContextResult::kTransientFailure: "
                   "Failed to make context current.";
     return gpu::ContextResult::kTransientFailure;
@@ -179,6 +196,22 @@
   if (!active_url_.is_empty())
     manager->delegate()->DidCreateOffscreenContext(active_url_);
 
+  if (use_virtualized_gl_context_) {
+    // If virtualized GL contexts are in use, then real GL context state
+    // is in an indeterminate state, since the GLStateRestorer was not
+    // initialized at the time the GLContextVirtual was made current. In
+    // the case that this command decoder is the next one to be
+    // processed, force a "full virtual" MakeCurrent to be performed.
+    // Note that GpuChannel's initialization of the gpu::Capabilities
+    // expects the context to be left current.
+    context->ForceReleaseVirtuallyCurrent();
+    if (!context->MakeCurrent(surface_.get())) {
+      LOG(ERROR) << "ContextResult::kTransientFailure: "
+                    "Failed to make context current after initialization.";
+      return gpu::ContextResult::kTransientFailure;
+    }
+  }
+
   manager->delegate()->DidCreateContextSuccessfully();
   initialized_ = true;
   return gpu::ContextResult::kSuccess;
diff --git a/gpu/ipc/service/shared_image_stub.cc b/gpu/ipc/service/shared_image_stub.cc
index 26aebcd..6b7ed3e 100644
--- a/gpu/ipc/service/shared_image_stub.cc
+++ b/gpu/ipc/service/shared_image_stub.cc
@@ -146,16 +146,13 @@
 
 bool SharedImageStub::MakeContextCurrent() {
   DCHECK(context_state_);
-  DCHECK(!context_state_->context_lost());
+  DCHECK(!context_state_->context_lost);
 
   // |factory_| never writes to the surface, so pass nullptr to
   // improve performance. https://crbug.com/457431
-  auto* context = context_state_->real_context();
-  if (context->IsCurrent(nullptr) ||
-      context_state_->real_context()->MakeCurrent(context_state_->surface())) {
+  if (context_state_->MakeCurrent(nullptr)) {
     return true;
   } else {
-    context_state_->MarkContextLost();
     LOG(ERROR) << "SharedImageStub: MakeCurrent failed";
     return false;
   }
@@ -172,7 +169,7 @@
       return false;
     }
     DCHECK(context_state_);
-    DCHECK(!context_state_->context_lost());
+    DCHECK(!context_state_->context_lost);
     if (!MakeContextCurrent())
       return false;
     gpu::GpuMemoryBufferFactory* gmb_factory =
@@ -187,12 +184,13 @@
     return true;
   } else {
     DCHECK(context_state_);
-    if (context_state_->context_lost()) {
+    if (context_state_->context_lost) {
       LOG(ERROR) << "SharedImageStub: context already lost";
       return false;
     } else {
       if (MakeContextCurrent())
         return true;
+      context_state_->context_lost = true;
       return false;
     }
   }