Commit 6b873dd7 by Jamie Madill Committed by Commit Bot

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: 's avatarFrank Henigman <fjhenigman@chromium.org>
parent 0cc29136
......@@ -253,6 +253,10 @@ std::string ToString(const T &value)
// TODO(jmadill): Clean this up at some point.
#define EGL_PLATFORM_ANGLE_PLATFORM_METHODS_ANGLEX 0x9999
// 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
#define GL_INTERNAL_ERROR_ANGLEX 0x6AEE
#define ANGLE_TRY_CHECKED_MATH(result) \
if (!result) \
{ \
......
......@@ -330,6 +330,7 @@ Context::Context(rx::EGLImplFactory *implFactory,
memoryProgramCache != nullptr),
mConfig(config),
mClientType(EGL_OPENGL_ES_API),
mErrors(this),
mHasBeenCurrent(false),
mContextLost(false),
mResetStatus(GL_NO_ERROR),
......@@ -2541,21 +2542,9 @@ void Context::getProgramInterfaceivRobust(GLuint program,
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 @@ GLenum Context::getError()
}
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 @@ void Context::maxShaderCompilerThreads(GLuint count)
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
......@@ -63,6 +63,21 @@ class TransformFeedback;
class VertexArray;
struct VertexAttribute;
class ErrorSet : angle::NonCopyable
{
public:
explicit ErrorSet(Context *context);
~ErrorSet();
void handleError(const Error &error);
bool empty() const;
GLenum popError();
private:
Context *mContext;
std::set<GLenum> mErrors;
};
class Context final : public egl::LabeledObject, angle::NonCopyable
{
public:
......@@ -1380,10 +1395,10 @@ class Context final : public egl::LabeledObject, angle::NonCopyable
void framebufferTexture(GLenum target, GLenum attachment, GLuint texture, GLint level);
// Consumes the error.
void handleError(const Error &error) const;
void handleError(const Error &error);
GLenum getError();
void markContextLost() const;
void markContextLost();
bool isContextLost() const;
GLenum getGraphicsResetStatus();
bool isResetNotificationEnabled();
......@@ -1574,17 +1589,16 @@ class Context final : public egl::LabeledObject, angle::NonCopyable
std::vector<const char *> mRequestableExtensionStrings;
// Recorded errors
typedef std::set<GLenum> ErrorSet;
mutable ErrorSet mErrors;
ErrorSet mErrors;
// GLES1 renderer state
std::unique_ptr<GLES1Renderer> mGLES1Renderer;
// Current/lost context flags
bool mHasBeenCurrent;
mutable bool mContextLost;
mutable GLenum mResetStatus;
mutable bool mContextLostForced;
bool mContextLost;
GLenum mResetStatus;
bool mContextLostForced;
GLenum mResetStrategy;
const bool mRobustAccess;
const bool mSurfacelessSupported;
......
......@@ -26,7 +26,6 @@ std::unique_ptr<std::string> EmplaceErrorString(std::string &&message)
namespace gl
{
Error::Error(GLenum errorCode, std::string &&message)
: mCode(errorCode), mID(errorCode), mMessage(EmplaceErrorString(std::move(message)))
{
......@@ -108,3 +107,19 @@ std::ostream &operator<<(std::ostream &os, const Error &err)
}
} // namespace egl
// angle::Result Implementation.
namespace angle
{
Result::operator gl::Error() const
{
if (mStop)
{
return gl::Error(GL_INTERNAL_ERROR_ANGLEX);
}
else
{
return gl::NoError();
}
}
} // namespace angle
......@@ -262,6 +262,35 @@ inline Error NoError()
#undef ANGLE_CONCAT2
#undef ANGLE_CONCAT1
namespace angle
{
// Result signals if calling code should continue running or early exit. A value of Stop() can
// either indicate and Error or a non-Error early exit condition such as a detected no-op.
class ANGLE_NO_DISCARD Result
{
public:
// TODO(jmadill): Rename when refactor is complete. http://anglebug.com/2491
bool isError() const { return mStop; }
static Result Stop() { return Result(true); }
static Result Continue() { return Result(false); }
// TODO(jmadill): Remove when refactor is complete. http://anglebug.com/2491
operator gl::Error() const;
// TODO(jmadill): Remove when refactor is complete. http://anglebug.com/2491
template <typename T>
operator gl::ErrorOrResult<T>() const
{
return operator gl::Error();
}
private:
Result(bool stop) : mStop(stop) {}
bool mStop;
};
} // namespace angle
#include "Error.inl"
#endif // LIBANGLE_ERROR_H_
......@@ -1024,7 +1024,8 @@ GLenum Framebuffer::checkStatus(const Context *context)
Error err = syncState(context);
if (err.isError())
{
context->handleError(err);
// TODO(jmadill): Remove when refactor complete. http://anglebug.com/2491
const_cast<Context *>(context)->handleError(err);
return GetDefaultReturnValue<EntryPoint::CheckFramebufferStatus, GLenum>();
}
if (!mImpl->checkStatus(context))
......
......@@ -9,11 +9,13 @@
#include "libANGLE/renderer/ContextImpl.h"
#include "libANGLE/Context.h"
namespace rx
{
ContextImpl::ContextImpl(const gl::ContextState &state)
: mState(state), mMemoryProgramCache(nullptr)
: mState(state), mMemoryProgramCache(nullptr), mErrors(nullptr)
{
}
......@@ -116,4 +118,13 @@ void ContextImpl::setMemoryProgramCache(gl::MemoryProgramCache *memoryProgramCac
mMemoryProgramCache = memoryProgramCache;
}
void ContextImpl::setErrorSet(gl::ErrorSet *errorSet)
{
mErrors = errorSet;
}
void ContextImpl::handleError(const gl::Error &error)
{
mErrors->handleError(error);
}
} // namespace rx
......@@ -18,6 +18,7 @@
namespace gl
{
class ErrorSet;
class MemoryProgramCache;
class Path;
struct Workarounds;
......@@ -181,9 +182,15 @@ class ContextImpl : public GLImplFactory
// on draw calls we can store the refreshed shaders in the cache.
void setMemoryProgramCache(gl::MemoryProgramCache *memoryProgramCache);
// TODO(jmadill): Move init into the constructor. http://anglebug.com/2491
void setErrorSet(gl::ErrorSet *errorSet);
void handleError(const gl::Error &error);
protected:
const gl::ContextState &mState;
gl::MemoryProgramCache *mMemoryProgramCache;
gl::ErrorSet *mErrors;
};
} // namespace rx
......
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