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"
40 #include "util/macros.h"
44 * Return the API bit (one of EGL_xxx_BIT) of the context.
47 _eglGetContextAPIBit(_EGLContext
*ctx
)
51 switch (ctx
->ClientAPI
) {
52 case EGL_OPENGL_ES_API
:
53 switch (ctx
->ClientMajorVersion
) {
55 bit
= EGL_OPENGL_ES_BIT
;
58 bit
= EGL_OPENGL_ES2_BIT
;
61 bit
= EGL_OPENGL_ES3_BIT_KHR
;
82 * Parse the list of context attributes and return the proper error code.
85 _eglParseContextAttribList(_EGLContext
*ctx
, _EGLDisplay
*disp
,
86 const EGLint
*attrib_list
)
88 EGLenum api
= ctx
->ClientAPI
;
89 EGLint i
, err
= EGL_SUCCESS
;
94 if (api
== EGL_OPENVG_API
&& attrib_list
[0] != EGL_NONE
) {
95 _eglLog(_EGL_DEBUG
, "bad context attribute 0x%04x", attrib_list
[0]);
96 return EGL_BAD_ATTRIBUTE
;
99 for (i
= 0; attrib_list
[i
] != EGL_NONE
; i
++) {
100 EGLint attr
= attrib_list
[i
++];
101 EGLint val
= attrib_list
[i
];
104 case EGL_CONTEXT_CLIENT_VERSION
:
105 /* The EGL 1.4 spec says:
107 * "attribute EGL_CONTEXT_CLIENT_VERSION is only valid when the
108 * current rendering API is EGL_OPENGL_ES_API"
110 * The EGL_KHR_create_context spec says:
112 * "EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098
113 * (this token is an alias for EGL_CONTEXT_CLIENT_VERSION)"
115 * "The values for attributes EGL_CONTEXT_MAJOR_VERSION_KHR and
116 * EGL_CONTEXT_MINOR_VERSION_KHR specify the requested client API
117 * version. They are only meaningful for OpenGL and OpenGL ES
118 * contexts, and specifying them for other types of contexts will
119 * generate an error."
121 if ((api
!= EGL_OPENGL_ES_API
&&
122 (!disp
->Extensions
.KHR_create_context
|| api
!= EGL_OPENGL_API
))) {
123 err
= EGL_BAD_ATTRIBUTE
;
127 ctx
->ClientMajorVersion
= val
;
130 case EGL_CONTEXT_MINOR_VERSION_KHR
:
131 /* The EGL_KHR_create_context spec says:
133 * "The values for attributes EGL_CONTEXT_MAJOR_VERSION_KHR and
134 * EGL_CONTEXT_MINOR_VERSION_KHR specify the requested client API
135 * version. They are only meaningful for OpenGL and OpenGL ES
136 * contexts, and specifying them for other types of contexts will
137 * generate an error."
139 if (!disp
->Extensions
.KHR_create_context
||
140 (api
!= EGL_OPENGL_ES_API
&& api
!= EGL_OPENGL_API
)) {
141 err
= EGL_BAD_ATTRIBUTE
;
145 ctx
->ClientMinorVersion
= val
;
148 case EGL_CONTEXT_FLAGS_KHR
:
149 if (!disp
->Extensions
.KHR_create_context
) {
150 err
= EGL_BAD_ATTRIBUTE
;
154 /* The EGL_KHR_create_context spec says:
156 * "If the EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR flag bit is set in
157 * EGL_CONTEXT_FLAGS_KHR, then a <debug context> will be created.
159 * In some cases a debug context may be identical to a non-debug
160 * context. This bit is supported for OpenGL and OpenGL ES
163 if ((val
& EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR
) &&
164 (api
!= EGL_OPENGL_API
&& api
!= EGL_OPENGL_ES_API
)) {
165 err
= EGL_BAD_ATTRIBUTE
;
169 /* The EGL_KHR_create_context spec says:
171 * "If the EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR flag bit
172 * is set in EGL_CONTEXT_FLAGS_KHR, then a <forward-compatible>
173 * context will be created. Forward-compatible contexts are
174 * defined only for OpenGL versions 3.0 and later. They must not
175 * support functionality marked as <deprecated> by that version of
176 * the API, while a non-forward-compatible context must support
177 * all functionality in that version, deprecated or not. This bit
178 * is supported for OpenGL contexts, and requesting a
179 * forward-compatible context for OpenGL versions less than 3.0
180 * will generate an error."
182 * Note: since the forward-compatible flag can be set more than one way,
183 * the OpenGL version check is performed once, below.
185 if ((val
& EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR
) &&
186 api
!= EGL_OPENGL_API
) {
187 err
= EGL_BAD_ATTRIBUTE
;
191 if ((val
& EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR
) &&
192 api
!= EGL_OPENGL_API
) {
193 /* The EGL_KHR_create_context spec says:
195 * 10) Which error should be generated if robust buffer access
196 * or reset notifications are requested under OpenGL ES?
198 * As per Issue 6, this extension does not support creating
199 * robust contexts for OpenGL ES. This is only supported via
200 * the EGL_EXT_create_context_robustness extension.
202 * Attempting to use this extension to create robust OpenGL
203 * ES context will generate an EGL_BAD_ATTRIBUTE error. This
204 * specific error is generated because this extension does
205 * not define the EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR
206 * and EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR
207 * bits for OpenGL ES contexts. Thus, use of these bits fall
208 * under condition described by: "If an attribute is
209 * specified that is not meaningful for the client API
210 * type.." in the above specification.
212 * The spec requires that we emit the error even if the display
213 * supports EGL_EXT_create_context_robustness. To create a robust
214 * GLES context, the *attribute*
215 * EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT must be used, not the
216 * *flag* EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR.
218 err
= EGL_BAD_ATTRIBUTE
;
225 case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR
:
226 if (!disp
->Extensions
.KHR_create_context
) {
227 err
= EGL_BAD_ATTRIBUTE
;
231 /* The EGL_KHR_create_context spec says:
233 * "[EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR] is only meaningful for
234 * OpenGL contexts, and specifying it for other types of
235 * contexts, including OpenGL ES contexts, will generate an
238 if (api
!= EGL_OPENGL_API
) {
239 err
= EGL_BAD_ATTRIBUTE
;
246 case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR
:
247 /* The EGL_KHR_create_context spec says:
249 * "[EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR] is only
250 * meaningful for OpenGL contexts, and specifying it for other
251 * types of contexts, including OpenGL ES contexts, will generate
254 * EGL 1.5 defines EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY
255 * (without a suffix) which has the same value as the KHR token,
256 * and specifies that it now works with both GL and ES contexts:
258 * "This attribute is supported only for OpenGL and OpenGL ES
261 if (!(disp
->Extensions
.KHR_create_context
&& api
== EGL_OPENGL_API
)
262 && !(disp
->Version
>= 15 && (api
== EGL_OPENGL_API
||
263 api
== EGL_OPENGL_ES_API
))) {
264 err
= EGL_BAD_ATTRIBUTE
;
268 ctx
->ResetNotificationStrategy
= val
;
271 case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT
:
272 /* The EGL_EXT_create_context_robustness spec says:
274 * "[EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT] is only
275 * meaningful for OpenGL ES contexts, and specifying it for other
276 * types of contexts will generate an EGL_BAD_ATTRIBUTE error."
278 if (!disp
->Extensions
.EXT_create_context_robustness
279 || api
!= EGL_OPENGL_ES_API
) {
280 err
= EGL_BAD_ATTRIBUTE
;
284 ctx
->ResetNotificationStrategy
= val
;
287 case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT
:
288 if (!disp
->Extensions
.EXT_create_context_robustness
) {
289 err
= EGL_BAD_ATTRIBUTE
;
294 ctx
->Flags
|= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR
;
297 case EGL_CONTEXT_OPENGL_ROBUST_ACCESS
:
298 if (disp
->Version
< 15) {
299 err
= EGL_BAD_ATTRIBUTE
;
304 ctx
->Flags
|= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR
;
307 case EGL_CONTEXT_OPENGL_DEBUG
:
308 if (disp
->Version
< 15) {
309 err
= EGL_BAD_ATTRIBUTE
;
314 ctx
->Flags
|= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR
;
317 case EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE
:
318 if (disp
->Version
< 15) {
319 err
= EGL_BAD_ATTRIBUTE
;
324 ctx
->Flags
|= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR
;
327 case EGL_CONTEXT_OPENGL_NO_ERROR_KHR
:
328 if (disp
->Version
< 14 ||
329 !disp
->Extensions
.KHR_create_context_no_error
) {
330 err
= EGL_BAD_ATTRIBUTE
;
334 /* The KHR_no_error spec only applies against OpenGL 2.0+ and
337 if ((api
!= EGL_OPENGL_API
&& api
!= EGL_OPENGL_ES_API
) ||
338 ctx
->ClientMajorVersion
< 2) {
339 err
= EGL_BAD_ATTRIBUTE
;
343 /* Canonicalize value to EGL_TRUE/EGL_FALSE definitions */
344 ctx
->NoError
= !!val
;
347 case EGL_CONTEXT_PRIORITY_LEVEL_IMG
:
348 /* The EGL_IMG_context_priority spec says:
350 * "EGL_CONTEXT_PRIORITY_LEVEL_IMG determines the priority level of
351 * the context to be created. This attribute is a hint, as an
352 * implementation may not support multiple contexts at some
353 * priority levels and system policy may limit access to high
354 * priority contexts to appropriate system privilege level. The
355 * default value for EGL_CONTEXT_PRIORITY_LEVEL_IMG is
356 * EGL_CONTEXT_PRIORITY_MEDIUM_IMG."
362 case EGL_CONTEXT_PRIORITY_HIGH_IMG
:
363 bit
= __EGL_CONTEXT_PRIORITY_HIGH_BIT
;
365 case EGL_CONTEXT_PRIORITY_MEDIUM_IMG
:
366 bit
= __EGL_CONTEXT_PRIORITY_MEDIUM_BIT
;
368 case EGL_CONTEXT_PRIORITY_LOW_IMG
:
369 bit
= __EGL_CONTEXT_PRIORITY_LOW_BIT
;
377 err
= EGL_BAD_ATTRIBUTE
;
381 /* "This extension allows an EGLContext to be created with a
382 * priority hint. It is possible that an implementation will not
383 * honour the hint, especially if there are constraints on the
384 * number of high priority contexts available in the system, or
385 * system policy limits access to high priority contexts to
386 * appropriate system privilege level. A query is provided to find
387 * the real priority level assigned to the context after creation."
389 * We currently assume that the driver applies the priority hint
390 * and filters out any it cannot handle during the screen setup,
391 * e.g. dri2_setup_screen(). As such we can mask any change that
392 * the driver would fail, and ctx->ContextPriority matches the
393 * hint applied to the driver/hardware backend.
395 if (disp
->Extensions
.IMG_context_priority
& (1 << bit
))
396 ctx
->ContextPriority
= val
;
401 case EGL_CONTEXT_RELEASE_BEHAVIOR_KHR
:
402 if (val
== EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR
||
403 val
== EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR
) {
404 ctx
->ReleaseBehavior
= val
;
406 err
= EGL_BAD_ATTRIBUTE
;
411 err
= EGL_BAD_ATTRIBUTE
;
415 if (err
!= EGL_SUCCESS
) {
416 _eglLog(_EGL_DEBUG
, "bad context attribute 0x%04x", attr
);
421 if (api
== EGL_OPENGL_API
) {
422 /* The EGL_KHR_create_context spec says:
424 * "If the requested OpenGL version is less than 3.2,
425 * EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR is ignored and the
426 * functionality of the context is determined solely by the
427 * requested version."
429 * Since the value is ignored, only validate the setting if the version
432 if (ctx
->ClientMajorVersion
>= 4
433 || (ctx
->ClientMajorVersion
== 3 && ctx
->ClientMinorVersion
>= 2)) {
434 switch (ctx
->Profile
) {
435 case EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR
:
436 case EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR
:
440 /* The EGL_KHR_create_context spec says:
442 * "* If an OpenGL context is requested, the requested version
443 * is greater than 3.2, and the value for attribute
444 * EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR has no bits set; has
445 * any bits set other than EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR
446 * and EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR; has
447 * more than one of these bits set; or if the implementation does
448 * not support the requested profile, then an EGL_BAD_MATCH error
456 /* The EGL_KHR_create_context spec says:
458 * "* If an OpenGL context is requested and the values for
459 * attributes EGL_CONTEXT_MAJOR_VERSION_KHR and
460 * EGL_CONTEXT_MINOR_VERSION_KHR, when considered together with
461 * the value for attribute
462 * EGL_CONTEXT_FORWARD_COMPATIBLE_BIT_KHR, specify an OpenGL
463 * version and feature set that are not defined, than an
464 * EGL_BAD_MATCH error is generated.
466 * ... Thus, examples of invalid combinations of attributes
469 * - Major version < 1 or > 4
470 * - Major version == 1 and minor version < 0 or > 5
471 * - Major version == 2 and minor version < 0 or > 1
472 * - Major version == 3 and minor version < 0 or > 2
473 * - Major version == 4 and minor version < 0 or > 2
474 * - Forward-compatible flag set and major version < 3"
476 if (ctx
->ClientMajorVersion
< 1 || ctx
->ClientMinorVersion
< 0)
479 switch (ctx
->ClientMajorVersion
) {
481 if (ctx
->ClientMinorVersion
> 5
482 || (ctx
->Flags
& EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR
) != 0)
487 if (ctx
->ClientMinorVersion
> 1
488 || (ctx
->Flags
& EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR
) != 0)
493 /* Note: The text above is incorrect. There *is* an OpenGL 3.3!
495 if (ctx
->ClientMinorVersion
> 3)
501 /* Don't put additional version checks here. We don't know that
502 * there won't be versions > 4.2.
506 } else if (api
== EGL_OPENGL_ES_API
) {
507 /* The EGL_KHR_create_context spec says:
509 * "* If an OpenGL ES context is requested and the values for
510 * attributes EGL_CONTEXT_MAJOR_VERSION_KHR and
511 * EGL_CONTEXT_MINOR_VERSION_KHR specify an OpenGL ES version that
512 * is not defined, than an EGL_BAD_MATCH error is generated.
514 * ... Examples of invalid combinations of attributes include:
516 * - Major version < 1 or > 2
517 * - Major version == 1 and minor version < 0 or > 1
518 * - Major version == 2 and minor version != 0
520 if (ctx
->ClientMajorVersion
< 1 || ctx
->ClientMinorVersion
< 0)
523 switch (ctx
->ClientMajorVersion
) {
525 if (ctx
->ClientMinorVersion
> 1)
530 if (ctx
->ClientMinorVersion
> 0)
535 /* Don't put additional version checks here. We don't know that
536 * there won't be versions > 3.0.
546 switch (ctx
->ResetNotificationStrategy
) {
547 case EGL_NO_RESET_NOTIFICATION_KHR
:
548 case EGL_LOSE_CONTEXT_ON_RESET_KHR
:
552 err
= EGL_BAD_ATTRIBUTE
;
556 /* The EGL_KHR_create_context_no_error spec says:
558 * "BAD_MATCH is generated if the EGL_CONTEXT_OPENGL_NO_ERROR_KHR is TRUE at
559 * the same time as a debug or robustness context is specified."
561 if (ctx
->NoError
&& (ctx
->Flags
& EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR
||
562 ctx
->Flags
& EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR
)) {
566 if ((ctx
->Flags
& ~(EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR
567 | EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR
568 | EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR
)) != 0) {
569 err
= EGL_BAD_ATTRIBUTE
;
577 * Initialize the given _EGLContext object to defaults and/or the values
578 * in the attrib_list.
580 * According to EGL 1.5 Section 3.7:
582 * "EGL_OPENGL_API and EGL_OPENGL_ES_API are interchangeable for all
583 * purposes except eglCreateContext."
585 * And since we only support GL and GLES, this is the only place where the
586 * bound API matters at all. We look up the current API from the current
587 * thread, and stash that in the context we're initializing. Our caller is
588 * responsible for determining whether that's an API it supports.
591 _eglInitContext(_EGLContext
*ctx
, _EGLDisplay
*disp
, _EGLConfig
*conf
,
592 const EGLint
*attrib_list
)
594 const EGLenum api
= eglQueryAPI();
598 return _eglError(EGL_BAD_MATCH
, "eglCreateContext(no client API)");
600 _eglInitResource(&ctx
->Resource
, sizeof(*ctx
), disp
);
601 ctx
->ClientAPI
= api
;
603 ctx
->Profile
= EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR
;
605 ctx
->ClientMajorVersion
= 1; /* the default, per EGL spec */
606 ctx
->ClientMinorVersion
= 0;
608 ctx
->ResetNotificationStrategy
= EGL_NO_RESET_NOTIFICATION_KHR
;
609 ctx
->ContextPriority
= EGL_CONTEXT_PRIORITY_MEDIUM_IMG
;
610 ctx
->ReleaseBehavior
= EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR
;
612 err
= _eglParseContextAttribList(ctx
, disp
, attrib_list
);
613 if (err
== EGL_SUCCESS
&& ctx
->Config
) {
616 api_bit
= _eglGetContextAPIBit(ctx
);
617 if (!(ctx
->Config
->RenderableType
& api_bit
)) {
618 _eglLog(_EGL_DEBUG
, "context api is 0x%x while config supports 0x%x",
619 api_bit
, ctx
->Config
->RenderableType
);
620 err
= EGL_BAD_CONFIG
;
623 if (err
!= EGL_SUCCESS
)
624 return _eglError(err
, "eglCreateContext");
631 _eglQueryContextRenderBuffer(_EGLContext
*ctx
)
633 _EGLSurface
*surf
= ctx
->DrawSurface
;
635 /* From the EGL 1.5 spec:
637 * - If the context is not bound to a surface, then EGL_NONE will be
643 switch (surf
->Type
) {
645 unreachable("bad EGLSurface type");
647 /* - If the context is bound to a pixmap surface, then EGL_SINGLE_BUFFER
650 return EGL_SINGLE_BUFFER
;
651 case EGL_PBUFFER_BIT
:
652 /* - If the context is bound to a pbuffer surface, then EGL_BACK_BUFFER
655 return EGL_BACK_BUFFER
;
657 /* - If the context is bound to a window surface, then either
658 * EGL_BACK_BUFFER or EGL_SINGLE_BUFFER may be returned. The value
659 * returned depends on both the buffer requested by the setting of the
660 * EGL_RENDER_BUFFER property of the surface [...], and on the client
661 * API (not all client APIs support single-buffer Rendering to window
662 * surfaces). Some client APIs allow control of whether rendering goes
663 * to the front or back buffer. This client API-specific choice is not
664 * reflected in the returned value, which only describes the buffer
665 * that will be rendered to by default if not overridden by the client
668 return surf
->ActiveRenderBuffer
;
674 _eglQueryContext(_EGLDriver
*drv
, _EGLDisplay
*disp
, _EGLContext
*c
,
675 EGLint attribute
, EGLint
*value
)
681 return _eglError(EGL_BAD_PARAMETER
, "eglQueryContext");
686 * From EGL_KHR_no_config_context:
688 * "Querying EGL_CONFIG_ID returns the ID of the EGLConfig with
689 * respect to which the context was created, or zero if created
690 * without respect to an EGLConfig."
692 *value
= c
->Config
? c
->Config
->ConfigID
: 0;
694 case EGL_CONTEXT_CLIENT_VERSION
:
695 *value
= c
->ClientMajorVersion
;
697 case EGL_CONTEXT_CLIENT_TYPE
:
698 *value
= c
->ClientAPI
;
700 case EGL_RENDER_BUFFER
:
701 *value
= _eglQueryContextRenderBuffer(c
);
703 case EGL_CONTEXT_PRIORITY_LEVEL_IMG
:
704 *value
= c
->ContextPriority
;
707 return _eglError(EGL_BAD_ATTRIBUTE
, "eglQueryContext");
715 * Bind the context to the thread and return the previous context.
717 * Note that the context may be NULL.
720 _eglBindContextToThread(_EGLContext
*ctx
, _EGLThreadInfo
*t
)
724 oldCtx
= t
->CurrentContext
;
727 oldCtx
->Binding
= NULL
;
731 t
->CurrentContext
= ctx
;
739 * Return true if the given context and surfaces can be made current.
742 _eglCheckMakeCurrent(_EGLContext
*ctx
, _EGLSurface
*draw
, _EGLSurface
*read
)
744 _EGLThreadInfo
*t
= _eglGetCurrentThread();
747 if (_eglIsCurrentThreadDummy())
748 return _eglError(EGL_BAD_ALLOC
, "eglMakeCurrent");
753 return _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
757 disp
= ctx
->Resource
.Display
;
758 if (!disp
->Extensions
.KHR_surfaceless_context
759 && (draw
== NULL
|| read
== NULL
))
760 return _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
765 * "If ctx is current to some other thread, or if either draw or read are
766 * bound to contexts in another thread, an EGL_BAD_ACCESS error is
771 * "at most one context may be bound to a particular surface at a given
774 if (ctx
->Binding
&& ctx
->Binding
!= t
)
775 return _eglError(EGL_BAD_ACCESS
, "eglMakeCurrent");
776 if (draw
&& draw
->CurrentContext
&& draw
->CurrentContext
!= ctx
) {
777 if (draw
->CurrentContext
->Binding
!= t
)
778 return _eglError(EGL_BAD_ACCESS
, "eglMakeCurrent");
780 if (read
&& read
->CurrentContext
&& read
->CurrentContext
!= ctx
) {
781 if (read
->CurrentContext
->Binding
!= t
)
782 return _eglError(EGL_BAD_ACCESS
, "eglMakeCurrent");
785 /* If the context has a config then it must match that of the two
788 if ((draw
&& draw
->Config
!= ctx
->Config
) ||
789 (read
&& read
->Config
!= ctx
->Config
))
790 return _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
792 /* Otherwise we must be using the EGL_KHR_no_config_context
794 assert(disp
->Extensions
.KHR_no_config_context
);
796 /* The extension doesn't permit binding draw and read buffers with
797 * differing contexts */
798 if (draw
&& read
&& draw
->Config
!= read
->Config
)
799 return _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
807 * Bind the context to the current thread and given surfaces. Return the
808 * previous bound context and surfaces. The caller should unreference the
809 * returned context and surfaces.
811 * Making a second call with the resources returned by the first call
812 * unsurprisingly undoes the first call, except for the resouce reference
816 _eglBindContext(_EGLContext
*ctx
, _EGLSurface
*draw
, _EGLSurface
*read
,
817 _EGLContext
**old_ctx
,
818 _EGLSurface
**old_draw
, _EGLSurface
**old_read
)
820 _EGLThreadInfo
*t
= _eglGetCurrentThread();
821 _EGLContext
*prev_ctx
;
822 _EGLSurface
*prev_draw
, *prev_read
;
824 if (!_eglCheckMakeCurrent(ctx
, draw
, read
))
827 /* increment refcounts before binding */
829 _eglGetSurface(draw
);
830 _eglGetSurface(read
);
832 /* bind the new context */
833 prev_ctx
= _eglBindContextToThread(ctx
, t
);
835 /* break previous bindings */
837 prev_draw
= prev_ctx
->DrawSurface
;
838 prev_read
= prev_ctx
->ReadSurface
;
841 prev_draw
->CurrentContext
= NULL
;
843 prev_read
->CurrentContext
= NULL
;
845 prev_ctx
->DrawSurface
= NULL
;
846 prev_ctx
->ReadSurface
= NULL
;
849 prev_draw
= prev_read
= NULL
;
852 /* establish new bindings */
855 draw
->CurrentContext
= ctx
;
857 read
->CurrentContext
= ctx
;
859 ctx
->DrawSurface
= draw
;
860 ctx
->ReadSurface
= read
;
863 assert(old_ctx
&& old_draw
&& old_read
);
865 *old_draw
= prev_draw
;
866 *old_read
= prev_read
;