Commit 05e08edf by Jeff Gilbert Committed by Commit Bot

Disable skipValidation when context is lost.

Lost no-error contexts should gracefully handle GetProgramiv, etc. Includes test that a lost no-error context doesn't crash on getProgramiv. Firefox bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1601703 Bug: angleproject:4244 Change-Id: I8c37df37e83308ab85ad958df6dab46b0ab348e1 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2003239Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 13c44dfe
...@@ -2777,7 +2777,16 @@ void Context::markContextLost(GraphicsResetStatus status) ...@@ -2777,7 +2777,16 @@ void Context::markContextLost(GraphicsResetStatus status)
mResetStatus = status; mResetStatus = status;
mContextLostForced = true; mContextLostForced = true;
} }
setContextLost();
}
void Context::setContextLost()
{
mContextLost = true; mContextLost = true;
// Stop skipping validation, since many implementation entrypoint assume they can't
// be called when lost, or with null object arguments, etc.
mSkipValidation = false;
} }
GLenum Context::getGraphicsResetStatus() GLenum Context::getGraphicsResetStatus()
...@@ -2786,9 +2795,9 @@ GLenum Context::getGraphicsResetStatus() ...@@ -2786,9 +2795,9 @@ GLenum Context::getGraphicsResetStatus()
// as it will allow us to skip all the calls. // as it will allow us to skip all the calls.
if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT) if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
{ {
if (!mContextLost && mImplementation->getResetStatus() != GraphicsResetStatus::NoError) if (!isContextLost() && mImplementation->getResetStatus() != GraphicsResetStatus::NoError)
{ {
mContextLost = true; setContextLost();
} }
// EXT_robustness, section 2.6: If the reset notification behavior is // EXT_robustness, section 2.6: If the reset notification behavior is
...@@ -2800,14 +2809,14 @@ GLenum Context::getGraphicsResetStatus() ...@@ -2800,14 +2809,14 @@ GLenum Context::getGraphicsResetStatus()
// The GL_EXT_robustness spec says that if a reset is encountered, a reset // The GL_EXT_robustness spec says that if a reset is encountered, a reset
// status should be returned at least once, and GL_NO_ERROR should be returned // status should be returned at least once, and GL_NO_ERROR should be returned
// once the device has finished resetting. // once the device has finished resetting.
if (!mContextLost) if (!isContextLost())
{ {
ASSERT(mResetStatus == GraphicsResetStatus::NoError); ASSERT(mResetStatus == GraphicsResetStatus::NoError);
mResetStatus = mImplementation->getResetStatus(); mResetStatus = mImplementation->getResetStatus();
if (mResetStatus != GraphicsResetStatus::NoError) if (mResetStatus != GraphicsResetStatus::NoError)
{ {
mContextLost = true; setContextLost();
} }
} }
else if (!mContextLostForced && mResetStatus != GraphicsResetStatus::NoError) else if (!mContextLostForced && mResetStatus != GraphicsResetStatus::NoError)
...@@ -5717,7 +5726,7 @@ void Context::framebufferTexture2DMultisample(GLenum target, ...@@ -5717,7 +5726,7 @@ void Context::framebufferTexture2DMultisample(GLenum target,
void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values) void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
{ {
const Sync *syncObject = nullptr; const Sync *syncObject = nullptr;
if (!mContextLost) if (!isContextLost())
{ {
syncObject = getSync(sync); syncObject = getSync(sync);
} }
...@@ -6430,7 +6439,7 @@ void Context::getIntegervRobust(GLenum pname, GLsizei bufSize, GLsizei *length, ...@@ -6430,7 +6439,7 @@ void Context::getIntegervRobust(GLenum pname, GLsizei bufSize, GLsizei *length,
void Context::getProgramiv(ShaderProgramID program, GLenum pname, GLint *params) void Context::getProgramiv(ShaderProgramID program, GLenum pname, GLint *params)
{ {
Program *programObject = nullptr; Program *programObject = nullptr;
if (!mContextLost) if (!isContextLost())
{ {
// Don't resolve link if checking the link completion status. // Don't resolve link if checking the link completion status.
programObject = (pname == GL_COMPLETION_STATUS_KHR ? getProgramNoResolveLink(program) programObject = (pname == GL_COMPLETION_STATUS_KHR ? getProgramNoResolveLink(program)
...@@ -6485,7 +6494,7 @@ void Context::getProgramPipelineInfoLog(ProgramPipelineID pipeline, ...@@ -6485,7 +6494,7 @@ void Context::getProgramPipelineInfoLog(ProgramPipelineID pipeline,
void Context::getShaderiv(ShaderProgramID shader, GLenum pname, GLint *params) void Context::getShaderiv(ShaderProgramID shader, GLenum pname, GLint *params)
{ {
Shader *shaderObject = nullptr; Shader *shaderObject = nullptr;
if (!mContextLost) if (!isContextLost())
{ {
shaderObject = getShader(shader); shaderObject = getShader(shader);
ASSERT(shaderObject); ASSERT(shaderObject);
......
...@@ -453,6 +453,7 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl ...@@ -453,6 +453,7 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl
void markContextLost(GraphicsResetStatus status); void markContextLost(GraphicsResetStatus status);
bool isContextLost() const { return mContextLost; } bool isContextLost() const { return mContextLost; }
void setContextLost();
GLenum getGraphicsResetStrategy() const { return mResetStrategy; } GLenum getGraphicsResetStrategy() const { return mResetStrategy; }
bool isResetNotificationEnabled(); bool isResetNotificationEnabled();
...@@ -512,9 +513,16 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl ...@@ -512,9 +513,16 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl
const TextureCapsMap &getTextureCaps() const { return mState.getTextureCaps(); } const TextureCapsMap &getTextureCaps() const { return mState.getTextureCaps(); }
const Extensions &getExtensions() const { return mState.getExtensions(); } const Extensions &getExtensions() const { return mState.getExtensions(); }
const Limitations &getLimitations() const { return mState.getLimitations(); } const Limitations &getLimitations() const { return mState.getLimitations(); }
bool skipValidation() const { return mSkipValidation; }
bool isGLES1() const; bool isGLES1() const;
bool skipValidation() const
{
// Ensure we don't skip validation when context becomes lost, since implementations
// generally assume a non-lost context, non-null objects, etc.
ASSERT(!isContextLost() || !mSkipValidation);
return mSkipValidation;
}
// Specific methods needed for validation. // Specific methods needed for validation.
bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) const; bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) const;
bool getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams) const; bool getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams) const;
...@@ -680,7 +688,7 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl ...@@ -680,7 +688,7 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl
// Current/lost context flags // Current/lost context flags
bool mHasBeenCurrent; bool mHasBeenCurrent;
bool mContextLost; bool mContextLost; // Set with setContextLost so that we also set mSkipValidation=false.
GraphicsResetStatus mResetStatus; GraphicsResetStatus mResetStatus;
bool mContextLostForced; bool mContextLostForced;
GLenum mResetStrategy; GLenum mResetStrategy;
......
...@@ -103,6 +103,29 @@ TEST_P(ContextLostTest, ParallelCompileReadyQuery) ...@@ -103,6 +103,29 @@ TEST_P(ContextLostTest, ParallelCompileReadyQuery)
EXPECT_GLENUM_EQ(linkStatus, 0xBADF00D); EXPECT_GLENUM_EQ(linkStatus, 0xBADF00D);
} }
class ContextLostSkipValidationTest : public ANGLETest
{
protected:
ContextLostSkipValidationTest()
{
setContextResetStrategy(EGL_LOSE_CONTEXT_ON_RESET_EXT);
setNoErrorEnabled(true);
}
};
// Use GL_CHROMIUM_lose_context to lose a context and verify
TEST_P(ContextLostSkipValidationTest, LostNoErrorGetProgram)
{
ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_CHROMIUM_lose_context"));
GLuint program = glCreateProgram();
glLoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET, GL_INNOCENT_CONTEXT_RESET);
GLint val = 0;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &val); // Should not crash.
}
// Use this to select which configurations (e.g. which renderer, which GLES major version) these // Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against. // tests should be run against.
ANGLE_INSTANTIATE_TEST(ContextLostTest, ANGLE_INSTANTIATE_TEST(ContextLostTest,
...@@ -113,4 +136,12 @@ ANGLE_INSTANTIATE_TEST(ContextLostTest, ...@@ -113,4 +136,12 @@ ANGLE_INSTANTIATE_TEST(ContextLostTest,
ES2_VULKAN(), ES2_VULKAN(),
ES3_VULKAN()); ES3_VULKAN());
ANGLE_INSTANTIATE_TEST(ContextLostSkipValidationTest,
ES2_NULL(),
ES2_D3D9(),
ES2_D3D11(),
ES3_D3D11(),
ES2_VULKAN(),
ES3_VULKAN());
} // namespace angle } // namespace angle
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