Skip to content

Commit

Permalink
Add a LOG(ERROR) message on each Fatal or Transient gpu context error
Browse files Browse the repository at this point in the history
When a fatal error happens on ChromeOS, we will crash the browser, so
these logs will be present in the crash report which will be important
in case any are wrong or we need to debug a device failure. For other
platforms they will help explain why the compositor drops into software
compositing (or why android aborts and crashes as well).

R=piman@chromium.org

Bug: 772574
Cq-Include-Trybots: master.tryserver.chromium.android:android_optional_gpu_tests_rel;master.tryserver.chromium.linux:linux_optional_gpu_tests_rel;master.tryserver.chromium.mac:mac_optional_gpu_tests_rel;master.tryserver.chromium.win:win_optional_gpu_tests_rel
Change-Id: I10fa8230a210df96b29d9d3767c0cd1e8d57a775
Reviewed-on: https://chromium-review.googlesource.com/727190
Commit-Queue: danakj <danakj@chromium.org>
Reviewed-by: Antoine Labour <piman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#510181}
  • Loading branch information
danakj authored and Commit Bot committed Oct 19, 2017
1 parent 880af47 commit 514516a
Show file tree
Hide file tree
Showing 10 changed files with 200 additions and 120 deletions.
2 changes: 2 additions & 0 deletions gpu/command_buffer/client/cmd_buffer_helper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ gpu::ContextResult CommandBufferHelper::Initialize(int32_t ring_buffer_size) {
if (!AllocateRingBuffer()) {
// This would fail if CreateTransferBuffer fails, which will not fail for
// transient reasons such as context loss. See http://crrev.com/c/720269
LOG(ERROR) << "ContextResult::kFatalFailure: "
<< "CommandBufferHelper::AllocateRingBuffer() failed";
return gpu::ContextResult::kFatalFailure;
}
return gpu::ContextResult::kSuccess;
Expand Down
4 changes: 4 additions & 0 deletions gpu/command_buffer/client/gles2_implementation.cc
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,8 @@ gpu::ContextResult GLES2Implementation::Initialize(
kAlignment, kSizeToFlush)) {
// TransferBuffer::Initialize doesn't fail for transient reasons such as if
// the context was lost. See http://crrev.com/c/720269
LOG(ERROR) << "ContextResult::kFatalFailure: "
<< "TransferBuffer::Initailize() failed";
return gpu::ContextResult::kFatalFailure;
}

Expand Down Expand Up @@ -255,6 +257,8 @@ gpu::ContextResult GLES2Implementation::Initialize(
SetGLError(GL_INVALID_OPERATION,
"Initialize",
"Service bind_generates_resource mismatch.");
LOG(ERROR) << "ContextResult::kFatalFailure: "
<< "bind_generates_resource mismatch";
return gpu::ContextResult::kFatalFailure;
}

Expand Down
178 changes: 99 additions & 79 deletions gpu/command_buffer/service/context_group.cc

Large diffs are not rendered by default.

36 changes: 28 additions & 8 deletions gpu/command_buffer/service/gles2_cmd_decoder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3241,6 +3241,8 @@ gpu::ContextResult GLES2DecoderImpl::Initialize(
feature_info_->feature_flags().is_swiftshader_for_webgl) {
group_ = NULL; // Must not destroy ContextGroup if it is not initialized.
Destroy(true);
LOG(ERROR) << "ContextResult::kFatalFailure: "
"fail_if_major_perf_caveat + swiftshader";
return gpu::ContextResult::kFatalFailure;
}

