1 /**************************************************************************
3 * Copyright 2008 VMware, Inc.
4 * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
5 * Copyright 2010-2011 LunarG, Inc.
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:
16 * The above copyright notice and this permission notice (including the
17 * next paragraph) shall be included in all copies or substantial portions
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.
28 **************************************************************************/
34 #include "eglconfig.h"
35 #include "eglcontext.h"
36 #include "egldisplay.h"
37 #include "eglcurrent.h"
38 #include "eglsurface.h"
43 * Return the API bit (one of EGL_xxx_BIT) of the context.
46 _eglGetContextAPIBit(_EGLContext
*ctx
)
50 switch (ctx
->ClientAPI
) {
51 case EGL_OPENGL_ES_API
:
52 switch (ctx
->ClientMajorVersion
) {
54 bit
= EGL_OPENGL_ES_BIT
;
57 bit
= EGL_OPENGL_ES2_BIT
;
60 bit
= EGL_OPENGL_ES3_BIT_KHR
;
81 * Parse the list of context attributes and return the proper error code.
84 _eglParseContextAttribList(_EGLContext
*ctx
, _EGLDisplay
*dpy
,
85 const EGLint
*attrib_list
)
87 EGLenum api
= ctx
->ClientAPI
;
88 EGLint i
, err
= EGL_SUCCESS
;
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
;
98 for (i
= 0; attrib_list
[i
] != EGL_NONE
; i
++) {
99 EGLint attr
= attrib_list
[i
++];
100 EGLint val
= attrib_list
[i
];
103 case EGL_CONTEXT_CLIENT_VERSION
:
104 /* The EGL 1.4 spec says:
106 * "attribute EGL_CONTEXT_CLIENT_VERSION is only valid when the
107 * current rendering API is EGL_OPENGL_ES_API"
109 * The EGL_KHR_create_context spec says:
111 * "EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098
112 * (this token is an alias for EGL_CONTEXT_CLIENT_VERSION)"
114 * "The values for attributes EGL_CONTEXT_MAJOR_VERSION_KHR and
115 * EGL_CONTEXT_MINOR_VERSION_KHR specify the requested client API
116 * version. They are only meaningful for OpenGL and OpenGL ES
117 * contexts, and specifying them for other types of contexts will
118 * generate an error."
120 if ((api
!= EGL_OPENGL_ES_API
&&
121 (!dpy
->Extensions
.KHR_create_context
|| api
!= EGL_OPENGL_API
))) {
122 err
= EGL_BAD_ATTRIBUTE
;
126 ctx
->ClientMajorVersion
= val
;
129 case EGL_CONTEXT_MINOR_VERSION_KHR
:
130 /* The EGL_KHR_create_context spec says:
132 * "The values for attributes EGL_CONTEXT_MAJOR_VERSION_KHR and
133 * EGL_CONTEXT_MINOR_VERSION_KHR specify the requested client API
134 * version. They are only meaningful for OpenGL and OpenGL ES
135 * contexts, and specifying them for other types of contexts will
136 * generate an error."
138 if (!dpy
->Extensions
.KHR_create_context
||
139 (api
!= EGL_OPENGL_ES_API
&& api
!= EGL_OPENGL_API
)) {
140 err
= EGL_BAD_ATTRIBUTE
;
144 ctx
->ClientMinorVersion
= val
;
147 case EGL_CONTEXT_FLAGS_KHR
:
148 if (!dpy
->Extensions
.KHR_create_context
) {
149 err
= EGL_BAD_ATTRIBUTE
;
153 /* The EGL_KHR_create_context spec says:
155 * "If the EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR flag bit is set in
156 * EGL_CONTEXT_FLAGS_KHR, then a <debug context> will be created.
158 * In some cases a debug context may be identical to a non-debug
159 * context. This bit is supported for OpenGL and OpenGL ES
162 if ((val
& EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR
) &&
163 (api
!= EGL_OPENGL_API
&& api
!= EGL_OPENGL_ES_API
)) {
164 err
= EGL_BAD_ATTRIBUTE
;
168 /* The EGL_KHR_create_context spec says:
170 * "If the EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR flag bit
171 * is set in EGL_CONTEXT_FLAGS_KHR, then a <forward-compatible>
172 * context will be created. Forward-compatible contexts are
173 * defined only for OpenGL versions 3.0 and later. They must not
174 * support functionality marked as <deprecated> by that version of
175 * the API, while a non-forward-compatible context must support
176 * all functionality in that version, deprecated or not. This bit
177 * is supported for OpenGL contexts, and requesting a
178 * forward-compatible context for OpenGL versions less than 3.0
179 * will generate an error."
181 if ((val
& EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR
) &&
182 (api
!= EGL_OPENGL_API
|| ctx
->ClientMajorVersion
< 3)) {
183 err
= EGL_BAD_ATTRIBUTE
;
187 if ((val
& EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR
) &&
188 api
!= EGL_OPENGL_API
) {
189 /* The EGL_KHR_create_context spec says:
191 * 10) Which error should be generated if robust buffer access
192 * or reset notifications are requested under OpenGL ES?
194 * As per Issue 6, this extension does not support creating
195 * robust contexts for OpenGL ES. This is only supported via
196 * the EGL_EXT_create_context_robustness extension.
198 * Attempting to use this extension to create robust OpenGL
199 * ES context will generate an EGL_BAD_ATTRIBUTE error. This
200 * specific error is generated because this extension does
201 * not define the EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR
202 * and EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR
203 * bits for OpenGL ES contexts. Thus, use of these bits fall
204 * under condition described by: "If an attribute is
205 * specified that is not meaningful for the client API
206 * type.." in the above specification.
208 * The spec requires that we emit the error even if the display
209 * supports EGL_EXT_create_context_robustness. To create a robust
210 * GLES context, the *attribute*
211 * EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT must be used, not the
212 * *flag* EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR.
214 err
= EGL_BAD_ATTRIBUTE
;
221 case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR
:
222 if (!dpy
->Extensions
.KHR_create_context
) {
223 err
= EGL_BAD_ATTRIBUTE
;
227 /* The EGL_KHR_create_context spec says:
229 * "[EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR] is only meaningful for
230 * OpenGL contexts, and specifying it for other types of
231 * contexts, including OpenGL ES contexts, will generate an
234 if (api
!= EGL_OPENGL_API
) {
235 err
= EGL_BAD_ATTRIBUTE
;
242 case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR
:
243 /* The EGL_KHR_create_context spec says:
245 * "[EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR] is only
246 * meaningful for OpenGL contexts, and specifying it for other
247 * types of contexts, including OpenGL ES contexts, will generate
250 if (!dpy
->Extensions
.KHR_create_context
251 || api
!= EGL_OPENGL_API
) {
252 err
= EGL_BAD_ATTRIBUTE
;
256 ctx
->ResetNotificationStrategy
= val
;
259 case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT
:
260 /* The EGL_EXT_create_context_robustness spec says:
262 * "[EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT] is only
263 * meaningful for OpenGL ES contexts, and specifying it for other
264 * types of contexts will generate an EGL_BAD_ATTRIBUTE error."
266 if (!dpy
->Extensions
.EXT_create_context_robustness
267 || api
!= EGL_OPENGL_ES_API
) {
268 err
= EGL_BAD_ATTRIBUTE
;
272 ctx
->ResetNotificationStrategy
= val
;
275 case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT
:
276 if (!dpy
->Extensions
.EXT_create_context_robustness
) {
277 err
= EGL_BAD_ATTRIBUTE
;
282 ctx
->Flags
|= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR
;
285 case EGL_CONTEXT_OPENGL_ROBUST_ACCESS
:
286 if (dpy
->Version
< 15) {
287 err
= EGL_BAD_ATTRIBUTE
;
292 ctx
->Flags
|= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR
;
295 case EGL_CONTEXT_OPENGL_DEBUG
:
296 if (dpy
->Version
< 15) {
297 err
= EGL_BAD_ATTRIBUTE
;
302 ctx
->Flags
|= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR
;
305 case EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE
:
306 if (dpy
->Version
< 15) {
307 err
= EGL_BAD_ATTRIBUTE
;
312 ctx
->Flags
|= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR
;
315 case EGL_CONTEXT_OPENGL_NO_ERROR_KHR
:
316 if (dpy
->Version
< 14 ||
317 !dpy
->Extensions
.KHR_create_context_no_error
) {
318 err
= EGL_BAD_ATTRIBUTE
;
322 /* The KHR_no_error spec only applies against OpenGL 2.0+ and
325 if ((api
!= EGL_OPENGL_API
&& api
!= EGL_OPENGL_ES_API
) ||
326 ctx
->ClientMajorVersion
< 2) {
327 err
= EGL_BAD_ATTRIBUTE
;
331 /* Canonicalize value to EGL_TRUE/EGL_FALSE definitions */
332 ctx
->NoError
= !!val
;
335 case EGL_CONTEXT_PRIORITY_LEVEL_IMG
:
336 /* The EGL_IMG_context_priority spec says:
338 * "EGL_CONTEXT_PRIORITY_LEVEL_IMG determines the priority level of
339 * the context to be created. This attribute is a hint, as an
340 * implementation may not support multiple contexts at some
341 * priority levels and system policy may limit access to high
342 * priority contexts to appropriate system privilege level. The
343 * default value for EGL_CONTEXT_PRIORITY_LEVEL_IMG is
344 * EGL_CONTEXT_PRIORITY_MEDIUM_IMG."
350 case EGL_CONTEXT_PRIORITY_HIGH_IMG
:
351 bit
= __EGL_CONTEXT_PRIORITY_HIGH_BIT
;
353 case EGL_CONTEXT_PRIORITY_MEDIUM_IMG
:
354 bit
= __EGL_CONTEXT_PRIORITY_MEDIUM_BIT
;
356 case EGL_CONTEXT_PRIORITY_LOW_IMG
:
357 bit
= __EGL_CONTEXT_PRIORITY_LOW_BIT
;
365 err
= EGL_BAD_ATTRIBUTE
;
369 /* "This extension allows an EGLContext to be created with a
370 * priority hint. It is possible that an implementation will not
371 * honour the hint, especially if there are constraints on the
372 * number of high priority contexts available in the system, or
373 * system policy limits access to high priority contexts to
374 * appropriate system privilege level. A query is provided to find
375 * the real priority level assigned to the context after creation."
377 * We currently assume that the driver applies the priority hint
378 * and filters out any it cannot handle during the screen setup,
379 * e.g. dri2_setup_screen(). As such we can mask any change that
380 * the driver would fail, and ctx->ContextPriority matches the
381 * hint applied to the driver/hardware backend.
383 if (dpy
->Extensions
.IMG_context_priority
& (1 << bit
))
384 ctx
->ContextPriority
= val
;
389 case EGL_CONTEXT_RELEASE_BEHAVIOR_KHR
:
390 if (val
== EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR
||
391 val
== EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR
) {
392 ctx
->ReleaseBehavior
= val
;
394 err
= EGL_BAD_ATTRIBUTE
;
399 err
= EGL_BAD_ATTRIBUTE
;
403 if (err
!= EGL_SUCCESS
) {
404 _eglLog(_EGL_DEBUG
, "bad context attribute 0x%04x", attr
);
409 if (api
== EGL_OPENGL_API
) {
410 /* The EGL_KHR_create_context spec says:
412 * "If the requested OpenGL version is less than 3.2,
413 * EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR is ignored and the
414 * functionality of the context is determined solely by the
415 * requested version."
417 * Since the value is ignored, only validate the setting if the version
420 if (ctx
->ClientMajorVersion
>= 4
421 || (ctx
->ClientMajorVersion
== 3 && ctx
->ClientMinorVersion
>= 2)) {
422 switch (ctx
->Profile
) {
423 case EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR
:
424 case EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR
:
428 /* The EGL_KHR_create_context spec says:
430 * "* If an OpenGL context is requested, the requested version
431 * is greater than 3.2, and the value for attribute
432 * EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR has no bits set; has
433 * any bits set other than EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR
434 * and EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR; has
435 * more than one of these bits set; or if the implementation does
436 * not support the requested profile, then an EGL_BAD_MATCH error
444 /* The EGL_KHR_create_context spec says:
446 * "* If an OpenGL context is requested and the values for
447 * attributes EGL_CONTEXT_MAJOR_VERSION_KHR and
448 * EGL_CONTEXT_MINOR_VERSION_KHR, when considered together with
449 * the value for attribute
450 * EGL_CONTEXT_FORWARD_COMPATIBLE_BIT_KHR, specify an OpenGL
451 * version and feature set that are not defined, than an
452 * EGL_BAD_MATCH error is generated.
454 * ... Thus, examples of invalid combinations of attributes
457 * - Major version < 1 or > 4
458 * - Major version == 1 and minor version < 0 or > 5
459 * - Major version == 2 and minor version < 0 or > 1
460 * - Major version == 3 and minor version < 0 or > 2
461 * - Major version == 4 and minor version < 0 or > 2
462 * - Forward-compatible flag set and major version < 3"
464 if (ctx
->ClientMajorVersion
< 1 || ctx
->ClientMinorVersion
< 0)
467 switch (ctx
->ClientMajorVersion
) {
469 if (ctx
->ClientMinorVersion
> 5
470 || (ctx
->Flags
& EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR
) != 0)
475 if (ctx
->ClientMinorVersion
> 1
476 || (ctx
->Flags
& EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR
) != 0)
481 /* Note: The text above is incorrect. There *is* an OpenGL 3.3!
483 if (ctx
->ClientMinorVersion
> 3)
489 /* Don't put additional version checks here. We don't know that
490 * there won't be versions > 4.2.
494 } else if (api
== EGL_OPENGL_ES_API
) {
495 /* The EGL_KHR_create_context spec says:
497 * "* If an OpenGL ES context is requested and the values for
498 * attributes EGL_CONTEXT_MAJOR_VERSION_KHR and
499 * EGL_CONTEXT_MINOR_VERSION_KHR specify an OpenGL ES version that
500 * is not defined, than an EGL_BAD_MATCH error is generated.
502 * ... Examples of invalid combinations of attributes include:
504 * - Major version < 1 or > 2
505 * - Major version == 1 and minor version < 0 or > 1
506 * - Major version == 2 and minor version != 0
508 if (ctx
->ClientMajorVersion
< 1 || ctx
->ClientMinorVersion
< 0)
511 switch (ctx
->ClientMajorVersion
) {
513 if (ctx
->ClientMinorVersion
> 1)
518 if (ctx
->ClientMinorVersion
> 0)
523 /* Don't put additional version checks here. We don't know that
524 * there won't be versions > 3.0.
534 switch (ctx
->ResetNotificationStrategy
) {
535 case EGL_NO_RESET_NOTIFICATION_KHR
:
536 case EGL_LOSE_CONTEXT_ON_RESET_KHR
:
540 err
= EGL_BAD_ATTRIBUTE
;
544 /* The EGL_KHR_create_context_no_error spec says:
546 * "BAD_MATCH is generated if the EGL_CONTEXT_OPENGL_NO_ERROR_KHR is TRUE at
547 * the same time as a debug or robustness context is specified."
549 if (ctx
->NoError
&& (ctx
->Flags
& EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR
||
550 ctx
->Flags
& EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR
)) {
554 if ((ctx
->Flags
& ~(EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR
555 | EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR
556 | EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR
)) != 0) {
557 err
= EGL_BAD_ATTRIBUTE
;
565 * Initialize the given _EGLContext object to defaults and/or the values
566 * in the attrib_list.
568 * According to EGL 1.5 Section 3.7:
570 * "EGL_OPENGL_API and EGL_OPENGL_ES_API are interchangeable for all
571 * purposes except eglCreateContext."
573 * And since we only support GL and GLES, this is the only place where the
574 * bound API matters at all. We look up the current API from the current
575 * thread, and stash that in the context we're initializing. Our caller is
576 * responsible for determining whether that's an API it supports.
579 _eglInitContext(_EGLContext
*ctx
, _EGLDisplay
*dpy
, _EGLConfig
*conf
,
580 const EGLint
*attrib_list
)
582 const EGLenum api
= eglQueryAPI();
586 return _eglError(EGL_BAD_MATCH
, "eglCreateContext(no client API)");
588 _eglInitResource(&ctx
->Resource
, sizeof(*ctx
), dpy
);
589 ctx
->ClientAPI
= api
;
591 ctx
->WindowRenderBuffer
= EGL_NONE
;
592 ctx
->Profile
= EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR
;
594 ctx
->ClientMajorVersion
= 1; /* the default, per EGL spec */
595 ctx
->ClientMinorVersion
= 0;
597 ctx
->ResetNotificationStrategy
= EGL_NO_RESET_NOTIFICATION_KHR
;
598 ctx
->ContextPriority
= EGL_CONTEXT_PRIORITY_MEDIUM_IMG
;
599 ctx
->ReleaseBehavior
= EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR
;
601 err
= _eglParseContextAttribList(ctx
, dpy
, attrib_list
);
602 if (err
== EGL_SUCCESS
&& ctx
->Config
) {
605 api_bit
= _eglGetContextAPIBit(ctx
);
606 if (!(ctx
->Config
->RenderableType
& api_bit
)) {
607 _eglLog(_EGL_DEBUG
, "context api is 0x%x while config supports 0x%x",
608 api_bit
, ctx
->Config
->RenderableType
);
609 err
= EGL_BAD_CONFIG
;
612 if (err
!= EGL_SUCCESS
)
613 return _eglError(err
, "eglCreateContext");
620 _eglQueryContextRenderBuffer(_EGLContext
*ctx
)
622 _EGLSurface
*surf
= ctx
->DrawSurface
;
627 if (surf
->Type
== EGL_WINDOW_BIT
&& ctx
->WindowRenderBuffer
!= EGL_NONE
)
628 rb
= ctx
->WindowRenderBuffer
;
630 rb
= surf
->RenderBuffer
;
636 _eglQueryContext(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLContext
*c
,
637 EGLint attribute
, EGLint
*value
)
643 return _eglError(EGL_BAD_PARAMETER
, "eglQueryContext");
648 * From EGL_KHR_no_config_context:
650 * "Querying EGL_CONFIG_ID returns the ID of the EGLConfig with
651 * respect to which the context was created, or zero if created
652 * without respect to an EGLConfig."
654 *value
= c
->Config
? c
->Config
->ConfigID
: 0;
656 case EGL_CONTEXT_CLIENT_VERSION
:
657 *value
= c
->ClientMajorVersion
;
659 case EGL_CONTEXT_CLIENT_TYPE
:
660 *value
= c
->ClientAPI
;
662 case EGL_RENDER_BUFFER
:
663 *value
= _eglQueryContextRenderBuffer(c
);
665 case EGL_CONTEXT_PRIORITY_LEVEL_IMG
:
666 *value
= c
->ContextPriority
;
669 return _eglError(EGL_BAD_ATTRIBUTE
, "eglQueryContext");
677 * Bind the context to the thread and return the previous context.
679 * Note that the context may be NULL.
682 _eglBindContextToThread(_EGLContext
*ctx
, _EGLThreadInfo
*t
)
686 oldCtx
= t
->CurrentContext
;
689 oldCtx
->Binding
= NULL
;
693 t
->CurrentContext
= ctx
;
701 * Return true if the given context and surfaces can be made current.
704 _eglCheckMakeCurrent(_EGLContext
*ctx
, _EGLSurface
*draw
, _EGLSurface
*read
)
706 _EGLThreadInfo
*t
= _eglGetCurrentThread();
709 if (_eglIsCurrentThreadDummy())
710 return _eglError(EGL_BAD_ALLOC
, "eglMakeCurrent");
715 return _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
719 dpy
= ctx
->Resource
.Display
;
720 if (!dpy
->Extensions
.KHR_surfaceless_context
721 && (draw
== NULL
|| read
== NULL
))
722 return _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
727 * "If ctx is current to some other thread, or if either draw or read are
728 * bound to contexts in another thread, an EGL_BAD_ACCESS error is
733 * "at most one context may be bound to a particular surface at a given
736 if (ctx
->Binding
&& ctx
->Binding
!= t
)
737 return _eglError(EGL_BAD_ACCESS
, "eglMakeCurrent");
738 if (draw
&& draw
->CurrentContext
&& draw
->CurrentContext
!= ctx
) {
739 if (draw
->CurrentContext
->Binding
!= t
)
740 return _eglError(EGL_BAD_ACCESS
, "eglMakeCurrent");
742 if (read
&& read
->CurrentContext
&& read
->CurrentContext
!= ctx
) {
743 if (read
->CurrentContext
->Binding
!= t
)
744 return _eglError(EGL_BAD_ACCESS
, "eglMakeCurrent");
747 /* If the context has a config then it must match that of the two
750 if ((draw
&& draw
->Config
!= ctx
->Config
) ||
751 (read
&& read
->Config
!= ctx
->Config
))
752 return _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
754 /* Otherwise we must be using the EGL_KHR_no_config_context
756 assert(dpy
->Extensions
.KHR_no_config_context
);
758 /* The extension doesn't permit binding draw and read buffers with
759 * differing contexts */
760 if (draw
&& read
&& draw
->Config
!= read
->Config
)
761 return _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
769 * Bind the context to the current thread and given surfaces. Return the
770 * previous bound context and surfaces. The caller should unreference the
771 * returned context and surfaces.
773 * Making a second call with the resources returned by the first call
774 * unsurprisingly undoes the first call, except for the resouce reference
778 _eglBindContext(_EGLContext
*ctx
, _EGLSurface
*draw
, _EGLSurface
*read
,
779 _EGLContext
**old_ctx
,
780 _EGLSurface
**old_draw
, _EGLSurface
**old_read
)
782 _EGLThreadInfo
*t
= _eglGetCurrentThread();
783 _EGLContext
*prev_ctx
;
784 _EGLSurface
*prev_draw
, *prev_read
;
786 if (!_eglCheckMakeCurrent(ctx
, draw
, read
))
789 /* increment refcounts before binding */
791 _eglGetSurface(draw
);
792 _eglGetSurface(read
);
794 /* bind the new context */
795 prev_ctx
= _eglBindContextToThread(ctx
, t
);
797 /* break previous bindings */
799 prev_draw
= prev_ctx
->DrawSurface
;
800 prev_read
= prev_ctx
->ReadSurface
;
803 prev_draw
->CurrentContext
= NULL
;
805 prev_read
->CurrentContext
= NULL
;
807 prev_ctx
->DrawSurface
= NULL
;
808 prev_ctx
->ReadSurface
= NULL
;
811 prev_draw
= prev_read
= NULL
;
814 /* establish new bindings */
817 draw
->CurrentContext
= ctx
;
819 read
->CurrentContext
= ctx
;
821 ctx
->DrawSurface
= draw
;
822 ctx
->ReadSurface
= read
;
825 assert(old_ctx
&& old_draw
&& old_read
);
827 *old_draw
= prev_draw
;
828 *old_read
= prev_read
;