Implemented context creation with reset notification.

TRAC #18607 Signed-off-by: Daniel Koch Authors: Shannon Woods, Nicolas Capens git-svn-id: https://angleproject.googlecode.com/svn/trunk@848 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 17f548cb
......@@ -318,6 +318,14 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay
#define EGL_COVERAGE_SAMPLE_RESOLVE_NONE_NV 0x3133
#endif
#ifndef EGL_EXT_create_context_robustness
#define EGL_EXT_create_context_robustness 1
#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT 0x30BF
#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT 0x3138
#define EGL_NO_RESET_NOTIFICATION_EXT 0x31BE
#define EGL_LOSE_CONTEXT_ON_RESET_EXT 0x31BF
#endif
#if KHRONOS_SUPPORT_INT64 /* EGLTimeKHR requires 64-bit uint support */
#ifndef EGL_NV_system_time
#define EGL_NV_system_time 1
......
......@@ -330,6 +330,10 @@ typedef void* GLeglImageOES;
#define GL_GUILTY_CONTEXT_RESET_EXT 0x8253
#define GL_INNOCENT_CONTEXT_RESET_EXT 0x8254
#define GL_UNKNOWN_CONTEXT_RESET_EXT 0x8255
#define GL_CONTEXT_ROBUST_ACCESS_EXT 0x90F3
#define GL_RESET_NOTIFICATION_STRATEGY_EXT 0x8256
#define GL_LOSE_CONTEXT_ON_RESET_EXT 0x8252
#define GL_NO_RESET_NOTIFICATION_EXT 0x8261
#endif
/*------------------------------------------------------------------------*
......
......@@ -667,7 +667,7 @@ EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle,
return success(surface);
}
EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *shareContext)
EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *shareContext, bool notifyResets, bool robustAccess)
{
if (!mDevice)
{
......@@ -684,7 +684,7 @@ EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *sha
const egl::Config *config = mConfigSet.get(configHandle);
gl::Context *context = glCreateContext(config, shareContext);
gl::Context *context = glCreateContext(config, shareContext, notifyResets, robustAccess);
mContextSet.insert(context);
mDeviceLost = false;
......
......@@ -44,7 +44,7 @@ class Display
EGLSurface createWindowSurface(HWND window, EGLConfig config, const EGLint *attribList);
EGLSurface createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList);
EGLContext createContext(EGLConfig configHandle, const gl::Context *shareContext);
EGLContext createContext(EGLConfig configHandle, const gl::Context *shareContext, bool notifyResets, bool robustAccess);
void destroySurface(egl::Surface *surface);
void destroyContext(gl::Context *context);
......
......@@ -814,16 +814,34 @@ EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLConte
{
// Get the requested client version (default is 1) and check it is two.
EGLint client_version = 1;
bool reset_notification = false;
bool robust_access = false;
if (attrib_list)
{
for (const EGLint* attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)
{
if (attribute[0] == EGL_CONTEXT_CLIENT_VERSION)
switch (attribute[0])
{
case EGL_CONTEXT_CLIENT_VERSION:
client_version = attribute[1];
}
else
{
break;
case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
if (attribute[1] == EGL_TRUE)
{
return error(EGL_BAD_CONFIG, EGL_NO_CONTEXT); // Unimplemented
robust_access = true;
}
else if (attribute[1] != EGL_FALSE)
return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
break;
case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
if (attribute[1] == EGL_LOSE_CONTEXT_ON_RESET_EXT)
reset_notification = true;
else if (attribute[1] != EGL_NO_RESET_NOTIFICATION_EXT)
return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
break;
default:
return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
}
}
......@@ -834,6 +852,11 @@ EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLConte
return error(EGL_BAD_CONFIG, EGL_NO_CONTEXT);
}
if (share_context && static_cast<gl::Context*>(share_context)->isResetNotificationEnabled() != reset_notification)
{
return error(EGL_BAD_MATCH, EGL_NO_CONTEXT);
}
egl::Display *display = static_cast<egl::Display*>(dpy);
if (!validateConfig(display, config))
......@@ -841,7 +864,7 @@ EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLConte
return EGL_NO_CONTEXT;
}
EGLContext context = display->createContext(config, static_cast<gl::Context*>(share_context));
EGLContext context = display->createContext(config, static_cast<gl::Context*>(share_context), reset_notification, robust_access);
return success(context);
}
......
......@@ -38,8 +38,10 @@ namespace
namespace gl
{
Context::Context(const egl::Config *config, const gl::Context *shareContext) : mConfig(config)
Context::Context(const egl::Config *config, const gl::Context *shareContext, bool notifyResets, bool robustAccess) : mConfig(config)
{
ASSERT(robustAccess == false); // Unimplemented
mDisplay = NULL;
mDevice = NULL;
......@@ -160,6 +162,8 @@ Context::Context(const egl::Config *config, const gl::Context *shareContext) : m
mHasBeenCurrent = false;
mContextLost = false;
mResetStatus = GL_NO_ERROR;
mResetStrategy = (notifyResets ? GL_LOSE_CONTEXT_ON_RESET_EXT : GL_NO_RESET_NOTIFICATION_EXT);
mRobustAccess = robustAccess;
mSupportsDXT1Textures = false;
mSupportsDXT3Textures = false;
......@@ -393,7 +397,8 @@ void Context::markAllStateDirty()
void Context::markContextLost()
{
mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
mContextLost = true;
}
......@@ -1171,24 +1176,25 @@ bool Context::getBooleanv(GLenum pname, GLboolean *params)
{
switch (pname)
{
case GL_SHADER_COMPILER: *params = GL_TRUE; break;
case GL_SAMPLE_COVERAGE_INVERT: *params = mState.sampleCoverageInvert; break;
case GL_DEPTH_WRITEMASK: *params = mState.depthMask; break;
case GL_SHADER_COMPILER: *params = GL_TRUE; break;
case GL_SAMPLE_COVERAGE_INVERT: *params = mState.sampleCoverageInvert; break;
case GL_DEPTH_WRITEMASK: *params = mState.depthMask; break;
case GL_COLOR_WRITEMASK:
params[0] = mState.colorMaskRed;
params[1] = mState.colorMaskGreen;
params[2] = mState.colorMaskBlue;
params[3] = mState.colorMaskAlpha;
break;
case GL_CULL_FACE: *params = mState.cullFace; break;
case GL_POLYGON_OFFSET_FILL: *params = mState.polygonOffsetFill; break;
case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverage; break;
case GL_SAMPLE_COVERAGE: *params = mState.sampleCoverage; break;
case GL_SCISSOR_TEST: *params = mState.scissorTest; break;
case GL_STENCIL_TEST: *params = mState.stencilTest; break;
case GL_DEPTH_TEST: *params = mState.depthTest; break;
case GL_BLEND: *params = mState.blend; break;
case GL_DITHER: *params = mState.dither; break;
case GL_CULL_FACE: *params = mState.cullFace; break;
case GL_POLYGON_OFFSET_FILL: *params = mState.polygonOffsetFill; break;
case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverage; break;
case GL_SAMPLE_COVERAGE: *params = mState.sampleCoverage; break;
case GL_SCISSOR_TEST: *params = mState.scissorTest; break;
case GL_STENCIL_TEST: *params = mState.stencilTest; break;
case GL_DEPTH_TEST: *params = mState.depthTest; break;
case GL_BLEND: *params = mState.blend; break;
case GL_DITHER: *params = mState.dither; break;
case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
default:
return false;
}
......@@ -1458,6 +1464,9 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
*params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].id();
}
break;
case GL_RESET_NOTIFICATION_STRATEGY_EXT:
*params = mResetStrategy;
break;
default:
return false;
}
......@@ -1547,6 +1556,7 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu
case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
case GL_TEXTURE_BINDING_2D:
case GL_TEXTURE_BINDING_CUBE_MAP:
case GL_RESET_NOTIFICATION_STRATEGY_EXT:
{
*type = GL_INT;
*numParams = 1;
......@@ -1590,6 +1600,7 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu
case GL_DEPTH_TEST:
case GL_BLEND:
case GL_DITHER:
case GL_CONTEXT_ROBUST_ACCESS_EXT:
{
*type = GL_BOOL;
*numParams = 1;
......@@ -3030,6 +3041,11 @@ GLenum Context::getResetStatus()
return status;
}
bool Context::isResetNotificationEnabled()
{
return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
}
bool Context::supportsShaderModel3() const
{
return mSupportsShaderModel3;
......@@ -3841,9 +3857,9 @@ void VertexDeclarationCache::markStateDirty()
extern "C"
{
gl::Context *glCreateContext(const egl::Config *config, const gl::Context *shareContext)
gl::Context *glCreateContext(const egl::Config *config, const gl::Context *shareContext, bool notifyResets, bool robustAccess)
{
return new gl::Context(config, shareContext);
return new gl::Context(config, shareContext, notifyResets, robustAccess);
}
void glDestroyContext(gl::Context *context)
......
......@@ -258,7 +258,7 @@ class VertexDeclarationCache
class Context
{
public:
Context(const egl::Config *config, const gl::Context *shareContext);
Context(const egl::Config *config, const gl::Context *shareContext, bool notifyResets, bool robustAccess);
~Context();
......@@ -438,6 +438,7 @@ class Context
GLenum getError();
GLenum getResetStatus();
virtual bool isResetNotificationEnabled();
bool supportsShaderModel3() const;
int getMaximumVaryingVectors() const;
......@@ -539,6 +540,8 @@ class Context
bool mHasBeenCurrent;
bool mContextLost;
GLenum mResetStatus;
GLenum mResetStrategy;
bool mRobustAccess;
unsigned int mAppliedTextureSerialPS[MAX_TEXTURE_IMAGE_UNITS];
unsigned int mAppliedTextureSerialVS[MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF];
......@@ -607,7 +610,7 @@ class Context
extern "C"
{
// Exported functions for use by EGL
gl::Context *glCreateContext(const egl::Config *config, const gl::Context *shareContext);
gl::Context *glCreateContext(const egl::Config *config, const gl::Context *shareContext, bool notifyResets, bool robustAccess);
void glDestroyContext(gl::Context *context);
void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface);
gl::Context *glGetCurrentContext();
......
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