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