зеркало из https://github.com/AvaloniaUI/angle.git
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/+/2003239 Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
This commit is contained in:
Родитель
13c44dfeb0
Коммит
05e08edf70
|
@ -2777,7 +2777,16 @@ void Context::markContextLost(GraphicsResetStatus status)
|
|||
mResetStatus = status;
|
||||
mContextLostForced = true;
|
||||
}
|
||||
setContextLost();
|
||||
}
|
||||
|
||||
void Context::setContextLost()
|
||||
{
|
||||
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()
|
||||
|
@ -2786,9 +2795,9 @@ GLenum Context::getGraphicsResetStatus()
|
|||
// as it will allow us to skip all the calls.
|
||||
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
|
||||
|
@ -2800,14 +2809,14 @@ GLenum Context::getGraphicsResetStatus()
|
|||
// 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
|
||||
// once the device has finished resetting.
|
||||
if (!mContextLost)
|
||||
if (!isContextLost())
|
||||
{
|
||||
ASSERT(mResetStatus == GraphicsResetStatus::NoError);
|
||||
mResetStatus = mImplementation->getResetStatus();
|
||||
|
||||
if (mResetStatus != GraphicsResetStatus::NoError)
|
||||
{
|
||||
mContextLost = true;
|
||||
setContextLost();
|
||||
}
|
||||
}
|
||||
else if (!mContextLostForced && mResetStatus != GraphicsResetStatus::NoError)
|
||||
|
@ -5717,7 +5726,7 @@ void Context::framebufferTexture2DMultisample(GLenum target,
|
|||
void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
|
||||
{
|
||||
const Sync *syncObject = nullptr;
|
||||
if (!mContextLost)
|
||||
if (!isContextLost())
|
||||
{
|
||||
syncObject = getSync(sync);
|
||||
}
|
||||
|
@ -6430,7 +6439,7 @@ void Context::getIntegervRobust(GLenum pname, GLsizei bufSize, GLsizei *length,
|
|||
void Context::getProgramiv(ShaderProgramID program, GLenum pname, GLint *params)
|
||||
{
|
||||
Program *programObject = nullptr;
|
||||
if (!mContextLost)
|
||||
if (!isContextLost())
|
||||
{
|
||||
// Don't resolve link if checking the link completion status.
|
||||
programObject = (pname == GL_COMPLETION_STATUS_KHR ? getProgramNoResolveLink(program)
|
||||
|
@ -6485,7 +6494,7 @@ void Context::getProgramPipelineInfoLog(ProgramPipelineID pipeline,
|
|||
void Context::getShaderiv(ShaderProgramID shader, GLenum pname, GLint *params)
|
||||
{
|
||||
Shader *shaderObject = nullptr;
|
||||
if (!mContextLost)
|
||||
if (!isContextLost())
|
||||
{
|
||||
shaderObject = getShader(shader);
|
||||
ASSERT(shaderObject);
|
||||
|
|
|
@ -453,6 +453,7 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl
|
|||
void markContextLost(GraphicsResetStatus status);
|
||||
|
||||
bool isContextLost() const { return mContextLost; }
|
||||
void setContextLost();
|
||||
|
||||
GLenum getGraphicsResetStrategy() const { return mResetStrategy; }
|
||||
bool isResetNotificationEnabled();
|
||||
|
@ -512,9 +513,16 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl
|
|||
const TextureCapsMap &getTextureCaps() const { return mState.getTextureCaps(); }
|
||||
const Extensions &getExtensions() const { return mState.getExtensions(); }
|
||||
const Limitations &getLimitations() const { return mState.getLimitations(); }
|
||||
bool skipValidation() const { return mSkipValidation; }
|
||||
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.
|
||||
bool getQueryParameterInfo(GLenum pname, 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
|
|||
|
||||
// Current/lost context flags
|
||||
bool mHasBeenCurrent;
|
||||
bool mContextLost;
|
||||
bool mContextLost; // Set with setContextLost so that we also set mSkipValidation=false.
|
||||
GraphicsResetStatus mResetStatus;
|
||||
bool mContextLostForced;
|
||||
GLenum mResetStrategy;
|
||||
|
|
|
@ -103,6 +103,29 @@ TEST_P(ContextLostTest, ParallelCompileReadyQuery)
|
|||
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
|
||||
// tests should be run against.
|
||||
ANGLE_INSTANTIATE_TEST(ContextLostTest,
|
||||
|
@ -113,4 +136,12 @@ ANGLE_INSTANTIATE_TEST(ContextLostTest,
|
|||
ES2_VULKAN(),
|
||||
ES3_VULKAN());
|
||||
|
||||
ANGLE_INSTANTIATE_TEST(ContextLostSkipValidationTest,
|
||||
ES2_NULL(),
|
||||
ES2_D3D9(),
|
||||
ES2_D3D11(),
|
||||
ES3_D3D11(),
|
||||
ES2_VULKAN(),
|
||||
ES3_VULKAN());
|
||||
|
||||
} // namespace angle
|
||||
|
|
Загрузка…
Ссылка в новой задаче