Implement GL_KHR_debug.

BUG=angleproject:520

Change-Id: I9ced3e7ab1515feddf2ec103c26b2610a45b1784
Reviewed-on: https://chromium-review.googlesource.com/319830
Tryjob-Request: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Tested-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index 1a13433..d652695 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -62,7 +62,8 @@
                  const Context *shareContext,
                  rx::Renderer *renderer,
                  bool notifyResets,
-                 bool robustAccess)
+                 bool robustAccess,
+                 bool debug)
     : ValidationContext(clientVersion,
                         mState,
                         mCaps,
@@ -77,7 +78,7 @@
     ASSERT(robustAccess == false);   // Unimplemented
 
     initCaps(clientVersion);
-    mState.initialize(mCaps, clientVersion);
+    mState.initialize(mCaps, mExtensions, clientVersion, debug);
 
     mClientVersion = clientVersion;
 
@@ -503,7 +504,7 @@
     }
 }
 
-Buffer *Context::getBuffer(GLuint handle)
+Buffer *Context::getBuffer(GLuint handle) const
 {
     return mResourceManager->getBuffer(handle);
 }
@@ -523,7 +524,7 @@
     return mResourceManager->getTexture(handle);
 }
 
-Renderbuffer *Context::getRenderbuffer(GLuint handle)
+Renderbuffer *Context::getRenderbuffer(GLuint handle) const
 {
     return mResourceManager->getRenderbuffer(handle);
 }
@@ -550,6 +551,41 @@
     return (iter != mTransformFeedbackMap.end()) ? iter->second : nullptr;
 }
 
+LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
+{
+    switch (identifier)
+    {
+        case GL_BUFFER:
+            return getBuffer(name);
+        case GL_SHADER:
+            return getShader(name);
+        case GL_PROGRAM:
+            return getProgram(name);
+        case GL_VERTEX_ARRAY:
+            return getVertexArray(name);
+        case GL_QUERY:
+            return getQuery(name);
+        case GL_TRANSFORM_FEEDBACK:
+            return getTransformFeedback(name);
+        case GL_SAMPLER:
+            return getSampler(name);
+        case GL_TEXTURE:
+            return getTexture(name);
+        case GL_RENDERBUFFER:
+            return getRenderbuffer(name);
+        case GL_FRAMEBUFFER:
+            return getFramebuffer(name);
+        default:
+            UNREACHABLE();
+            return nullptr;
+    }
+}
+
+LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
+{
+    return getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
+}
+
 bool Context::isSampler(GLuint samplerName) const
 {
     return mResourceManager->isSampler(samplerName);
@@ -776,6 +812,12 @@
     }
 }
 
+Query *Context::getQuery(GLuint handle) const
+{
+    auto iter = mQueryMap.find(handle);
+    return (iter != mQueryMap.end()) ? iter->second : nullptr;
+}
+
 Texture *Context::getTargetTexture(GLenum target) const
 {
     ASSERT(ValidTextureTarget(this, target));
@@ -905,6 +947,21 @@
       case GL_NUM_EXTENSIONS:
         *params = static_cast<GLint>(mExtensionStrings.size());
         break;
+
+      // GL_KHR_debug
+      case GL_MAX_DEBUG_MESSAGE_LENGTH:
+          *params = mExtensions.maxDebugMessageLength;
+          break;
+      case GL_MAX_DEBUG_LOGGED_MESSAGES:
+          *params = mExtensions.maxDebugLoggedMessages;
+          break;
+      case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
+          *params = mExtensions.maxDebugGroupStackDepth;
+          break;
+      case GL_MAX_LABEL_LENGTH:
+          *params = mExtensions.maxLabelLength;
+          break;
+
       default:
         mState.getIntegerv(getData(), pname, params);
         break;
@@ -938,6 +995,11 @@
     }
 }
 
+void Context::getPointerv(GLenum pname, void **params) const
+{
+    mState.getPointerv(pname, params);
+}
+
 bool Context::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
 {
     // Queries about context capabilities and maximums are answered by Context.
@@ -1149,6 +1211,29 @@
         return true;
     }
 
+    if (mExtensions.debug)
+    {
+        switch (pname)
+        {
+            case GL_DEBUG_LOGGED_MESSAGES:
+            case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
+            case GL_DEBUG_GROUP_STACK_DEPTH:
+            case GL_MAX_DEBUG_MESSAGE_LENGTH:
+            case GL_MAX_DEBUG_LOGGED_MESSAGES:
+            case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
+            case GL_MAX_LABEL_LENGTH:
+                *type      = GL_INT;
+                *numParams = 1;
+                return true;
+
+            case GL_DEBUG_OUTPUT_SYNCHRONOUS:
+            case GL_DEBUG_OUTPUT:
+                *type      = GL_BOOL;
+                *numParams = 1;
+                return true;
+        }
+    }
+
     // Check for ES3.0+ parameter names which are also exposed as ES2 extensions
     switch (pname)
     {
@@ -1393,6 +1478,13 @@
     if (error.isError())
     {
         mErrors.insert(error.getCode());
+
+        if (!error.getMessage().empty())
+        {
+            auto &debug = mState.getDebug();
+            debug.insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
+                                GL_DEBUG_SEVERITY_HIGH, error.getMessage());
+        }
     }
 }
 
@@ -1740,6 +1832,13 @@
         //mExtensions.sRGB = false;
     }
 
+    // Explicitly enable GL_KHR_debug
+    mExtensions.debug                   = true;
+    mExtensions.maxDebugMessageLength   = 1024;
+    mExtensions.maxDebugLoggedMessages  = 1024;
+    mExtensions.maxDebugGroupStackDepth = 1024;
+    mExtensions.maxLabelLength          = 1024;
+
     // Apply implementation limits
     mCaps.maxVertexAttributes = std::min<GLuint>(mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
     mCaps.maxVertexUniformBlocks = std::min<GLuint>(mCaps.maxVertexUniformBlocks, IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);