xref: /aosp_15_r20/external/mesa3d/src/egl/main/eglcontext.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /**************************************************************************
2*61046927SAndroid Build Coastguard Worker  *
3*61046927SAndroid Build Coastguard Worker  * Copyright 2008 VMware, Inc.
4*61046927SAndroid Build Coastguard Worker  * Copyright 2009-2010 Chia-I Wu <[email protected]>
5*61046927SAndroid Build Coastguard Worker  * Copyright 2010-2011 LunarG, Inc.
6*61046927SAndroid Build Coastguard Worker  * All Rights Reserved.
7*61046927SAndroid Build Coastguard Worker  *
8*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
9*61046927SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the
10*61046927SAndroid Build Coastguard Worker  * "Software"), to deal in the Software without restriction, including
11*61046927SAndroid Build Coastguard Worker  * without limitation the rights to use, copy, modify, merge, publish,
12*61046927SAndroid Build Coastguard Worker  * distribute, sub license, and/or sell copies of the Software, and to
13*61046927SAndroid Build Coastguard Worker  * permit persons to whom the Software is furnished to do so, subject to
14*61046927SAndroid Build Coastguard Worker  * the following conditions:
15*61046927SAndroid Build Coastguard Worker  *
16*61046927SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the
17*61046927SAndroid Build Coastguard Worker  * next paragraph) shall be included in all copies or substantial portions
18*61046927SAndroid Build Coastguard Worker  * of the Software.
19*61046927SAndroid Build Coastguard Worker  *
20*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21*61046927SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22*61046927SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
23*61046927SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24*61046927SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25*61046927SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26*61046927SAndroid Build Coastguard Worker  * DEALINGS IN THE SOFTWARE.
27*61046927SAndroid Build Coastguard Worker  *
28*61046927SAndroid Build Coastguard Worker  **************************************************************************/
29*61046927SAndroid Build Coastguard Worker 
30*61046927SAndroid Build Coastguard Worker #include "eglcontext.h"
31*61046927SAndroid Build Coastguard Worker #include <assert.h>
32*61046927SAndroid Build Coastguard Worker #include <stdlib.h>
33*61046927SAndroid Build Coastguard Worker #include <string.h>
34*61046927SAndroid Build Coastguard Worker #include "util/macros.h"
35*61046927SAndroid Build Coastguard Worker #include "eglconfig.h"
36*61046927SAndroid Build Coastguard Worker #include "eglcurrent.h"
37*61046927SAndroid Build Coastguard Worker #include "egldisplay.h"
38*61046927SAndroid Build Coastguard Worker #include "egllog.h"
39*61046927SAndroid Build Coastguard Worker #include "eglsurface.h"
40*61046927SAndroid Build Coastguard Worker 
41*61046927SAndroid Build Coastguard Worker /**
42*61046927SAndroid Build Coastguard Worker  * Return the API bit (one of EGL_xxx_BIT) of the context.
43*61046927SAndroid Build Coastguard Worker  */
44*61046927SAndroid Build Coastguard Worker static EGLint
_eglGetContextAPIBit(_EGLContext * ctx)45*61046927SAndroid Build Coastguard Worker _eglGetContextAPIBit(_EGLContext *ctx)
46*61046927SAndroid Build Coastguard Worker {
47*61046927SAndroid Build Coastguard Worker    EGLint bit = 0;
48*61046927SAndroid Build Coastguard Worker 
49*61046927SAndroid Build Coastguard Worker    switch (ctx->ClientAPI) {
50*61046927SAndroid Build Coastguard Worker    case EGL_OPENGL_ES_API:
51*61046927SAndroid Build Coastguard Worker       switch (ctx->ClientMajorVersion) {
52*61046927SAndroid Build Coastguard Worker       case 1:
53*61046927SAndroid Build Coastguard Worker          bit = EGL_OPENGL_ES_BIT;
54*61046927SAndroid Build Coastguard Worker          break;
55*61046927SAndroid Build Coastguard Worker       case 2:
56*61046927SAndroid Build Coastguard Worker          bit = EGL_OPENGL_ES2_BIT;
57*61046927SAndroid Build Coastguard Worker          break;
58*61046927SAndroid Build Coastguard Worker       case 3:
59*61046927SAndroid Build Coastguard Worker          bit = EGL_OPENGL_ES3_BIT_KHR;
60*61046927SAndroid Build Coastguard Worker          break;
61*61046927SAndroid Build Coastguard Worker       default:
62*61046927SAndroid Build Coastguard Worker          break;
63*61046927SAndroid Build Coastguard Worker       }
64*61046927SAndroid Build Coastguard Worker       break;
65*61046927SAndroid Build Coastguard Worker    case EGL_OPENVG_API:
66*61046927SAndroid Build Coastguard Worker       bit = EGL_OPENVG_BIT;
67*61046927SAndroid Build Coastguard Worker       break;
68*61046927SAndroid Build Coastguard Worker    case EGL_OPENGL_API:
69*61046927SAndroid Build Coastguard Worker       bit = EGL_OPENGL_BIT;
70*61046927SAndroid Build Coastguard Worker       break;
71*61046927SAndroid Build Coastguard Worker    default:
72*61046927SAndroid Build Coastguard Worker       break;
73*61046927SAndroid Build Coastguard Worker    }
74*61046927SAndroid Build Coastguard Worker 
75*61046927SAndroid Build Coastguard Worker    return bit;
76*61046927SAndroid Build Coastguard Worker }
77*61046927SAndroid Build Coastguard Worker 
78*61046927SAndroid Build Coastguard Worker /**
79*61046927SAndroid Build Coastguard Worker  * Parse the list of context attributes and return the proper error code.
80*61046927SAndroid Build Coastguard Worker  */
81*61046927SAndroid Build Coastguard Worker static EGLint
_eglParseContextAttribList(_EGLContext * ctx,_EGLDisplay * disp,const EGLint * attrib_list)82*61046927SAndroid Build Coastguard Worker _eglParseContextAttribList(_EGLContext *ctx, _EGLDisplay *disp,
83*61046927SAndroid Build Coastguard Worker                            const EGLint *attrib_list)
84*61046927SAndroid Build Coastguard Worker {
85*61046927SAndroid Build Coastguard Worker    EGLenum api = ctx->ClientAPI;
86*61046927SAndroid Build Coastguard Worker    EGLint i, err = EGL_SUCCESS;
87*61046927SAndroid Build Coastguard Worker 
88*61046927SAndroid Build Coastguard Worker    if (!attrib_list)
89*61046927SAndroid Build Coastguard Worker       return EGL_SUCCESS;
90*61046927SAndroid Build Coastguard Worker 
91*61046927SAndroid Build Coastguard Worker    if (api == EGL_OPENVG_API && attrib_list[0] != EGL_NONE) {
92*61046927SAndroid Build Coastguard Worker       _eglLog(_EGL_DEBUG, "bad context attribute 0x%04x", attrib_list[0]);
93*61046927SAndroid Build Coastguard Worker       return EGL_BAD_ATTRIBUTE;
94*61046927SAndroid Build Coastguard Worker    }
95*61046927SAndroid Build Coastguard Worker 
96*61046927SAndroid Build Coastguard Worker    for (i = 0; attrib_list[i] != EGL_NONE; i++) {
97*61046927SAndroid Build Coastguard Worker       EGLint attr = attrib_list[i++];
98*61046927SAndroid Build Coastguard Worker       EGLint val = attrib_list[i];
99*61046927SAndroid Build Coastguard Worker 
100*61046927SAndroid Build Coastguard Worker       switch (attr) {
101*61046927SAndroid Build Coastguard Worker       case EGL_CONTEXT_CLIENT_VERSION:
102*61046927SAndroid Build Coastguard Worker          /* The EGL 1.4 spec says:
103*61046927SAndroid Build Coastguard Worker           *
104*61046927SAndroid Build Coastguard Worker           *     "attribute EGL_CONTEXT_CLIENT_VERSION is only valid when the
105*61046927SAndroid Build Coastguard Worker           *      current rendering API is EGL_OPENGL_ES_API"
106*61046927SAndroid Build Coastguard Worker           *
107*61046927SAndroid Build Coastguard Worker           * The EGL_KHR_create_context spec says:
108*61046927SAndroid Build Coastguard Worker           *
109*61046927SAndroid Build Coastguard Worker           *     "EGL_CONTEXT_MAJOR_VERSION_KHR           0x3098
110*61046927SAndroid Build Coastguard Worker           *      (this token is an alias for EGL_CONTEXT_CLIENT_VERSION)"
111*61046927SAndroid Build Coastguard Worker           *
112*61046927SAndroid Build Coastguard Worker           *     "The values for attributes EGL_CONTEXT_MAJOR_VERSION_KHR and
113*61046927SAndroid Build Coastguard Worker           *      EGL_CONTEXT_MINOR_VERSION_KHR specify the requested client API
114*61046927SAndroid Build Coastguard Worker           *      version. They are only meaningful for OpenGL and OpenGL ES
115*61046927SAndroid Build Coastguard Worker           *      contexts, and specifying them for other types of contexts will
116*61046927SAndroid Build Coastguard Worker           *      generate an error."
117*61046927SAndroid Build Coastguard Worker           */
118*61046927SAndroid Build Coastguard Worker          if ((api != EGL_OPENGL_ES_API &&
119*61046927SAndroid Build Coastguard Worker               (!disp->Extensions.KHR_create_context ||
120*61046927SAndroid Build Coastguard Worker                api != EGL_OPENGL_API))) {
121*61046927SAndroid Build Coastguard Worker             err = EGL_BAD_ATTRIBUTE;
122*61046927SAndroid Build Coastguard Worker             break;
123*61046927SAndroid Build Coastguard Worker          }
124*61046927SAndroid Build Coastguard Worker 
125*61046927SAndroid Build Coastguard Worker          ctx->ClientMajorVersion = val;
126*61046927SAndroid Build Coastguard Worker          break;
127*61046927SAndroid Build Coastguard Worker 
128*61046927SAndroid Build Coastguard Worker       case EGL_CONTEXT_MINOR_VERSION_KHR:
129*61046927SAndroid Build Coastguard Worker          /* The EGL_KHR_create_context spec says:
130*61046927SAndroid Build Coastguard Worker           *
131*61046927SAndroid Build Coastguard Worker           *     "The values for attributes EGL_CONTEXT_MAJOR_VERSION_KHR and
132*61046927SAndroid Build Coastguard Worker           *      EGL_CONTEXT_MINOR_VERSION_KHR specify the requested client API
133*61046927SAndroid Build Coastguard Worker           *      version. They are only meaningful for OpenGL and OpenGL ES
134*61046927SAndroid Build Coastguard Worker           *      contexts, and specifying them for other types of contexts will
135*61046927SAndroid Build Coastguard Worker           *      generate an error."
136*61046927SAndroid Build Coastguard Worker           */
137*61046927SAndroid Build Coastguard Worker          if (!disp->Extensions.KHR_create_context ||
138*61046927SAndroid Build Coastguard Worker              (api != EGL_OPENGL_ES_API && api != EGL_OPENGL_API)) {
139*61046927SAndroid Build Coastguard Worker             err = EGL_BAD_ATTRIBUTE;
140*61046927SAndroid Build Coastguard Worker             break;
141*61046927SAndroid Build Coastguard Worker          }
142*61046927SAndroid Build Coastguard Worker 
143*61046927SAndroid Build Coastguard Worker          ctx->ClientMinorVersion = val;
144*61046927SAndroid Build Coastguard Worker          break;
145*61046927SAndroid Build Coastguard Worker 
146*61046927SAndroid Build Coastguard Worker       case EGL_CONTEXT_FLAGS_KHR:
147*61046927SAndroid Build Coastguard Worker          if (!disp->Extensions.KHR_create_context) {
148*61046927SAndroid Build Coastguard Worker             err = EGL_BAD_ATTRIBUTE;
149*61046927SAndroid Build Coastguard Worker             break;
150*61046927SAndroid Build Coastguard Worker          }
151*61046927SAndroid Build Coastguard Worker 
152*61046927SAndroid Build Coastguard Worker          /* The EGL_KHR_create_context spec says:
153*61046927SAndroid Build Coastguard Worker           *
154*61046927SAndroid Build Coastguard Worker           *     "If the EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR flag bit is set in
155*61046927SAndroid Build Coastguard Worker           *     EGL_CONTEXT_FLAGS_KHR, then a <debug context> will be created.
156*61046927SAndroid Build Coastguard Worker           *     [...]
157*61046927SAndroid Build Coastguard Worker           *     In some cases a debug context may be identical to a non-debug
158*61046927SAndroid Build Coastguard Worker           *     context. This bit is supported for OpenGL and OpenGL ES
159*61046927SAndroid Build Coastguard Worker           *     contexts."
160*61046927SAndroid Build Coastguard Worker           */
161*61046927SAndroid Build Coastguard Worker          if ((val & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) &&
162*61046927SAndroid Build Coastguard Worker              (api != EGL_OPENGL_API && api != EGL_OPENGL_ES_API)) {
163*61046927SAndroid Build Coastguard Worker             err = EGL_BAD_ATTRIBUTE;
164*61046927SAndroid Build Coastguard Worker             break;
165*61046927SAndroid Build Coastguard Worker          }
166*61046927SAndroid Build Coastguard Worker 
167*61046927SAndroid Build Coastguard Worker          /* The EGL_KHR_create_context spec says:
168*61046927SAndroid Build Coastguard Worker           *
169*61046927SAndroid Build Coastguard Worker           *     "If the EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR flag bit
170*61046927SAndroid Build Coastguard Worker           *     is set in EGL_CONTEXT_FLAGS_KHR, then a <forward-compatible>
171*61046927SAndroid Build Coastguard Worker           *     context will be created. Forward-compatible contexts are
172*61046927SAndroid Build Coastguard Worker           *     defined only for OpenGL versions 3.0 and later. They must not
173*61046927SAndroid Build Coastguard Worker           *     support functionality marked as <deprecated> by that version of
174*61046927SAndroid Build Coastguard Worker           *     the API, while a non-forward-compatible context must support
175*61046927SAndroid Build Coastguard Worker           *     all functionality in that version, deprecated or not. This bit
176*61046927SAndroid Build Coastguard Worker           *     is supported for OpenGL contexts, and requesting a
177*61046927SAndroid Build Coastguard Worker           *     forward-compatible context for OpenGL versions less than 3.0
178*61046927SAndroid Build Coastguard Worker           *     will generate an error."
179*61046927SAndroid Build Coastguard Worker           *
180*61046927SAndroid Build Coastguard Worker           * Note: since the forward-compatible flag can be set more than one
181*61046927SAndroid Build Coastguard Worker           * way, the OpenGL version check is performed once, below.
182*61046927SAndroid Build Coastguard Worker           */
183*61046927SAndroid Build Coastguard Worker          if ((val & EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR) &&
184*61046927SAndroid Build Coastguard Worker              api != EGL_OPENGL_API) {
185*61046927SAndroid Build Coastguard Worker             err = EGL_BAD_ATTRIBUTE;
186*61046927SAndroid Build Coastguard Worker             break;
187*61046927SAndroid Build Coastguard Worker          }
188*61046927SAndroid Build Coastguard Worker 
189*61046927SAndroid Build Coastguard Worker          if ((val & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) &&
190*61046927SAndroid Build Coastguard Worker              api != EGL_OPENGL_API) {
191*61046927SAndroid Build Coastguard Worker             /* The EGL_KHR_create_context spec says:
192*61046927SAndroid Build Coastguard Worker              *
193*61046927SAndroid Build Coastguard Worker              *   10) Which error should be generated if robust buffer access
194*61046927SAndroid Build Coastguard Worker              *       or reset notifications are requested under OpenGL ES?
195*61046927SAndroid Build Coastguard Worker              *
196*61046927SAndroid Build Coastguard Worker              *       As per Issue 6, this extension does not support creating
197*61046927SAndroid Build Coastguard Worker              *       robust contexts for OpenGL ES. This is only supported via
198*61046927SAndroid Build Coastguard Worker              *       the EGL_EXT_create_context_robustness extension.
199*61046927SAndroid Build Coastguard Worker              *
200*61046927SAndroid Build Coastguard Worker              *       Attempting to use this extension to create robust OpenGL
201*61046927SAndroid Build Coastguard Worker              *       ES context will generate an EGL_BAD_ATTRIBUTE error. This
202*61046927SAndroid Build Coastguard Worker              *       specific error is generated because this extension does
203*61046927SAndroid Build Coastguard Worker              *       not define the EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR
204*61046927SAndroid Build Coastguard Worker              *       and EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR
205*61046927SAndroid Build Coastguard Worker              *       bits for OpenGL ES contexts. Thus, use of these bits fall
206*61046927SAndroid Build Coastguard Worker              *       under condition described by: "If an attribute is
207*61046927SAndroid Build Coastguard Worker              *       specified that is not meaningful for the client API
208*61046927SAndroid Build Coastguard Worker              *       type.." in the above specification.
209*61046927SAndroid Build Coastguard Worker              *
210*61046927SAndroid Build Coastguard Worker              * The spec requires that we emit the error even if the display
211*61046927SAndroid Build Coastguard Worker              * supports EGL_EXT_create_context_robustness. To create a robust
212*61046927SAndroid Build Coastguard Worker              * GLES context, the *attribute*
213*61046927SAndroid Build Coastguard Worker              * EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT must be used, not the
214*61046927SAndroid Build Coastguard Worker              * *flag* EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR.
215*61046927SAndroid Build Coastguard Worker              */
216*61046927SAndroid Build Coastguard Worker             err = EGL_BAD_ATTRIBUTE;
217*61046927SAndroid Build Coastguard Worker             break;
218*61046927SAndroid Build Coastguard Worker          }
219*61046927SAndroid Build Coastguard Worker 
220*61046927SAndroid Build Coastguard Worker          /* The EGL_KHR_create_context spec says:
221*61046927SAndroid Build Coastguard Worker           *     "If <config> does not support a client API context compatible
222*61046927SAndroid Build Coastguard Worker           *     with the requested API major and minor version, context flags,
223*61046927SAndroid Build Coastguard Worker           *     and context reset notification behavior (for client API types
224*61046927SAndroid Build Coastguard Worker           *     where these attributes are supported), then an EGL_BAD_MATCH
225*61046927SAndroid Build Coastguard Worker           *     error is generated."
226*61046927SAndroid Build Coastguard Worker           */
227*61046927SAndroid Build Coastguard Worker          if ((val & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) &&
228*61046927SAndroid Build Coastguard Worker              !disp->RobustBufferAccess) {
229*61046927SAndroid Build Coastguard Worker             err = EGL_BAD_MATCH;
230*61046927SAndroid Build Coastguard Worker             break;
231*61046927SAndroid Build Coastguard Worker          }
232*61046927SAndroid Build Coastguard Worker 
233*61046927SAndroid Build Coastguard Worker          ctx->Flags |= val;
234*61046927SAndroid Build Coastguard Worker          break;
235*61046927SAndroid Build Coastguard Worker 
236*61046927SAndroid Build Coastguard Worker       case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR:
237*61046927SAndroid Build Coastguard Worker          if (!disp->Extensions.KHR_create_context) {
238*61046927SAndroid Build Coastguard Worker             err = EGL_BAD_ATTRIBUTE;
239*61046927SAndroid Build Coastguard Worker             break;
240*61046927SAndroid Build Coastguard Worker          }
241*61046927SAndroid Build Coastguard Worker 
242*61046927SAndroid Build Coastguard Worker          /* The EGL_KHR_create_context spec says:
243*61046927SAndroid Build Coastguard Worker           *
244*61046927SAndroid Build Coastguard Worker           *     "[EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR] is only meaningful for
245*61046927SAndroid Build Coastguard Worker           *     OpenGL contexts, and specifying it for other types of
246*61046927SAndroid Build Coastguard Worker           *     contexts, including OpenGL ES contexts, will generate an
247*61046927SAndroid Build Coastguard Worker           *     error."
248*61046927SAndroid Build Coastguard Worker           */
249*61046927SAndroid Build Coastguard Worker          if (api != EGL_OPENGL_API) {
250*61046927SAndroid Build Coastguard Worker             err = EGL_BAD_ATTRIBUTE;
251*61046927SAndroid Build Coastguard Worker             break;
252*61046927SAndroid Build Coastguard Worker          }
253*61046927SAndroid Build Coastguard Worker 
254*61046927SAndroid Build Coastguard Worker          ctx->Profile = val;
255*61046927SAndroid Build Coastguard Worker          break;
256*61046927SAndroid Build Coastguard Worker 
257*61046927SAndroid Build Coastguard Worker       case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR:
258*61046927SAndroid Build Coastguard Worker          /* The EGL_KHR_create_context spec says:
259*61046927SAndroid Build Coastguard Worker           *
260*61046927SAndroid Build Coastguard Worker           *     "[EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR] is only
261*61046927SAndroid Build Coastguard Worker           *     meaningful for OpenGL contexts, and specifying it for other
262*61046927SAndroid Build Coastguard Worker           *     types of contexts, including OpenGL ES contexts, will generate
263*61046927SAndroid Build Coastguard Worker           *     an error."
264*61046927SAndroid Build Coastguard Worker           *
265*61046927SAndroid Build Coastguard Worker           * EGL 1.5 defines EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY
266*61046927SAndroid Build Coastguard Worker           * (without a suffix) which has the same value as the KHR token,
267*61046927SAndroid Build Coastguard Worker           * and specifies that it now works with both GL and ES contexts:
268*61046927SAndroid Build Coastguard Worker           *
269*61046927SAndroid Build Coastguard Worker           *    "This attribute is supported only for OpenGL and OpenGL ES
270*61046927SAndroid Build Coastguard Worker           *     contexts."
271*61046927SAndroid Build Coastguard Worker           */
272*61046927SAndroid Build Coastguard Worker          if (!(disp->Extensions.KHR_create_context && api == EGL_OPENGL_API) &&
273*61046927SAndroid Build Coastguard Worker              !(disp->Version >= 15 &&
274*61046927SAndroid Build Coastguard Worker                (api == EGL_OPENGL_API || api == EGL_OPENGL_ES_API))) {
275*61046927SAndroid Build Coastguard Worker             err = EGL_BAD_ATTRIBUTE;
276*61046927SAndroid Build Coastguard Worker             break;
277*61046927SAndroid Build Coastguard Worker          }
278*61046927SAndroid Build Coastguard Worker 
279*61046927SAndroid Build Coastguard Worker          /* The EGL 1.5 spec says:
280*61046927SAndroid Build Coastguard Worker           *     "An EGL_BAD_MATCH error is generated if an OpenGL or OpenGL ES
281*61046927SAndroid Build Coastguard Worker           *     context is requested with robust buffer access and with a
282*61046927SAndroid Build Coastguard Worker           *     specified reset notification behavior, and the implementation
283*61046927SAndroid Build Coastguard Worker           *     does not support that behavior."
284*61046927SAndroid Build Coastguard Worker           *
285*61046927SAndroid Build Coastguard Worker           * and the EGL_KHR_create_context spec says:
286*61046927SAndroid Build Coastguard Worker           *     "If <config> does not support a client API context compatible
287*61046927SAndroid Build Coastguard Worker           *     with the requested API major and minor version, context flags,
288*61046927SAndroid Build Coastguard Worker           *     and context reset notification behavior (for client API types
289*61046927SAndroid Build Coastguard Worker           *     where these attributes are supported), then an EGL_BAD_MATCH
290*61046927SAndroid Build Coastguard Worker           *     error is generated."
291*61046927SAndroid Build Coastguard Worker           */
292*61046927SAndroid Build Coastguard Worker          if (val != EGL_NO_RESET_NOTIFICATION_KHR &&
293*61046927SAndroid Build Coastguard Worker              !disp->Extensions.EXT_create_context_robustness) {
294*61046927SAndroid Build Coastguard Worker             err = EGL_BAD_MATCH;
295*61046927SAndroid Build Coastguard Worker             break;
296*61046927SAndroid Build Coastguard Worker          }
297*61046927SAndroid Build Coastguard Worker 
298*61046927SAndroid Build Coastguard Worker          ctx->ResetNotificationStrategy = val;
299*61046927SAndroid Build Coastguard Worker          break;
300*61046927SAndroid Build Coastguard Worker 
301*61046927SAndroid Build Coastguard Worker       case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
302*61046927SAndroid Build Coastguard Worker          /* The EGL_EXT_create_context_robustness spec says:
303*61046927SAndroid Build Coastguard Worker           *
304*61046927SAndroid Build Coastguard Worker           *     "[EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT] is only
305*61046927SAndroid Build Coastguard Worker           *     meaningful for OpenGL ES contexts, and specifying it for other
306*61046927SAndroid Build Coastguard Worker           *     types of contexts will generate an EGL_BAD_ATTRIBUTE error."
307*61046927SAndroid Build Coastguard Worker           */
308*61046927SAndroid Build Coastguard Worker          if (!disp->Extensions.EXT_create_context_robustness ||
309*61046927SAndroid Build Coastguard Worker              api != EGL_OPENGL_ES_API) {
310*61046927SAndroid Build Coastguard Worker             err = EGL_BAD_ATTRIBUTE;
311*61046927SAndroid Build Coastguard Worker             break;
312*61046927SAndroid Build Coastguard Worker          }
313*61046927SAndroid Build Coastguard Worker 
314*61046927SAndroid Build Coastguard Worker          ctx->ResetNotificationStrategy = val;
315*61046927SAndroid Build Coastguard Worker          break;
316*61046927SAndroid Build Coastguard Worker 
317*61046927SAndroid Build Coastguard Worker       case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
318*61046927SAndroid Build Coastguard Worker          if (!disp->Extensions.EXT_create_context_robustness) {
319*61046927SAndroid Build Coastguard Worker             err = EGL_BAD_ATTRIBUTE;
320*61046927SAndroid Build Coastguard Worker             break;
321*61046927SAndroid Build Coastguard Worker          }
322*61046927SAndroid Build Coastguard Worker 
323*61046927SAndroid Build Coastguard Worker          /* The EGL_EXT_create_context_robustness spec says:
324*61046927SAndroid Build Coastguard Worker           *
325*61046927SAndroid Build Coastguard Worker           *     "EGL_BAD_CONFIG is generated if
326*61046927SAndroid Build Coastguard Worker           *     [EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT] is set to EGL_TRUE and
327*61046927SAndroid Build Coastguard Worker           *     no GL context supporting the GL_EXT_robustness extension and
328*61046927SAndroid Build Coastguard Worker           *     robust access as described therein can be created."
329*61046927SAndroid Build Coastguard Worker           */
330*61046927SAndroid Build Coastguard Worker          if (val == EGL_TRUE && !disp->RobustBufferAccess) {
331*61046927SAndroid Build Coastguard Worker             err = EGL_BAD_CONFIG;
332*61046927SAndroid Build Coastguard Worker             break;
333*61046927SAndroid Build Coastguard Worker          }
334*61046927SAndroid Build Coastguard Worker 
335*61046927SAndroid Build Coastguard Worker          if (val == EGL_TRUE)
336*61046927SAndroid Build Coastguard Worker             ctx->Flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR;
337*61046927SAndroid Build Coastguard Worker          break;
338*61046927SAndroid Build Coastguard Worker 
339*61046927SAndroid Build Coastguard Worker       case EGL_CONTEXT_OPENGL_ROBUST_ACCESS:
340*61046927SAndroid Build Coastguard Worker          if (disp->Version < 15) {
341*61046927SAndroid Build Coastguard Worker             err = EGL_BAD_ATTRIBUTE;
342*61046927SAndroid Build Coastguard Worker             break;
343*61046927SAndroid Build Coastguard Worker          }
344*61046927SAndroid Build Coastguard Worker 
345*61046927SAndroid Build Coastguard Worker          /* The EGL 1.5 spec says:
346*61046927SAndroid Build Coastguard Worker           *     "An EGL_BAD_MATCH error is generated if an OpenGL or OpenGL ES
347*61046927SAndroid Build Coastguard Worker           *     context is requested with robust buffer access, and the
348*61046927SAndroid Build Coastguard Worker           *     implementation does not support the corresponding OpenGL or
349*61046927SAndroid Build Coastguard Worker           *     OpenGL ES extension".
350*61046927SAndroid Build Coastguard Worker           */
351*61046927SAndroid Build Coastguard Worker          if (val == EGL_TRUE && !disp->RobustBufferAccess) {
352*61046927SAndroid Build Coastguard Worker             err = EGL_BAD_MATCH;
353*61046927SAndroid Build Coastguard Worker             break;
354*61046927SAndroid Build Coastguard Worker          }
355*61046927SAndroid Build Coastguard Worker 
356*61046927SAndroid Build Coastguard Worker          if (val == EGL_TRUE)
357*61046927SAndroid Build Coastguard Worker             ctx->Flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR;
358*61046927SAndroid Build Coastguard Worker          break;
359*61046927SAndroid Build Coastguard Worker 
360*61046927SAndroid Build Coastguard Worker       case EGL_CONTEXT_OPENGL_DEBUG:
361*61046927SAndroid Build Coastguard Worker          if (disp->Version < 15) {
362*61046927SAndroid Build Coastguard Worker             err = EGL_BAD_ATTRIBUTE;
363*61046927SAndroid Build Coastguard Worker             break;
364*61046927SAndroid Build Coastguard Worker          }
365*61046927SAndroid Build Coastguard Worker 
366*61046927SAndroid Build Coastguard Worker          if (val == EGL_TRUE)
367*61046927SAndroid Build Coastguard Worker             ctx->Flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
368*61046927SAndroid Build Coastguard Worker          break;
369*61046927SAndroid Build Coastguard Worker 
370*61046927SAndroid Build Coastguard Worker       case EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE:
371*61046927SAndroid Build Coastguard Worker          if (disp->Version < 15) {
372*61046927SAndroid Build Coastguard Worker             err = EGL_BAD_ATTRIBUTE;
373*61046927SAndroid Build Coastguard Worker             break;
374*61046927SAndroid Build Coastguard Worker          }
375*61046927SAndroid Build Coastguard Worker 
376*61046927SAndroid Build Coastguard Worker          if (val == EGL_TRUE)
377*61046927SAndroid Build Coastguard Worker             ctx->Flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
378*61046927SAndroid Build Coastguard Worker          break;
379*61046927SAndroid Build Coastguard Worker 
380*61046927SAndroid Build Coastguard Worker       case EGL_CONTEXT_OPENGL_NO_ERROR_KHR:
381*61046927SAndroid Build Coastguard Worker          if (disp->Version < 14 ||
382*61046927SAndroid Build Coastguard Worker              !disp->Extensions.KHR_create_context_no_error) {
383*61046927SAndroid Build Coastguard Worker             err = EGL_BAD_ATTRIBUTE;
384*61046927SAndroid Build Coastguard Worker             break;
385*61046927SAndroid Build Coastguard Worker          }
386*61046927SAndroid Build Coastguard Worker 
387*61046927SAndroid Build Coastguard Worker          /* The KHR_no_error spec only applies against OpenGL 2.0+ and
388*61046927SAndroid Build Coastguard Worker           * OpenGL ES 2.0+
389*61046927SAndroid Build Coastguard Worker           */
390*61046927SAndroid Build Coastguard Worker          if (((api != EGL_OPENGL_API && api != EGL_OPENGL_ES_API) ||
391*61046927SAndroid Build Coastguard Worker               ctx->ClientMajorVersion < 2) &&
392*61046927SAndroid Build Coastguard Worker              val == EGL_TRUE) {
393*61046927SAndroid Build Coastguard Worker             err = EGL_BAD_ATTRIBUTE;
394*61046927SAndroid Build Coastguard Worker             break;
395*61046927SAndroid Build Coastguard Worker          }
396*61046927SAndroid Build Coastguard Worker 
397*61046927SAndroid Build Coastguard Worker          /* Canonicalize value to EGL_TRUE/EGL_FALSE definitions */
398*61046927SAndroid Build Coastguard Worker          ctx->NoError = !!val;
399*61046927SAndroid Build Coastguard Worker          break;
400*61046927SAndroid Build Coastguard Worker 
401*61046927SAndroid Build Coastguard Worker       case EGL_CONTEXT_PRIORITY_LEVEL_IMG:
402*61046927SAndroid Build Coastguard Worker          /* The  EGL_IMG_context_priority spec says:
403*61046927SAndroid Build Coastguard Worker           *
404*61046927SAndroid Build Coastguard Worker           * "EGL_CONTEXT_PRIORITY_LEVEL_IMG determines the priority level of
405*61046927SAndroid Build Coastguard Worker           * the context to be created. This attribute is a hint, as an
406*61046927SAndroid Build Coastguard Worker           * implementation may not support multiple contexts at some
407*61046927SAndroid Build Coastguard Worker           * priority levels and system policy may limit access to high
408*61046927SAndroid Build Coastguard Worker           * priority contexts to appropriate system privilege level. The
409*61046927SAndroid Build Coastguard Worker           * default value for EGL_CONTEXT_PRIORITY_LEVEL_IMG is
410*61046927SAndroid Build Coastguard Worker           * EGL_CONTEXT_PRIORITY_MEDIUM_IMG."
411*61046927SAndroid Build Coastguard Worker           */
412*61046927SAndroid Build Coastguard Worker          {
413*61046927SAndroid Build Coastguard Worker             int bit;
414*61046927SAndroid Build Coastguard Worker 
415*61046927SAndroid Build Coastguard Worker             switch (val) {
416*61046927SAndroid Build Coastguard Worker             case EGL_CONTEXT_PRIORITY_HIGH_IMG:
417*61046927SAndroid Build Coastguard Worker                bit = __EGL_CONTEXT_PRIORITY_HIGH_BIT;
418*61046927SAndroid Build Coastguard Worker                break;
419*61046927SAndroid Build Coastguard Worker             case EGL_CONTEXT_PRIORITY_MEDIUM_IMG:
420*61046927SAndroid Build Coastguard Worker                bit = __EGL_CONTEXT_PRIORITY_MEDIUM_BIT;
421*61046927SAndroid Build Coastguard Worker                break;
422*61046927SAndroid Build Coastguard Worker             case EGL_CONTEXT_PRIORITY_LOW_IMG:
423*61046927SAndroid Build Coastguard Worker                bit = __EGL_CONTEXT_PRIORITY_LOW_BIT;
424*61046927SAndroid Build Coastguard Worker                break;
425*61046927SAndroid Build Coastguard Worker             default:
426*61046927SAndroid Build Coastguard Worker                bit = -1;
427*61046927SAndroid Build Coastguard Worker                break;
428*61046927SAndroid Build Coastguard Worker             }
429*61046927SAndroid Build Coastguard Worker 
430*61046927SAndroid Build Coastguard Worker             if (bit < 0) {
431*61046927SAndroid Build Coastguard Worker                err = EGL_BAD_ATTRIBUTE;
432*61046927SAndroid Build Coastguard Worker                break;
433*61046927SAndroid Build Coastguard Worker             }
434*61046927SAndroid Build Coastguard Worker 
435*61046927SAndroid Build Coastguard Worker             /* "This extension allows an EGLContext to be created with a
436*61046927SAndroid Build Coastguard Worker              * priority hint. It is possible that an implementation will not
437*61046927SAndroid Build Coastguard Worker              * honour the hint, especially if there are constraints on the
438*61046927SAndroid Build Coastguard Worker              * number of high priority contexts available in the system, or
439*61046927SAndroid Build Coastguard Worker              * system policy limits access to high priority contexts to
440*61046927SAndroid Build Coastguard Worker              * appropriate system privilege level. A query is provided to find
441*61046927SAndroid Build Coastguard Worker              * the real priority level assigned to the context after creation."
442*61046927SAndroid Build Coastguard Worker              *
443*61046927SAndroid Build Coastguard Worker              * We currently assume that the driver applies the priority hint
444*61046927SAndroid Build Coastguard Worker              * and filters out any it cannot handle during the screen setup,
445*61046927SAndroid Build Coastguard Worker              * e.g. dri2_setup_screen(). As such we can mask any change that
446*61046927SAndroid Build Coastguard Worker              * the driver would fail, and ctx->ContextPriority matches the
447*61046927SAndroid Build Coastguard Worker              * hint applied to the driver/hardware backend.
448*61046927SAndroid Build Coastguard Worker              */
449*61046927SAndroid Build Coastguard Worker             if (disp->Extensions.IMG_context_priority & (1 << bit))
450*61046927SAndroid Build Coastguard Worker                ctx->ContextPriority = val;
451*61046927SAndroid Build Coastguard Worker 
452*61046927SAndroid Build Coastguard Worker             break;
453*61046927SAndroid Build Coastguard Worker          }
454*61046927SAndroid Build Coastguard Worker 
455*61046927SAndroid Build Coastguard Worker       case EGL_CONTEXT_RELEASE_BEHAVIOR_KHR:
456*61046927SAndroid Build Coastguard Worker          if (val == EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR ||
457*61046927SAndroid Build Coastguard Worker              val == EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR) {
458*61046927SAndroid Build Coastguard Worker             ctx->ReleaseBehavior = val;
459*61046927SAndroid Build Coastguard Worker          } else {
460*61046927SAndroid Build Coastguard Worker             err = EGL_BAD_ATTRIBUTE;
461*61046927SAndroid Build Coastguard Worker          }
462*61046927SAndroid Build Coastguard Worker          break;
463*61046927SAndroid Build Coastguard Worker 
464*61046927SAndroid Build Coastguard Worker       case EGL_PROTECTED_CONTENT_EXT:
465*61046927SAndroid Build Coastguard Worker          if (!disp->Extensions.EXT_protected_content) {
466*61046927SAndroid Build Coastguard Worker             err = EGL_BAD_ATTRIBUTE;
467*61046927SAndroid Build Coastguard Worker             break;
468*61046927SAndroid Build Coastguard Worker          }
469*61046927SAndroid Build Coastguard Worker          ctx->Protected = val == EGL_TRUE;
470*61046927SAndroid Build Coastguard Worker          break;
471*61046927SAndroid Build Coastguard Worker 
472*61046927SAndroid Build Coastguard Worker       default:
473*61046927SAndroid Build Coastguard Worker          err = EGL_BAD_ATTRIBUTE;
474*61046927SAndroid Build Coastguard Worker          break;
475*61046927SAndroid Build Coastguard Worker       }
476*61046927SAndroid Build Coastguard Worker 
477*61046927SAndroid Build Coastguard Worker       if (err != EGL_SUCCESS) {
478*61046927SAndroid Build Coastguard Worker          _eglLog(_EGL_DEBUG, "bad context attribute 0x%04x", attr);
479*61046927SAndroid Build Coastguard Worker          break;
480*61046927SAndroid Build Coastguard Worker       }
481*61046927SAndroid Build Coastguard Worker    }
482*61046927SAndroid Build Coastguard Worker 
483*61046927SAndroid Build Coastguard Worker    if (api == EGL_OPENGL_API) {
484*61046927SAndroid Build Coastguard Worker       /* The EGL_KHR_create_context spec says:
485*61046927SAndroid Build Coastguard Worker        *
486*61046927SAndroid Build Coastguard Worker        *     "If the requested OpenGL version is less than 3.2,
487*61046927SAndroid Build Coastguard Worker        *     EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR is ignored and the
488*61046927SAndroid Build Coastguard Worker        *     functionality of the context is determined solely by the
489*61046927SAndroid Build Coastguard Worker        *     requested version."
490*61046927SAndroid Build Coastguard Worker        *
491*61046927SAndroid Build Coastguard Worker        * Since the value is ignored, only validate the setting if the version
492*61046927SAndroid Build Coastguard Worker        * is >= 3.2.
493*61046927SAndroid Build Coastguard Worker        */
494*61046927SAndroid Build Coastguard Worker       if (ctx->ClientMajorVersion >= 4 ||
495*61046927SAndroid Build Coastguard Worker           (ctx->ClientMajorVersion == 3 && ctx->ClientMinorVersion >= 2)) {
496*61046927SAndroid Build Coastguard Worker          switch (ctx->Profile) {
497*61046927SAndroid Build Coastguard Worker          case EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR:
498*61046927SAndroid Build Coastguard Worker          case EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR:
499*61046927SAndroid Build Coastguard Worker             break;
500*61046927SAndroid Build Coastguard Worker 
501*61046927SAndroid Build Coastguard Worker          default:
502*61046927SAndroid Build Coastguard Worker             /* The EGL_KHR_create_context spec says:
503*61046927SAndroid Build Coastguard Worker              *
504*61046927SAndroid Build Coastguard Worker              *     "* If an OpenGL context is requested, the requested version
505*61046927SAndroid Build Coastguard Worker              *        is greater than 3.2, and the value for attribute
506*61046927SAndroid Build Coastguard Worker              *        EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR has no bits set; has
507*61046927SAndroid Build Coastguard Worker              *        any bits set other than
508*61046927SAndroid Build Coastguard Worker              * EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR and
509*61046927SAndroid Build Coastguard Worker              * EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR; has more than
510*61046927SAndroid Build Coastguard Worker              * one of these bits set; or if the implementation does not support
511*61046927SAndroid Build Coastguard Worker              * the requested profile, then an EGL_BAD_MATCH error is generated."
512*61046927SAndroid Build Coastguard Worker              */
513*61046927SAndroid Build Coastguard Worker             err = EGL_BAD_MATCH;
514*61046927SAndroid Build Coastguard Worker             break;
515*61046927SAndroid Build Coastguard Worker          }
516*61046927SAndroid Build Coastguard Worker       }
517*61046927SAndroid Build Coastguard Worker 
518*61046927SAndroid Build Coastguard Worker       /* The EGL_KHR_create_context spec says:
519*61046927SAndroid Build Coastguard Worker        *
520*61046927SAndroid Build Coastguard Worker        *     "* If an OpenGL context is requested and the values for
521*61046927SAndroid Build Coastguard Worker        *        attributes EGL_CONTEXT_MAJOR_VERSION_KHR and
522*61046927SAndroid Build Coastguard Worker        *        EGL_CONTEXT_MINOR_VERSION_KHR, when considered together with
523*61046927SAndroid Build Coastguard Worker        *        the value for attribute
524*61046927SAndroid Build Coastguard Worker        *        EGL_CONTEXT_FORWARD_COMPATIBLE_BIT_KHR, specify an OpenGL
525*61046927SAndroid Build Coastguard Worker        *        version and feature set that are not defined, than an
526*61046927SAndroid Build Coastguard Worker        *        EGL_BAD_MATCH error is generated.
527*61046927SAndroid Build Coastguard Worker        *
528*61046927SAndroid Build Coastguard Worker        *        ... Thus, examples of invalid combinations of attributes
529*61046927SAndroid Build Coastguard Worker        *        include:
530*61046927SAndroid Build Coastguard Worker        *
531*61046927SAndroid Build Coastguard Worker        *          - Major version < 1 or > 4
532*61046927SAndroid Build Coastguard Worker        *          - Major version == 1 and minor version < 0 or > 5
533*61046927SAndroid Build Coastguard Worker        *          - Major version == 2 and minor version < 0 or > 1
534*61046927SAndroid Build Coastguard Worker        *          - Major version == 3 and minor version < 0 or > 2
535*61046927SAndroid Build Coastguard Worker        *          - Major version == 4 and minor version < 0 or > 2
536*61046927SAndroid Build Coastguard Worker        *          - Forward-compatible flag set and major version < 3"
537*61046927SAndroid Build Coastguard Worker        */
538*61046927SAndroid Build Coastguard Worker       if (ctx->ClientMajorVersion < 1 || ctx->ClientMinorVersion < 0)
539*61046927SAndroid Build Coastguard Worker          err = EGL_BAD_MATCH;
540*61046927SAndroid Build Coastguard Worker 
541*61046927SAndroid Build Coastguard Worker       switch (ctx->ClientMajorVersion) {
542*61046927SAndroid Build Coastguard Worker       case 1:
543*61046927SAndroid Build Coastguard Worker          if (ctx->ClientMinorVersion > 5 ||
544*61046927SAndroid Build Coastguard Worker              (ctx->Flags & EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR) != 0)
545*61046927SAndroid Build Coastguard Worker             err = EGL_BAD_MATCH;
546*61046927SAndroid Build Coastguard Worker          break;
547*61046927SAndroid Build Coastguard Worker 
548*61046927SAndroid Build Coastguard Worker       case 2:
549*61046927SAndroid Build Coastguard Worker          if (ctx->ClientMinorVersion > 1 ||
550*61046927SAndroid Build Coastguard Worker              (ctx->Flags & EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR) != 0)
551*61046927SAndroid Build Coastguard Worker             err = EGL_BAD_MATCH;
552*61046927SAndroid Build Coastguard Worker          break;
553*61046927SAndroid Build Coastguard Worker 
554*61046927SAndroid Build Coastguard Worker       case 3:
555*61046927SAndroid Build Coastguard Worker          /* Note: The text above is incorrect.  There *is* an OpenGL 3.3!
556*61046927SAndroid Build Coastguard Worker           */
557*61046927SAndroid Build Coastguard Worker          if (ctx->ClientMinorVersion > 3)
558*61046927SAndroid Build Coastguard Worker             err = EGL_BAD_MATCH;
559*61046927SAndroid Build Coastguard Worker          break;
560*61046927SAndroid Build Coastguard Worker 
561*61046927SAndroid Build Coastguard Worker       case 4:
562*61046927SAndroid Build Coastguard Worker       default:
563*61046927SAndroid Build Coastguard Worker          /* Don't put additional version checks here.  We don't know that
564*61046927SAndroid Build Coastguard Worker           * there won't be versions > 4.2.
565*61046927SAndroid Build Coastguard Worker           */
566*61046927SAndroid Build Coastguard Worker          break;
567*61046927SAndroid Build Coastguard Worker       }
568*61046927SAndroid Build Coastguard Worker    } else if (api == EGL_OPENGL_ES_API) {
569*61046927SAndroid Build Coastguard Worker       /* The EGL_KHR_create_context spec says:
570*61046927SAndroid Build Coastguard Worker        *
571*61046927SAndroid Build Coastguard Worker        *     "* If an OpenGL ES context is requested and the values for
572*61046927SAndroid Build Coastguard Worker        *        attributes EGL_CONTEXT_MAJOR_VERSION_KHR and
573*61046927SAndroid Build Coastguard Worker        *        EGL_CONTEXT_MINOR_VERSION_KHR specify an OpenGL ES version that
574*61046927SAndroid Build Coastguard Worker        *        is not defined, than an EGL_BAD_MATCH error is generated.
575*61046927SAndroid Build Coastguard Worker        *
576*61046927SAndroid Build Coastguard Worker        *        ... Examples of invalid combinations of attributes include:
577*61046927SAndroid Build Coastguard Worker        *
578*61046927SAndroid Build Coastguard Worker        *          - Major version < 1 or > 2
579*61046927SAndroid Build Coastguard Worker        *          - Major version == 1 and minor version < 0 or > 1
580*61046927SAndroid Build Coastguard Worker        *          - Major version == 2 and minor version != 0
581*61046927SAndroid Build Coastguard Worker        */
582*61046927SAndroid Build Coastguard Worker       if (ctx->ClientMajorVersion < 1 || ctx->ClientMinorVersion < 0)
583*61046927SAndroid Build Coastguard Worker          err = EGL_BAD_MATCH;
584*61046927SAndroid Build Coastguard Worker 
585*61046927SAndroid Build Coastguard Worker       switch (ctx->ClientMajorVersion) {
586*61046927SAndroid Build Coastguard Worker       case 1:
587*61046927SAndroid Build Coastguard Worker          if (ctx->ClientMinorVersion > 1)
588*61046927SAndroid Build Coastguard Worker             err = EGL_BAD_MATCH;
589*61046927SAndroid Build Coastguard Worker          break;
590*61046927SAndroid Build Coastguard Worker 
591*61046927SAndroid Build Coastguard Worker       case 2:
592*61046927SAndroid Build Coastguard Worker          if (ctx->ClientMinorVersion > 0)
593*61046927SAndroid Build Coastguard Worker             err = EGL_BAD_MATCH;
594*61046927SAndroid Build Coastguard Worker          break;
595*61046927SAndroid Build Coastguard Worker 
596*61046927SAndroid Build Coastguard Worker       case 3:
597*61046927SAndroid Build Coastguard Worker          /* Don't put additional version checks here.  We don't know that
598*61046927SAndroid Build Coastguard Worker           * there won't be versions > 3.0.
599*61046927SAndroid Build Coastguard Worker           */
600*61046927SAndroid Build Coastguard Worker          break;
601*61046927SAndroid Build Coastguard Worker 
602*61046927SAndroid Build Coastguard Worker       default:
603*61046927SAndroid Build Coastguard Worker          err = EGL_BAD_MATCH;
604*61046927SAndroid Build Coastguard Worker          break;
605*61046927SAndroid Build Coastguard Worker       }
606*61046927SAndroid Build Coastguard Worker    }
607*61046927SAndroid Build Coastguard Worker 
608*61046927SAndroid Build Coastguard Worker    switch (ctx->ResetNotificationStrategy) {
609*61046927SAndroid Build Coastguard Worker    case EGL_NO_RESET_NOTIFICATION_KHR:
610*61046927SAndroid Build Coastguard Worker    case EGL_LOSE_CONTEXT_ON_RESET_KHR:
611*61046927SAndroid Build Coastguard Worker       break;
612*61046927SAndroid Build Coastguard Worker 
613*61046927SAndroid Build Coastguard Worker    default:
614*61046927SAndroid Build Coastguard Worker       err = EGL_BAD_ATTRIBUTE;
615*61046927SAndroid Build Coastguard Worker       break;
616*61046927SAndroid Build Coastguard Worker    }
617*61046927SAndroid Build Coastguard Worker 
618*61046927SAndroid Build Coastguard Worker    /* The EGL_KHR_create_context_no_error spec says:
619*61046927SAndroid Build Coastguard Worker     *
620*61046927SAndroid Build Coastguard Worker     *    "BAD_MATCH is generated if the EGL_CONTEXT_OPENGL_NO_ERROR_KHR is TRUE
621*61046927SAndroid Build Coastguard Worker     * at the same time as a debug or robustness context is specified."
622*61046927SAndroid Build Coastguard Worker     */
623*61046927SAndroid Build Coastguard Worker    if (ctx->NoError &&
624*61046927SAndroid Build Coastguard Worker        (ctx->Flags & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR ||
625*61046927SAndroid Build Coastguard Worker         ctx->Flags & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR)) {
626*61046927SAndroid Build Coastguard Worker       err = EGL_BAD_MATCH;
627*61046927SAndroid Build Coastguard Worker    }
628*61046927SAndroid Build Coastguard Worker 
629*61046927SAndroid Build Coastguard Worker    if ((ctx->Flags & ~(EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR |
630*61046927SAndroid Build Coastguard Worker                        EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR |
631*61046927SAndroid Build Coastguard Worker                        EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR)) != 0) {
632*61046927SAndroid Build Coastguard Worker       err = EGL_BAD_ATTRIBUTE;
633*61046927SAndroid Build Coastguard Worker    }
634*61046927SAndroid Build Coastguard Worker 
635*61046927SAndroid Build Coastguard Worker    return err;
636*61046927SAndroid Build Coastguard Worker }
637*61046927SAndroid Build Coastguard Worker 
638*61046927SAndroid Build Coastguard Worker /**
639*61046927SAndroid Build Coastguard Worker  * Initialize the given _EGLContext object to defaults and/or the values
640*61046927SAndroid Build Coastguard Worker  * in the attrib_list.
641*61046927SAndroid Build Coastguard Worker  *
642*61046927SAndroid Build Coastguard Worker  * According to EGL 1.5 Section 3.7:
643*61046927SAndroid Build Coastguard Worker  *
644*61046927SAndroid Build Coastguard Worker  *	"EGL_OPENGL_API and EGL_OPENGL_ES_API are interchangeable for all
645*61046927SAndroid Build Coastguard Worker  *	purposes except eglCreateContext."
646*61046927SAndroid Build Coastguard Worker  *
647*61046927SAndroid Build Coastguard Worker  * And since we only support GL and GLES, this is the only place where the
648*61046927SAndroid Build Coastguard Worker  * bound API matters at all. We look up the current API from the current
649*61046927SAndroid Build Coastguard Worker  * thread, and stash that in the context we're initializing. Our caller is
650*61046927SAndroid Build Coastguard Worker  * responsible for determining whether that's an API it supports.
651*61046927SAndroid Build Coastguard Worker  */
652*61046927SAndroid Build Coastguard Worker EGLBoolean
_eglInitContext(_EGLContext * ctx,_EGLDisplay * disp,_EGLConfig * conf,_EGLContext * share_list,const EGLint * attrib_list)653*61046927SAndroid Build Coastguard Worker _eglInitContext(_EGLContext *ctx, _EGLDisplay *disp, _EGLConfig *conf,
654*61046927SAndroid Build Coastguard Worker                 _EGLContext *share_list, const EGLint *attrib_list)
655*61046927SAndroid Build Coastguard Worker {
656*61046927SAndroid Build Coastguard Worker    const EGLenum api = eglQueryAPI();
657*61046927SAndroid Build Coastguard Worker    EGLint err;
658*61046927SAndroid Build Coastguard Worker 
659*61046927SAndroid Build Coastguard Worker    if (api == EGL_NONE)
660*61046927SAndroid Build Coastguard Worker       return _eglError(EGL_BAD_MATCH, "eglCreateContext(no client API)");
661*61046927SAndroid Build Coastguard Worker 
662*61046927SAndroid Build Coastguard Worker    _eglInitResource(&ctx->Resource, sizeof(*ctx), disp);
663*61046927SAndroid Build Coastguard Worker    ctx->ClientAPI = api;
664*61046927SAndroid Build Coastguard Worker    ctx->Config = conf;
665*61046927SAndroid Build Coastguard Worker    ctx->Profile = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
666*61046927SAndroid Build Coastguard Worker 
667*61046927SAndroid Build Coastguard Worker    ctx->ClientMajorVersion = 1; /* the default, per EGL spec */
668*61046927SAndroid Build Coastguard Worker    ctx->ClientMinorVersion = 0;
669*61046927SAndroid Build Coastguard Worker    ctx->Flags = 0;
670*61046927SAndroid Build Coastguard Worker    ctx->ResetNotificationStrategy = EGL_NO_RESET_NOTIFICATION_KHR;
671*61046927SAndroid Build Coastguard Worker    ctx->ContextPriority = EGL_CONTEXT_PRIORITY_MEDIUM_IMG;
672*61046927SAndroid Build Coastguard Worker    ctx->ReleaseBehavior = EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR;
673*61046927SAndroid Build Coastguard Worker 
674*61046927SAndroid Build Coastguard Worker    err = _eglParseContextAttribList(ctx, disp, attrib_list);
675*61046927SAndroid Build Coastguard Worker    if (err == EGL_SUCCESS && ctx->Config) {
676*61046927SAndroid Build Coastguard Worker       EGLint api_bit;
677*61046927SAndroid Build Coastguard Worker 
678*61046927SAndroid Build Coastguard Worker       api_bit = _eglGetContextAPIBit(ctx);
679*61046927SAndroid Build Coastguard Worker       if (!(ctx->Config->RenderableType & api_bit)) {
680*61046927SAndroid Build Coastguard Worker          _eglLog(_EGL_DEBUG, "context api is 0x%x while config supports 0x%x",
681*61046927SAndroid Build Coastguard Worker                  api_bit, ctx->Config->RenderableType);
682*61046927SAndroid Build Coastguard Worker          err = EGL_BAD_CONFIG;
683*61046927SAndroid Build Coastguard Worker       }
684*61046927SAndroid Build Coastguard Worker    }
685*61046927SAndroid Build Coastguard Worker    if (err != EGL_SUCCESS)
686*61046927SAndroid Build Coastguard Worker       return _eglError(err, "eglCreateContext");
687*61046927SAndroid Build Coastguard Worker 
688*61046927SAndroid Build Coastguard Worker    /* The EGL_EXT_create_context_robustness spec says:
689*61046927SAndroid Build Coastguard Worker     *
690*61046927SAndroid Build Coastguard Worker     *    "Add to the eglCreateContext context creation errors: [...]
691*61046927SAndroid Build Coastguard Worker     *
692*61046927SAndroid Build Coastguard Worker     *     * If the reset notification behavior of <share_context> and the
693*61046927SAndroid Build Coastguard Worker     *       newly created context are different then an EGL_BAD_MATCH error is
694*61046927SAndroid Build Coastguard Worker     *       generated."
695*61046927SAndroid Build Coastguard Worker     */
696*61046927SAndroid Build Coastguard Worker    if (share_list && share_list->ResetNotificationStrategy !=
697*61046927SAndroid Build Coastguard Worker                         ctx->ResetNotificationStrategy) {
698*61046927SAndroid Build Coastguard Worker       return _eglError(
699*61046927SAndroid Build Coastguard Worker          EGL_BAD_MATCH,
700*61046927SAndroid Build Coastguard Worker          "eglCreateContext() share list notification strategy mismatch");
701*61046927SAndroid Build Coastguard Worker    }
702*61046927SAndroid Build Coastguard Worker 
703*61046927SAndroid Build Coastguard Worker    /* The EGL_KHR_create_context_no_error spec says:
704*61046927SAndroid Build Coastguard Worker     *
705*61046927SAndroid Build Coastguard Worker     *    "BAD_MATCH is generated if the value of EGL_CONTEXT_OPENGL_NO_ERROR_KHR
706*61046927SAndroid Build Coastguard Worker     *    used to create <share_context> does not match the value of
707*61046927SAndroid Build Coastguard Worker     *    EGL_CONTEXT_OPENGL_NO_ERROR_KHR for the context being created."
708*61046927SAndroid Build Coastguard Worker     */
709*61046927SAndroid Build Coastguard Worker    if (share_list && share_list->NoError != ctx->NoError) {
710*61046927SAndroid Build Coastguard Worker       return _eglError(EGL_BAD_MATCH,
711*61046927SAndroid Build Coastguard Worker                        "eglCreateContext() share list no-error mismatch");
712*61046927SAndroid Build Coastguard Worker    }
713*61046927SAndroid Build Coastguard Worker 
714*61046927SAndroid Build Coastguard Worker    return EGL_TRUE;
715*61046927SAndroid Build Coastguard Worker }
716*61046927SAndroid Build Coastguard Worker 
717*61046927SAndroid Build Coastguard Worker static EGLint
_eglQueryContextRenderBuffer(_EGLContext * ctx)718*61046927SAndroid Build Coastguard Worker _eglQueryContextRenderBuffer(_EGLContext *ctx)
719*61046927SAndroid Build Coastguard Worker {
720*61046927SAndroid Build Coastguard Worker    _EGLSurface *surf = ctx->DrawSurface;
721*61046927SAndroid Build Coastguard Worker 
722*61046927SAndroid Build Coastguard Worker    /* From the EGL 1.5 spec:
723*61046927SAndroid Build Coastguard Worker     *
724*61046927SAndroid Build Coastguard Worker     *    - If the context is not bound to a surface, then EGL_NONE will be
725*61046927SAndroid Build Coastguard Worker     *      returned.
726*61046927SAndroid Build Coastguard Worker     */
727*61046927SAndroid Build Coastguard Worker    if (!surf)
728*61046927SAndroid Build Coastguard Worker       return EGL_NONE;
729*61046927SAndroid Build Coastguard Worker 
730*61046927SAndroid Build Coastguard Worker    switch (surf->Type) {
731*61046927SAndroid Build Coastguard Worker    default:
732*61046927SAndroid Build Coastguard Worker       unreachable("bad EGLSurface type");
733*61046927SAndroid Build Coastguard Worker    case EGL_PIXMAP_BIT:
734*61046927SAndroid Build Coastguard Worker       /* - If the context is bound to a pixmap surface, then EGL_SINGLE_BUFFER
735*61046927SAndroid Build Coastguard Worker        *   will be returned.
736*61046927SAndroid Build Coastguard Worker        */
737*61046927SAndroid Build Coastguard Worker       return EGL_SINGLE_BUFFER;
738*61046927SAndroid Build Coastguard Worker    case EGL_PBUFFER_BIT:
739*61046927SAndroid Build Coastguard Worker       /* - If the context is bound to a pbuffer surface, then EGL_BACK_BUFFER
740*61046927SAndroid Build Coastguard Worker        *   will be returned.
741*61046927SAndroid Build Coastguard Worker        */
742*61046927SAndroid Build Coastguard Worker       return EGL_BACK_BUFFER;
743*61046927SAndroid Build Coastguard Worker    case EGL_WINDOW_BIT:
744*61046927SAndroid Build Coastguard Worker       /* - If the context is bound to a window surface, then either
745*61046927SAndroid Build Coastguard Worker        *   EGL_BACK_BUFFER or EGL_SINGLE_BUFFER may be returned. The value
746*61046927SAndroid Build Coastguard Worker        *   returned depends on both the buffer requested by the setting of the
747*61046927SAndroid Build Coastguard Worker        *   EGL_RENDER_BUFFER property of the surface [...], and on the client
748*61046927SAndroid Build Coastguard Worker        *   API (not all client APIs support single-buffer Rendering to window
749*61046927SAndroid Build Coastguard Worker        *   surfaces). Some client APIs allow control of whether rendering goes
750*61046927SAndroid Build Coastguard Worker        *   to the front or back buffer. This client API-specific choice is not
751*61046927SAndroid Build Coastguard Worker        *   reflected in the returned value, which only describes the buffer
752*61046927SAndroid Build Coastguard Worker        *   that will be rendered to by default if not overridden by the client
753*61046927SAndroid Build Coastguard Worker        *   API.
754*61046927SAndroid Build Coastguard Worker        */
755*61046927SAndroid Build Coastguard Worker       return surf->ActiveRenderBuffer;
756*61046927SAndroid Build Coastguard Worker    }
757*61046927SAndroid Build Coastguard Worker }
758*61046927SAndroid Build Coastguard Worker 
759*61046927SAndroid Build Coastguard Worker EGLBoolean
_eglQueryContext(_EGLContext * c,EGLint attribute,EGLint * value)760*61046927SAndroid Build Coastguard Worker _eglQueryContext(_EGLContext *c, EGLint attribute, EGLint *value)
761*61046927SAndroid Build Coastguard Worker {
762*61046927SAndroid Build Coastguard Worker    _EGLDisplay *disp = c->Resource.Display;
763*61046927SAndroid Build Coastguard Worker 
764*61046927SAndroid Build Coastguard Worker    if (!value)
765*61046927SAndroid Build Coastguard Worker       return _eglError(EGL_BAD_PARAMETER, "eglQueryContext");
766*61046927SAndroid Build Coastguard Worker 
767*61046927SAndroid Build Coastguard Worker    switch (attribute) {
768*61046927SAndroid Build Coastguard Worker    case EGL_CONFIG_ID:
769*61046927SAndroid Build Coastguard Worker       /*
770*61046927SAndroid Build Coastguard Worker        * From EGL_KHR_no_config_context:
771*61046927SAndroid Build Coastguard Worker        *
772*61046927SAndroid Build Coastguard Worker        *    "Querying EGL_CONFIG_ID returns the ID of the EGLConfig with
773*61046927SAndroid Build Coastguard Worker        *     respect to which the context was created, or zero if created
774*61046927SAndroid Build Coastguard Worker        *     without respect to an EGLConfig."
775*61046927SAndroid Build Coastguard Worker        */
776*61046927SAndroid Build Coastguard Worker       *value = c->Config ? c->Config->ConfigID : 0;
777*61046927SAndroid Build Coastguard Worker       break;
778*61046927SAndroid Build Coastguard Worker    case EGL_CONTEXT_CLIENT_VERSION:
779*61046927SAndroid Build Coastguard Worker       *value = c->ClientMajorVersion;
780*61046927SAndroid Build Coastguard Worker       break;
781*61046927SAndroid Build Coastguard Worker    case EGL_CONTEXT_CLIENT_TYPE:
782*61046927SAndroid Build Coastguard Worker       *value = c->ClientAPI;
783*61046927SAndroid Build Coastguard Worker       break;
784*61046927SAndroid Build Coastguard Worker    case EGL_RENDER_BUFFER:
785*61046927SAndroid Build Coastguard Worker       *value = _eglQueryContextRenderBuffer(c);
786*61046927SAndroid Build Coastguard Worker       break;
787*61046927SAndroid Build Coastguard Worker    case EGL_CONTEXT_PRIORITY_LEVEL_IMG:
788*61046927SAndroid Build Coastguard Worker       *value = c->ContextPriority;
789*61046927SAndroid Build Coastguard Worker       break;
790*61046927SAndroid Build Coastguard Worker    case EGL_PROTECTED_CONTENT_EXT:
791*61046927SAndroid Build Coastguard Worker       if (!disp->Extensions.EXT_protected_content)
792*61046927SAndroid Build Coastguard Worker          return _eglError(EGL_BAD_ATTRIBUTE, "eglQueryContext");
793*61046927SAndroid Build Coastguard Worker       *value = c->Protected;
794*61046927SAndroid Build Coastguard Worker       break;
795*61046927SAndroid Build Coastguard Worker    case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
796*61046927SAndroid Build Coastguard Worker       if (!disp->Extensions.EXT_query_reset_notification_strategy)
797*61046927SAndroid Build Coastguard Worker          return _eglError(EGL_BAD_ATTRIBUTE, "eglQueryContext");
798*61046927SAndroid Build Coastguard Worker       *value = c->ResetNotificationStrategy;
799*61046927SAndroid Build Coastguard Worker       break;
800*61046927SAndroid Build Coastguard Worker    default:
801*61046927SAndroid Build Coastguard Worker       return _eglError(EGL_BAD_ATTRIBUTE, "eglQueryContext");
802*61046927SAndroid Build Coastguard Worker    }
803*61046927SAndroid Build Coastguard Worker 
804*61046927SAndroid Build Coastguard Worker    return EGL_TRUE;
805*61046927SAndroid Build Coastguard Worker }
806*61046927SAndroid Build Coastguard Worker 
807*61046927SAndroid Build Coastguard Worker /**
808*61046927SAndroid Build Coastguard Worker  * Bind the context to the thread and return the previous context.
809*61046927SAndroid Build Coastguard Worker  *
810*61046927SAndroid Build Coastguard Worker  * Note that the context may be NULL.
811*61046927SAndroid Build Coastguard Worker  */
812*61046927SAndroid Build Coastguard Worker _EGLContext *
_eglBindContextToThread(_EGLContext * ctx,_EGLThreadInfo * t)813*61046927SAndroid Build Coastguard Worker _eglBindContextToThread(_EGLContext *ctx, _EGLThreadInfo *t)
814*61046927SAndroid Build Coastguard Worker {
815*61046927SAndroid Build Coastguard Worker    _EGLContext *oldCtx;
816*61046927SAndroid Build Coastguard Worker 
817*61046927SAndroid Build Coastguard Worker    oldCtx = t->CurrentContext;
818*61046927SAndroid Build Coastguard Worker    if (ctx != oldCtx) {
819*61046927SAndroid Build Coastguard Worker       if (oldCtx)
820*61046927SAndroid Build Coastguard Worker          oldCtx->Binding = NULL;
821*61046927SAndroid Build Coastguard Worker       if (ctx)
822*61046927SAndroid Build Coastguard Worker          ctx->Binding = t;
823*61046927SAndroid Build Coastguard Worker 
824*61046927SAndroid Build Coastguard Worker       t->CurrentContext = ctx;
825*61046927SAndroid Build Coastguard Worker    }
826*61046927SAndroid Build Coastguard Worker 
827*61046927SAndroid Build Coastguard Worker    return oldCtx;
828*61046927SAndroid Build Coastguard Worker }
829*61046927SAndroid Build Coastguard Worker 
830*61046927SAndroid Build Coastguard Worker /**
831*61046927SAndroid Build Coastguard Worker  * Return true if the given context and surfaces can be made current.
832*61046927SAndroid Build Coastguard Worker  */
833*61046927SAndroid Build Coastguard Worker static EGLBoolean
_eglCheckMakeCurrent(_EGLContext * ctx,_EGLSurface * draw,_EGLSurface * read)834*61046927SAndroid Build Coastguard Worker _eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read)
835*61046927SAndroid Build Coastguard Worker {
836*61046927SAndroid Build Coastguard Worker    _EGLThreadInfo *t = _eglGetCurrentThread();
837*61046927SAndroid Build Coastguard Worker    _EGLDisplay *disp;
838*61046927SAndroid Build Coastguard Worker 
839*61046927SAndroid Build Coastguard Worker    /* this is easy */
840*61046927SAndroid Build Coastguard Worker    if (!ctx) {
841*61046927SAndroid Build Coastguard Worker       if (draw || read)
842*61046927SAndroid Build Coastguard Worker          return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
843*61046927SAndroid Build Coastguard Worker       return EGL_TRUE;
844*61046927SAndroid Build Coastguard Worker    }
845*61046927SAndroid Build Coastguard Worker 
846*61046927SAndroid Build Coastguard Worker    disp = ctx->Resource.Display;
847*61046927SAndroid Build Coastguard Worker    if (!disp->Extensions.KHR_surfaceless_context &&
848*61046927SAndroid Build Coastguard Worker        (draw == NULL || read == NULL))
849*61046927SAndroid Build Coastguard Worker       return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
850*61046927SAndroid Build Coastguard Worker 
851*61046927SAndroid Build Coastguard Worker    /*
852*61046927SAndroid Build Coastguard Worker     * The spec says
853*61046927SAndroid Build Coastguard Worker     *
854*61046927SAndroid Build Coastguard Worker     * "If ctx is current to some other thread, or if either draw or read are
855*61046927SAndroid Build Coastguard Worker     * bound to contexts in another thread, an EGL_BAD_ACCESS error is
856*61046927SAndroid Build Coastguard Worker     * generated."
857*61046927SAndroid Build Coastguard Worker     *
858*61046927SAndroid Build Coastguard Worker     * and
859*61046927SAndroid Build Coastguard Worker     *
860*61046927SAndroid Build Coastguard Worker     * "at most one context may be bound to a particular surface at a given
861*61046927SAndroid Build Coastguard Worker     * time"
862*61046927SAndroid Build Coastguard Worker     */
863*61046927SAndroid Build Coastguard Worker    if (ctx->Binding && ctx->Binding != t)
864*61046927SAndroid Build Coastguard Worker       return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
865*61046927SAndroid Build Coastguard Worker    if (draw && draw->CurrentContext && draw->CurrentContext != ctx) {
866*61046927SAndroid Build Coastguard Worker       if (draw->CurrentContext->Binding != t)
867*61046927SAndroid Build Coastguard Worker          return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
868*61046927SAndroid Build Coastguard Worker    }
869*61046927SAndroid Build Coastguard Worker    if (read && read->CurrentContext && read->CurrentContext != ctx) {
870*61046927SAndroid Build Coastguard Worker       if (read->CurrentContext->Binding != t)
871*61046927SAndroid Build Coastguard Worker          return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
872*61046927SAndroid Build Coastguard Worker    }
873*61046927SAndroid Build Coastguard Worker 
874*61046927SAndroid Build Coastguard Worker    /* If the context has a config then it must match that of the two
875*61046927SAndroid Build Coastguard Worker     * surfaces */
876*61046927SAndroid Build Coastguard Worker    if (ctx->Config) {
877*61046927SAndroid Build Coastguard Worker       if ((draw && draw->Config != ctx->Config) ||
878*61046927SAndroid Build Coastguard Worker           (read && read->Config != ctx->Config))
879*61046927SAndroid Build Coastguard Worker          return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
880*61046927SAndroid Build Coastguard Worker    } else {
881*61046927SAndroid Build Coastguard Worker       /* Otherwise we must be using the EGL_KHR_no_config_context
882*61046927SAndroid Build Coastguard Worker        * extension */
883*61046927SAndroid Build Coastguard Worker       assert(disp->Extensions.KHR_no_config_context);
884*61046927SAndroid Build Coastguard Worker    }
885*61046927SAndroid Build Coastguard Worker 
886*61046927SAndroid Build Coastguard Worker    return EGL_TRUE;
887*61046927SAndroid Build Coastguard Worker }
888*61046927SAndroid Build Coastguard Worker 
889*61046927SAndroid Build Coastguard Worker /**
890*61046927SAndroid Build Coastguard Worker  * Bind the context to the current thread and given surfaces.  Return the
891*61046927SAndroid Build Coastguard Worker  * previous bound context and surfaces.  The caller should unreference the
892*61046927SAndroid Build Coastguard Worker  * returned context and surfaces.
893*61046927SAndroid Build Coastguard Worker  *
894*61046927SAndroid Build Coastguard Worker  * Making a second call with the resources returned by the first call
895*61046927SAndroid Build Coastguard Worker  * unsurprisingly undoes the first call, except for the resource reference
896*61046927SAndroid Build Coastguard Worker  * counts.
897*61046927SAndroid Build Coastguard Worker  */
898*61046927SAndroid Build Coastguard Worker EGLBoolean
_eglBindContext(_EGLContext * ctx,_EGLSurface * draw,_EGLSurface * read,_EGLContext ** old_ctx,_EGLSurface ** old_draw,_EGLSurface ** old_read)899*61046927SAndroid Build Coastguard Worker _eglBindContext(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read,
900*61046927SAndroid Build Coastguard Worker                 _EGLContext **old_ctx, _EGLSurface **old_draw,
901*61046927SAndroid Build Coastguard Worker                 _EGLSurface **old_read)
902*61046927SAndroid Build Coastguard Worker {
903*61046927SAndroid Build Coastguard Worker    _EGLThreadInfo *t = _eglGetCurrentThread();
904*61046927SAndroid Build Coastguard Worker    _EGLContext *prev_ctx;
905*61046927SAndroid Build Coastguard Worker    _EGLSurface *prev_draw, *prev_read;
906*61046927SAndroid Build Coastguard Worker 
907*61046927SAndroid Build Coastguard Worker    if (!_eglCheckMakeCurrent(ctx, draw, read))
908*61046927SAndroid Build Coastguard Worker       return EGL_FALSE;
909*61046927SAndroid Build Coastguard Worker 
910*61046927SAndroid Build Coastguard Worker    /* increment refcounts before binding */
911*61046927SAndroid Build Coastguard Worker    _eglGetContext(ctx);
912*61046927SAndroid Build Coastguard Worker    _eglGetSurface(draw);
913*61046927SAndroid Build Coastguard Worker    _eglGetSurface(read);
914*61046927SAndroid Build Coastguard Worker 
915*61046927SAndroid Build Coastguard Worker    /* bind the new context */
916*61046927SAndroid Build Coastguard Worker    prev_ctx = _eglBindContextToThread(ctx, t);
917*61046927SAndroid Build Coastguard Worker 
918*61046927SAndroid Build Coastguard Worker    /* break previous bindings */
919*61046927SAndroid Build Coastguard Worker    if (prev_ctx) {
920*61046927SAndroid Build Coastguard Worker       prev_draw = prev_ctx->DrawSurface;
921*61046927SAndroid Build Coastguard Worker       prev_read = prev_ctx->ReadSurface;
922*61046927SAndroid Build Coastguard Worker 
923*61046927SAndroid Build Coastguard Worker       if (prev_draw)
924*61046927SAndroid Build Coastguard Worker          prev_draw->CurrentContext = NULL;
925*61046927SAndroid Build Coastguard Worker       if (prev_read)
926*61046927SAndroid Build Coastguard Worker          prev_read->CurrentContext = NULL;
927*61046927SAndroid Build Coastguard Worker 
928*61046927SAndroid Build Coastguard Worker       prev_ctx->DrawSurface = NULL;
929*61046927SAndroid Build Coastguard Worker       prev_ctx->ReadSurface = NULL;
930*61046927SAndroid Build Coastguard Worker    } else {
931*61046927SAndroid Build Coastguard Worker       prev_draw = prev_read = NULL;
932*61046927SAndroid Build Coastguard Worker    }
933*61046927SAndroid Build Coastguard Worker 
934*61046927SAndroid Build Coastguard Worker    /* establish new bindings */
935*61046927SAndroid Build Coastguard Worker    if (ctx) {
936*61046927SAndroid Build Coastguard Worker       if (draw)
937*61046927SAndroid Build Coastguard Worker          draw->CurrentContext = ctx;
938*61046927SAndroid Build Coastguard Worker       if (read)
939*61046927SAndroid Build Coastguard Worker          read->CurrentContext = ctx;
940*61046927SAndroid Build Coastguard Worker 
941*61046927SAndroid Build Coastguard Worker       ctx->DrawSurface = draw;
942*61046927SAndroid Build Coastguard Worker       ctx->ReadSurface = read;
943*61046927SAndroid Build Coastguard Worker    }
944*61046927SAndroid Build Coastguard Worker 
945*61046927SAndroid Build Coastguard Worker    assert(old_ctx && old_draw && old_read);
946*61046927SAndroid Build Coastguard Worker    *old_ctx = prev_ctx;
947*61046927SAndroid Build Coastguard Worker    *old_draw = prev_draw;
948*61046927SAndroid Build Coastguard Worker    *old_read = prev_read;
949*61046927SAndroid Build Coastguard Worker 
950*61046927SAndroid Build Coastguard Worker    return EGL_TRUE;
951*61046927SAndroid Build Coastguard Worker }
952