5 #include "eglcontext.h"
6 #include "egldisplay.h"
8 #include "eglglobals.h"
10 #include "eglsurface.h"
14 * Initialize the given _EGLContext object to defaults.
17 _eglInitContext(_EGLDriver
*drv
, EGLDisplay dpy
, _EGLContext
*ctx
,
18 EGLConfig config
, const EGLint
*attrib_list
)
21 _EGLDisplay
*display
= _eglLookupDisplay(dpy
);
24 conf
= _eglLookupConfig(drv
, dpy
, config
);
26 _eglError(EGL_BAD_CONFIG
, "eglCreateContext");
30 for (i
= 0; attrib_list
&& attrib_list
[i
] != EGL_NONE
; i
++) {
31 switch (attrib_list
[i
]) {
32 /* no attribs defined for now */
34 _eglError(EGL_BAD_ATTRIBUTE
, "eglCreateContext");
39 memset(ctx
, 0, sizeof(_EGLContext
));
40 ctx
->Display
= display
;
42 ctx
->DrawSurface
= EGL_NO_SURFACE
;
43 ctx
->ReadSurface
= EGL_NO_SURFACE
;
50 * Assign an EGLContext handle to the _EGLContext object then put it into
54 _eglSaveContext(_EGLContext
*ctx
)
56 EGLuint key
= _eglHashGenKey(_eglGlobal
.Contexts
);
58 ctx
->Handle
= (EGLContext
) key
;
59 _eglHashInsert(_eglGlobal
.Contexts
, key
, ctx
);
64 * Remove the given _EGLContext object from the hash table.
67 _eglRemoveContext(_EGLContext
*ctx
)
69 EGLuint key
= (EGLuint
) ctx
->Handle
;
70 _eglHashRemove(_eglGlobal
.Contexts
, key
);
75 * Return the _EGLContext object that corresponds to the given
79 _eglLookupContext(EGLContext ctx
)
81 EGLuint key
= (EGLuint
) ctx
;
82 _EGLContext
*c
= (_EGLContext
*) _eglHashLookup(_eglGlobal
.Contexts
, key
);
88 * Return the currently bound _EGLContext object, or NULL.
91 _eglGetCurrentContext(void)
93 _EGLThreadInfo
*t
= _eglGetCurrentThread();
94 return t
->CurrentContext
;
99 * Just a placeholder/demo function. Real driver will never use this!
102 _eglCreateContext(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig config
,
103 EGLContext share_list
, const EGLint
*attrib_list
)
105 #if 0 /* example code */
106 _EGLContext
*context
;
108 context
= (_EGLContext
*) calloc(1, sizeof(_EGLContext
));
110 return EGL_NO_CONTEXT
;
112 if (!_eglInitContext(drv
, dpy
, context
, config
, attrib_list
)) {
114 return EGL_NO_CONTEXT
;
117 _eglSaveContext(context
);
118 return context
->Handle
;
120 return EGL_NO_CONTEXT
;
125 * Default fallback routine - drivers should usually override this.
128 _eglDestroyContext(_EGLDriver
*drv
, EGLDisplay dpy
, EGLContext ctx
)
130 _EGLContext
*context
= _eglLookupContext(ctx
);
132 EGLuint key
= (EGLuint
) ctx
;
133 _eglHashRemove(_eglGlobal
.Contexts
, key
);
134 if (context
->IsBound
) {
135 context
->DeletePending
= EGL_TRUE
;
143 _eglError(EGL_BAD_CONTEXT
, "eglDestroyContext");
150 _eglQueryContext(_EGLDriver
*drv
, EGLDisplay dpy
, EGLContext ctx
,
151 EGLint attribute
, EGLint
*value
)
153 _EGLContext
*c
= _eglLookupContext(ctx
);
159 _eglError(EGL_BAD_CONTEXT
, "eglQueryContext");
165 *value
= GET_CONFIG_ATTRIB(c
->Config
, EGL_CONFIG_ID
);
167 #ifdef EGL_VERSION_1_2
168 case EGL_CONTEXT_CLIENT_TYPE
:
169 *value
= c
->ClientAPI
;
171 #endif /* EGL_VERSION_1_2 */
173 _eglError(EGL_BAD_ATTRIBUTE
, "eglQueryContext");
180 * Drivers will typically call this to do the error checking and
181 * update the various IsBound and DeletePending flags.
182 * Then, the driver will do its device-dependent Make-Current stuff.
185 _eglMakeCurrent(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface d
,
186 EGLSurface r
, EGLContext context
)
188 _EGLThreadInfo
*t
= _eglGetCurrentThread();
189 _EGLContext
*ctx
= _eglLookupContext(context
);
190 _EGLSurface
*draw
= _eglLookupSurface(d
);
191 _EGLSurface
*read
= _eglLookupSurface(r
);
193 _EGLContext
*oldContext
= _eglGetCurrentContext();
194 _EGLSurface
*oldDrawSurface
= _eglGetCurrentSurface(EGL_DRAW
);
195 _EGLSurface
*oldReadSurface
= _eglGetCurrentSurface(EGL_READ
);
199 if (draw
== NULL
|| read
== NULL
) {
200 _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
203 if (draw
->Config
!= ctx
->Config
) {
204 _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
207 if (read
->Config
!= ctx
->Config
) {
208 _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
214 * check if the old context or surfaces need to be deleted
216 if (oldDrawSurface
!= NULL
) {
217 oldDrawSurface
->IsBound
= EGL_FALSE
;
218 if (oldDrawSurface
->DeletePending
) {
219 /* make sure we don't try to rebind a deleted surface */
220 if (draw
== oldDrawSurface
|| draw
== oldReadSurface
) {
223 /* really delete surface now */
224 drv
->API
.DestroySurface(drv
, dpy
, oldDrawSurface
->Handle
);
227 if (oldReadSurface
!= NULL
&& oldReadSurface
!= oldDrawSurface
) {
228 oldReadSurface
->IsBound
= EGL_FALSE
;
229 if (oldReadSurface
->DeletePending
) {
230 /* make sure we don't try to rebind a deleted surface */
231 if (read
== oldDrawSurface
|| read
== oldReadSurface
) {
234 /* really delete surface now */
235 drv
->API
.DestroySurface(drv
, dpy
, oldReadSurface
->Handle
);
238 if (oldContext
!= NULL
) {
239 oldContext
->IsBound
= EGL_FALSE
;
240 if (oldContext
->DeletePending
) {
241 /* make sure we don't try to rebind a deleted context */
242 if (ctx
== oldContext
) {
245 /* really delete context now */
246 drv
->API
.DestroyContext(drv
, dpy
, oldContext
->Handle
);
251 /* check read/draw again, in case we deleted them above */
252 if (draw
== NULL
|| read
== NULL
) {
253 _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
256 ctx
->DrawSurface
= draw
;
257 ctx
->ReadSurface
= read
;
258 ctx
->IsBound
= EGL_TRUE
;
259 draw
->IsBound
= EGL_TRUE
;
260 read
->IsBound
= EGL_TRUE
;
263 t
->CurrentContext
= ctx
;
270 * This is defined by the EGL_MESA_copy_context extension.
273 _eglCopyContextMESA(_EGLDriver
*drv
, EGLDisplay dpy
, EGLContext source
,
274 EGLContext dest
, EGLint mask
)
276 /* This function will always have to be overridden/implemented in the
277 * device driver. If the driver is based on Mesa, use _mesa_copy_context().