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/FunctionsGL.cpp b/src/libANGLE/renderer/gl/FunctionsGL.cpp
index 423678c..fcb771d 100644
--- a/src/libANGLE/renderer/gl/FunctionsGL.cpp
+++ b/src/libANGLE/renderer/gl/FunctionsGL.cpp
@@ -618,6 +618,7 @@
       getDebugMessageLog(nullptr),
       getFramebufferParameteriv(nullptr),
       getInternalformati64v(nullptr),
+      getPointerv(nullptr),
       getObjectLabel(nullptr),
       getObjectPtrLabel(nullptr),
       getProgramInterfaceiv(nullptr),
@@ -863,6 +864,19 @@
         AssignGLEntryPoint(loadProcAddress("glPolygonOffset"), &polygonOffset);
         AssignGLEntryPoint(loadProcAddress("glTexSubImage1D"), &texSubImage1D);
         AssignGLEntryPoint(loadProcAddress("glTexSubImage2D"), &texSubImage2D);
+
+        // Extensions
+        AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glDebugMessageControl"), &debugMessageControl);
+        AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glDebugMessageInsert"), &debugMessageInsert);
+        AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glDebugMessageCallback"), &debugMessageCallback);
+        AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glGetDebugMessageLog"), &getDebugMessageLog);
+        AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glGetPointerv"), &getPointerv);
+        AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glPushDebugGroup"), &pushDebugGroup);
+        AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glPopDebugGroup"), &popDebugGroup);
+        AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glObjectLabel"), &objectLabel);
+        AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glGetObjectLabel"), &getObjectLabel);
+        AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glObjectPtrLabel"), &objectPtrLabel);
+        AssignGLExtensionEntryPoint(extensions, "GL_KHR_debug", loadProcAddress("glGetObjectPtrLabel"), &getObjectPtrLabel);
     }
 
     // 1.2
@@ -1397,6 +1411,7 @@
         AssignGLEntryPoint(loadProcAddress("glGetDebugMessageLog"), &getDebugMessageLog);
         AssignGLEntryPoint(loadProcAddress("glGetFramebufferParameteriv"), &getFramebufferParameteriv);
         AssignGLEntryPoint(loadProcAddress("glGetInternalformati64v"), &getInternalformati64v);
+        AssignGLEntryPoint(loadProcAddress("glGetPointerv"), &getPointerv);
         AssignGLEntryPoint(loadProcAddress("glGetObjectLabel"), &getObjectLabel);
         AssignGLEntryPoint(loadProcAddress("glGetObjectPtrLabel"), &getObjectPtrLabel);
         AssignGLEntryPoint(loadProcAddress("glGetProgramInterfaceiv"), &getProgramInterfaceiv);
diff --git a/src/libANGLE/renderer/gl/FunctionsGL.h b/src/libANGLE/renderer/gl/FunctionsGL.h
index bf6c2bf..4a0d5e0 100644
--- a/src/libANGLE/renderer/gl/FunctionsGL.h
+++ b/src/libANGLE/renderer/gl/FunctionsGL.h
@@ -576,6 +576,7 @@
     PFNGLGETDEBUGMESSAGELOGPROC getDebugMessageLog;
     PFNGLGETFRAMEBUFFERPARAMETERIVPROC getFramebufferParameteriv;
     PFNGLGETINTERNALFORMATI64VPROC getInternalformati64v;
+    PFNGLGETPOINTERVPROC getPointerv;
     PFNGLGETOBJECTLABELPROC getObjectLabel;
     PFNGLGETOBJECTPTRLABELPROC getObjectPtrLabel;
     PFNGLGETPROGRAMINTERFACEIVPROC getProgramInterfaceiv;
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()
diff --git a/src/libANGLE/renderer/gl/functionsgl_typedefs.h b/src/libANGLE/renderer/gl/functionsgl_typedefs.h
index 82fb5d8..50888e6 100644
--- a/src/libANGLE/renderer/gl/functionsgl_typedefs.h
+++ b/src/libANGLE/renderer/gl/functionsgl_typedefs.h
@@ -595,6 +595,7 @@
 typedef GLuint (INTERNAL_GL_APIENTRY *PFNGLGETDEBUGMESSAGELOGPROC)(GLuint, GLsizei, GLenum *, GLenum *, GLuint *, GLenum *, GLsizei *, GLchar *);
 typedef void (INTERNAL_GL_APIENTRY *PFNGLGETFRAMEBUFFERPARAMETERIVPROC)(GLenum, GLenum, GLint *);
 typedef void (INTERNAL_GL_APIENTRY *PFNGLGETINTERNALFORMATI64VPROC)(GLenum, GLenum, GLenum, GLsizei, GLint64 *);
+typedef void (INTERNAL_GL_APIENTRY *PFNGLGETPOINTERVPROC)(GLenum, void **);
 typedef void (INTERNAL_GL_APIENTRY *PFNGLGETOBJECTLABELPROC)(GLenum, GLuint, GLsizei, GLsizei *, GLchar *);
 typedef void (INTERNAL_GL_APIENTRY *PFNGLGETOBJECTPTRLABELPROC)(const void *, GLsizei, GLsizei *, GLchar *);
 typedef void (INTERNAL_GL_APIENTRY *PFNGLGETPROGRAMINTERFACEIVPROC)(GLuint, GLenum, GLenum, GLint *);