switch (attr) {
case EGL_CONTEXT_CLIENT_VERSION:
+ /* The EGL 1.4 spec says:
+ *
+ * "attribute EGL_CONTEXT_CLIENT_VERSION is only valid when the
+ * current rendering API is EGL_OPENGL_ES_API"
+ *
+ * The EGL_KHR_create_context spec says:
+ *
+ * "EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098
+ * (this token is an alias for EGL_CONTEXT_CLIENT_VERSION)"
+ *
+ * "The values for attributes EGL_CONTEXT_MAJOR_VERSION_KHR and
+ * EGL_CONTEXT_MINOR_VERSION_KHR specify the requested client API
+ * version. They are only meaningful for OpenGL and OpenGL ES
+ * contexts, and specifying them for other types of contexts will
+ * generate an error."
+ */
+ if ((api != EGL_OPENGL_ES_API &&
+ (!dpy->Extensions.KHR_create_context || api != EGL_OPENGL_API))) {
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+
ctx->ClientMajorVersion = val;
break;
case EGL_CONTEXT_MINOR_VERSION_KHR:
- if (!dpy->Extensions.KHR_create_context) {
+ /* The EGL_KHR_create_context spec says:
+ *
+ * "The values for attributes EGL_CONTEXT_MAJOR_VERSION_KHR and
+ * EGL_CONTEXT_MINOR_VERSION_KHR specify the requested client API
+ * version. They are only meaningful for OpenGL and OpenGL ES
+ * contexts, and specifying them for other types of contexts will
+ * generate an error."
+ */
+ if (!dpy->Extensions.KHR_create_context ||
+ (api != EGL_OPENGL_ES_API && api != EGL_OPENGL_API)) {
err = EGL_BAD_ATTRIBUTE;
break;
}
/* The EGL_KHR_create_context spec says:
*
- * "Flags are only defined for OpenGL context creation, and
- * specifying a flags value other than zero for other types of
- * contexts, including OpenGL ES contexts, will generate an
- * error."
+ * "If the EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR flag bit is set in
+ * EGL_CONTEXT_FLAGS_KHR, then a <debug context> will be created.
+ * [...]
+ * In some cases a debug context may be identical to a non-debug
+ * context. This bit is supported for OpenGL and OpenGL ES
+ * contexts."
*/
- if (api != EGL_OPENGL_API && val != 0) {
+ if ((val & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) &&
+ (api != EGL_OPENGL_API && api != EGL_OPENGL_ES_API)) {
err = EGL_BAD_ATTRIBUTE;
break;
}
- ctx->Flags = val;
+ /* The EGL_KHR_create_context spec says:
+ *
+ * "If the EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR flag bit
+ * is set in EGL_CONTEXT_FLAGS_KHR, then a <forward-compatible>
+ * context will be created. Forward-compatible contexts are
+ * defined only for OpenGL versions 3.0 and later. They must not
+ * support functionality marked as <deprecated> by that version of
+ * the API, while a non-forward-compatible context must support
+ * all functionality in that version, deprecated or not. This bit
+ * is supported for OpenGL contexts, and requesting a
+ * forward-compatible context for OpenGL versions less than 3.0
+ * will generate an error."
+ */
+ if ((val & EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR) &&
+ (api != EGL_OPENGL_API || ctx->ClientMajorVersion < 3)) {
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+
+ /* The EGL_KHR_create_context_spec says:
+ *
+ * "If the EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR bit is set in
+ * EGL_CONTEXT_FLAGS_KHR, then a context supporting <robust buffer
+ * access> will be created. Robust buffer access is defined in the
+ * GL_ARB_robustness extension specification, and the resulting
+ * context must also support either the GL_ARB_robustness
+ * extension, or a version of OpenGL incorporating equivalent
+ * functionality. This bit is supported for OpenGL contexts.
+ */
+ if ((val & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) &&
+ (api != EGL_OPENGL_API ||
+ !dpy->Extensions.EXT_create_context_robustness)) {
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+
+ ctx->Flags |= val;
break;
case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR:
break;
}
- ctx->Flags = EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR;
+ if (val == EGL_TRUE)
+ ctx->Flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR;
+ break;
+
+ case EGL_CONTEXT_OPENGL_ROBUST_ACCESS:
+ if (dpy->Version < 15) {
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+
+ if (val == EGL_TRUE)
+ ctx->Flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR;
+ break;
+
+ case EGL_CONTEXT_OPENGL_DEBUG:
+ if (dpy->Version < 15) {
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+
+ if (val == EGL_TRUE)
+ ctx->Flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
+ break;
+
+ case EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE:
+ if (dpy->Version < 15) {
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+
+ if (val == EGL_TRUE)
+ ctx->Flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
break;
default:
break;
case 3:
- default:
/* Don't put additional version checks here. We don't know that
* there won't be versions > 3.0.
*/
break;
+
+ default:
+ err = EGL_BAD_MATCH;
+ break;
}
}
/**
* Initialize the given _EGLContext object to defaults and/or the values
* in the attrib_list.
+ *
+ * According to EGL 1.5 Section 3.7:
+ *
+ * "EGL_OPENGL_API and EGL_OPENGL_ES_API are interchangeable for all
+ * purposes except eglCreateContext."
+ *
+ * And since we only support GL and GLES, this is the only place where the
+ * bound API matters at all. We look up the current API from the current
+ * thread, and stash that in the context we're initializing. Our caller is
+ * responsible for determining whether that's an API it supports.
*/
EGLBoolean
_eglInitContext(_EGLContext *ctx, _EGLDisplay *dpy, _EGLConfig *conf,
switch (attribute) {
case EGL_CONFIG_ID:
- if (!c->Config)
- return _eglError(EGL_BAD_ATTRIBUTE, "eglQueryContext");
- *value = c->Config->ConfigID;
+ /*
+ * From EGL_KHR_no_config_context:
+ *
+ * "Querying EGL_CONFIG_ID returns the ID of the EGLConfig with
+ * respect to which the context was created, or zero if created
+ * without respect to an EGLConfig."
+ */
+ *value = c->Config ? c->Config->ConfigID : 0;
break;
case EGL_CONTEXT_CLIENT_VERSION:
*value = c->ClientMajorVersion;
static _EGLContext *
_eglBindContextToThread(_EGLContext *ctx, _EGLThreadInfo *t)
{
- EGLint apiIndex;
_EGLContext *oldCtx;
- apiIndex = (ctx) ?
- _eglConvertApiToIndex(ctx->ClientAPI) : t->CurrentAPIIndex;
-
- oldCtx = t->CurrentContexts[apiIndex];
+ oldCtx = t->CurrentContext;
if (ctx != oldCtx) {
if (oldCtx)
oldCtx->Binding = NULL;
if (ctx)
ctx->Binding = t;
- t->CurrentContexts[apiIndex] = ctx;
+ t->CurrentContext = ctx;
}
return oldCtx;
{
_EGLThreadInfo *t = _eglGetCurrentThread();
_EGLDisplay *dpy;
- EGLint conflict_api;
if (_eglIsCurrentThreadDummy())
return _eglError(EGL_BAD_ALLOC, "eglMakeCurrent");
if (ctx->Binding && ctx->Binding != t)
return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
if (draw && draw->CurrentContext && draw->CurrentContext != ctx) {
- if (draw->CurrentContext->Binding != t ||
- draw->CurrentContext->ClientAPI != ctx->ClientAPI)
+ if (draw->CurrentContext->Binding != t)
return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
}
if (read && read->CurrentContext && read->CurrentContext != ctx) {
- if (read->CurrentContext->Binding != t ||
- read->CurrentContext->ClientAPI != ctx->ClientAPI)
+ if (read->CurrentContext->Binding != t)
return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
}
(read && read->Config != ctx->Config))
return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
} else {
- /* Otherwise we must be using the EGL_MESA_configless_context
+ /* Otherwise we must be using the EGL_KHR_no_config_context
* extension */
- assert(dpy->Extensions.MESA_configless_context);
+ assert(dpy->Extensions.KHR_no_config_context);
/* The extension doesn't permit binding draw and read buffers with
* differing contexts */
return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
}
- switch (ctx->ClientAPI) {
- /* OpenGL and OpenGL ES are conflicting */
- case EGL_OPENGL_ES_API:
- conflict_api = EGL_OPENGL_API;
- break;
- case EGL_OPENGL_API:
- conflict_api = EGL_OPENGL_ES_API;
- break;
- default:
- conflict_api = -1;
- break;
- }
-
- if (conflict_api >= 0 && _eglGetAPIContext(conflict_api))
- return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
-
return EGL_TRUE;
}