Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4358 | Serge | 1 | /************************************************************************** |
2 | * |
||
3 | * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
||
4 | * Copyright 2009-2010 Chia-I Wu |
||
5 | * Copyright 2010-2011 LunarG, Inc. |
||
6 | * All Rights Reserved. |
||
7 | * |
||
8 | * Permission is hereby granted, free of charge, to any person obtaining a |
||
9 | * copy of this software and associated documentation files (the |
||
10 | * "Software"), to deal in the Software without restriction, including |
||
11 | * without limitation the rights to use, copy, modify, merge, publish, |
||
12 | * distribute, sub license, and/or sell copies of the Software, and to |
||
13 | * permit persons to whom the Software is furnished to do so, subject to |
||
14 | * the following conditions: |
||
15 | * |
||
16 | * The above copyright notice and this permission notice (including the |
||
17 | * next paragraph) shall be included in all copies or substantial portions |
||
18 | * of the Software. |
||
19 | * |
||
20 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||
21 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||
22 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||
23 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||
24 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
||
25 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||
26 | * DEALINGS IN THE SOFTWARE. |
||
27 | * |
||
28 | **************************************************************************/ |
||
29 | |||
30 | |||
31 | #include |
||
32 | #include |
||
33 | #include |
||
34 | #include "eglconfig.h" |
||
35 | #include "eglcontext.h" |
||
36 | #include "egldisplay.h" |
||
37 | #include "eglcurrent.h" |
||
38 | #include "eglsurface.h" |
||
39 | #include "egllog.h" |
||
40 | |||
41 | |||
42 | /** |
||
43 | * Return the API bit (one of EGL_xxx_BIT) of the context. |
||
44 | */ |
||
45 | static EGLint |
||
46 | _eglGetContextAPIBit(_EGLContext *ctx) |
||
47 | { |
||
48 | EGLint bit = 0; |
||
49 | |||
50 | switch (ctx->ClientAPI) { |
||
51 | case EGL_OPENGL_ES_API: |
||
52 | switch (ctx->ClientMajorVersion) { |
||
53 | case 1: |
||
54 | bit = EGL_OPENGL_ES_BIT; |
||
55 | break; |
||
56 | case 2: |
||
57 | bit = EGL_OPENGL_ES2_BIT; |
||
58 | break; |
||
59 | case 3: |
||
60 | bit = EGL_OPENGL_ES3_BIT_KHR; |
||
61 | break; |
||
62 | default: |
||
63 | break; |
||
64 | } |
||
65 | break; |
||
66 | case EGL_OPENVG_API: |
||
67 | bit = EGL_OPENVG_BIT; |
||
68 | break; |
||
69 | case EGL_OPENGL_API: |
||
70 | bit = EGL_OPENGL_BIT; |
||
71 | break; |
||
72 | default: |
||
73 | break; |
||
74 | } |
||
75 | |||
76 | return bit; |
||
77 | } |
||
78 | |||
79 | |||
80 | /** |
||
81 | * Parse the list of context attributes and return the proper error code. |
||
82 | */ |
||
83 | static EGLint |
||
84 | _eglParseContextAttribList(_EGLContext *ctx, _EGLDisplay *dpy, |
||
85 | const EGLint *attrib_list) |
||
86 | { |
||
87 | EGLenum api = ctx->ClientAPI; |
||
88 | EGLint i, err = EGL_SUCCESS; |
||
89 | |||
90 | if (!attrib_list) |
||
91 | return EGL_SUCCESS; |
||
92 | |||
93 | if (api == EGL_OPENVG_API && attrib_list[0] != EGL_NONE) { |
||
94 | _eglLog(_EGL_DEBUG, "bad context attribute 0x%04x", attrib_list[0]); |
||
95 | return EGL_BAD_ATTRIBUTE; |
||
96 | } |
||
97 | |||
98 | for (i = 0; attrib_list[i] != EGL_NONE; i++) { |
||
99 | EGLint attr = attrib_list[i++]; |
||
100 | EGLint val = attrib_list[i]; |
||
101 | |||
102 | switch (attr) { |
||
103 | case EGL_CONTEXT_CLIENT_VERSION: |
||
104 | ctx->ClientMajorVersion = val; |
||
105 | break; |
||
106 | |||
107 | case EGL_CONTEXT_MINOR_VERSION_KHR: |
||
108 | if (!dpy->Extensions.KHR_create_context) { |
||
109 | err = EGL_BAD_ATTRIBUTE; |
||
110 | break; |
||
111 | } |
||
112 | |||
113 | ctx->ClientMinorVersion = val; |
||
114 | break; |
||
115 | |||
116 | case EGL_CONTEXT_FLAGS_KHR: |
||
117 | if (!dpy->Extensions.KHR_create_context) { |
||
118 | err = EGL_BAD_ATTRIBUTE; |
||
119 | break; |
||
120 | } |
||
121 | |||
122 | /* The EGL_KHR_create_context spec says: |
||
123 | * |
||
124 | * "Flags are only defined for OpenGL context creation, and |
||
125 | * specifying a flags value other than zero for other types of |
||
126 | * contexts, including OpenGL ES contexts, will generate an |
||
127 | * error." |
||
128 | */ |
||
129 | if (api != EGL_OPENGL_API && val != 0) { |
||
130 | err = EGL_BAD_ATTRIBUTE; |
||
131 | break; |
||
132 | } |
||
133 | |||
134 | ctx->Flags = val; |
||
135 | break; |
||
136 | |||
137 | case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR: |
||
138 | if (!dpy->Extensions.KHR_create_context) { |
||
139 | err = EGL_BAD_ATTRIBUTE; |
||
140 | break; |
||
141 | } |
||
142 | |||
143 | /* The EGL_KHR_create_context spec says: |
||
144 | * |
||
145 | * "[EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR] is only meaningful for |
||
146 | * OpenGL contexts, and specifying it for other types of |
||
147 | * contexts, including OpenGL ES contexts, will generate an |
||
148 | * error." |
||
149 | */ |
||
150 | if (api != EGL_OPENGL_API) { |
||
151 | err = EGL_BAD_ATTRIBUTE; |
||
152 | break; |
||
153 | } |
||
154 | |||
155 | ctx->Profile = val; |
||
156 | break; |
||
157 | |||
158 | case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR: |
||
159 | /* The EGL_KHR_create_context spec says: |
||
160 | * |
||
161 | * "[EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR] is only |
||
162 | * meaningful for OpenGL contexts, and specifying it for other |
||
163 | * types of contexts, including OpenGL ES contexts, will generate |
||
164 | * an error." |
||
165 | */ |
||
166 | if (!dpy->Extensions.KHR_create_context |
||
167 | || api != EGL_OPENGL_API) { |
||
168 | err = EGL_BAD_ATTRIBUTE; |
||
169 | break; |
||
170 | } |
||
171 | |||
172 | ctx->ResetNotificationStrategy = val; |
||
173 | break; |
||
174 | |||
175 | case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT: |
||
176 | /* The EGL_EXT_create_context_robustness spec says: |
||
177 | * |
||
178 | * "[EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT] is only |
||
179 | * meaningful for OpenGL ES contexts, and specifying it for other |
||
180 | * types of contexts will generate an EGL_BAD_ATTRIBUTE error." |
||
181 | */ |
||
182 | if (!dpy->Extensions.EXT_create_context_robustness |
||
183 | || api != EGL_OPENGL_ES_API) { |
||
184 | err = EGL_BAD_ATTRIBUTE; |
||
185 | break; |
||
186 | } |
||
187 | |||
188 | ctx->ResetNotificationStrategy = val; |
||
189 | break; |
||
190 | |||
191 | case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT: |
||
192 | if (!dpy->Extensions.EXT_create_context_robustness) { |
||
193 | err = EGL_BAD_ATTRIBUTE; |
||
194 | break; |
||
195 | } |
||
196 | |||
197 | ctx->Flags = EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR; |
||
198 | break; |
||
199 | |||
200 | default: |
||
201 | err = EGL_BAD_ATTRIBUTE; |
||
202 | break; |
||
203 | } |
||
204 | |||
205 | if (err != EGL_SUCCESS) { |
||
206 | _eglLog(_EGL_DEBUG, "bad context attribute 0x%04x", attr); |
||
207 | break; |
||
208 | } |
||
209 | } |
||
210 | |||
211 | if (api == EGL_OPENGL_API) { |
||
212 | /* The EGL_KHR_create_context spec says: |
||
213 | * |
||
214 | * "If the requested OpenGL version is less than 3.2, |
||
215 | * EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR is ignored and the |
||
216 | * functionality of the context is determined solely by the |
||
217 | * requested version." |
||
218 | * |
||
219 | * Since the value is ignored, only validate the setting if the version |
||
220 | * is >= 3.2. |
||
221 | */ |
||
222 | if (ctx->ClientMajorVersion >= 4 |
||
223 | || (ctx->ClientMajorVersion == 3 && ctx->ClientMinorVersion >= 2)) { |
||
224 | switch (ctx->Profile) { |
||
225 | case EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR: |
||
226 | case EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR: |
||
227 | break; |
||
228 | |||
229 | default: |
||
230 | /* The EGL_KHR_create_context spec says: |
||
231 | * |
||
232 | * "* If an OpenGL context is requested, the requested version |
||
233 | * is greater than 3.2, and the value for attribute |
||
234 | * EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR has no bits set; has |
||
235 | * any bits set other than EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR |
||
236 | * and EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR; has |
||
237 | * more than one of these bits set; or if the implementation does |
||
238 | * not support the requested profile, then an EGL_BAD_MATCH error |
||
239 | * is generated." |
||
240 | */ |
||
241 | err = EGL_BAD_MATCH; |
||
242 | break; |
||
243 | } |
||
244 | } |
||
245 | |||
246 | /* The EGL_KHR_create_context spec says: |
||
247 | * |
||
248 | * "* If an OpenGL context is requested and the values for |
||
249 | * attributes EGL_CONTEXT_MAJOR_VERSION_KHR and |
||
250 | * EGL_CONTEXT_MINOR_VERSION_KHR, when considered together with |
||
251 | * the value for attribute |
||
252 | * EGL_CONTEXT_FORWARD_COMPATIBLE_BIT_KHR, specify an OpenGL |
||
253 | * version and feature set that are not defined, than an |
||
254 | * EGL_BAD_MATCH error is generated. |
||
255 | * |
||
256 | * ... Thus, examples of invalid combinations of attributes |
||
257 | * include: |
||
258 | * |
||
259 | * - Major version < 1 or > 4 |
||
260 | * - Major version == 1 and minor version < 0 or > 5 |
||
261 | * - Major version == 2 and minor version < 0 or > 1 |
||
262 | * - Major version == 3 and minor version < 0 or > 2 |
||
263 | * - Major version == 4 and minor version < 0 or > 2 |
||
264 | * - Forward-compatible flag set and major version < 3" |
||
265 | */ |
||
266 | if (ctx->ClientMajorVersion < 1 || ctx->ClientMinorVersion < 0) |
||
267 | err = EGL_BAD_MATCH; |
||
268 | |||
269 | switch (ctx->ClientMajorVersion) { |
||
270 | case 1: |
||
271 | if (ctx->ClientMinorVersion > 5 |
||
272 | || (ctx->Flags & EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR) != 0) |
||
273 | err = EGL_BAD_MATCH; |
||
274 | break; |
||
275 | |||
276 | case 2: |
||
277 | if (ctx->ClientMinorVersion > 1 |
||
278 | || (ctx->Flags & EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR) != 0) |
||
279 | err = EGL_BAD_MATCH; |
||
280 | break; |
||
281 | |||
282 | case 3: |
||
283 | /* Note: The text above is incorrect. There *is* an OpenGL 3.3! |
||
284 | */ |
||
285 | if (ctx->ClientMinorVersion > 3) |
||
286 | err = EGL_BAD_MATCH; |
||
287 | break; |
||
288 | |||
289 | case 4: |
||
290 | default: |
||
291 | /* Don't put additional version checks here. We don't know that |
||
292 | * there won't be versions > 4.2. |
||
293 | */ |
||
294 | break; |
||
295 | } |
||
296 | } else if (api == EGL_OPENGL_ES_API) { |
||
297 | /* The EGL_KHR_create_context spec says: |
||
298 | * |
||
299 | * "* If an OpenGL ES context is requested and the values for |
||
300 | * attributes EGL_CONTEXT_MAJOR_VERSION_KHR and |
||
301 | * EGL_CONTEXT_MINOR_VERSION_KHR specify an OpenGL ES version that |
||
302 | * is not defined, than an EGL_BAD_MATCH error is generated. |
||
303 | * |
||
304 | * ... Examples of invalid combinations of attributes include: |
||
305 | * |
||
306 | * - Major version < 1 or > 2 |
||
307 | * - Major version == 1 and minor version < 0 or > 1 |
||
308 | * - Major version == 2 and minor version != 0 |
||
309 | */ |
||
310 | if (ctx->ClientMajorVersion < 1 || ctx->ClientMinorVersion < 0) |
||
311 | err = EGL_BAD_MATCH; |
||
312 | |||
313 | switch (ctx->ClientMajorVersion) { |
||
314 | case 1: |
||
315 | if (ctx->ClientMinorVersion > 1) |
||
316 | err = EGL_BAD_MATCH; |
||
317 | break; |
||
318 | |||
319 | case 2: |
||
320 | if (ctx->ClientMinorVersion > 0) |
||
321 | err = EGL_BAD_MATCH; |
||
322 | break; |
||
323 | |||
324 | case 3: |
||
325 | default: |
||
326 | /* Don't put additional version checks here. We don't know that |
||
327 | * there won't be versions > 3.0. |
||
328 | */ |
||
329 | break; |
||
330 | } |
||
331 | } |
||
332 | |||
333 | switch (ctx->ResetNotificationStrategy) { |
||
334 | case EGL_NO_RESET_NOTIFICATION_KHR: |
||
335 | case EGL_LOSE_CONTEXT_ON_RESET_KHR: |
||
336 | break; |
||
337 | |||
338 | default: |
||
339 | err = EGL_BAD_ATTRIBUTE; |
||
340 | break; |
||
341 | } |
||
342 | |||
343 | if ((ctx->Flags & ~(EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR |
||
344 | | EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR |
||
345 | | EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR)) != 0) { |
||
346 | err = EGL_BAD_ATTRIBUTE; |
||
347 | } |
||
348 | |||
349 | return err; |
||
350 | } |
||
351 | |||
352 | |||
353 | /** |
||
354 | * Initialize the given _EGLContext object to defaults and/or the values |
||
355 | * in the attrib_list. |
||
356 | */ |
||
357 | EGLBoolean |
||
358 | _eglInitContext(_EGLContext *ctx, _EGLDisplay *dpy, _EGLConfig *conf, |
||
359 | const EGLint *attrib_list) |
||
360 | { |
||
361 | const EGLenum api = eglQueryAPI(); |
||
362 | EGLint err; |
||
363 | |||
364 | if (api == EGL_NONE) { |
||
365 | _eglError(EGL_BAD_MATCH, "eglCreateContext(no client API)"); |
||
366 | return EGL_FALSE; |
||
367 | } |
||
368 | |||
369 | _eglInitResource(&ctx->Resource, sizeof(*ctx), dpy); |
||
370 | ctx->ClientAPI = api; |
||
371 | ctx->Config = conf; |
||
372 | ctx->WindowRenderBuffer = EGL_NONE; |
||
373 | ctx->Profile = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR; |
||
374 | |||
375 | ctx->ClientMajorVersion = 1; /* the default, per EGL spec */ |
||
376 | ctx->ClientMinorVersion = 0; |
||
377 | ctx->Flags = 0; |
||
378 | ctx->Profile = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR; |
||
379 | ctx->ResetNotificationStrategy = EGL_NO_RESET_NOTIFICATION_KHR; |
||
380 | |||
381 | err = _eglParseContextAttribList(ctx, dpy, attrib_list); |
||
382 | if (err == EGL_SUCCESS && ctx->Config) { |
||
383 | EGLint api_bit; |
||
384 | |||
385 | api_bit = _eglGetContextAPIBit(ctx); |
||
386 | if (!(ctx->Config->RenderableType & api_bit)) { |
||
387 | _eglLog(_EGL_DEBUG, "context api is 0x%x while config supports 0x%x", |
||
388 | api_bit, ctx->Config->RenderableType); |
||
389 | err = EGL_BAD_CONFIG; |
||
390 | } |
||
391 | } |
||
392 | if (err != EGL_SUCCESS) |
||
393 | return _eglError(err, "eglCreateContext"); |
||
394 | |||
395 | return EGL_TRUE; |
||
396 | } |
||
397 | |||
398 | |||
399 | static EGLint |
||
400 | _eglQueryContextRenderBuffer(_EGLContext *ctx) |
||
401 | { |
||
402 | _EGLSurface *surf = ctx->DrawSurface; |
||
403 | EGLint rb; |
||
404 | |||
405 | if (!surf) |
||
406 | return EGL_NONE; |
||
407 | if (surf->Type == EGL_WINDOW_BIT && ctx->WindowRenderBuffer != EGL_NONE) |
||
408 | rb = ctx->WindowRenderBuffer; |
||
409 | else |
||
410 | rb = surf->RenderBuffer; |
||
411 | return rb; |
||
412 | } |
||
413 | |||
414 | |||
415 | EGLBoolean |
||
416 | _eglQueryContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *c, |
||
417 | EGLint attribute, EGLint *value) |
||
418 | { |
||
419 | (void) drv; |
||
420 | (void) dpy; |
||
421 | |||
422 | if (!value) |
||
423 | return _eglError(EGL_BAD_PARAMETER, "eglQueryContext"); |
||
424 | |||
425 | switch (attribute) { |
||
426 | case EGL_CONFIG_ID: |
||
427 | if (!c->Config) |
||
428 | return _eglError(EGL_BAD_ATTRIBUTE, "eglQueryContext"); |
||
429 | *value = c->Config->ConfigID; |
||
430 | break; |
||
431 | case EGL_CONTEXT_CLIENT_VERSION: |
||
432 | *value = c->ClientMajorVersion; |
||
433 | break; |
||
434 | case EGL_CONTEXT_CLIENT_TYPE: |
||
435 | *value = c->ClientAPI; |
||
436 | break; |
||
437 | case EGL_RENDER_BUFFER: |
||
438 | *value = _eglQueryContextRenderBuffer(c); |
||
439 | break; |
||
440 | default: |
||
441 | return _eglError(EGL_BAD_ATTRIBUTE, "eglQueryContext"); |
||
442 | } |
||
443 | |||
444 | return EGL_TRUE; |
||
445 | } |
||
446 | |||
447 | |||
448 | /** |
||
449 | * Bind the context to the thread and return the previous context. |
||
450 | * |
||
451 | * Note that the context may be NULL. |
||
452 | */ |
||
453 | static _EGLContext * |
||
454 | _eglBindContextToThread(_EGLContext *ctx, _EGLThreadInfo *t) |
||
455 | { |
||
456 | EGLint apiIndex; |
||
457 | _EGLContext *oldCtx; |
||
458 | |||
459 | apiIndex = (ctx) ? |
||
460 | _eglConvertApiToIndex(ctx->ClientAPI) : t->CurrentAPIIndex; |
||
461 | |||
462 | oldCtx = t->CurrentContexts[apiIndex]; |
||
463 | if (ctx != oldCtx) { |
||
464 | if (oldCtx) |
||
465 | oldCtx->Binding = NULL; |
||
466 | if (ctx) |
||
467 | ctx->Binding = t; |
||
468 | |||
469 | t->CurrentContexts[apiIndex] = ctx; |
||
470 | } |
||
471 | |||
472 | return oldCtx; |
||
473 | } |
||
474 | |||
475 | |||
476 | /** |
||
477 | * Return true if the given context and surfaces can be made current. |
||
478 | */ |
||
479 | static EGLBoolean |
||
480 | _eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read) |
||
481 | { |
||
482 | _EGLThreadInfo *t = _eglGetCurrentThread(); |
||
483 | _EGLDisplay *dpy; |
||
484 | EGLint conflict_api; |
||
485 | |||
486 | if (_eglIsCurrentThreadDummy()) |
||
487 | return _eglError(EGL_BAD_ALLOC, "eglMakeCurrent"); |
||
488 | |||
489 | /* this is easy */ |
||
490 | if (!ctx) { |
||
491 | if (draw || read) |
||
492 | return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); |
||
493 | return EGL_TRUE; |
||
494 | } |
||
495 | |||
496 | dpy = ctx->Resource.Display; |
||
497 | if (!dpy->Extensions.KHR_surfaceless_context |
||
498 | && (draw == NULL || read == NULL)) |
||
499 | return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); |
||
500 | |||
501 | /* |
||
502 | * The spec says |
||
503 | * |
||
504 | * "If ctx is current to some other thread, or if either draw or read are |
||
505 | * bound to contexts in another thread, an EGL_BAD_ACCESS error is |
||
506 | * generated." |
||
507 | * |
||
508 | * and |
||
509 | * |
||
510 | * "at most one context may be bound to a particular surface at a given |
||
511 | * time" |
||
512 | */ |
||
513 | if (ctx->Binding && ctx->Binding != t) |
||
514 | return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); |
||
515 | if (draw && draw->CurrentContext && draw->CurrentContext != ctx) { |
||
516 | if (draw->CurrentContext->Binding != t || |
||
517 | draw->CurrentContext->ClientAPI != ctx->ClientAPI) |
||
518 | return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); |
||
519 | } |
||
520 | if (read && read->CurrentContext && read->CurrentContext != ctx) { |
||
521 | if (read->CurrentContext->Binding != t || |
||
522 | read->CurrentContext->ClientAPI != ctx->ClientAPI) |
||
523 | return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); |
||
524 | } |
||
525 | |||
526 | /* simply require the configs to be equal */ |
||
527 | if ((draw && draw->Config != ctx->Config) || |
||
528 | (read && read->Config != ctx->Config)) |
||
529 | return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); |
||
530 | |||
531 | switch (ctx->ClientAPI) { |
||
532 | /* OpenGL and OpenGL ES are conflicting */ |
||
533 | case EGL_OPENGL_ES_API: |
||
534 | conflict_api = EGL_OPENGL_API; |
||
535 | break; |
||
536 | case EGL_OPENGL_API: |
||
537 | conflict_api = EGL_OPENGL_ES_API; |
||
538 | break; |
||
539 | default: |
||
540 | conflict_api = -1; |
||
541 | break; |
||
542 | } |
||
543 | |||
544 | if (conflict_api >= 0 && _eglGetAPIContext(conflict_api)) |
||
545 | return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); |
||
546 | |||
547 | return EGL_TRUE; |
||
548 | } |
||
549 | |||
550 | |||
551 | /** |
||
552 | * Bind the context to the current thread and given surfaces. Return the |
||
553 | * previous bound context and surfaces. The caller should unreference the |
||
554 | * returned context and surfaces. |
||
555 | * |
||
556 | * Making a second call with the resources returned by the first call |
||
557 | * unsurprisingly undoes the first call, except for the resouce reference |
||
558 | * counts. |
||
559 | */ |
||
560 | EGLBoolean |
||
561 | _eglBindContext(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read, |
||
562 | _EGLContext **old_ctx, |
||
563 | _EGLSurface **old_draw, _EGLSurface **old_read) |
||
564 | { |
||
565 | _EGLThreadInfo *t = _eglGetCurrentThread(); |
||
566 | _EGLContext *prev_ctx; |
||
567 | _EGLSurface *prev_draw, *prev_read; |
||
568 | |||
569 | printf("%s\n",__FUNCTION__); |
||
570 | |||
571 | if (!_eglCheckMakeCurrent(ctx, draw, read)) |
||
572 | return EGL_FALSE; |
||
573 | |||
574 | /* increment refcounts before binding */ |
||
575 | _eglGetContext(ctx); |
||
576 | _eglGetSurface(draw); |
||
577 | _eglGetSurface(read); |
||
578 | |||
579 | /* bind the new context */ |
||
580 | prev_ctx = _eglBindContextToThread(ctx, t); |
||
581 | |||
582 | /* break previous bindings */ |
||
583 | if (prev_ctx) { |
||
584 | prev_draw = prev_ctx->DrawSurface; |
||
585 | prev_read = prev_ctx->ReadSurface; |
||
586 | |||
587 | if (prev_draw) |
||
588 | prev_draw->CurrentContext = NULL; |
||
589 | if (prev_read) |
||
590 | prev_read->CurrentContext = NULL; |
||
591 | |||
592 | prev_ctx->DrawSurface = NULL; |
||
593 | prev_ctx->ReadSurface = NULL; |
||
594 | } |
||
595 | else { |
||
596 | prev_draw = prev_read = NULL; |
||
597 | } |
||
598 | |||
599 | /* establish new bindings */ |
||
600 | if (ctx) { |
||
601 | if (draw) |
||
602 | draw->CurrentContext = ctx; |
||
603 | if (read) |
||
604 | read->CurrentContext = ctx; |
||
605 | |||
606 | ctx->DrawSurface = draw; |
||
607 | ctx->ReadSurface = read; |
||
608 | } |
||
609 | |||
610 | assert(old_ctx && old_draw && old_read); |
||
611 | *old_ctx = prev_ctx; |
||
612 | *old_draw = prev_draw; |
||
613 | *old_read = prev_read; |
||
614 | |||
615 | printf("leave %s\n",__FUNCTION__); |
||
616 | |||
617 | return EGL_TRUE; |
||
618 | }>>>>>>>>>>>> |