Commit 989f7a70 authored by Christopher Cameron's avatar Christopher Cameron Committed by Commit Bot

Dump flushed GL commands to crash key

Instrument GLES2DecoderImpl::DoCommandsImpl to
- record in a crash key all of the GL commands that have been flushed
- flush at the end of every time that it is called

This will severely regress performance.

What we hope to learn:
- There's a good chance this will make the bug vanish (egregious glFlush
  calls have been known to do this), in which case we'll learn nothing.
  - But maybe we can add less egregious glFlush calls to avoid the issue
    in Chrome 69
- If elevated crash rates persist, hopefully this will point to a particular
  call or sequence of calls that is causing the crash

Bug: 863817
Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel
Change-Id: I462fab8a6d86ee3896dcd9c0c3c4aa68f9de0a69
Reviewed-on: https://chromium-review.googlesource.com/1159831
Commit-Queue: ccameron <ccameron@chromium.org>
Reviewed-by: default avatarKenneth Russell <kbr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#580213}
parent cf64e143
...@@ -110,6 +110,10 @@ uint64_t GLContextVirtual::BackpressureFenceCreate() { ...@@ -110,6 +110,10 @@ uint64_t GLContextVirtual::BackpressureFenceCreate() {
void GLContextVirtual::BackpressureFenceWait(uint64_t fence) { void GLContextVirtual::BackpressureFenceWait(uint64_t fence) {
shared_context_->BackpressureFenceWait(fence); shared_context_->BackpressureFenceWait(fence);
} }
void GLContextVirtual::FlushForDebugging() {
shared_context_->FlushForDebugging();
}
#endif #endif
GLContextVirtual::~GLContextVirtual() { GLContextVirtual::~GLContextVirtual() {
......
...@@ -50,6 +50,7 @@ class GPU_GLES2_EXPORT GLContextVirtual : public gl::GLContext { ...@@ -50,6 +50,7 @@ class GPU_GLES2_EXPORT GLContextVirtual : public gl::GLContext {
#if defined(OS_MACOSX) #if defined(OS_MACOSX)
uint64_t BackpressureFenceCreate() override; uint64_t BackpressureFenceCreate() override;
void BackpressureFenceWait(uint64_t fence) override; void BackpressureFenceWait(uint64_t fence) override;
void FlushForDebugging() override;
#endif #endif
protected: protected:
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "base/containers/queue.h" #include "base/containers/queue.h"
#include "base/containers/span.h" #include "base/containers/span.h"
#include "base/debug/alias.h" #include "base/debug/alias.h"
#include "base/debug/crash_logging.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "base/numerics/ranges.h" #include "base/numerics/ranges.h"
...@@ -5617,6 +5618,14 @@ error::Error GLES2DecoderImpl::DoCommandsImpl(unsigned int num_commands, ...@@ -5617,6 +5618,14 @@ error::Error GLES2DecoderImpl::DoCommandsImpl(unsigned int num_commands,
int process_pos = 0; int process_pos = 0;
unsigned int command = 0; unsigned int command = 0;
// Instrumentation for https://crbug.com/863817. Keep a list of all commands
// that are flushed, to see what calls may be the culprit.
#if defined(OS_MACOSX)
static auto* crash_key = base::debug::AllocateCrashKeyString(
"mac_gl_commands_in_flush", base::debug::CrashKeySize::Size256);
std::string crash_info;
#endif
while (process_pos < num_entries && result == error::kNoError && while (process_pos < num_entries && result == error::kNoError &&
commands_to_process_--) { commands_to_process_--) {
const unsigned int size = cmd_data->value_header.size; const unsigned int size = cmd_data->value_header.size;
...@@ -5632,6 +5641,19 @@ error::Error GLES2DecoderImpl::DoCommandsImpl(unsigned int num_commands, ...@@ -5632,6 +5641,19 @@ error::Error GLES2DecoderImpl::DoCommandsImpl(unsigned int num_commands,
break; break;
} }
// Continued instrumentation for https://crbug.com/863817. If we run out of
// buffer space then flush.
#if defined(OS_MACOSX)
std::string command_name = GetCommandName(command);
if (!crash_info.empty() && crash_info.size() + command_name.size() > 256) {
TRACE_EVENT0("gpu", "Egregious Flush");
context_->FlushForDebugging();
crash_info = "";
}
crash_info += command_name + ",";
base::debug::SetCrashKeyString(crash_key, crash_info);
#endif
if (DebugImpl && log_commands()) { if (DebugImpl && log_commands()) {
LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]" LOG(ERROR) << "[" << logger_.GetLogPrefix() << "]"
<< "cmd: " << GetCommandName(command); << "cmd: " << GetCommandName(command);
...@@ -5690,6 +5712,15 @@ error::Error GLES2DecoderImpl::DoCommandsImpl(unsigned int num_commands, ...@@ -5690,6 +5712,15 @@ error::Error GLES2DecoderImpl::DoCommandsImpl(unsigned int num_commands,
} }
} }
// Continued instrumentation for https://crbug.com/863817
#if defined(OS_MACOSX)
{
TRACE_EVENT0("gpu", "Egregious Flush");
context_->FlushForDebugging();
base::debug::ClearCrashKeyString(crash_key);
}
#endif
*entries_processed = process_pos; *entries_processed = process_pos;
if (error::IsError(result)) { if (error::IsError(result)) {
......
...@@ -194,6 +194,8 @@ uint64_t GLContext::BackpressureFenceCreate() { ...@@ -194,6 +194,8 @@ uint64_t GLContext::BackpressureFenceCreate() {
} }
void GLContext::BackpressureFenceWait(uint64_t fence) {} void GLContext::BackpressureFenceWait(uint64_t fence) {}
void GLContext::FlushForDebugging() {}
#endif #endif
bool GLContext::HasExtension(const char* name) { bool GLContext::HasExtension(const char* name) {
......
...@@ -202,6 +202,8 @@ class GL_EXPORT GLContext : public base::RefCounted<GLContext> { ...@@ -202,6 +202,8 @@ class GL_EXPORT GLContext : public base::RefCounted<GLContext> {
virtual uint64_t BackpressureFenceCreate(); virtual uint64_t BackpressureFenceCreate();
// Perform a client-side wait on a previously-created fence. // Perform a client-side wait on a previously-created fence.
virtual void BackpressureFenceWait(uint64_t fence); virtual void BackpressureFenceWait(uint64_t fence);
// Temporary instrumentation for https://crbug.com/863817
virtual void FlushForDebugging();
#endif #endif
protected: protected:
......
...@@ -286,6 +286,12 @@ void GLContextCGL::BackpressureFenceWait(uint64_t fence_id) { ...@@ -286,6 +286,12 @@ void GLContextCGL::BackpressureFenceWait(uint64_t fence_id) {
backpressure_fences_.erase(backpressure_fences_.begin()); backpressure_fences_.erase(backpressure_fences_.begin());
} }
void GLContextCGL::FlushForDebugging() {
if (!context_ || CGLGetCurrentContext() != context_)
return;
glFlush();
}
bool GLContextCGL::MakeCurrent(GLSurface* surface) { bool GLContextCGL::MakeCurrent(GLSurface* surface) {
DCHECK(context_); DCHECK(context_);
......
...@@ -38,6 +38,7 @@ class GL_EXPORT GLContextCGL : public GLContextReal { ...@@ -38,6 +38,7 @@ class GL_EXPORT GLContextCGL : public GLContextReal {
const gfx::ColorSpace& color_space) override; const gfx::ColorSpace& color_space) override;
uint64_t BackpressureFenceCreate() override; uint64_t BackpressureFenceCreate() override;
void BackpressureFenceWait(uint64_t fence) override; void BackpressureFenceWait(uint64_t fence) override;
void FlushForDebugging() override;
protected: protected:
~GLContextCGL() override; ~GLContextCGL() override;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment