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)) {
+ api != EGL_OPENGL_API) {
+ /* The EGL_KHR_create_context spec says:
+ *
+ * 10) Which error should be generated if robust buffer access
+ * or reset notifications are requested under OpenGL ES?
+ *
+ * As per Issue 6, this extension does not support creating
+ * robust contexts for OpenGL ES. This is only supported via
+ * the EGL_EXT_create_context_robustness extension.
+ *
+ * Attempting to use this extension to create robust OpenGL
+ * ES context will generate an EGL_BAD_ATTRIBUTE error. This
+ * specific error is generated because this extension does
+ * not define the EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR
+ * and EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR
+ * bits for OpenGL ES contexts. Thus, use of these bits fall
+ * under condition described by: "If an attribute is
+ * specified that is not meaningful for the client API
+ * type.." in the above specification.
+ *
+ * The spec requires that we emit the error even if the display
+ * supports EGL_EXT_create_context_robustness. To create a robust
+ * GLES context, the *attribute*
+ * EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT must be used, not the
+ * *flag* EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR.
+ */
err = EGL_BAD_ATTRIBUTE;
break;
}
ctx->Flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
break;
+ case EGL_CONTEXT_OPENGL_NO_ERROR_KHR:
+ if (dpy->Version < 14 ||
+ !dpy->Extensions.KHR_create_context_no_error) {
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+
+ /* The KHR_no_error spec only applies against OpenGL 2.0+ and
+ * OpenGL ES 2.0+
+ */
+ if ((api != EGL_OPENGL_API && api != EGL_OPENGL_ES_API) ||
+ ctx->ClientMajorVersion < 2) {
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+
+ /* Canonicalize value to EGL_TRUE/EGL_FALSE definitions */
+ ctx->NoError = !!val;
+ break;
+
+ case EGL_CONTEXT_PRIORITY_LEVEL_IMG:
+ /* The EGL_IMG_context_priority spec says:
+ *
+ * "EGL_CONTEXT_PRIORITY_LEVEL_IMG determines the priority level of
+ * the context to be created. This attribute is a hint, as an
+ * implementation may not support multiple contexts at some
+ * priority levels and system policy may limit access to high
+ * priority contexts to appropriate system privilege level. The
+ * default value for EGL_CONTEXT_PRIORITY_LEVEL_IMG is
+ * EGL_CONTEXT_PRIORITY_MEDIUM_IMG."
+ */
+ {
+ int bit;
+
+ switch (val) {
+ case EGL_CONTEXT_PRIORITY_HIGH_IMG:
+ bit = __EGL_CONTEXT_PRIORITY_HIGH_BIT;
+ break;
+ case EGL_CONTEXT_PRIORITY_MEDIUM_IMG:
+ bit = __EGL_CONTEXT_PRIORITY_MEDIUM_BIT;
+ break;
+ case EGL_CONTEXT_PRIORITY_LOW_IMG:
+ bit = __EGL_CONTEXT_PRIORITY_LOW_BIT;
+ break;
+ default:
+ bit = -1;
+ break;
+ }
+
+ if (bit < 0) {
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+
+ /* "This extension allows an EGLContext to be created with a
+ * priority hint. It is possible that an implementation will not
+ * honour the hint, especially if there are constraints on the
+ * number of high priority contexts available in the system, or
+ * system policy limits access to high priority contexts to
+ * appropriate system privilege level. A query is provided to find
+ * the real priority level assigned to the context after creation."
+ *
+ * We currently assume that the driver applies the priority hint
+ * and filters out any it cannot handle during the screen setup,
+ * e.g. dri2_setup_screen(). As such we can mask any change that
+ * the driver would fail, and ctx->ContextPriority matches the
+ * hint applied to the driver/hardware backend.
+ */
+ if (dpy->Extensions.IMG_context_priority & (1 << bit))
+ ctx->ContextPriority = val;
+
+ break;
+ }
+
+ case EGL_CONTEXT_RELEASE_BEHAVIOR_KHR:
+ if (val == EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR ||
+ val == EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR) {
+ ctx->ReleaseBehavior = val;
+ } else {
+ err = EGL_BAD_ATTRIBUTE;
+ }
+ break;
+
default:
err = EGL_BAD_ATTRIBUTE;
break;
break;
}
+ /* The EGL_KHR_create_context_no_error spec says:
+ *
+ * "BAD_MATCH is generated if the EGL_CONTEXT_OPENGL_NO_ERROR_KHR is TRUE at
+ * the same time as a debug or robustness context is specified."
+ */
+ if (ctx->NoError && (ctx->Flags & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR ||
+ ctx->Flags & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR)) {
+ err = EGL_BAD_MATCH;
+ }
+
if ((ctx->Flags & ~(EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR
| EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR
| EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR)) != 0) {
*
* According to EGL 1.5 Section 3.7:
*
- * "EGL_OPENGL_API and EGL_OPENGL_ES_API are interchangeable for all
- * purposes except eglCreateContext."
+ * "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
const EGLenum api = eglQueryAPI();
EGLint err;
- if (api == EGL_NONE) {
- _eglError(EGL_BAD_MATCH, "eglCreateContext(no client API)");
- return EGL_FALSE;
- }
+ if (api == EGL_NONE)
+ return _eglError(EGL_BAD_MATCH, "eglCreateContext(no client API)");
_eglInitResource(&ctx->Resource, sizeof(*ctx), dpy);
ctx->ClientAPI = api;
ctx->Config = conf;
- ctx->WindowRenderBuffer = EGL_NONE;
ctx->Profile = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
ctx->ClientMajorVersion = 1; /* the default, per EGL spec */
ctx->ClientMinorVersion = 0;
ctx->Flags = 0;
- ctx->Profile = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
ctx->ResetNotificationStrategy = EGL_NO_RESET_NOTIFICATION_KHR;
+ ctx->ContextPriority = EGL_CONTEXT_PRIORITY_MEDIUM_IMG;
+ ctx->ReleaseBehavior = EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR;
err = _eglParseContextAttribList(ctx, dpy, attrib_list);
if (err == EGL_SUCCESS && ctx->Config) {
_eglQueryContextRenderBuffer(_EGLContext *ctx)
{
_EGLSurface *surf = ctx->DrawSurface;
- EGLint rb;
+ /* From the EGL 1.5 spec:
+ *
+ * - If the context is not bound to a surface, then EGL_NONE will be
+ * returned.
+ */
if (!surf)
return EGL_NONE;
- if (surf->Type == EGL_WINDOW_BIT && ctx->WindowRenderBuffer != EGL_NONE)
- rb = ctx->WindowRenderBuffer;
- else
- rb = surf->RenderBuffer;
- return rb;
+
+ switch (surf->Type) {
+ default:
+ unreachable("bad EGLSurface type");
+ case EGL_PIXMAP_BIT:
+ /* - If the context is bound to a pixmap surface, then EGL_SINGLE_BUFFER
+ * will be returned.
+ */
+ return EGL_SINGLE_BUFFER;
+ case EGL_PBUFFER_BIT:
+ /* - If the context is bound to a pbuffer surface, then EGL_BACK_BUFFER
+ * will be returned.
+ */
+ return EGL_BACK_BUFFER;
+ case EGL_WINDOW_BIT:
+ /* - If the context is bound to a window surface, then either
+ * EGL_BACK_BUFFER or EGL_SINGLE_BUFFER may be returned. The value
+ * returned depends on both the buffer requested by the setting of the
+ * EGL_RENDER_BUFFER property of the surface [...], and on the client
+ * API (not all client APIs support single-buffer Rendering to window
+ * surfaces). Some client APIs allow control of whether rendering goes
+ * to the front or back buffer. This client API-specific choice is not
+ * reflected in the returned value, which only describes the buffer
+ * that will be rendered to by default if not overridden by the client
+ * API.
+ */
+ return surf->ActiveRenderBuffer;
+ }
}
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;
case EGL_RENDER_BUFFER:
*value = _eglQueryContextRenderBuffer(c);
break;
+ case EGL_CONTEXT_PRIORITY_LEVEL_IMG:
+ *value = c->ContextPriority;
+ break;
default:
return _eglError(EGL_BAD_ATTRIBUTE, "eglQueryContext");
}
*
* Note that the context may be NULL.
*/
-static _EGLContext *
+_EGLContext *
_eglBindContextToThread(_EGLContext *ctx, _EGLThreadInfo *t)
{
_EGLContext *oldCtx;
(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 */