Expand Down Expand Up @@ -3276,6 +3278,8 @@ gpu::ContextResult GLES2DecoderImpl::Initialize(

if (!supported) {
Destroy(true);
LOG(ERROR) << "ContextResult::kFatalFailure: "
"native gmb format not supported";
return gpu::ContextResult::kFatalFailure;
}
}
Expand All @@ -3289,8 +3293,9 @@ gpu::ContextResult GLES2DecoderImpl::Initialize(

if (feature_info_->IsWebGL2OrES3Context()) {
if (!feature_info_->IsES3Capable()) {
LOG(ERROR) << "ES3 is blacklisted/disabled/unsupported by driver.";
Destroy(true);
LOG(ERROR) << "ContextResult::kFatalFailure: "
"ES3 is blacklisted/disabled/unsupported by driver.";
return gpu::ContextResult::kFatalFailure;
}
feature_info_->EnableES3Validators();
Expand Down Expand Up @@ -3625,8 +3630,9 @@ gpu::ContextResult GLES2DecoderImpl::Initialize(
// of the frame buffers is okay.
if (!ResizeOffscreenFramebuffer(
gfx::Size(state_.viewport_width, state_.viewport_height))) {
LOG(ERROR) << "Could not allocate offscreen buffer storage.";
Destroy(true);
LOG(ERROR) << "ContextResult::kFatalFailure: "
"Could not allocate offscreen buffer storage.";
return gpu::ContextResult::kFatalFailure;
}
if (!offscreen_single_buffer_) {
Expand All @@ -3639,9 +3645,11 @@ gpu::ContextResult GLES2DecoderImpl::Initialize(
offscreen_saved_color_texture_.get());
if (offscreen_saved_frame_buffer_->CheckStatus() !=
GL_FRAMEBUFFER_COMPLETE) {
LOG(ERROR) << "Offscreen saved FBO was incomplete.";
bool was_lost = CheckResetStatus();
Destroy(true);
LOG(ERROR) << (was_lost ? "ContextResult::kTransientFailure: "
: "ContextResult::kFatalFailure: ")
<< "Offscreen saved FBO was incomplete.";
return was_lost ? gpu::ContextResult::kTransientFailure
: gpu::ContextResult::kFatalFailure;
}
Expand Down Expand Up @@ -3707,9 +3715,13 @@ gpu::ContextResult GLES2DecoderImpl::Initialize(
if (workarounds().gl_clear_broken) {
DCHECK(!clear_framebuffer_blit_.get());
LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glClearWorkaroundInit");
clear_framebuffer_blit_.reset(new ClearFramebufferResourceManager(this));
if (LOCAL_PEEK_GL_ERROR("glClearWorkaroundInit") != GL_NO_ERROR)
clear_framebuffer_blit_ =
std::make_unique<ClearFramebufferResourceManager>(this);
if (LOCAL_PEEK_GL_ERROR("glClearWorkaroundInit") != GL_NO_ERROR) {
LOG(ERROR) << "ContextResult::kFatalFailure: "
"glClearWorkaroundInit failed";
return gpu::ContextResult::kFatalFailure;
}
}

if (group_->gpu_preferences().enable_gpu_driver_debug_logging &&
Expand All @@ -3723,22 +3735,30 @@ gpu::ContextResult GLES2DecoderImpl::Initialize(
}

if (attrib_helper.enable_oop_rasterization) {
if (!features().chromium_raster_transport)
if (!features().chromium_raster_transport) {
LOG(ERROR) << "ContextResult::kFatalFailure: "
"chromium_raster_transport not present";
return gpu::ContextResult::kFatalFailure;
}
sk_sp<const GrGLInterface> interface(
CreateGrGLInterface(gl_version_info()));
// TODO(enne): if this or gr_context creation below fails in practice for
// different reasons than the ones the renderer would fail on for gpu
// raster, expose this in gpu::Capabilities so the renderer can handle it.
if (!interface)
if (!interface) {
LOG(ERROR) << "ContextResult::kFatalFailure: "
"GrGLInterface creation failed";
return gpu::ContextResult::kFatalFailure;
}

gr_context_ = sk_sp<GrContext>(
GrContext::Create(kOpenGL_GrBackend,
reinterpret_cast<GrBackendContext>(interface.get())));
if (!gr_context_) {
LOG(ERROR) << "Could not create GrContext";
bool was_lost = CheckResetStatus();
LOG(ERROR) << (was_lost ? "ContextResult::kTransientFailure: "
: "ContextResult::kFatalFailure: ")
<< "Could not create GrContext";
return was_lost ? gpu::ContextResult::kTransientFailure
: gpu::ContextResult::kFatalFailure;
}
Expand Down
13 changes: 11 additions & 2 deletions gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
Original file line number Diff line number Diff line change
Expand Up @@ -638,11 +638,15 @@ gpu::ContextResult GLES2DecoderPassthroughImpl::Initialize(
IsWebGLContextType(attrib_helper.context_type) ||
!feature_info_->feature_flags().angle_request_extension) {
Destroy(true);
LOG(ERROR) << "ContextResult::kFatalFailure: "
"missing required extension";
return gpu::ContextResult::kFatalFailure;
}

if (attrib_helper.enable_oop_rasterization) {
Destroy(true);
LOG(ERROR) << "ContextResult::kFatalFailure: "
"oop rasterization not supported";
return gpu::ContextResult::kFatalFailure;
}

Expand Down Expand Up @@ -770,15 +774,20 @@ gpu::ContextResult GLES2DecoderPassthroughImpl::Initialize(
feature_info_.get())) {
bool was_lost = CheckResetStatus();
Destroy(true);
LOG(ERROR) << (was_lost ? "ContextResult::kTransientFailure: "
: "ContextResult::kFatalFailure: ")
<< "Resize of emulated back buffer failed";
return was_lost ? gpu::ContextResult::kTransientFailure
: gpu::ContextResult::kFatalFailure;
}

if (FlushErrors()) {
LOG(ERROR) << "Creation of the offscreen framebuffer failed because "
"errors were generated.";
Destroy(true);
// Errors are considered fatal, including OOM.
LOG(ERROR)
<< "ContextResult::kFatalFailure: "
"Creation of the offscreen framebuffer failed because errors were "
"generated.";
return gpu::ContextResult::kFatalFailure;
}

Expand Down
18 changes: 14 additions & 4 deletions gpu/ipc/client/command_buffer_proxy_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,17 @@ ContextResult CommandBufferProxyImpl::Initialize(
TRACE_EVENT0("gpu", "CommandBufferProxyImpl::Initialize");
shared_state_shm_ =
channel->factory()->AllocateSharedMemory(sizeof(*shared_state()));
if (!shared_state_shm_)
if (!shared_state_shm_) {
LOG(ERROR) << "ContextResult::kFatalFailure: "
"AllocateSharedMemory failed";
return ContextResult::kFatalFailure;
}

if (!shared_state_shm_->Map(sizeof(*shared_state())))
if (!shared_state_shm_->Map(sizeof(*shared_state()))) {
LOG(ERROR) << "ContextResult::kFatalFailure: "
"Map shared memory failed";
return ContextResult::kFatalFailure;
}

shared_state()->Initialize();

Expand All @@ -108,8 +114,11 @@ ContextResult CommandBufferProxyImpl::Initialize(
// sending of the CreateCommandBuffer IPC below.
base::SharedMemoryHandle handle =
channel->ShareToGpuProcess(shared_state_shm_->handle());
if (!base::SharedMemory::IsHandleValid(handle))
if (!base::SharedMemory::IsHandleValid(handle)) {
LOG(ERROR) << "ContextResult::kFatalFailure: "
"Shared memory handle is not valid";
return ContextResult::kFatalFailure;
}

// Route must be added before sending the message, otherwise messages sent
// from the GPU process could race against adding ourselves to the filter.
Expand All @@ -124,8 +133,9 @@ ContextResult CommandBufferProxyImpl::Initialize(
bool sent = channel->Send(new GpuChannelMsg_CreateCommandBuffer(
init_params, route_id_, handle, &result, &capabilities_));
if (!sent) {
DLOG(ERROR) << "Failed to send GpuChannelMsg_CreateCommandBuffer.";
channel->RemoveRoute(route_id_);
LOG(ERROR) << "ContextResult::kTransientFailure: "
"Failed to send GpuChannelMsg_CreateCommandBuffer.";
return ContextResult::kTransientFailure;
}
if (result != ContextResult::kSuccess) {
Expand Down
12 changes: 8 additions & 4 deletions gpu/ipc/in_process_command_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -339,15 +339,17 @@ gpu::ContextResult InProcessCommandBuffer::InitializeOnGpuThread(
gl::GLSurfaceFormat());
if (!surface_ || !surface_->Initialize(gl::GLSurfaceFormat())) {
surface_ = nullptr;
DLOG(ERROR) << "Failed to create surface.";
LOG(ERROR) << "ContextResult::kFatalFailure: "
"Failed to create surface.";
return gpu::ContextResult::kFatalFailure;
}
}
}

if (!surface_.get()) {
DLOG(ERROR) << "Could not create GLSurface.";
DestroyOnGpuThread();
LOG(ERROR) << "ContextResult::kFatalFailure: "
"Could not create GLSurface.";
return gpu::ContextResult::kFatalFailure;
}

Expand Down Expand Up @@ -400,15 +402,17 @@ gpu::ContextResult InProcessCommandBuffer::InitializeOnGpuThread(
}

if (!context_.get()) {
LOG(ERROR) << "Could not create GLContext.";
DestroyOnGpuThread();
LOG(ERROR) << "ContextResult::kFatalFailure: "
"Could not create GLContext.";
return gpu::ContextResult::kFatalFailure;
}

if (!context_->MakeCurrent(surface_.get())) {
LOG(ERROR) << "Could not make context current.";
DestroyOnGpuThread();
// The caller should retry making a context, but this one won't work.
LOG(ERROR) << "ContextResult::kTransientFailure: "
"Could not make context current.";
return gpu::ContextResult::kTransientFailure;
}

Expand Down
26 changes: 14 additions & 12 deletions gpu/ipc/service/gpu_channel.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1080,45 +1080,47 @@ void GpuChannel::OnCreateCommandBuffer(
*capabilities = gpu::Capabilities();

if (init_params.surface_handle != kNullSurfaceHandle && !is_gpu_host_) {
DLOG(ERROR) << "GpuChannel::CreateCommandBuffer(): attempt to create a "
"view context on a non-privileged channel";
LOG(ERROR)
<< "ContextResult::kFatalFailure: "
"attempt to create a view context on a non-privileged channel";
return;
}

int32_t share_group_id = init_params.share_group_id;
GpuCommandBufferStub* share_group = LookupCommandBuffer(share_group_id);

if (!share_group && share_group_id != MSG_ROUTING_NONE) {
DLOG(ERROR) << "GpuChannel::CreateCommandBuffer(): invalid share group id";
LOG(ERROR) << "ContextResult::kFatalFailure: invalid share group id";
return;
}

int32_t stream_id = init_params.stream_id;
if (share_group && stream_id != share_group->stream_id()) {
DLOG(ERROR) << "GpuChannel::CreateCommandBuffer(): stream id does not "
"match share group stream id";
LOG(ERROR) << "ContextResult::kFatalFailure: "
"stream id does not match share group stream id";
return;
}

SchedulingPriority stream_priority = init_params.stream_priority;
if (stream_priority <= SchedulingPriority::kHigh && !is_gpu_host_) {
DLOG(ERROR) << "GpuChannel::CreateCommandBuffer(): high priority stream "
"not allowed on a non-privileged channel";
LOG(ERROR)
<< "ContextResult::kFatalFailure: "
"high priority stream not allowed on a non-privileged channel";
return;
}

if (share_group && !share_group->decoder()) {
// This should catch test errors where we did not Initialize the
// share_group's CommandBuffer.
DLOG(ERROR) << "GpuChannel::CreateCommandBuffer(): shared context was "
"not initialized";
LOG(ERROR) << "ContextResult::kFatalFailure: "
"shared context was not initialized";
return;
}

if (share_group && share_group->decoder()->WasContextLost()) {
DLOG(ERROR) << "GpuChannel::CreateCommandBuffer(): shared context was "
"already lost";
// The caller should retry to get a context.
LOG(ERROR) << "ContextResult::kTransientFailure: "
"shared context was already lost";
*result = gpu::ContextResult::kTransientFailure;
return;
}
Expand Down Expand Up @@ -1149,7 +1151,7 @@ void GpuChannel::OnCreateCommandBuffer(
}

if (!AddRoute(route_id, sequence_id, stub.get())) {
DLOG(ERROR) << "GpuChannel::CreateCommandBuffer(): failed to add route";
LOG(ERROR) << "ContextResult::kFatalFailure: failed to add route";
return;
}

Expand Down
Loading

0 comments on commit 514516a

Please sign in to comment.