Reland "Share one GLContext for all RasterDecoder when virtual context is used."
Original change's description:
> 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}
TBR=penghuang@chromium.org,piman@chromium.org
Change-Id: Ie409d5d631509efa978a8741381cedbbbcdb3904
Bug: 902904
Reviewed-on: https://chromium-review.googlesource.com/c/1368031
Reviewed-by: Peng Huang <penghuang@chromium.org>
Commit-Queue: Peng Huang <penghuang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#614796}
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 64b4e99..4501800 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.get(); }
+ gl::GLContext* gl_context() { return context_state_->context(); }
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 eec9603..9ce7beb2 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 abc53a0..523bf03 100644
--- a/gpu/command_buffer/service/decoder_context.h
+++ b/gpu/command_buffer/service/decoder_context.h
@@ -213,6 +213,12 @@
// 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 1b2ffc57..0db2f14 100644
--- a/gpu/command_buffer/service/gl_context_virtual_delegate.h
+++ b/gpu/command_buffer/service/gl_context_virtual_delegate.h
@@ -32,7 +32,6 @@
// 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;
@@ -42,7 +41,6 @@
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 d47a8d4..0d20724 100644
--- a/gpu/command_buffer/service/gl_state_restorer_impl.cc
+++ b/gpu/command_buffer/service/gl_state_restorer_impl.cc
@@ -71,12 +71,14 @@
void GLStateRestorerImpl::PauseQueries() {
DCHECK(delegate_.get());
- delegate_->GetQueryManager()->PauseQueries();
+ if (auto* query_manager = delegate_->GetQueryManager())
+ query_manager->PauseQueries();
}
void GLStateRestorerImpl::ResumeQueries() {
DCHECK(delegate_.get());
- delegate_->GetQueryManager()->ResumeQueries();
+ if (auto* query_manager = delegate_->GetQueryManager())
+ query_manager->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 4bb1cc1..787ef40 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_->context->IsCurrent(nullptr));
+ DCHECK(context_state_->IsCurrent(nullptr));
if (!context_state_->gr_context)
return;
@@ -35,7 +35,6 @@
// 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));
@@ -64,7 +63,6 @@
return;
}
- context_state_->context->DirtyVirtualContextState();
context_state_->need_context_state_reset = true;
context_state_->gr_context->freeGpuResources();
}
diff --git a/gpu/command_buffer/service/gr_cache_controller_unittest.cc b/gpu/command_buffer/service/gr_cache_controller_unittest.cc
index ccd865d..b4c489cc 100644
--- a/gpu/command_buffer/service/gr_cache_controller_unittest.cc
+++ b/gpu/command_buffer/service/gr_cache_controller_unittest.cc
@@ -8,6 +8,7 @@
#include "base/test/test_mock_time_task_runner.h"
#include "gpu/command_buffer/service/raster_decoder_context_state.h"
#include "gpu/config/gpu_driver_bug_workarounds.h"
+#include "gpu/config/gpu_feature_info.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkImage.h"
@@ -38,6 +39,7 @@
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, GpuFeatureInfo());
controller_ =
std::make_unique<GrCacheController>(context_state_.get(), task_runner_);
diff --git a/gpu/command_buffer/service/raster_decoder.cc b/gpu/command_buffer/service/raster_decoder.cc
index 7b9f9d8..e34d92f 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(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, \
+ 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, \
static_cast<uint32_t>(value), label)
#define LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER(function_name) \
- ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(GetErrorState(), function_name)
+ ERRORSTATE_COPY_REAL_GL_ERRORS_TO_WRAPPER(error_state_.get(), function_name)
#define LOCAL_PEEK_GL_ERROR(function_name) \
- ERRORSTATE_PEEK_GL_ERROR(GetErrorState(), function_name)
+ ERRORSTATE_PEEK_GL_ERROR(error_state_.get(), function_name)
#define LOCAL_CLEAR_REAL_GL_ERRORS(function_name) \
- ERRORSTATE_CLEAR_REAL_GL_ERRORS(GetErrorState(), function_name)
+ ERRORSTATE_CLEAR_REAL_GL_ERRORS(error_state_.get(), function_name)
#define LOCAL_PERFORMANCE_WARNING(msg) \
PerformanceWarning(__FILE__, __LINE__, msg)
#define LOCAL_RENDER_WARNING(msg) RenderWarning(__FILE__, __LINE__, msg)
@@ -284,6 +284,8 @@
}
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;
@@ -302,6 +304,7 @@
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;
@@ -404,7 +407,10 @@
return &it->second;
}
- gl::GLApi* api() const { return state_.api(); }
+ gles2::ContextState* state() const {
+ return raster_decoder_context_state_->context_state();
+ }
+ gl::GLApi* api() const { return state()->api(); }
GrContext* gr_context() const {
return raster_decoder_context_state_->gr_context;
}
@@ -422,7 +428,8 @@
bool IsRobustnessSupported() {
return has_robustness_extension_ &&
- context_->WasAllocatedUsingRobustnessExtension();
+ raster_decoder_context_state_->context()
+ ->WasAllocatedUsingRobustnessExtension();
}
const gl::GLVersionInfo& gl_version_info() {
@@ -598,7 +605,6 @@
// 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_;
@@ -606,6 +612,7 @@
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_;
@@ -615,9 +622,6 @@
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.
@@ -737,8 +741,6 @@
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(
@@ -767,8 +769,6 @@
DCHECK(context->IsCurrent(surface.get()));
DCHECK(!context_.get());
- state_.set_api(gl::g_current_gl_context);
-
set_initialized();
if (!offscreen) {
@@ -781,7 +781,8 @@
if (group_->gpu_preferences().enable_gpu_command_logging)
SetLogCommands(true);
- surface_ = surface;
+ DCHECK_EQ(surface.get(), raster_decoder_context_state_->surface());
+ DCHECK_EQ(context.get(), raster_decoder_context_state_->context());
context_ = context;
// Create GPU Tracer for timing values.
@@ -799,22 +800,15 @@
Destroy(true);
return result;
}
+
CHECK_GL_ERROR();
- state_.InitGenericAttribs(group_->max_vertex_attribs());
-
- query_manager_.reset(new QueryManager());
+ query_manager_ = std::make_unique<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: "
@@ -836,7 +830,8 @@
if (!initialized())
return;
- DCHECK(!have_context || context_->IsCurrent(nullptr));
+ DCHECK(!have_context ||
+ raster_decoder_context_state_->context()->IsCurrent(nullptr));
if (have_context) {
if (copy_tex_image_blit_.get()) {
@@ -861,14 +856,8 @@
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();
@@ -884,8 +873,6 @@
// Destroy the surface before the context, some surface destructors make GL
// calls.
- surface_ = nullptr;
-
if (context_.get()) {
context_->ReleaseCurrent(nullptr);
context_ = nullptr;
@@ -897,23 +884,22 @@
// Make this decoder's GL context current.
bool RasterDecoderImpl::MakeCurrent() {
- DCHECK(surface_);
if (!context_.get())
return false;
- if (WasContextLost()) {
+ if (context_lost_) {
LOG(ERROR) << " RasterDecoderImpl: Trying to make lost context current.";
return false;
}
- // TODO(https://crbug.com/902904): Switch to
- // raster_decoder_context_state_->MakeCurrent(nullptr).
- if (!context_->MakeCurrent(surface_.get())) {
+ if (raster_decoder_context_state_->context_lost() ||
+ !raster_decoder_context_state_->MakeCurrent(nullptr)) {
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()) {
@@ -934,7 +920,7 @@
}
gl::GLSurface* RasterDecoderImpl::GetGLSurface() {
- return surface_.get();
+ return raster_decoder_context_state_->surface();
}
Capabilities RasterDecoderImpl::GetCapabilities() {
@@ -966,18 +952,12 @@
}
const gles2::ContextState* RasterDecoderImpl::GetContextState() {
- 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_;
+ NOTREACHED();
+ return nullptr;
}
void RasterDecoderImpl::RestoreGlobalState() const {
raster_decoder_context_state_->PessimisticallyResetGrContext();
- state_.RestoreGlobalState(nullptr);
}
void RasterDecoderImpl::ClearAllAttributes() const {}
@@ -987,10 +967,6 @@
}
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();
}
@@ -1010,36 +986,22 @@
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 {
@@ -1067,7 +1029,7 @@
}
void RasterDecoderImpl::RestoreVertexAttribArray(unsigned index) {
- NOTIMPLEMENTED();
+ raster_decoder_context_state_->PessimisticallyResetGrContext();
}
void RasterDecoderImpl::RestoreAllExternalTextureBindingsIfNeeded() {
@@ -1096,13 +1058,12 @@
}
bool RasterDecoderImpl::HasPendingQueries() const {
- return query_manager_.get() && query_manager_->HavePendingQueries();
+ return query_manager_ && query_manager_->HavePendingQueries();
}
void RasterDecoderImpl::ProcessPendingQueries(bool did_finish) {
- if (!query_manager_.get())
- return;
- query_manager_->ProcessPendingQueries(did_finish);
+ if (query_manager_)
+ query_manager_->ProcessPendingQueries(did_finish);
}
bool RasterDecoderImpl::HasMoreIdleWork() const {
@@ -1137,7 +1098,7 @@
}
bool RasterDecoderImpl::WasContextLost() const {
- return raster_decoder_context_state_->context_lost;
+ return context_lost_;
}
bool RasterDecoderImpl::WasContextLostByRobustnessExtension() const {
@@ -1150,16 +1111,14 @@
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(context_->IsCurrent(nullptr));
+ DCHECK(raster_decoder_context_state_->context()->IsCurrent(nullptr));
if (IsRobustnessSupported()) {
// If the reason for the call was a GL error, we can try to determine the
@@ -1201,7 +1160,7 @@
}
void RasterDecoderImpl::SetIgnoreCachedStateForTest(bool ignore) {
- state_.SetIgnoreCachedStateForTest(ignore);
+ state()->SetIgnoreCachedStateForTest(ignore);
}
gles2::ImageManager* RasterDecoderImpl::GetImageManagerForTest() {
@@ -1440,12 +1399,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.
@@ -1882,7 +1841,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;
@@ -1921,7 +1880,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 */,
@@ -1982,7 +1941,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.
@@ -2095,7 +2054,8 @@
gl::GLImage* image = texture->GetLevelImage(textarget, 0, &image_state);
if (image && image_state == gles2::Texture::UNBOUND) {
ScopedGLErrorSuppressor suppressor(
- "RasterDecoderImpl::DoBindOrCopyTexImageIfNeeded", GetErrorState());
+ "RasterDecoderImpl::DoBindOrCopyTexImageIfNeeded",
+ error_state_.get());
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 5ebefe8..9dc7b516 100644
--- a/gpu/command_buffer/service/raster_decoder_context_state.cc
+++ b/gpu/command_buffer/service/raster_decoder_context_state.cc
@@ -7,6 +7,8 @@
#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"
@@ -30,17 +32,19 @@
bool use_virtualized_gl_contexts,
base::OnceClosure context_lost_callback,
viz::VulkanContextProvider* vulkan_context_provider)
- : share_group(std::move(share_group)),
- surface(std::move(surface)),
- context(std::move(context)),
- use_virtualized_gl_contexts(use_virtualized_gl_contexts),
+ : 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) {
+ 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) {
if (base::ThreadTaskRunnerHandle::IsSet()) {
base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
this, "RasterDecoderContextState", base::ThreadTaskRunnerHandle::Get());
@@ -60,10 +64,10 @@
GpuProcessActivityFlags* activity_flags,
gl::ProgressReporter* progress_reporter) {
if (!use_vulkan_gr_context) {
- DCHECK(context->IsCurrent(surface.get()));
+ DCHECK(context_->IsCurrent(surface()));
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 "
@@ -111,6 +115,77 @@
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) {
@@ -127,7 +202,7 @@
}
// Ensure the context is current before doing any GPU cleanup.
- context->MakeCurrent(surface.get());
+ MakeCurrent(nullptr);
switch (memory_pressure_level) {
case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE:
@@ -155,28 +230,92 @@
gr_context->resetContext();
}
-void RasterDecoderContextState::MarkContextLost() {
- if (!context_lost) {
- context_lost = true;
- if (gr_context)
- gr_context->abandonContext();
- std::move(context_lost_callback).Run();
- }
+bool RasterDecoderContextState::initialized() const {
+ return true;
}
-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;
+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 true;
+ 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
diff --git a/gpu/command_buffer/service/raster_decoder_context_state.h b/gpu/command_buffer/service/raster_decoder_context_state.h
index 84bed6c..d34c622 100644
--- a/gpu/command_buffer/service/raster_decoder_context_state.h
+++ b/gpu/command_buffer/service/raster_decoder_context_state.h
@@ -7,8 +7,10 @@
#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"
@@ -25,14 +27,21 @@
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::RefCounted<RasterDecoderContextState>,
- public base::trace_event::MemoryDumpProvider {
+ : public base::trace_event::MemoryDumpProvider,
+ public gpu::GLContextVirtualDelegate,
+ public base::RefCounted<RasterDecoderContextState> {
public:
// TODO: Refactor code to have seperate constructor for GL and Vulkan and not
// initialize/use GL related info for vulkan and vice-versa.
@@ -48,20 +57,27 @@
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;
- void MarkContextLost();
+ 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_; }
- // 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;
@@ -69,7 +85,6 @@
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
@@ -84,7 +99,43 @@
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 89d2836..efce9b9 100644
--- a/gpu/command_buffer/service/raster_decoder_unittest.cc
+++ b/gpu/command_buffer/service/raster_decoder_unittest.cc
@@ -214,6 +214,10 @@
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());
@@ -225,10 +229,8 @@
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(
@@ -263,10 +265,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;
}
@@ -313,7 +315,7 @@
EXPECT_TRUE(context_state_->need_context_state_reset);
decoder1->Destroy(true);
- context_state_->context->MakeCurrent(context_state_->surface.get());
+ context_state_->MakeCurrent(nullptr);
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 0c9edddb..af44348 100644
--- a/gpu/command_buffer/service/raster_decoder_unittest_base.cc
+++ b/gpu/command_buffer/service/raster_decoder_unittest_base.cc
@@ -230,7 +230,10 @@
// we can use the ContextGroup to figure out how the real RasterDecoder
// will initialize itself.
command_buffer_service_.reset(new FakeCommandBufferServiceBase());
- mock_decoder_.reset(new MockRasterDecoder(command_buffer_service_.get()));
+ command_buffer_service_for_mock_decoder_.reset(
+ new FakeCommandBufferServiceBase());
+ mock_decoder_.reset(
+ new MockRasterDecoder(command_buffer_service_for_mock_decoder_.get()));
EXPECT_EQ(group_->Initialize(mock_decoder_.get(), context_type,
gles2::DisallowedFeatures()),
@@ -250,6 +253,14 @@
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());
@@ -257,6 +268,10 @@
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_));
@@ -266,9 +281,10 @@
copy_texture_manager_ = new gles2::MockCopyTextureResourceManager();
decoder_->SetCopyTextureResourceManagerForTest(copy_texture_manager_);
- ASSERT_EQ(decoder_->Initialize(surface_, context_, true,
- gles2::DisallowedFeatures(), attribs),
- gpu::ContextResult::kSuccess);
+ ASSERT_EQ(
+ decoder_->Initialize(surface_, raster_decoder_context_state_->context(),
+ true, gles2::DisallowedFeatures(), attribs),
+ gpu::ContextResult::kSuccess);
EXPECT_CALL(*context_, MakeCurrent(surface_.get())).WillOnce(Return(true));
if (context_->WasAllocatedUsingRobustnessExtension()) {
@@ -302,6 +318,7 @@
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 1eae7d8..84e84f9b 100644
--- a/gpu/command_buffer/service/raster_decoder_unittest_base.h
+++ b/gpu/command_buffer/service/raster_decoder_unittest_base.h
@@ -250,6 +250,8 @@
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 be57e397a..57bd17f 100644
--- a/gpu/command_buffer/service/raster_decoder_unittest_context_lost.cc
+++ b/gpu/command_buffer/service/raster_decoder_unittest_context_lost.cc
@@ -145,6 +145,7 @@
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());
@@ -285,18 +286,6 @@
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/shared_image_backing_factory_ahardwarebuffer_unittest.cc b/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer_unittest.cc
index 99fde99..a810817 100644
--- a/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer_unittest.cc
+++ b/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer_unittest.cc
@@ -16,6 +16,7 @@
#include "gpu/command_buffer/service/shared_image_representation.h"
#include "gpu/command_buffer/service/texture_manager.h"
#include "gpu/config/gpu_driver_bug_workarounds.h"
+#include "gpu/config/gpu_feature_info.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkSurface.h"
@@ -56,6 +57,7 @@
std::move(share_group), surface_, context_,
false /* use_virtualized_gl_contexts */, base::DoNothing());
context_state_->InitializeGrContext(workarounds, nullptr);
+ context_state_->InitializeGL(workarounds, GpuFeatureInfo());
memory_type_tracker_ = std::make_unique<MemoryTypeTracker>(nullptr);
shared_image_representation_factory_ =
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_gl_texture_unittest.cc b/gpu/command_buffer/service/shared_image_backing_factory_gl_texture_unittest.cc
index 6e6b802..c813a51 100644
--- a/gpu/command_buffer/service/shared_image_backing_factory_gl_texture_unittest.cc
+++ b/gpu/command_buffer/service/shared_image_backing_factory_gl_texture_unittest.cc
@@ -59,6 +59,7 @@
std::move(share_group), surface_, context_,
false /* use_virtualized_gl_contexts */, base::DoNothing());
context_state_->InitializeGrContext(workarounds, nullptr);
+ context_state_->InitializeGL(workarounds, GpuFeatureInfo());
memory_type_tracker_ = std::make_unique<MemoryTypeTracker>(nullptr);
shared_image_representation_factory_ =
diff --git a/gpu/command_buffer/service/wrapped_sk_image.cc b/gpu/command_buffer/service/wrapped_sk_image.cc
index 911e917..ae7940f 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/command_buffer/tests/fuzzer_main.cc b/gpu/command_buffer/tests/fuzzer_main.cc
index daad321..06f7f63 100644
--- a/gpu/command_buffer/tests/fuzzer_main.cc
+++ b/gpu/command_buffer/tests/fuzzer_main.cc
@@ -366,6 +366,7 @@
share_group_, surface_, context_,
config_.workarounds.use_virtualized_gl_contexts, base::DoNothing());
context_state->InitializeGrContext(config_.workarounds, nullptr);
+ context_state->InitializeGL(config_.workarounds, gpu_feature_info);
decoder_.reset(raster::RasterDecoder::Create(
command_buffer_.get(), command_buffer_->service(), &outputter_,
context_group.get(), std::move(context_state)));
diff --git a/gpu/ipc/in_process_command_buffer.cc b/gpu/ipc/in_process_command_buffer.cc
index 827a1f5..9cd41524 100644
--- a/gpu/ipc/in_process_command_buffer.cc
+++ b/gpu/ipc/in_process_command_buffer.cc
@@ -563,6 +563,8 @@
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);
@@ -582,18 +584,22 @@
}
if (use_virtualized_gl_context_) {
- 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_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;
+ }
}
if (!context_->MakeCurrent(surface_.get())) {
diff --git a/gpu/ipc/service/gpu_channel_manager.cc b/gpu/ipc/service/gpu_channel_manager.cc
index e72dc596..124f6865 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_->context_lost = true;
+ raster_decoder_context_state_->MarkContextLost();
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,6 +442,14 @@
/*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 78adb55..1751107 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,26 +138,9 @@
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 (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())) {
+ scoped_refptr<gl::GLContext> context =
+ raster_decoder_context_state->context();
+ if (!raster_decoder_context_state->MakeCurrent(nullptr)) {
LOG(ERROR) << "ContextResult::kTransientFailure: "
"Failed to make context current.";
return gpu::ContextResult::kTransientFailure;
@@ -196,22 +179,6 @@
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 6b7ed3ec..26aebcd 100644
--- a/gpu/ipc/service/shared_image_stub.cc
+++ b/gpu/ipc/service/shared_image_stub.cc
@@ -146,13 +146,16 @@
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
- if (context_state_->MakeCurrent(nullptr)) {
+ auto* context = context_state_->real_context();
+ if (context->IsCurrent(nullptr) ||
+ context_state_->real_context()->MakeCurrent(context_state_->surface())) {
return true;
} else {
+ context_state_->MarkContextLost();
LOG(ERROR) << "SharedImageStub: MakeCurrent failed";
return false;
}
@@ -169,7 +172,7 @@
return false;
}
DCHECK(context_state_);
- DCHECK(!context_state_->context_lost);
+ DCHECK(!context_state_->context_lost());
if (!MakeContextCurrent())
return false;
gpu::GpuMemoryBufferFactory* gmb_factory =
@@ -184,13 +187,12 @@
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;
}
}