summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-10-15 12:29:49 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-10-17 10:03:26 +0000
commit4f553e3a0c6270e66a64ec88f2212d4bc55742e8 (patch)
tree7cd9ff5bfda09d905c3a63ee7bc2607e000a6948
parentb5d06a4582837e4fa6e021688fccdefa7417af16 (diff)
downloadqtwebengine-chromium-4f553e3a0c6270e66a64ec88f2212d4bc55742e8.tar.gz
[Backport] Security issue 946978 [2/2]
Make GL lost context sticky. Move from GraphicsResetStatus logic from decoders to GLContext and make it sticky. This is to ensure that once the GL context is lost once, we never try to use the context again, as some drivers wrongly claim they recovered from it. Bug: 946978 Change-Id: I1527fe6ac997ddb766c7c3fec30270c3ae84a5cd Commit-Queue: Antoine Labour <piman@chromium.org> Auto-Submit: Antoine Labour <piman@chromium.org> Reviewed-by: Zhenyao Mo <zmo@chromium.org> Cr-Commit-Position: refs/heads/master@{#671503} Reviewed-by: Michal Klocek <michal.klocek@qt.io>
-rw-r--r--chromium/gpu/command_buffer/service/feature_info.cc6
-rw-r--r--chromium/gpu/command_buffer/service/feature_info.h3
-rw-r--r--chromium/gpu/command_buffer/service/gl_context_virtual.cc7
-rw-r--r--chromium/gpu/command_buffer/service/gl_context_virtual.h2
-rw-r--r--chromium/gpu/command_buffer/service/gl_context_virtual_unittest.cc44
-rw-r--r--chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc64
-rw-r--r--chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc53
-rw-r--r--chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h3
-rw-r--r--chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc4
-rw-r--r--chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_lost.cc24
-rw-r--r--chromium/gpu/command_buffer/service/raster_decoder.cc67
-rw-r--r--chromium/gpu/command_buffer/service/raster_decoder_unittest_base.cc4
-rw-r--r--chromium/gpu/command_buffer/service/raster_decoder_unittest_context_lost.cc2
-rw-r--r--chromium/gpu/command_buffer/service/shared_context_state.cc26
-rw-r--r--chromium/ui/gl/gl_context.cc5
-rw-r--r--chromium/ui/gl/gl_context.h7
-rw-r--r--chromium/ui/gl/gl_context_egl.cc13
-rw-r--r--chromium/ui/gl/gl_context_egl.h3
-rw-r--r--chromium/ui/gl/gl_context_glx.cc13
-rw-r--r--chromium/ui/gl/gl_context_glx.h3
-rw-r--r--chromium/ui/gl/gl_context_stub.cc14
-rw-r--r--chromium/ui/gl/gl_context_stub.h4
-rw-r--r--chromium/ui/gl/gl_fence_arb.cc8
23 files changed, 179 insertions, 200 deletions
diff --git a/chromium/gpu/command_buffer/service/feature_info.cc b/chromium/gpu/command_buffer/service/feature_info.cc
index ae7705b8d6a..f5813a71f23 100644
--- a/chromium/gpu/command_buffer/service/feature_info.cc
+++ b/chromium/gpu/command_buffer/service/feature_info.cc
@@ -1490,12 +1490,6 @@ void FeatureInfo::InitializeFeatures() {
gfx::HasExtension(extensions, "GL_ANGLE_request_extension");
feature_flags_.ext_debug_marker =
gfx::HasExtension(extensions, "GL_EXT_debug_marker");
- feature_flags_.arb_robustness =
- gfx::HasExtension(extensions, "GL_ARB_robustness");
- feature_flags_.khr_robustness =
- gfx::HasExtension(extensions, "GL_KHR_robustness");
- feature_flags_.ext_robustness =
- gfx::HasExtension(extensions, "GL_EXT_robustness");
feature_flags_.ext_pixel_buffer_object =
gfx::HasExtension(extensions, "GL_ARB_pixel_buffer_object") ||
gfx::HasExtension(extensions, "GL_NV_pixel_buffer_object");
diff --git a/chromium/gpu/command_buffer/service/feature_info.h b/chromium/gpu/command_buffer/service/feature_info.h
index 922eb929adf..6c2666c7169 100644
--- a/chromium/gpu/command_buffer/service/feature_info.h
+++ b/chromium/gpu/command_buffer/service/feature_info.h
@@ -123,9 +123,6 @@ class GPU_GLES2_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> {
bool angle_client_arrays = false;
bool angle_request_extension = false;
bool ext_debug_marker = false;
- bool arb_robustness = false;
- bool khr_robustness = false;
- bool ext_robustness = false;
bool ext_pixel_buffer_object = false;
bool ext_unpack_subimage = false;
bool oes_rgb8_rgba8 = false;
diff --git a/chromium/gpu/command_buffer/service/gl_context_virtual.cc b/chromium/gpu/command_buffer/service/gl_context_virtual.cc
index 8eea6084343..81703702c64 100644
--- a/chromium/gpu/command_buffer/service/gl_context_virtual.cc
+++ b/chromium/gpu/command_buffer/service/gl_context_virtual.cc
@@ -97,8 +97,11 @@ void GLContextVirtual::SetSafeToForceGpuSwitch() {
return shared_context_->SetSafeToForceGpuSwitch();
}
-bool GLContextVirtual::WasAllocatedUsingRobustnessExtension() {
- return shared_context_->WasAllocatedUsingRobustnessExtension();
+unsigned int GLContextVirtual::CheckStickyGraphicsResetStatus() {
+ // Don't pretend we know which one of the virtual contexts was responsible.
+ unsigned int reset_status = shared_context_->CheckStickyGraphicsResetStatus();
+ return reset_status == GL_NO_ERROR ? GL_NO_ERROR
+ : GL_UNKNOWN_CONTEXT_RESET_ARB;
}
void GLContextVirtual::SetUnbindFboOnMakeCurrent() {
diff --git a/chromium/gpu/command_buffer/service/gl_context_virtual.h b/chromium/gpu/command_buffer/service/gl_context_virtual.h
index dc3d4d54de1..3e6f297a0ab 100644
--- a/chromium/gpu/command_buffer/service/gl_context_virtual.h
+++ b/chromium/gpu/command_buffer/service/gl_context_virtual.h
@@ -42,7 +42,7 @@ class GPU_GLES2_EXPORT GLContextVirtual : public gl::GLContext {
std::string GetGLRenderer() override;
const gfx::ExtensionSet& GetExtensions() override;
void SetSafeToForceGpuSwitch() override;
- bool WasAllocatedUsingRobustnessExtension() override;
+ unsigned int CheckStickyGraphicsResetStatus() override;
void SetUnbindFboOnMakeCurrent() override;
gl::YUVToRGBConverter* GetYUVToRGBConverter(
const gfx::ColorSpace& color_space) override;
diff --git a/chromium/gpu/command_buffer/service/gl_context_virtual_unittest.cc b/chromium/gpu/command_buffer/service/gl_context_virtual_unittest.cc
index fb9ab6c27b6..3e84862c419 100644
--- a/chromium/gpu/command_buffer/service/gl_context_virtual_unittest.cc
+++ b/chromium/gpu/command_buffer/service/gl_context_virtual_unittest.cc
@@ -44,25 +44,57 @@ TEST_F(GLContextVirtualTest, Reinitialize) {
.Times(AnyNumber())
.WillRepeatedly(Return(reinterpret_cast<unsigned const char *>("")));
{
- scoped_refptr<gl::GLContextStub> base_context = new gl::GLContextStub;
+ auto base_context = base::MakeRefCounted<gl::GLContextStub>();
gl::GLShareGroup* share_group = base_context->share_group();
share_group->SetSharedContext(GetGLSurface(), base_context.get());
- scoped_refptr<GLContextVirtual> context(new GLContextVirtual(
- share_group, base_context.get(), decoder_->AsWeakPtr()));
+ auto context = base::MakeRefCounted<GLContextVirtual>(
+ share_group, base_context.get(), decoder_->AsWeakPtr());
EXPECT_TRUE(context->Initialize(GetGLSurface(), gl::GLContextAttribs()));
EXPECT_TRUE(context->MakeCurrent(GetGLSurface()));
}
{
- scoped_refptr<gl::GLContextStub> base_context = new gl::GLContextStub;
+ auto base_context = base::MakeRefCounted<gl::GLContextStub>();
gl::GLShareGroup* share_group = base_context->share_group();
share_group->SetSharedContext(GetGLSurface(), base_context.get());
- scoped_refptr<GLContextVirtual> context(new GLContextVirtual(
- share_group, base_context.get(), decoder_->AsWeakPtr()));
+ auto context = base::MakeRefCounted<GLContextVirtual>(
+ share_group, base_context.get(), decoder_->AsWeakPtr());
EXPECT_TRUE(context->Initialize(GetGLSurface(), gl::GLContextAttribs()));
EXPECT_TRUE(context->MakeCurrent(GetGLSurface()));
}
}
+// Tests that CheckStickyGraphicsResetStatus gets the state from the real
+// context, but "virtualizes" the guilty party (i.e. makes it unknown).
+TEST_F(GLContextVirtualTest, CheckStickyGraphicsResetStatus) {
+ EXPECT_CALL(*gl_, GetError())
+ .Times(AnyNumber())
+ .WillRepeatedly(Return(GL_NO_ERROR));
+ auto base_context = base::MakeRefCounted<gl::GLContextStub>();
+ const char gl_extensions[] = "GL_KHR_robustness";
+ base_context->SetExtensionsString(gl_extensions);
+
+ gl::GLShareGroup* share_group = base_context->share_group();
+ share_group->SetSharedContext(GetGLSurface(), base_context.get());
+ auto context = base::MakeRefCounted<GLContextVirtual>(
+ share_group, base_context.get(), decoder_->AsWeakPtr());
+ EXPECT_TRUE(context->Initialize(GetGLSurface(), gl::GLContextAttribs()));
+ EXPECT_TRUE(context->MakeCurrent(GetGLSurface()));
+
+ // If no reset, GLContextVirtual should report no error.
+ EXPECT_CALL(*gl_, GetGraphicsResetStatusARB()).WillOnce(Return(GL_NO_ERROR));
+ EXPECT_EQ(unsigned{GL_NO_ERROR}, context->CheckStickyGraphicsResetStatus());
+
+ // If reset, GLContextVirtual should report an error, but with an unknown
+ // guilty context.
+ EXPECT_CALL(*gl_, GetGraphicsResetStatusARB())
+ .WillOnce(Return(GL_GUILTY_CONTEXT_RESET_ARB));
+ EXPECT_EQ(unsigned{GL_UNKNOWN_CONTEXT_RESET_ARB},
+ context->CheckStickyGraphicsResetStatus());
+ // The underlying real context still knows, though.
+ EXPECT_EQ(unsigned{GL_GUILTY_CONTEXT_RESET_ARB},
+ base_context->CheckStickyGraphicsResetStatus());
+}
+
} // anonymous namespace
} // namespace gles2
} // namespace gpu
diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 51d566483ac..d39dcd02e28 100644
--- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -2338,11 +2338,6 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient {
surface_->DeferDraws();
}
- bool IsRobustnessSupported() {
- return has_robustness_extension_ &&
- context_->WasAllocatedUsingRobustnessExtension();
- }
-
error::Error WillAccessBoundFramebufferForDraw() {
if (ShouldDeferDraws())
return error::kDeferCommandUntilLater;
@@ -2645,7 +2640,6 @@ class GLES2DecoderImpl : public GLES2Decoder, public ErrorStateClient {
// Number of commands remaining to be processed in DoCommands().
int commands_to_process_;
- bool has_robustness_extension_;
bool context_was_lost_;
bool reset_by_robustness_extension_;
bool supports_post_sub_buffer_;
@@ -3423,7 +3417,6 @@ GLES2DecoderImpl::GLES2DecoderImpl(
validators_(group_->feature_info()->validators()),
feature_info_(group_->feature_info()),
frame_number_(0),
- has_robustness_extension_(false),
context_was_lost_(false),
reset_by_robustness_extension_(false),
supports_post_sub_buffer_(false),
@@ -3878,10 +3871,6 @@ gpu::ContextResult GLES2DecoderImpl::Initialize(
api()->glEnableFn(GL_TEXTURE_CUBE_MAP_SEAMLESS);
}
- has_robustness_extension_ = features().arb_robustness ||
- features().khr_robustness ||
- features().ext_robustness;
-
GLint range[2] = {0, 0};
GLint precision = 0;
QueryShaderPrecisionFormat(gl_version_info(), GL_FRAGMENT_SHADER,
@@ -16650,39 +16639,32 @@ bool GLES2DecoderImpl::CheckResetStatus() {
DCHECK(!WasContextLost());
DCHECK(context_->IsCurrent(nullptr));
- if (IsRobustnessSupported()) {
- // If the reason for the call was a GL error, we can try to determine the
- // reset status more accurately.
- GLenum driver_status = api()->glGetGraphicsResetStatusARBFn();
- if (driver_status == GL_NO_ERROR)
- return false;
-
- LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
- << " context lost via ARB/EXT_robustness. Reset status = "
- << GLES2Util::GetStringEnum(driver_status);
+ // If the reason for the call was a GL error, we can try to determine the
+ // reset status more accurately.
+ GLenum driver_status = context_->CheckStickyGraphicsResetStatus();
+ if (driver_status == GL_NO_ERROR)
+ return false;
- // Don't pretend we know which client was responsible.
- if (workarounds().use_virtualized_gl_contexts)
- driver_status = GL_UNKNOWN_CONTEXT_RESET_ARB;
+ LOG(ERROR) << (surface_->IsOffscreen() ? "Offscreen" : "Onscreen")
+ << " context lost via ARB/EXT_robustness. Reset status = "
+ << GLES2Util::GetStringEnum(driver_status);
- switch (driver_status) {
- case GL_GUILTY_CONTEXT_RESET_ARB:
- MarkContextLost(error::kGuilty);
- break;
- case GL_INNOCENT_CONTEXT_RESET_ARB:
- MarkContextLost(error::kInnocent);
- break;
- case GL_UNKNOWN_CONTEXT_RESET_ARB:
- MarkContextLost(error::kUnknown);
- break;
- default:
- NOTREACHED();
- return false;
- }
- reset_by_robustness_extension_ = true;
- return true;
+ switch (driver_status) {
+ case GL_GUILTY_CONTEXT_RESET_ARB:
+ MarkContextLost(error::kGuilty);
+ break;
+ case GL_INNOCENT_CONTEXT_RESET_ARB:
+ MarkContextLost(error::kInnocent);
+ break;
+ case GL_UNKNOWN_CONTEXT_RESET_ARB:
+ MarkContextLost(error::kUnknown);
+ break;
+ default:
+ NOTREACHED();
+ return false;
}
- return false;
+ reset_by_robustness_extension_ = true;
+ return true;
}
error::Error GLES2DecoderImpl::HandleDescheduleUntilFinishedCHROMIUM(
diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
index c99eae41382..59678a46e21 100644
--- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
+++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
@@ -569,7 +569,6 @@ GLES2DecoderPassthroughImpl::GLES2DecoderPassthroughImpl(
gpu_trace_level_(2),
gpu_trace_commands_(false),
gpu_debug_commands_(false),
- has_robustness_extension_(false),
context_lost_(false),
reset_by_robustness_extension_(false),
lose_context_when_out_of_memory_(false),
@@ -884,8 +883,6 @@ gpu::ContextResult GLES2DecoderPassthroughImpl::Initialize(
api()->glHintFn(GL_TEXTURE_FILTERING_HINT_CHROMIUM, GL_NICEST);
}
- has_robustness_extension_ = feature_info_->feature_flags().khr_robustness ||
- feature_info_->feature_flags().ext_robustness;
lose_context_when_out_of_memory_ =
attrib_helper.lose_context_when_out_of_memory;
@@ -2009,37 +2006,29 @@ bool GLES2DecoderPassthroughImpl::CheckResetStatus() {
DCHECK(!WasContextLost());
DCHECK(context_->IsCurrent(nullptr));
- if (IsRobustnessSupported()) {
- // If the reason for the call was a GL error, we can try to determine the
- // reset status more accurately.
- GLenum driver_status = api()->glGetGraphicsResetStatusARBFn();
- if (driver_status == GL_NO_ERROR) {
- return false;
- }
-
- switch (driver_status) {
- case GL_GUILTY_CONTEXT_RESET_ARB:
- MarkContextLost(error::kGuilty);
- break;
- case GL_INNOCENT_CONTEXT_RESET_ARB:
- MarkContextLost(error::kInnocent);
- break;
- case GL_UNKNOWN_CONTEXT_RESET_ARB:
- MarkContextLost(error::kUnknown);
- break;
- default:
- NOTREACHED();
- return false;
- }
- reset_by_robustness_extension_ = true;
- return true;
+ // If the reason for the call was a GL error, we can try to determine the
+ // reset status more accurately.
+ GLenum driver_status = context_->CheckStickyGraphicsResetStatus();
+ if (driver_status == GL_NO_ERROR) {
+ return false;
}
- return false;
-}
-bool GLES2DecoderPassthroughImpl::IsRobustnessSupported() {
- return has_robustness_extension_ &&
- context_->WasAllocatedUsingRobustnessExtension();
+ switch (driver_status) {
+ case GL_GUILTY_CONTEXT_RESET_ARB:
+ MarkContextLost(error::kGuilty);
+ break;
+ case GL_INNOCENT_CONTEXT_RESET_ARB:
+ MarkContextLost(error::kInnocent);
+ break;
+ case GL_UNKNOWN_CONTEXT_RESET_ARB:
+ MarkContextLost(error::kUnknown);
+ break;
+ default:
+ NOTREACHED();
+ return false;
+ }
+ reset_by_robustness_extension_ = true;
+ return true;
}
bool GLES2DecoderPassthroughImpl::IsEmulatedQueryTarget(GLenum target) const {
diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
index ed682013976..a19ad2b080d 100644
--- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
+++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
@@ -427,8 +427,6 @@ class GPU_GLES2_EXPORT GLES2DecoderPassthroughImpl : public GLES2Decoder {
GLenum PopError();
bool FlushErrors();
- bool IsRobustnessSupported();
-
bool IsEmulatedQueryTarget(GLenum target) const;
error::Error ProcessQueries(bool did_finish);
void RemovePendingQuery(GLuint service_id);
@@ -838,7 +836,6 @@ class GPU_GLES2_EXPORT GLES2DecoderPassthroughImpl : public GLES2Decoder {
bool gpu_debug_commands_;
// Context lost state
- bool has_robustness_extension_;
bool context_lost_;
bool reset_by_robustness_extension_;
bool lose_context_when_out_of_memory_;
diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
index 314fa42670d..b700fa90f9e 100644
--- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
+++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
@@ -476,7 +476,7 @@ ContextResult GLES2DecoderTestBase::MaybeInitDecoderWithWorkarounds(
}
#endif
- if (context_->WasAllocatedUsingRobustnessExtension()) {
+ if (context_->HasRobustness()) {
EXPECT_CALL(*gl_, GetGraphicsResetStatusARB())
.WillOnce(Return(init.lose_context_on_init ? GL_GUILTY_CONTEXT_RESET_ARB
: GL_NO_ERROR));
@@ -522,7 +522,7 @@ ContextResult GLES2DecoderTestBase::MaybeInitDecoderWithWorkarounds(
}
EXPECT_CALL(*context_, MakeCurrent(surface_.get())).WillOnce(Return(true));
- if (context_->WasAllocatedUsingRobustnessExtension()) {
+ if (context_->HasRobustness()) {
EXPECT_CALL(*gl_, GetGraphicsResetStatusARB())
.WillOnce(Return(GL_NO_ERROR));
}
diff --git a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_lost.cc b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_lost.cc
index 254648101bf..e5f6049284f 100644
--- a/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_lost.cc
+++ b/chromium/gpu/command_buffer/service/gles2_cmd_decoder_unittest_context_lost.cc
@@ -35,7 +35,7 @@ class GLES2DecoderDrawOOMTest : public GLES2DecoderManualInitTest {
error::ContextLostReason expected_other_reason) {
const GLsizei kFakeLargeCount = 0x1234;
SetupTexture();
- if (context_->WasAllocatedUsingRobustnessExtension()) {
+ if (context_->HasRobustness()) {
EXPECT_CALL(*gl_, GetGraphicsResetStatusARB())
.WillOnce(Return(reset_status));
}
@@ -108,15 +108,6 @@ class GLES2DecoderLostContextTest : public GLES2DecoderManualInitTest {
InitDecoder(init);
}
- void InitWithVirtualContextsAndRobustness() {
- gpu::GpuDriverBugWorkarounds workarounds;
- workarounds.use_virtualized_gl_contexts = true;
- InitState init;
- init.gl_version = "OpenGL ES 2.0";
- init.extensions = "GL_KHR_robustness";
- InitDecoderWithWorkarounds(init, workarounds);
- }
-
void DoGetErrorWithContextLost(GLenum reset_status) {
DCHECK(context_->HasExtension("GL_KHR_robustness"));
EXPECT_CALL(*gl_, GetError())
@@ -309,19 +300,6 @@ TEST_P(GLES2DecoderLostContextTest, LoseInnocentFromGLError) {
EXPECT_EQ(error::kInnocent, GetContextLostReason());
}
-TEST_P(GLES2DecoderLostContextTest, 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(GLES2DecoderLostContextTest, 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/chromium/gpu/command_buffer/service/raster_decoder.cc b/chromium/gpu/command_buffer/service/raster_decoder.cc
index b306574e4a5..b54c7fb9e77 100644
--- a/chromium/gpu/command_buffer/service/raster_decoder.cc
+++ b/chromium/gpu/command_buffer/service/raster_decoder.cc
@@ -379,12 +379,6 @@ class RasterDecoderImpl final : public RasterDecoder,
return feature_info_->workarounds();
}
- bool IsRobustnessSupported() {
- return has_robustness_extension_ &&
- shared_context_state_->context()
- ->WasAllocatedUsingRobustnessExtension();
- }
-
const gl::GLVersionInfo& gl_version_info() {
return feature_info_->gl_version_info();
}
@@ -523,7 +517,6 @@ class RasterDecoderImpl final : public RasterDecoder,
bool supports_oop_raster_ = false;
bool use_ddl_ = false;
- bool has_robustness_extension_ = false;
bool reset_by_robustness_extension_ = false;
// The current decoder error communicates the decoder error through command
@@ -741,10 +734,6 @@ ContextResult RasterDecoderImpl::Initialize(
query_manager_ = std::make_unique<QueryManager>();
- has_robustness_extension_ = features().arb_robustness ||
- features().khr_robustness ||
- features().ext_robustness;
-
if (attrib_helper.enable_oop_rasterization) {
if (!features().chromium_raster_transport) {
LOG(ERROR) << "ContextResult::kFatalFailure: "
@@ -1046,39 +1035,33 @@ bool RasterDecoderImpl::CheckResetStatus() {
DCHECK(!WasContextLost());
DCHECK(shared_context_state_->context()->IsCurrent(nullptr));
- if (IsRobustnessSupported()) {
- // If the reason for the call was a GL error, we can try to determine the
- // reset status more accurately.
- GLenum driver_status = api()->glGetGraphicsResetStatusARBFn();
- if (driver_status == GL_NO_ERROR)
- return false;
+ // If the reason for the call was a GL error, we can try to determine the
+ // reset status more accurately.
+ GLenum driver_status =
+ shared_context_state_->context()->CheckStickyGraphicsResetStatus();
+ if (driver_status == GL_NO_ERROR)
+ return false;
- LOG(ERROR) << "RasterDecoder context lost via ARB/EXT_robustness. Reset "
- "status = "
- << gles2::GLES2Util::GetStringEnum(driver_status);
-
- // Don't pretend we know which client was responsible.
- if (workarounds().use_virtualized_gl_contexts)
- driver_status = GL_UNKNOWN_CONTEXT_RESET_ARB;
-
- switch (driver_status) {
- case GL_GUILTY_CONTEXT_RESET_ARB:
- MarkContextLost(error::kGuilty);
- break;
- case GL_INNOCENT_CONTEXT_RESET_ARB:
- MarkContextLost(error::kInnocent);
- break;
- case GL_UNKNOWN_CONTEXT_RESET_ARB:
- MarkContextLost(error::kUnknown);
- break;
- default:
- NOTREACHED();
- return false;
- }
- reset_by_robustness_extension_ = true;
- return true;
+ LOG(ERROR) << "RasterDecoder context lost via ARB/EXT_robustness. Reset "
+ "status = "
+ << gles2::GLES2Util::GetStringEnum(driver_status);
+
+ switch (driver_status) {
+ case GL_GUILTY_CONTEXT_RESET_ARB:
+ MarkContextLost(error::kGuilty);
+ break;
+ case GL_INNOCENT_CONTEXT_RESET_ARB:
+ MarkContextLost(error::kInnocent);
+ break;
+ case GL_UNKNOWN_CONTEXT_RESET_ARB:
+ MarkContextLost(error::kUnknown);
+ break;
+ default:
+ NOTREACHED();
+ return false;
}
- return false;
+ reset_by_robustness_extension_ = true;
+ return true;
}
gles2::Logger* RasterDecoderImpl::GetLogger() {
diff --git a/chromium/gpu/command_buffer/service/raster_decoder_unittest_base.cc b/chromium/gpu/command_buffer/service/raster_decoder_unittest_base.cc
index 983f8dca4d1..f39a7e91981 100644
--- a/chromium/gpu/command_buffer/service/raster_decoder_unittest_base.cc
+++ b/chromium/gpu/command_buffer/service/raster_decoder_unittest_base.cc
@@ -240,7 +240,7 @@ void RasterDecoderTestBase::InitDecoder(const InitState& init) {
SetupInitCapabilitiesExpectations(group_->feature_info()->IsES3Capable());
SetupInitStateExpectations(group_->feature_info()->IsES3Capable());
- if (context_->WasAllocatedUsingRobustnessExtension()) {
+ if (context_->HasRobustness()) {
EXPECT_CALL(*gl_, GetGraphicsResetStatusARB())
.WillOnce(Return(GL_NO_ERROR));
}
@@ -267,7 +267,7 @@ void RasterDecoderTestBase::InitDecoder(const InitState& init) {
gpu::ContextResult::kSuccess);
EXPECT_CALL(*context_, MakeCurrent(surface_.get())).WillOnce(Return(true));
- if (context_->WasAllocatedUsingRobustnessExtension()) {
+ if (context_->HasRobustness()) {
EXPECT_CALL(*gl_, GetGraphicsResetStatusARB())
.WillOnce(Return(GL_NO_ERROR));
}
diff --git a/chromium/gpu/command_buffer/service/raster_decoder_unittest_context_lost.cc b/chromium/gpu/command_buffer/service/raster_decoder_unittest_context_lost.cc
index 3c47d6845da..3b4ab363318 100644
--- a/chromium/gpu/command_buffer/service/raster_decoder_unittest_context_lost.cc
+++ b/chromium/gpu/command_buffer/service/raster_decoder_unittest_context_lost.cc
@@ -33,7 +33,7 @@ class RasterDecoderOOMTest : public RasterDecoderManualInitTest {
void OOM(GLenum reset_status,
error::ContextLostReason expected_other_reason) {
- if (context_->WasAllocatedUsingRobustnessExtension()) {
+ if (context_->HasRobustness()) {
EXPECT_CALL(*gl_, GetGraphicsResetStatusARB())
.WillOnce(Return(reset_status));
}
diff --git a/chromium/gpu/command_buffer/service/shared_context_state.cc b/chromium/gpu/command_buffer/service/shared_context_state.cc
index ffb188ceb82..b3b89d3c1f3 100644
--- a/chromium/gpu/command_buffer/service/shared_context_state.cc
+++ b/chromium/gpu/command_buffer/service/shared_context_state.cc
@@ -169,22 +169,16 @@ bool SharedContextState::InitializeGL(
context_state_->InitCapabilities(nullptr);
context_state_->InitState(nullptr);
- bool has_robustness = (feature_info_->feature_flags().arb_robustness ||
- feature_info_->feature_flags().khr_robustness ||
- feature_info_->feature_flags().ext_robustness) &&
- real_context_->WasAllocatedUsingRobustnessExtension();
- if (has_robustness) {
- GLenum driver_status = api->glGetGraphicsResetStatusARBFn();
- if (driver_status != GL_NO_ERROR) {
- // If the context was lost at any point before or during initialization,
- // the values queried from the driver could be bogus, and potentially
- // inconsistent between various ContextStates on the same underlying real
- // GL context. Make sure to report the failure early, to not allow
- // virtualized context switches in that case.
- feature_info_ = nullptr;
- context_state_ = nullptr;
- return false;
- }
+ GLenum driver_status = real_context_->CheckStickyGraphicsResetStatus();
+ if (driver_status != GL_NO_ERROR) {
+ // If the context was lost at any point before or during initialization,
+ // the values queried from the driver could be bogus, and potentially
+ // inconsistent between various ContextStates on the same underlying real
+ // GL context. Make sure to report the failure early, to not allow
+ // virtualized context switches in that case.
+ feature_info_ = nullptr;
+ context_state_ = nullptr;
+ return false;
}
if (use_virtualized_gl_contexts_) {
diff --git a/chromium/ui/gl/gl_context.cc b/chromium/ui/gl/gl_context.cc
index af8acbffcc6..228eadbd5f6 100644
--- a/chromium/ui/gl/gl_context.cc
+++ b/chromium/ui/gl/gl_context.cc
@@ -283,8 +283,9 @@ void GLContext::SetGLStateRestorer(GLStateRestorer* state_restorer) {
state_restorer_ = base::WrapUnique(state_restorer);
}
-bool GLContext::WasAllocatedUsingRobustnessExtension() {
- return false;
+GLenum GLContext::CheckStickyGraphicsResetStatus() {
+ DCHECK(IsCurrent(nullptr));
+ return GL_NO_ERROR;
}
void GLContext::InitializeDynamicBindings() {
diff --git a/chromium/ui/gl/gl_context.h b/chromium/ui/gl/gl_context.h
index e1668245e3d..3169aa856b7 100644
--- a/chromium/ui/gl/gl_context.h
+++ b/chromium/ui/gl/gl_context.h
@@ -159,7 +159,12 @@ class GL_EXPORT GLContext : public base::RefCounted<GLContext> {
// Returns the last GLContext made current, virtual or real.
static GLContext* GetCurrent();
- virtual bool WasAllocatedUsingRobustnessExtension();
+ // Returns the 'sticky' value of glGetGraphicsResetStatus, if available.
+ // 'sticky' implies that if glGetGraphicsResetStatus ever returns a value
+ // other than GL_NO_ERROR, that value is returned until the context is
+ // destroyed.
+ // The context must be current.
+ virtual unsigned int CheckStickyGraphicsResetStatus();
// Make this context current when used for context virtualization.
bool MakeVirtuallyCurrent(GLContext* virtual_context, GLSurface* surface);
diff --git a/chromium/ui/gl/gl_context_egl.cc b/chromium/ui/gl/gl_context_egl.cc
index 00471969c41..5d71e1ed675 100644
--- a/chromium/ui/gl/gl_context_egl.cc
+++ b/chromium/ui/gl/gl_context_egl.cc
@@ -361,8 +361,17 @@ void* GLContextEGL::GetHandle() {
return context_;
}
-bool GLContextEGL::WasAllocatedUsingRobustnessExtension() {
- return GLSurfaceEGL::IsCreateContextRobustnessSupported();
+unsigned int GLContextEGL::CheckStickyGraphicsResetStatus() {
+ DCHECK(IsCurrent(nullptr));
+ DCHECK(g_current_gl_driver);
+ const ExtensionsGL& ext = g_current_gl_driver->ext;
+ if ((graphics_reset_status_ == GL_NO_ERROR) &&
+ GLSurfaceEGL::IsCreateContextRobustnessSupported() &&
+ (ext.b_GL_KHR_robustness || ext.b_GL_EXT_robustness ||
+ ext.b_GL_ARB_robustness)) {
+ graphics_reset_status_ = glGetGraphicsResetStatusARB();
+ }
+ return graphics_reset_status_;
}
GLContextEGL::~GLContextEGL() {
diff --git a/chromium/ui/gl/gl_context_egl.h b/chromium/ui/gl/gl_context_egl.h
index 09ffe6a477c..0cba37904f8 100644
--- a/chromium/ui/gl/gl_context_egl.h
+++ b/chromium/ui/gl/gl_context_egl.h
@@ -33,7 +33,7 @@ class GL_EXPORT GLContextEGL : public GLContextReal {
void ReleaseCurrent(GLSurface* surface) override;
bool IsCurrent(GLSurface* surface) override;
void* GetHandle() override;
- bool WasAllocatedUsingRobustnessExtension() override;
+ unsigned int CheckStickyGraphicsResetStatus() override;
void SetUnbindFboOnMakeCurrent() override;
YUVToRGBConverter* GetYUVToRGBConverter(
const gfx::ColorSpace& color_space) override;
@@ -48,6 +48,7 @@ class GL_EXPORT GLContextEGL : public GLContextReal {
EGLContext context_ = nullptr;
EGLDisplay display_ = nullptr;
EGLConfig config_ = nullptr;
+ unsigned int graphics_reset_status_ = 0; // GL_NO_ERROR;
bool unbind_fbo_on_makecurrent_ = false;
bool lost_ = false;
std::map<gfx::ColorSpace, std::unique_ptr<YUVToRGBConverter>>
diff --git a/chromium/ui/gl/gl_context_glx.cc b/chromium/ui/gl/gl_context_glx.cc
index 5c1372e6168..139ba01c96e 100644
--- a/chromium/ui/gl/gl_context_glx.cc
+++ b/chromium/ui/gl/gl_context_glx.cc
@@ -283,8 +283,17 @@ void* GLContextGLX::GetHandle() {
return context_;
}
-bool GLContextGLX::WasAllocatedUsingRobustnessExtension() {
- return GLSurfaceGLX::IsCreateContextRobustnessSupported();
+unsigned int GLContextGLX::CheckStickyGraphicsResetStatus() {
+ DCHECK(IsCurrent(nullptr));
+ DCHECK(g_current_gl_driver);
+ const ExtensionsGL& ext = g_current_gl_driver->ext;
+ if ((graphics_reset_status_ == GL_NO_ERROR) &&
+ GLSurfaceGLX::IsCreateContextRobustnessSupported() &&
+ (ext.b_GL_KHR_robustness || ext.b_GL_EXT_robustness ||
+ ext.b_GL_ARB_robustness)) {
+ graphics_reset_status_ = glGetGraphicsResetStatusARB();
+ }
+ return graphics_reset_status_;
}
GLContextGLX::~GLContextGLX() {
diff --git a/chromium/ui/gl/gl_context_glx.h b/chromium/ui/gl/gl_context_glx.h
index 5cc8d23a816..ed203cb607a 100644
--- a/chromium/ui/gl/gl_context_glx.h
+++ b/chromium/ui/gl/gl_context_glx.h
@@ -31,7 +31,7 @@ class GL_EXPORT GLContextGLX : public GLContextReal {
void ReleaseCurrent(GLSurface* surface) override;
bool IsCurrent(GLSurface* surface) override;
void* GetHandle() override;
- bool WasAllocatedUsingRobustnessExtension() override;
+ unsigned int CheckStickyGraphicsResetStatus() override;
protected:
~GLContextGLX() override;
@@ -41,6 +41,7 @@ class GL_EXPORT GLContextGLX : public GLContextReal {
void* context_;
XDisplay* display_;
+ unsigned int graphics_reset_status_ = 0; // GL_NO_ERROR
DISALLOW_COPY_AND_ASSIGN(GLContextGLX);
};
diff --git a/chromium/ui/gl/gl_context_stub.cc b/chromium/ui/gl/gl_context_stub.cc
index d4646caef31..0d49bfb5d40 100644
--- a/chromium/ui/gl/gl_context_stub.cc
+++ b/chromium/ui/gl/gl_context_stub.cc
@@ -49,9 +49,12 @@ std::string GLContextStub::GetGLRenderer() {
return std::string("CHROMIUM");
}
-bool GLContextStub::WasAllocatedUsingRobustnessExtension() {
- return HasExtension("GL_ARB_robustness") ||
- HasExtension("GL_KHR_robustness") || HasExtension("GL_EXT_robustness");
+unsigned int GLContextStub::CheckStickyGraphicsResetStatus() {
+ DCHECK(IsCurrent(nullptr));
+ if ((graphics_reset_status_ == GL_NO_ERROR) && HasRobustness()) {
+ graphics_reset_status_ = glGetGraphicsResetStatusARB();
+ }
+ return graphics_reset_status_;
}
void GLContextStub::SetUseStubApi(bool stub_api) {
@@ -66,6 +69,11 @@ void GLContextStub::SetGLVersionString(const char* version_str) {
version_str_ = std::string(version_str ? version_str : "");
}
+bool GLContextStub::HasRobustness() {
+ return HasExtension("GL_ARB_robustness") ||
+ HasExtension("GL_KHR_robustness") || HasExtension("GL_EXT_robustness");
+}
+
GLContextStub::~GLContextStub() {}
GLApi* GLContextStub::CreateGLApi(DriverGL* driver) {
diff --git a/chromium/ui/gl/gl_context_stub.h b/chromium/ui/gl/gl_context_stub.h
index db4a0a37842..53107a35969 100644
--- a/chromium/ui/gl/gl_context_stub.h
+++ b/chromium/ui/gl/gl_context_stub.h
@@ -28,11 +28,12 @@ class GL_EXPORT GLContextStub : public GLContextReal {
void* GetHandle() override;
std::string GetGLVersion() override;
std::string GetGLRenderer() override;
- bool WasAllocatedUsingRobustnessExtension() override;
+ unsigned int CheckStickyGraphicsResetStatus() override;
void SetUseStubApi(bool stub_api);
void SetExtensionsString(const char* extensions);
void SetGLVersionString(const char* version_str);
+ bool HasRobustness();
protected:
~GLContextStub() override;
@@ -42,6 +43,7 @@ class GL_EXPORT GLContextStub : public GLContextReal {
private:
bool use_stub_api_;
std::string version_str_;
+ unsigned int graphics_reset_status_ = 0; // GL_NO_ERROR
DISALLOW_COPY_AND_ASSIGN(GLContextStub);
};
diff --git a/chromium/ui/gl/gl_fence_arb.cc b/chromium/ui/gl/gl_fence_arb.cc
index 52d9394df86..ada3120522d 100644
--- a/chromium/ui/gl/gl_fence_arb.cc
+++ b/chromium/ui/gl/gl_fence_arb.cc
@@ -85,13 +85,7 @@ void GLFenceARB::Invalidate() {
void GLFenceARB::HandleClientWaitFailure() {
DCHECK(GLContext::GetCurrent());
- if (GLContext::GetCurrent()->WasAllocatedUsingRobustnessExtension()) {
- // This function pointer is only set if one of the robustness
- // extensions was available.
- DCHECK(g_current_gl_driver &&
- g_current_gl_driver->fn.glGetGraphicsResetStatusARBFn);
- DCHECK(g_current_gl_driver->fn.glGetGraphicsResetStatusARBFn() !=
- GL_NO_ERROR);
+ if (GLContext::GetCurrent()->CheckStickyGraphicsResetStatus()) {
LOG(ERROR) << "Failed to wait for GLFence; context was lost. Error code: "
<< GetGLErrors();
} else {