Add gl::ErrorSet and angle::Result.

gl::ErrorSet can handle errors and is accessible from ContextImpl.
It allows the implementation to mutate the error set without using
the gl::Context directly.

angle::Result is the faster POD return value class. It should generate
optimal code. It can also be used seamlessly with the ANGLE_TRY macro.

Also introduces an internal enum as a workaround for generating and
consuming errors in the back-end. When the internal enum is used as
an error return value the error is not consumed in the front-end. This
is a temporary workaround only.

Bug: angleproject:2491
Bug: angleproject:2713
Change-Id: I6cbdaadd075ccbdf241844cbcbc4ed5c3be40a8b
Reviewed-on: https://chromium-review.googlesource.com/1133200
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Frank Henigman <fjhenigman@chromium.org>
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index a263510..80a90d7 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -330,6 +330,7 @@
                memoryProgramCache != nullptr),
       mConfig(config),
       mClientType(EGL_OPENGL_ES_API),
+      mErrors(this),
       mHasBeenCurrent(false),
       mContextLost(false),
       mResetStatus(GL_NO_ERROR),
@@ -2541,21 +2542,9 @@
     UNIMPLEMENTED();
 }
 
-void Context::handleError(const Error &error) const
+void Context::handleError(const Error &error)
 {
-    if (ANGLE_UNLIKELY(error.isError()))
-    {
-        GLenum code = error.getCode();
-        mErrors.insert(code);
-        if (code == GL_OUT_OF_MEMORY && getWorkarounds().loseContextOnOutOfMemory)
-        {
-            markContextLost();
-        }
-
-        ASSERT(!error.getMessage().empty());
-        mGLState.getDebug().insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, error.getID(),
-                                          GL_DEBUG_SEVERITY_HIGH, error.getMessage());
-    }
+    mErrors.handleError(error);
 }
 
 // Get one of the recorded errors and clear its flag, if any.
@@ -2568,14 +2557,12 @@
     }
     else
     {
-        GLenum error = *mErrors.begin();
-        mErrors.erase(mErrors.begin());
-        return error;
+        return mErrors.popError();
     }
 }
 
 // NOTE: this function should not assume that this context is current!
-void Context::markContextLost() const
+void Context::markContextLost()
 {
     if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
     {
@@ -7542,4 +7529,48 @@
     mGLState.setMaxShaderCompilerThreads(count);
 }
 
+// ErrorSet implementation.
+ErrorSet::ErrorSet(Context *context) : mContext(context)
+{
+}
+
+ErrorSet::~ErrorSet() = default;
+
+void ErrorSet::handleError(const Error &error)
+{
+    // This internal enum is used to filter internal errors that are already handled.
+    // TODO(jmadill): Remove this when refactor is done. http://anglebug.com/2491
+    if (error.getCode() == GL_INTERNAL_ERROR_ANGLEX)
+    {
+        return;
+    }
+
+    if (ANGLE_UNLIKELY(error.isError()))
+    {
+        GLenum code = error.getCode();
+        mErrors.insert(code);
+        if (code == GL_OUT_OF_MEMORY && mContext->getWorkarounds().loseContextOnOutOfMemory)
+        {
+            mContext->markContextLost();
+        }
+
+        ASSERT(!error.getMessage().empty());
+        mContext->getGLState().getDebug().insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR,
+                                                        error.getID(), GL_DEBUG_SEVERITY_HIGH,
+                                                        error.getMessage());
+    }
+}
+
+bool ErrorSet::empty() const
+{
+    return mErrors.empty();
+}
+
+GLenum ErrorSet::popError()
+{
+    ASSERT(!empty());
+    GLenum error = *mErrors.begin();
+    mErrors.erase(mErrors.begin());
+    return error;
+}
 }  // namespace gl