Load the KHR_debug extension entry points and print debug messages.

Change-Id: If1b64a7d5cc80205683062586a56fb50da6c1a21
Reviewed-on: https://chromium-review.googlesource.com/269143
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Tested-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/renderer/gl/RendererGL.cpp b/src/libANGLE/renderer/gl/RendererGL.cpp
index 7e1b0b0..5d530d0 100644
--- a/src/libANGLE/renderer/gl/RendererGL.cpp
+++ b/src/libANGLE/renderer/gl/RendererGL.cpp
@@ -28,6 +28,50 @@
 #include "libANGLE/renderer/gl/VertexArrayGL.h"
 #include "libANGLE/renderer/gl/renderergl_utils.h"
 
+#ifndef NDEBUG
+static void INTERNAL_GL_APIENTRY LogGLDebugMessage(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length,
+                                                   const GLchar *message, const void *userParam)
+{
+    std::string sourceText;
+    switch (source)
+    {
+      case GL_DEBUG_SOURCE_API:             sourceText = "OpenGL";          break;
+      case GL_DEBUG_SOURCE_WINDOW_SYSTEM:   sourceText = "Windows";         break;
+      case GL_DEBUG_SOURCE_SHADER_COMPILER: sourceText = "Shader Compiler"; break;
+      case GL_DEBUG_SOURCE_THIRD_PARTY:     sourceText = "Third Party";     break;
+      case GL_DEBUG_SOURCE_APPLICATION:     sourceText = "Application";     break;
+      case GL_DEBUG_SOURCE_OTHER:           sourceText = "Other";           break;
+      default:                              sourceText = "UNKNOWN";         break;
+    }
+
+    std::string typeText;
+    switch (type)
+    {
+      case GL_DEBUG_TYPE_ERROR:               typeText = "Error";               break;
+      case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: typeText = "Deprecated behavior"; break;
+      case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:  typeText = "Undefined behavior";  break;
+      case GL_DEBUG_TYPE_PORTABILITY:         typeText = "Portability";         break;
+      case GL_DEBUG_TYPE_PERFORMANCE:         typeText = "Performance";         break;
+      case GL_DEBUG_TYPE_OTHER:               typeText = "Other";               break;
+      case GL_DEBUG_TYPE_MARKER:              typeText = "Marker";              break;
+      default:                                typeText = "UNKNOWN";             break;
+    }
+
+    std::string severityText;
+    switch (severity)
+    {
+      case GL_DEBUG_SEVERITY_HIGH:         severityText = "High";         break;
+      case GL_DEBUG_SEVERITY_MEDIUM:       severityText = "Medium";       break;
+      case GL_DEBUG_SEVERITY_LOW:          severityText = "Low";          break;
+      case GL_DEBUG_SEVERITY_NOTIFICATION: severityText = "Notification"; break;
+      default:                             severityText = "UNKNOWN";      break;
+    }
+
+    ERR("\n\tSource: %s\n\tType: %s\n\tID: %d\n\tSeverity: %s\n\tMessage: %s", sourceText.c_str(), typeText.c_str(), id,
+        severityText.c_str(), message);
+}
+#endif
+
 namespace rx
 {
 
@@ -38,6 +82,18 @@
 {
     ASSERT(mFunctions);
     mStateManager = new StateManagerGL(mFunctions, getRendererCaps());
+
+#ifndef NDEBUG
+    if (mFunctions->debugMessageControl && mFunctions->debugMessageCallback)
+    {
+        mFunctions->enable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
+        mFunctions->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH, 0, nullptr, GL_TRUE);
+        mFunctions->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM, 0, nullptr, GL_TRUE);
+        mFunctions->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0, nullptr, GL_FALSE);
+        mFunctions->debugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, nullptr, GL_FALSE);
+        mFunctions->debugMessageCallback(&LogGLDebugMessage, nullptr);
+    }
+#endif
 }
 
 RendererGL::~RendererGL()