0

Align CheckResetStatus and MarkContextLost

CheckResetStatus need to three different things and in specific order if
it detects problem:

1. Set `device_needs_reset_` to true. This needs to happen first as it's
   used in MarkContextLost.
2. Call MarkContextLost
3. Return true. This must happen only if context was lost.

Before this CL there was couple of problems:
* default case in switch would return true, but never lose context.
* OutOfMemory case would lost context before setting device_needs_reset_

This CL extracts logic for checking errors from CheckResetStatus into
GetResetStatus to make sure we do all the actions above in one place and
make code less error prone.

Bug: 1126490

Change-Id: I1a86ad2cc783ee2fd2dcf828612f2b657aba23ce
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2401400
Reviewed-by: Jonathan Backer <backer@chromium.org>
Commit-Queue: Vasiliy Telezhnikov <vasilyt@chromium.org>
Cr-Commit-Position: refs/heads/master@{#805765}
This commit is contained in:
Vasiliy Telezhnikov
2020-09-10 15:49:08 +00:00
committed by Commit Bot
parent 4ef6b07520
commit f785e652d2
2 changed files with 35 additions and 29 deletions

@ -734,45 +734,40 @@ QueryManager* SharedContextState::GetQueryManager() {
return nullptr;
}
bool SharedContextState::CheckResetStatus(bool needs_gl) {
base::Optional<error::ContextLostReason> SharedContextState::GetResetStatus(
bool needs_gl) {
DCHECK(!context_lost());
if (device_needs_reset_)
return true;
if (gr_context_) {
// Maybe Skia detected VK_ERROR_DEVICE_LOST.
if (gr_context_->abandoned()) {
LOG(ERROR) << "SharedContextState context lost via Skia.";
device_needs_reset_ = true;
MarkContextLost(error::kUnknown);
return true;
return error::kUnknown;
}
if (gr_context_->oomed()) {
LOG(ERROR) << "SharedContextState context lost via Skia OOM.";
device_needs_reset_ = true;
MarkContextLost(error::kOutOfMemory);
return true;
return error::kOutOfMemory;
}
}
// Not using GL.
if (!GrContextIsGL() && !needs_gl)
return false;
return base::nullopt;
// GL is not initialized.
if (!context_state_)
return false;
return base::nullopt;
GLenum error = context_state_->api()->glGetErrorFn();
if (error == GL_OUT_OF_MEMORY) {
LOG(ERROR) << "SharedContextState lost due to GL_OUT_OF_MEMORY";
MarkContextLost(error::kOutOfMemory);
device_needs_reset_ = true;
return true;
GLenum error;
while ((error = context_state_->api()->glGetErrorFn()) != GL_NO_ERROR) {
if (error == GL_OUT_OF_MEMORY) {
LOG(ERROR) << "SharedContextState lost due to GL_OUT_OF_MEMORY";
return error::kOutOfMemory;
}
if (error == GL_CONTEXT_LOST_KHR)
break;
}
// Checking the reset status is expensive on some OS/drivers
// (https://crbug.com/1090232). Rate limit it.
constexpr base::TimeDelta kMinCheckDelay =
@ -780,33 +775,42 @@ bool SharedContextState::CheckResetStatus(bool needs_gl) {
base::Time now = base::Time::Now();
if (!disable_check_reset_status_throttling_for_test_ &&
now < last_gl_check_graphics_reset_status_ + kMinCheckDelay) {
return false;
return base::nullopt;
}
last_gl_check_graphics_reset_status_ = now;
GLenum driver_status = context()->CheckStickyGraphicsResetStatus();
if (driver_status == GL_NO_ERROR)
return false;
return base::nullopt;
LOG(ERROR) << "SharedContextState context lost via ARB/EXT_robustness. Reset "
"status = "
<< gles2::GLES2Util::GetStringEnum(driver_status);
device_needs_reset_ = true;
switch (driver_status) {
case GL_GUILTY_CONTEXT_RESET_ARB:
MarkContextLost(error::kGuilty);
break;
return error::kGuilty;
case GL_INNOCENT_CONTEXT_RESET_ARB:
MarkContextLost(error::kInnocent);
break;
return error::kInnocent;
case GL_UNKNOWN_CONTEXT_RESET_ARB:
MarkContextLost(error::kUnknown);
break;
return error::kUnknown;
default:
NOTREACHED();
break;
}
return true;
return base::nullopt;
}
bool SharedContextState::CheckResetStatus(bool need_gl) {
DCHECK(!context_lost());
DCHECK(!device_needs_reset_);
auto status = GetResetStatus(need_gl);
if (status.has_value()) {
device_needs_reset_ = true;
MarkContextLost(status.value());
return true;
}
return false;
}
} // namespace gpu

@ -273,6 +273,8 @@ class GPU_GLES2_EXPORT SharedContextState
~SharedContextState() override;
base::Optional<error::ContextLostReason> GetResetStatus(bool needs_gl);
// gpu::GLContextVirtualDelegate implementation.
bool initialized() const override;
const gles2::ContextState* GetContextState() override;