2011-07-02 09:57:30 +01:00
|
|
|
/**************************************************************************
|
|
|
|
*
|
s/Tungsten Graphics/VMware/
Tungsten Graphics Inc. was acquired by VMware Inc. in 2008. Leaving the
old copyright name is creating unnecessary confusion, hence this change.
This was the sed script I used:
$ cat tg2vmw.sed
# Run as:
#
# git reset --hard HEAD && find include scons src -type f -not -name 'sed*' -print0 | xargs -0 sed -i -f tg2vmw.sed
#
# Rename copyrights
s/Tungsten Gra\(ph\|hp\)ics,\? [iI]nc\.\?\(, Cedar Park\)\?\(, Austin\)\?\(, \(Texas\|TX\)\)\?\.\?/VMware, Inc./g
/Copyright/s/Tungsten Graphics\(,\? [iI]nc\.\)\?\(, Cedar Park\)\?\(, Austin\)\?\(, \(Texas\|TX\)\)\?\.\?/VMware, Inc./
s/TUNGSTEN GRAPHICS/VMWARE/g
# Rename emails
s/alanh@tungstengraphics.com/alanh@vmware.com/
s/jens@tungstengraphics.com/jowen@vmware.com/g
s/jrfonseca-at-tungstengraphics-dot-com/jfonseca-at-vmware-dot-com/
s/jrfonseca\?@tungstengraphics.com/jfonseca@vmware.com/g
s/keithw\?@tungstengraphics.com/keithw@vmware.com/g
s/michel@tungstengraphics.com/daenzer@vmware.com/g
s/thomas-at-tungstengraphics-dot-com/thellstom-at-vmware-dot-com/
s/zack@tungstengraphics.com/zackr@vmware.com/
# Remove dead links
s@Tungsten Graphics (http://www.tungstengraphics.com)@Tungsten Graphics@g
# C string src/gallium/state_trackers/vega/api_misc.c
s/"Tungsten Graphics, Inc"/"VMware, Inc"/
Reviewed-by: Brian Paul <brianp@vmware.com>
2014-01-17 16:27:50 +00:00
|
|
|
* Copyright 2008 VMware, Inc.
|
2011-07-02 09:57:30 +01:00
|
|
|
* Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
|
|
|
|
* Copyright 2010-2011 LunarG, Inc.
|
|
|
|
* All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
* copy of this software and associated documentation files (the
|
|
|
|
* "Software"), to deal in the Software without restriction, including
|
|
|
|
* without limitation the rights to use, copy, modify, merge, publish,
|
|
|
|
* distribute, sub license, and/or sell copies of the Software, and to
|
|
|
|
* permit persons to whom the Software is furnished to do so, subject to
|
|
|
|
* the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice (including the
|
|
|
|
* next paragraph) shall be included in all copies or substantial portions
|
|
|
|
* of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
* DEALINGS IN THE SOFTWARE.
|
|
|
|
*
|
|
|
|
**************************************************************************/
|
|
|
|
|
|
|
|
|
2005-04-22 22:09:39 +01:00
|
|
|
#include <assert.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include "eglconfig.h"
|
|
|
|
#include "eglcontext.h"
|
2005-11-27 23:57:19 +00:00
|
|
|
#include "egldisplay.h"
|
2010-01-29 01:00:30 +00:00
|
|
|
#include "eglcurrent.h"
|
2005-04-22 22:09:39 +01:00
|
|
|
#include "eglsurface.h"
|
2010-01-31 04:57:53 +00:00
|
|
|
#include "egllog.h"
|
2018-05-16 14:17:30 +01:00
|
|
|
#include "util/macros.h"
|
2010-01-31 04:57:53 +00:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the API bit (one of EGL_xxx_BIT) of the context.
|
|
|
|
*/
|
|
|
|
static EGLint
|
|
|
|
_eglGetContextAPIBit(_EGLContext *ctx)
|
|
|
|
{
|
|
|
|
EGLint bit = 0;
|
|
|
|
|
|
|
|
switch (ctx->ClientAPI) {
|
|
|
|
case EGL_OPENGL_ES_API:
|
2012-07-18 23:59:15 +01:00
|
|
|
switch (ctx->ClientMajorVersion) {
|
2010-01-31 04:57:53 +00:00
|
|
|
case 1:
|
|
|
|
bit = EGL_OPENGL_ES_BIT;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
bit = EGL_OPENGL_ES2_BIT;
|
|
|
|
break;
|
egl/dri2: Add plumbing for EGL_OPENGL_ES3_BIT_KHR
Fixes error EGL_BAD_ATTRIBUTE in the tests below on Intel Sandybridge:
* piglit egl-create-context-verify-gl-flavor, testcase OpenGL ES 3.0
* gles3conform, revision 19700, when runnning GL3Tests with -fbo
This plumbing is added in order to comply with the EGL_KHR_create_context
spec. According to the EGL_KHR_create_context spec, it is illegal to call
eglCreateContext(EGL_CONTEXT_MAJOR_VERSION_KHR=3) with a config whose
EGL_RENDERABLE_TYPE does not contain the EGL_OPENGL_ES3_BIT_KHR. The
pertinent
portion of the spec is quoted below; the key word is "respectively".
* If <config> is not a valid EGLConfig, or does not support the
requested client API, then an EGL_BAD_CONFIG error is generated
(this includes requesting creation of an OpenGL ES 1.x, 2.0, or
3.0 context when the EGL_RENDERABLE_TYPE attribute of <config>
does not contain EGL_OPENGL_ES_BIT, EGL_OPENGL_ES2_BIT, or
EGL_OPENGL_ES3_BIT_KHR respectively).
To create this patch, I searched for all the ES2 bit plumbing by calling
`git grep "ES2_BIT\|DRI_API_GLES2" src/egl`, and then at each location
added a case for ES3.
Signed-off-by: Chad Versace <chad.versace@linux.intel.com>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
2012-11-20 21:43:11 +00:00
|
|
|
case 3:
|
|
|
|
bit = EGL_OPENGL_ES3_BIT_KHR;
|
|
|
|
break;
|
2010-01-31 04:57:53 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EGL_OPENVG_API:
|
|
|
|
bit = EGL_OPENVG_BIT;
|
|
|
|
break;
|
|
|
|
case EGL_OPENGL_API:
|
|
|
|
bit = EGL_OPENGL_BIT;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return bit;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Parse the list of context attributes and return the proper error code.
|
|
|
|
*/
|
|
|
|
static EGLint
|
2019-02-02 11:38:45 +00:00
|
|
|
_eglParseContextAttribList(_EGLContext *ctx, _EGLDisplay *disp,
|
2012-07-19 19:10:15 +01:00
|
|
|
const EGLint *attrib_list)
|
2010-01-31 04:57:53 +00:00
|
|
|
{
|
|
|
|
EGLenum api = ctx->ClientAPI;
|
|
|
|
EGLint i, err = EGL_SUCCESS;
|
|
|
|
|
|
|
|
if (!attrib_list)
|
|
|
|
return EGL_SUCCESS;
|
|
|
|
|
2012-07-19 19:10:15 +01:00
|
|
|
if (api == EGL_OPENVG_API && attrib_list[0] != EGL_NONE) {
|
|
|
|
_eglLog(_EGL_DEBUG, "bad context attribute 0x%04x", attrib_list[0]);
|
|
|
|
return EGL_BAD_ATTRIBUTE;
|
|
|
|
}
|
|
|
|
|
2010-01-31 04:57:53 +00:00
|
|
|
for (i = 0; attrib_list[i] != EGL_NONE; i++) {
|
|
|
|
EGLint attr = attrib_list[i++];
|
|
|
|
EGLint val = attrib_list[i];
|
|
|
|
|
|
|
|
switch (attr) {
|
|
|
|
case EGL_CONTEXT_CLIENT_VERSION:
|
2015-08-12 16:36:00 +01:00
|
|
|
/* 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 &&
|
2019-02-02 11:38:45 +00:00
|
|
|
(!disp->Extensions.KHR_create_context || api != EGL_OPENGL_API))) {
|
2015-08-12 16:36:00 +01:00
|
|
|
err = EGL_BAD_ATTRIBUTE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2012-07-19 19:10:15 +01:00
|
|
|
ctx->ClientMajorVersion = val;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EGL_CONTEXT_MINOR_VERSION_KHR:
|
2015-08-12 16:36:00 +01:00
|
|
|
/* 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."
|
|
|
|
*/
|
2019-02-02 11:38:45 +00:00
|
|
|
if (!disp->Extensions.KHR_create_context ||
|
2015-08-12 16:36:00 +01:00
|
|
|
(api != EGL_OPENGL_ES_API && api != EGL_OPENGL_API)) {
|
2010-01-31 04:57:53 +00:00
|
|
|
err = EGL_BAD_ATTRIBUTE;
|
|
|
|
break;
|
|
|
|
}
|
2012-07-19 19:10:15 +01:00
|
|
|
|
|
|
|
ctx->ClientMinorVersion = val;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EGL_CONTEXT_FLAGS_KHR:
|
2019-02-02 11:38:45 +00:00
|
|
|
if (!disp->Extensions.KHR_create_context) {
|
2010-01-31 04:57:53 +00:00
|
|
|
err = EGL_BAD_ATTRIBUTE;
|
|
|
|
break;
|
|
|
|
}
|
2012-07-19 19:10:15 +01:00
|
|
|
|
|
|
|
/* The EGL_KHR_create_context spec says:
|
|
|
|
*
|
2015-09-14 18:35:45 +01:00
|
|
|
* "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."
|
2012-07-19 19:10:15 +01:00
|
|
|
*/
|
2015-09-14 18:35:45 +01:00
|
|
|
if ((val & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) &&
|
|
|
|
(api != EGL_OPENGL_API && api != EGL_OPENGL_ES_API)) {
|
|
|
|
err = EGL_BAD_ATTRIBUTE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 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."
|
2018-10-11 11:53:21 +01:00
|
|
|
*
|
|
|
|
* Note: since the forward-compatible flag can be set more than one way,
|
|
|
|
* the OpenGL version check is performed once, below.
|
2015-09-14 18:35:45 +01:00
|
|
|
*/
|
|
|
|
if ((val & EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR) &&
|
2018-10-11 11:53:21 +01:00
|
|
|
api != EGL_OPENGL_API) {
|
2015-09-14 18:35:45 +01:00
|
|
|
err = EGL_BAD_ATTRIBUTE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((val & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) &&
|
2016-12-23 01:06:14 +00:00
|
|
|
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.
|
|
|
|
*/
|
2012-07-19 19:10:15 +01:00
|
|
|
err = EGL_BAD_ATTRIBUTE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2015-05-11 23:44:20 +01:00
|
|
|
ctx->Flags |= val;
|
2010-01-31 04:57:53 +00:00
|
|
|
break;
|
2012-07-19 19:10:15 +01:00
|
|
|
|
|
|
|
case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR:
|
2019-02-02 11:38:45 +00:00
|
|
|
if (!disp->Extensions.KHR_create_context) {
|
2012-07-19 19:10:15 +01:00
|
|
|
err = EGL_BAD_ATTRIBUTE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The EGL_KHR_create_context spec says:
|
|
|
|
*
|
|
|
|
* "[EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR] is only meaningful for
|
|
|
|
* OpenGL contexts, and specifying it for other types of
|
|
|
|
* contexts, including OpenGL ES contexts, will generate an
|
|
|
|
* error."
|
|
|
|
*/
|
|
|
|
if (api != EGL_OPENGL_API) {
|
|
|
|
err = EGL_BAD_ATTRIBUTE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx->Profile = val;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR:
|
|
|
|
/* The EGL_KHR_create_context spec says:
|
|
|
|
*
|
|
|
|
* "[EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR] is only
|
|
|
|
* meaningful for OpenGL contexts, and specifying it for other
|
|
|
|
* types of contexts, including OpenGL ES contexts, will generate
|
|
|
|
* an error."
|
2019-05-17 06:05:51 +01:00
|
|
|
*
|
|
|
|
* EGL 1.5 defines EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY
|
|
|
|
* (without a suffix) which has the same value as the KHR token,
|
|
|
|
* and specifies that it now works with both GL and ES contexts:
|
|
|
|
*
|
|
|
|
* "This attribute is supported only for OpenGL and OpenGL ES
|
|
|
|
* contexts."
|
2012-07-19 19:10:15 +01:00
|
|
|
*/
|
2019-05-17 06:05:51 +01:00
|
|
|
if (!(disp->Extensions.KHR_create_context && api == EGL_OPENGL_API)
|
|
|
|
&& !(disp->Version >= 15 && (api == EGL_OPENGL_API ||
|
|
|
|
api == EGL_OPENGL_ES_API))) {
|
2012-07-19 19:10:15 +01:00
|
|
|
err = EGL_BAD_ATTRIBUTE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx->ResetNotificationStrategy = val;
|
|
|
|
break;
|
|
|
|
|
2012-07-19 23:08:06 +01:00
|
|
|
case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
|
|
|
|
/* The EGL_EXT_create_context_robustness spec says:
|
|
|
|
*
|
|
|
|
* "[EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT] is only
|
|
|
|
* meaningful for OpenGL ES contexts, and specifying it for other
|
|
|
|
* types of contexts will generate an EGL_BAD_ATTRIBUTE error."
|
|
|
|
*/
|
2019-02-02 11:38:45 +00:00
|
|
|
if (!disp->Extensions.EXT_create_context_robustness
|
2012-07-19 23:08:06 +01:00
|
|
|
|| api != EGL_OPENGL_ES_API) {
|
|
|
|
err = EGL_BAD_ATTRIBUTE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx->ResetNotificationStrategy = val;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
|
2019-02-02 11:38:45 +00:00
|
|
|
if (!disp->Extensions.EXT_create_context_robustness) {
|
2012-07-19 23:08:06 +01:00
|
|
|
err = EGL_BAD_ATTRIBUTE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2015-05-11 23:44:20 +01:00
|
|
|
if (val == EGL_TRUE)
|
|
|
|
ctx->Flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR;
|
2012-07-19 23:08:06 +01:00
|
|
|
break;
|
|
|
|
|
2015-05-11 23:44:56 +01:00
|
|
|
case EGL_CONTEXT_OPENGL_ROBUST_ACCESS:
|
2019-02-02 11:38:45 +00:00
|
|
|
if (disp->Version < 15) {
|
2015-05-11 23:44:56 +01:00
|
|
|
err = EGL_BAD_ATTRIBUTE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (val == EGL_TRUE)
|
|
|
|
ctx->Flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EGL_CONTEXT_OPENGL_DEBUG:
|
2019-02-02 11:38:45 +00:00
|
|
|
if (disp->Version < 15) {
|
2015-05-11 23:44:56 +01:00
|
|
|
err = EGL_BAD_ATTRIBUTE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (val == EGL_TRUE)
|
|
|
|
ctx->Flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE:
|
2019-02-02 11:38:45 +00:00
|
|
|
if (disp->Version < 15) {
|
2015-05-11 23:44:56 +01:00
|
|
|
err = EGL_BAD_ATTRIBUTE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (val == EGL_TRUE)
|
|
|
|
ctx->Flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
|
|
|
|
break;
|
|
|
|
|
2017-06-29 01:44:03 +01:00
|
|
|
case EGL_CONTEXT_OPENGL_NO_ERROR_KHR:
|
2019-02-02 11:38:45 +00:00
|
|
|
if (disp->Version < 14 ||
|
|
|
|
!disp->Extensions.KHR_create_context_no_error) {
|
2017-06-29 01:44:03 +01:00
|
|
|
err = EGL_BAD_ATTRIBUTE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The KHR_no_error spec only applies against OpenGL 2.0+ and
|
|
|
|
* OpenGL ES 2.0+
|
|
|
|
*/
|
2021-04-06 17:03:04 +01:00
|
|
|
if (((api != EGL_OPENGL_API && api != EGL_OPENGL_ES_API) ||
|
|
|
|
ctx->ClientMajorVersion < 2) && val == EGL_TRUE) {
|
2017-06-29 01:44:03 +01:00
|
|
|
err = EGL_BAD_ATTRIBUTE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Canonicalize value to EGL_TRUE/EGL_FALSE definitions */
|
|
|
|
ctx->NoError = !!val;
|
|
|
|
break;
|
|
|
|
|
2016-10-27 19:34:46 +01:00
|
|
|
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.
|
|
|
|
*/
|
2019-02-02 11:38:45 +00:00
|
|
|
if (disp->Extensions.IMG_context_priority & (1 << bit))
|
2016-10-27 19:34:46 +01:00
|
|
|
ctx->ContextPriority = val;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2016-09-22 08:47:55 +01:00
|
|
|
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;
|
|
|
|
|
2010-01-31 04:57:53 +00:00
|
|
|
default:
|
|
|
|
err = EGL_BAD_ATTRIBUTE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (err != EGL_SUCCESS) {
|
|
|
|
_eglLog(_EGL_DEBUG, "bad context attribute 0x%04x", attr);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-19 19:10:15 +01:00
|
|
|
if (api == EGL_OPENGL_API) {
|
|
|
|
/* The EGL_KHR_create_context spec says:
|
|
|
|
*
|
|
|
|
* "If the requested OpenGL version is less than 3.2,
|
|
|
|
* EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR is ignored and the
|
|
|
|
* functionality of the context is determined solely by the
|
|
|
|
* requested version."
|
|
|
|
*
|
|
|
|
* Since the value is ignored, only validate the setting if the version
|
|
|
|
* is >= 3.2.
|
|
|
|
*/
|
|
|
|
if (ctx->ClientMajorVersion >= 4
|
|
|
|
|| (ctx->ClientMajorVersion == 3 && ctx->ClientMinorVersion >= 2)) {
|
|
|
|
switch (ctx->Profile) {
|
|
|
|
case EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR:
|
|
|
|
case EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR:
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
/* The EGL_KHR_create_context spec says:
|
|
|
|
*
|
|
|
|
* "* If an OpenGL context is requested, the requested version
|
|
|
|
* is greater than 3.2, and the value for attribute
|
2012-10-09 01:01:34 +01:00
|
|
|
* EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR has no bits set; has
|
|
|
|
* any bits set other than EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR
|
|
|
|
* and EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR; has
|
|
|
|
* more than one of these bits set; or if the implementation does
|
|
|
|
* not support the requested profile, then an EGL_BAD_MATCH error
|
|
|
|
* is generated."
|
2012-07-19 19:10:15 +01:00
|
|
|
*/
|
2012-10-09 01:01:34 +01:00
|
|
|
err = EGL_BAD_MATCH;
|
2012-07-19 19:10:15 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The EGL_KHR_create_context spec says:
|
|
|
|
*
|
|
|
|
* "* If an OpenGL context is requested and the values for
|
|
|
|
* attributes EGL_CONTEXT_MAJOR_VERSION_KHR and
|
|
|
|
* EGL_CONTEXT_MINOR_VERSION_KHR, when considered together with
|
|
|
|
* the value for attribute
|
|
|
|
* EGL_CONTEXT_FORWARD_COMPATIBLE_BIT_KHR, specify an OpenGL
|
|
|
|
* version and feature set that are not defined, than an
|
|
|
|
* EGL_BAD_MATCH error is generated.
|
|
|
|
*
|
|
|
|
* ... Thus, examples of invalid combinations of attributes
|
|
|
|
* include:
|
|
|
|
*
|
|
|
|
* - Major version < 1 or > 4
|
|
|
|
* - Major version == 1 and minor version < 0 or > 5
|
|
|
|
* - Major version == 2 and minor version < 0 or > 1
|
|
|
|
* - Major version == 3 and minor version < 0 or > 2
|
|
|
|
* - Major version == 4 and minor version < 0 or > 2
|
|
|
|
* - Forward-compatible flag set and major version < 3"
|
|
|
|
*/
|
|
|
|
if (ctx->ClientMajorVersion < 1 || ctx->ClientMinorVersion < 0)
|
|
|
|
err = EGL_BAD_MATCH;
|
|
|
|
|
|
|
|
switch (ctx->ClientMajorVersion) {
|
|
|
|
case 1:
|
|
|
|
if (ctx->ClientMinorVersion > 5
|
|
|
|
|| (ctx->Flags & EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR) != 0)
|
|
|
|
err = EGL_BAD_MATCH;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
if (ctx->ClientMinorVersion > 1
|
|
|
|
|| (ctx->Flags & EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR) != 0)
|
|
|
|
err = EGL_BAD_MATCH;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3:
|
|
|
|
/* Note: The text above is incorrect. There *is* an OpenGL 3.3!
|
|
|
|
*/
|
|
|
|
if (ctx->ClientMinorVersion > 3)
|
|
|
|
err = EGL_BAD_MATCH;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
|
|
|
default:
|
|
|
|
/* Don't put additional version checks here. We don't know that
|
|
|
|
* there won't be versions > 4.2.
|
|
|
|
*/
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else if (api == EGL_OPENGL_ES_API) {
|
|
|
|
/* The EGL_KHR_create_context spec says:
|
|
|
|
*
|
|
|
|
* "* If an OpenGL ES context is requested and the values for
|
|
|
|
* attributes EGL_CONTEXT_MAJOR_VERSION_KHR and
|
|
|
|
* EGL_CONTEXT_MINOR_VERSION_KHR specify an OpenGL ES version that
|
|
|
|
* is not defined, than an EGL_BAD_MATCH error is generated.
|
|
|
|
*
|
|
|
|
* ... Examples of invalid combinations of attributes include:
|
|
|
|
*
|
|
|
|
* - Major version < 1 or > 2
|
|
|
|
* - Major version == 1 and minor version < 0 or > 1
|
|
|
|
* - Major version == 2 and minor version != 0
|
|
|
|
*/
|
|
|
|
if (ctx->ClientMajorVersion < 1 || ctx->ClientMinorVersion < 0)
|
|
|
|
err = EGL_BAD_MATCH;
|
|
|
|
|
|
|
|
switch (ctx->ClientMajorVersion) {
|
|
|
|
case 1:
|
|
|
|
if (ctx->ClientMinorVersion > 1)
|
|
|
|
err = EGL_BAD_MATCH;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
2012-07-20 00:12:13 +01:00
|
|
|
if (ctx->ClientMinorVersion > 0)
|
|
|
|
err = EGL_BAD_MATCH;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3:
|
2012-07-19 19:10:15 +01:00
|
|
|
/* Don't put additional version checks here. We don't know that
|
2012-07-20 00:12:13 +01:00
|
|
|
* there won't be versions > 3.0.
|
2012-07-19 19:10:15 +01:00
|
|
|
*/
|
|
|
|
break;
|
2014-06-19 01:35:18 +01:00
|
|
|
|
|
|
|
default:
|
|
|
|
err = EGL_BAD_MATCH;
|
|
|
|
break;
|
2012-07-19 19:10:15 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (ctx->ResetNotificationStrategy) {
|
|
|
|
case EGL_NO_RESET_NOTIFICATION_KHR:
|
|
|
|
case EGL_LOSE_CONTEXT_ON_RESET_KHR:
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
err = EGL_BAD_ATTRIBUTE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2017-07-19 22:51:55 +01:00
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
2012-08-25 00:26:54 +01:00
|
|
|
if ((ctx->Flags & ~(EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR
|
2012-07-19 19:10:15 +01:00
|
|
|
| EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR
|
|
|
|
| EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR)) != 0) {
|
|
|
|
err = EGL_BAD_ATTRIBUTE;
|
|
|
|
}
|
|
|
|
|
2010-01-31 04:57:53 +00:00
|
|
|
return err;
|
|
|
|
}
|
2005-04-22 22:09:39 +01:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
2008-05-27 21:21:25 +01:00
|
|
|
* Initialize the given _EGLContext object to defaults and/or the values
|
|
|
|
* in the attrib_list.
|
2016-09-07 22:41:56 +01:00
|
|
|
*
|
|
|
|
* According to EGL 1.5 Section 3.7:
|
|
|
|
*
|
2016-09-08 18:21:24 +01:00
|
|
|
* "EGL_OPENGL_API and EGL_OPENGL_ES_API are interchangeable for all
|
|
|
|
* purposes except eglCreateContext."
|
2016-09-07 22:41:56 +01:00
|
|
|
*
|
|
|
|
* 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.
|
2005-04-22 22:09:39 +01:00
|
|
|
*/
|
2005-11-27 23:57:19 +00:00
|
|
|
EGLBoolean
|
2019-02-02 11:38:45 +00:00
|
|
|
_eglInitContext(_EGLContext *ctx, _EGLDisplay *disp, _EGLConfig *conf,
|
2010-01-31 05:33:57 +00:00
|
|
|
const EGLint *attrib_list)
|
2005-04-22 22:09:39 +01:00
|
|
|
{
|
2008-05-30 20:45:40 +01:00
|
|
|
const EGLenum api = eglQueryAPI();
|
2010-01-31 04:57:53 +00:00
|
|
|
EGLint err;
|
2008-05-30 20:45:40 +01:00
|
|
|
|
2017-06-20 15:40:28 +01:00
|
|
|
if (api == EGL_NONE)
|
|
|
|
return _eglError(EGL_BAD_MATCH, "eglCreateContext(no client API)");
|
2005-11-27 23:57:19 +00:00
|
|
|
|
2019-02-02 11:38:45 +00:00
|
|
|
_eglInitResource(&ctx->Resource, sizeof(*ctx), disp);
|
2010-01-31 04:57:53 +00:00
|
|
|
ctx->ClientAPI = api;
|
|
|
|
ctx->Config = conf;
|
2012-07-19 19:10:15 +01:00
|
|
|
ctx->Profile = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
|
2008-06-20 04:19:33 +01:00
|
|
|
|
2012-07-18 23:59:15 +01:00
|
|
|
ctx->ClientMajorVersion = 1; /* the default, per EGL spec */
|
|
|
|
ctx->ClientMinorVersion = 0;
|
2012-07-19 19:10:15 +01:00
|
|
|
ctx->Flags = 0;
|
|
|
|
ctx->ResetNotificationStrategy = EGL_NO_RESET_NOTIFICATION_KHR;
|
2016-10-27 19:34:46 +01:00
|
|
|
ctx->ContextPriority = EGL_CONTEXT_PRIORITY_MEDIUM_IMG;
|
2016-09-22 08:47:55 +01:00
|
|
|
ctx->ReleaseBehavior = EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR;
|
2008-06-19 23:06:56 +01:00
|
|
|
|
2019-02-02 11:38:45 +00:00
|
|
|
err = _eglParseContextAttribList(ctx, disp, attrib_list);
|
2010-08-20 06:19:10 +01:00
|
|
|
if (err == EGL_SUCCESS && ctx->Config) {
|
2010-10-14 09:38:58 +01:00
|
|
|
EGLint api_bit;
|
2010-08-20 06:19:10 +01:00
|
|
|
|
|
|
|
api_bit = _eglGetContextAPIBit(ctx);
|
2010-10-14 09:38:58 +01:00
|
|
|
if (!(ctx->Config->RenderableType & api_bit)) {
|
2010-08-20 06:19:10 +01:00
|
|
|
_eglLog(_EGL_DEBUG, "context api is 0x%x while config supports 0x%x",
|
2010-10-14 09:38:58 +01:00
|
|
|
api_bit, ctx->Config->RenderableType);
|
2010-08-20 06:19:10 +01:00
|
|
|
err = EGL_BAD_CONFIG;
|
|
|
|
}
|
|
|
|
}
|
2010-01-31 04:57:53 +00:00
|
|
|
if (err != EGL_SUCCESS)
|
|
|
|
return _eglError(err, "eglCreateContext");
|
2005-11-27 23:57:19 +00:00
|
|
|
|
|
|
|
return EGL_TRUE;
|
2005-04-22 22:09:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-09-27 10:00:51 +01:00
|
|
|
static EGLint
|
|
|
|
_eglQueryContextRenderBuffer(_EGLContext *ctx)
|
|
|
|
{
|
|
|
|
_EGLSurface *surf = ctx->DrawSurface;
|
|
|
|
|
egl: Simplify queries for EGL_RENDER_BUFFER
There exist *two* queryable EGL_RENDER_BUFFER states in EGL:
eglQuerySurface(EGL_RENDER_BUFFER) and
eglQueryContext(EGL_RENDER_BUFFER).
These changes eliminate potentially very fragile code in the upcoming
EGL_KHR_mutable_render_buffer implementation.
* eglQuerySurface(EGL_RENDER_BUFFER)
The implementation of eglQuerySurface(EGL_RENDER_BUFFER) contained
abstruse logic which required comprehending the specification
complexities of how the two EGL_RENDER_BUFFER states interact. The
function sometimes returned _EGLContext::WindowRenderBuffer, sometimes
_EGLSurface::RenderBuffer. Why? The function tried to encode the
actual logic from the EGL spec. When did the function return which
variable? Go study the EGL spec, hope you understand it, then hope
Mesa mutated the EGL_RENDER_BUFFER state in all the correct places.
Have fun.
To simplify eglQuerySurface(EGL_RENDER_BUFFER), and to improve
confidence in its correctness, flatten its indirect logic. For pixmap
and pbuffer surfaces, simply return a hard-coded literal value, as the
spec suggests. For window surfaces, simply return
_EGLSurface::RequestedRenderBuffer. Nothing difficult here.
* eglQueryContext(EGL_RENDER_BUFFER)
The implementation of this suffered from the same issues as
eglQuerySurface, and the solution is the same. confidence in its
correctness, flatten its indirect logic. For pixmap and pbuffer
surfaces, simply return a hard-coded literal value, as the spec
suggests. For window surfaces, simply return
_EGLSurface::ActiveRenderBuffer.
Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
2018-04-07 22:23:48 +01:00
|
|
|
/* From the EGL 1.5 spec:
|
|
|
|
*
|
|
|
|
* - If the context is not bound to a surface, then EGL_NONE will be
|
|
|
|
* returned.
|
|
|
|
*/
|
2009-09-27 10:00:51 +01:00
|
|
|
if (!surf)
|
|
|
|
return EGL_NONE;
|
egl: Simplify queries for EGL_RENDER_BUFFER
There exist *two* queryable EGL_RENDER_BUFFER states in EGL:
eglQuerySurface(EGL_RENDER_BUFFER) and
eglQueryContext(EGL_RENDER_BUFFER).
These changes eliminate potentially very fragile code in the upcoming
EGL_KHR_mutable_render_buffer implementation.
* eglQuerySurface(EGL_RENDER_BUFFER)
The implementation of eglQuerySurface(EGL_RENDER_BUFFER) contained
abstruse logic which required comprehending the specification
complexities of how the two EGL_RENDER_BUFFER states interact. The
function sometimes returned _EGLContext::WindowRenderBuffer, sometimes
_EGLSurface::RenderBuffer. Why? The function tried to encode the
actual logic from the EGL spec. When did the function return which
variable? Go study the EGL spec, hope you understand it, then hope
Mesa mutated the EGL_RENDER_BUFFER state in all the correct places.
Have fun.
To simplify eglQuerySurface(EGL_RENDER_BUFFER), and to improve
confidence in its correctness, flatten its indirect logic. For pixmap
and pbuffer surfaces, simply return a hard-coded literal value, as the
spec suggests. For window surfaces, simply return
_EGLSurface::RequestedRenderBuffer. Nothing difficult here.
* eglQueryContext(EGL_RENDER_BUFFER)
The implementation of this suffered from the same issues as
eglQuerySurface, and the solution is the same. confidence in its
correctness, flatten its indirect logic. For pixmap and pbuffer
surfaces, simply return a hard-coded literal value, as the spec
suggests. For window surfaces, simply return
_EGLSurface::ActiveRenderBuffer.
Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
2018-04-07 22:23:48 +01:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
2009-09-27 10:00:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-04-22 22:09:39 +01:00
|
|
|
EGLBoolean
|
2020-08-03 16:03:44 +01:00
|
|
|
_eglQueryContext(_EGLContext *c, EGLint attribute, EGLint *value)
|
2005-04-22 22:09:39 +01:00
|
|
|
{
|
2009-09-27 10:00:51 +01:00
|
|
|
if (!value)
|
|
|
|
return _eglError(EGL_BAD_PARAMETER, "eglQueryContext");
|
|
|
|
|
2005-04-22 22:09:39 +01:00
|
|
|
switch (attribute) {
|
|
|
|
case EGL_CONFIG_ID:
|
2016-09-09 17:25:33 +01:00
|
|
|
/*
|
|
|
|
* 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;
|
2009-09-27 10:00:51 +01:00
|
|
|
break;
|
|
|
|
case EGL_CONTEXT_CLIENT_VERSION:
|
2012-07-18 23:59:15 +01:00
|
|
|
*value = c->ClientMajorVersion;
|
2009-09-27 10:00:51 +01:00
|
|
|
break;
|
2006-01-30 00:10:55 +00:00
|
|
|
case EGL_CONTEXT_CLIENT_TYPE:
|
|
|
|
*value = c->ClientAPI;
|
2009-09-27 10:00:51 +01:00
|
|
|
break;
|
|
|
|
case EGL_RENDER_BUFFER:
|
|
|
|
*value = _eglQueryContextRenderBuffer(c);
|
|
|
|
break;
|
2016-10-27 19:34:46 +01:00
|
|
|
case EGL_CONTEXT_PRIORITY_LEVEL_IMG:
|
|
|
|
*value = c->ContextPriority;
|
|
|
|
break;
|
2005-04-22 22:09:39 +01:00
|
|
|
default:
|
2009-09-27 10:00:51 +01:00
|
|
|
return _eglError(EGL_BAD_ATTRIBUTE, "eglQueryContext");
|
2005-04-22 22:09:39 +01:00
|
|
|
}
|
2009-09-27 10:00:51 +01:00
|
|
|
|
|
|
|
return EGL_TRUE;
|
2005-04-22 22:09:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-01-26 08:53:40 +00:00
|
|
|
/**
|
|
|
|
* Bind the context to the thread and return the previous context.
|
|
|
|
*
|
|
|
|
* Note that the context may be NULL.
|
|
|
|
*/
|
2012-12-28 01:39:37 +00:00
|
|
|
_EGLContext *
|
2010-01-26 08:53:40 +00:00
|
|
|
_eglBindContextToThread(_EGLContext *ctx, _EGLThreadInfo *t)
|
2005-04-22 22:09:39 +01:00
|
|
|
{
|
2010-01-26 08:53:40 +00:00
|
|
|
_EGLContext *oldCtx;
|
|
|
|
|
2016-07-08 22:21:17 +01:00
|
|
|
oldCtx = t->CurrentContext;
|
2010-03-27 18:11:16 +00:00
|
|
|
if (ctx != oldCtx) {
|
|
|
|
if (oldCtx)
|
|
|
|
oldCtx->Binding = NULL;
|
|
|
|
if (ctx)
|
|
|
|
ctx->Binding = t;
|
2010-01-26 08:53:40 +00:00
|
|
|
|
2016-07-08 22:21:17 +01:00
|
|
|
t->CurrentContext = ctx;
|
2010-03-27 18:11:16 +00:00
|
|
|
}
|
2010-01-26 08:53:40 +00:00
|
|
|
|
|
|
|
return oldCtx;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return true if the given context and surfaces can be made current.
|
|
|
|
*/
|
|
|
|
static EGLBoolean
|
|
|
|
_eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read)
|
|
|
|
{
|
|
|
|
_EGLThreadInfo *t = _eglGetCurrentThread();
|
2019-02-02 11:38:45 +00:00
|
|
|
_EGLDisplay *disp;
|
2005-04-22 22:09:39 +01:00
|
|
|
|
2010-01-26 08:53:40 +00:00
|
|
|
/* this is easy */
|
|
|
|
if (!ctx) {
|
|
|
|
if (draw || read)
|
2009-08-03 18:35:14 +01:00
|
|
|
return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
|
2010-01-26 08:53:40 +00:00
|
|
|
return EGL_TRUE;
|
|
|
|
}
|
|
|
|
|
2019-02-02 11:38:45 +00:00
|
|
|
disp = ctx->Resource.Display;
|
|
|
|
if (!disp->Extensions.KHR_surfaceless_context
|
2012-07-18 17:38:34 +01:00
|
|
|
&& (draw == NULL || read == NULL))
|
2010-01-26 08:53:40 +00:00
|
|
|
return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The spec says
|
|
|
|
*
|
|
|
|
* "If ctx is current to some other thread, or if either draw or read are
|
|
|
|
* bound to contexts in another thread, an EGL_BAD_ACCESS error is
|
|
|
|
* generated."
|
|
|
|
*
|
2010-10-23 09:51:01 +01:00
|
|
|
* and
|
2010-01-26 08:53:40 +00:00
|
|
|
*
|
|
|
|
* "at most one context may be bound to a particular surface at a given
|
|
|
|
* time"
|
|
|
|
*/
|
2010-10-23 09:51:01 +01:00
|
|
|
if (ctx->Binding && ctx->Binding != t)
|
2010-01-26 08:53:40 +00:00
|
|
|
return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
|
2010-10-23 09:51:01 +01:00
|
|
|
if (draw && draw->CurrentContext && draw->CurrentContext != ctx) {
|
2016-07-08 22:21:17 +01:00
|
|
|
if (draw->CurrentContext->Binding != t)
|
2010-10-23 09:51:01 +01:00
|
|
|
return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
|
|
|
|
}
|
|
|
|
if (read && read->CurrentContext && read->CurrentContext != ctx) {
|
2016-07-08 22:21:17 +01:00
|
|
|
if (read->CurrentContext->Binding != t)
|
2010-10-23 09:51:01 +01:00
|
|
|
return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
|
|
|
|
}
|
2010-01-26 08:53:40 +00:00
|
|
|
|
2014-03-07 18:05:47 +00:00
|
|
|
/* If the context has a config then it must match that of the two
|
|
|
|
* surfaces */
|
|
|
|
if (ctx->Config) {
|
|
|
|
if ((draw && draw->Config != ctx->Config) ||
|
|
|
|
(read && read->Config != ctx->Config))
|
|
|
|
return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
|
|
|
|
} else {
|
2016-09-09 17:25:34 +01:00
|
|
|
/* Otherwise we must be using the EGL_KHR_no_config_context
|
2014-03-07 18:05:47 +00:00
|
|
|
* extension */
|
2019-02-02 11:38:45 +00:00
|
|
|
assert(disp->Extensions.KHR_no_config_context);
|
2014-03-07 18:05:47 +00:00
|
|
|
|
|
|
|
/* The extension doesn't permit binding draw and read buffers with
|
|
|
|
* differing contexts */
|
|
|
|
if (draw && read && draw->Config != read->Config)
|
|
|
|
return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
|
|
|
|
}
|
2009-07-17 18:42:04 +01:00
|
|
|
|
2010-01-26 08:53:40 +00:00
|
|
|
return EGL_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-01-27 15:31:20 +00:00
|
|
|
/**
|
|
|
|
* Bind the context to the current thread and given surfaces. Return the
|
2010-10-23 05:52:26 +01:00
|
|
|
* previous bound context and surfaces. The caller should unreference the
|
|
|
|
* returned context and surfaces.
|
|
|
|
*
|
|
|
|
* Making a second call with the resources returned by the first call
|
|
|
|
* unsurprisingly undoes the first call, except for the resouce reference
|
|
|
|
* counts.
|
2010-01-27 15:31:20 +00:00
|
|
|
*/
|
|
|
|
EGLBoolean
|
2010-10-23 05:52:26 +01:00
|
|
|
_eglBindContext(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read,
|
|
|
|
_EGLContext **old_ctx,
|
|
|
|
_EGLSurface **old_draw, _EGLSurface **old_read)
|
2010-01-27 15:31:20 +00:00
|
|
|
{
|
|
|
|
_EGLThreadInfo *t = _eglGetCurrentThread();
|
2010-10-23 05:52:26 +01:00
|
|
|
_EGLContext *prev_ctx;
|
|
|
|
_EGLSurface *prev_draw, *prev_read;
|
2010-01-27 15:31:20 +00:00
|
|
|
|
2010-10-23 05:52:26 +01:00
|
|
|
if (!_eglCheckMakeCurrent(ctx, draw, read))
|
2010-01-27 15:31:20 +00:00
|
|
|
return EGL_FALSE;
|
|
|
|
|
2010-10-23 05:52:26 +01:00
|
|
|
/* increment refcounts before binding */
|
|
|
|
_eglGetContext(ctx);
|
|
|
|
_eglGetSurface(draw);
|
|
|
|
_eglGetSurface(read);
|
|
|
|
|
2010-01-27 15:31:20 +00:00
|
|
|
/* bind the new context */
|
2010-10-23 05:52:26 +01:00
|
|
|
prev_ctx = _eglBindContextToThread(ctx, t);
|
2010-04-05 14:26:34 +01:00
|
|
|
|
2010-10-23 05:52:26 +01:00
|
|
|
/* break previous bindings */
|
|
|
|
if (prev_ctx) {
|
|
|
|
prev_draw = prev_ctx->DrawSurface;
|
|
|
|
prev_read = prev_ctx->ReadSurface;
|
2010-04-06 04:51:25 +01:00
|
|
|
|
2010-10-23 05:52:26 +01:00
|
|
|
if (prev_draw)
|
|
|
|
prev_draw->CurrentContext = NULL;
|
|
|
|
if (prev_read)
|
|
|
|
prev_read->CurrentContext = NULL;
|
2010-09-10 11:26:03 +01:00
|
|
|
|
2010-10-23 05:52:26 +01:00
|
|
|
prev_ctx->DrawSurface = NULL;
|
|
|
|
prev_ctx->ReadSurface = NULL;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
prev_draw = prev_read = NULL;
|
2010-09-10 11:26:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* establish new bindings */
|
2010-10-23 05:52:26 +01:00
|
|
|
if (ctx) {
|
|
|
|
if (draw)
|
|
|
|
draw->CurrentContext = ctx;
|
|
|
|
if (read)
|
|
|
|
read->CurrentContext = ctx;
|
|
|
|
|
|
|
|
ctx->DrawSurface = draw;
|
|
|
|
ctx->ReadSurface = read;
|
2010-01-27 15:31:20 +00:00
|
|
|
}
|
|
|
|
|
2010-10-23 05:52:26 +01:00
|
|
|
assert(old_ctx && old_draw && old_read);
|
|
|
|
*old_ctx = prev_ctx;
|
|
|
|
*old_draw = prev_draw;
|
|
|
|
*old_read = prev_read;
|
2010-04-05 14:26:34 +01:00
|
|
|
|
2010-01-27 15:31:20 +00:00
|
|
|
return EGL_TRUE;
|
|
|
|
}
|