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");
35 return EGL_NO_CONTEXT
;
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
)
57 ctx
->Handle
= _eglHashGenKey(_eglGlobal
.Contexts
);
58 _eglHashInsert(_eglGlobal
.Contexts
, ctx
->Handle
, ctx
);
63 * Remove the given _EGLContext object from the hash table.
66 _eglRemoveContext(_EGLContext
*ctx
)
68 _eglHashRemove(_eglGlobal
.Contexts
, ctx
->Handle
);
73 * Return the _EGLContext object that corresponds to the given
77 _eglLookupContext(EGLContext ctx
)
79 _EGLContext
*c
= (_EGLContext
*) _eglHashLookup(_eglGlobal
.Contexts
, ctx
);
85 * Return the currently bound _EGLContext object, or NULL.
88 _eglGetCurrentContext(void)
90 _EGLThreadInfo
*t
= _eglGetCurrentThread();
91 return t
->CurrentContext
;
96 * Just a placeholder/demo function. Real driver will never use this!
99 _eglCreateContext(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig config
,
100 EGLContext share_list
, const EGLint
*attrib_list
)
102 #if 0 /* example code */
103 _EGLContext
*context
;
105 context
= (_EGLContext
*) calloc(1, sizeof(_EGLContext
));
107 return EGL_NO_CONTEXT
;
109 if (!_eglInitContext(drv
, dpy
, context
, config
, attrib_list
)) {
111 return EGL_NO_CONTEXT
;
114 _eglSaveContext(context
);
115 return context
->Handle
;
117 return EGL_NO_CONTEXT
;
122 * Default fallback routine - drivers should usually override this.
125 _eglDestroyContext(_EGLDriver
*drv
, EGLDisplay dpy
, EGLContext ctx
)
127 _EGLContext
*context
= _eglLookupContext(ctx
);
129 _eglHashRemove(_eglGlobal
.Contexts
, ctx
);
130 if (context
->IsBound
) {
131 context
->DeletePending
= EGL_TRUE
;
139 _eglError(EGL_BAD_CONTEXT
, "eglDestroyContext");
146 _eglQueryContext(_EGLDriver
*drv
, EGLDisplay dpy
, EGLContext ctx
,
147 EGLint attribute
, EGLint
*value
)
149 _EGLContext
*c
= _eglLookupContext(ctx
);
155 _eglError(EGL_BAD_CONTEXT
, "eglQueryContext");
161 *value
= GET_CONFIG_ATTRIB(c
->Config
, EGL_CONFIG_ID
);
164 _eglError(EGL_BAD_ATTRIBUTE
, "eglQueryContext");
171 * Drivers will typically call this to do the error checking and
172 * update the various IsBound and DeletePending flags.
173 * Then, the driver will do its device-dependent Make-Current stuff.
176 _eglMakeCurrent(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface d
,
177 EGLSurface r
, EGLContext context
)
179 _EGLThreadInfo
*t
= _eglGetCurrentThread();
180 _EGLContext
*ctx
= _eglLookupContext(context
);
181 _EGLSurface
*draw
= _eglLookupSurface(d
);
182 _EGLSurface
*read
= _eglLookupSurface(r
);
184 _EGLContext
*oldContext
= _eglGetCurrentContext();
185 _EGLSurface
*oldDrawSurface
= _eglGetCurrentSurface(EGL_DRAW
);
186 _EGLSurface
*oldReadSurface
= _eglGetCurrentSurface(EGL_READ
);
190 if (draw
== NULL
|| read
== NULL
) {
191 _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
194 if (draw
->Config
!= ctx
->Config
) {
195 _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
198 if (read
->Config
!= ctx
->Config
) {
199 _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
205 * check if the old context or surfaces need to be deleted
207 if (oldDrawSurface
!= NULL
) {
208 oldDrawSurface
->IsBound
= EGL_FALSE
;
209 if (oldDrawSurface
->DeletePending
) {
210 /* make sure we don't try to rebind a deleted surface */
211 if (draw
== oldDrawSurface
|| draw
== oldReadSurface
) {
214 /* really delete surface now */
215 drv
->API
.DestroySurface(drv
, dpy
, oldDrawSurface
->Handle
);
218 if (oldReadSurface
!= NULL
&& oldReadSurface
!= oldDrawSurface
) {
219 oldReadSurface
->IsBound
= EGL_FALSE
;
220 if (oldReadSurface
->DeletePending
) {
221 /* make sure we don't try to rebind a deleted surface */
222 if (read
== oldDrawSurface
|| read
== oldReadSurface
) {
225 /* really delete surface now */
226 drv
->API
.DestroySurface(drv
, dpy
, oldReadSurface
->Handle
);
229 if (oldContext
!= NULL
) {
230 oldContext
->IsBound
= EGL_FALSE
;
231 if (oldContext
->DeletePending
) {
232 /* make sure we don't try to rebind a deleted context */
233 if (ctx
== oldContext
) {
236 /* really delete context now */
237 drv
->API
.DestroyContext(drv
, dpy
, oldContext
->Handle
);
242 /* check read/draw again, in case we deleted them above */
243 if (draw
== NULL
|| read
== NULL
) {
244 _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
247 ctx
->DrawSurface
= draw
;
248 ctx
->ReadSurface
= read
;
249 ctx
->IsBound
= EGL_TRUE
;
250 draw
->IsBound
= EGL_TRUE
;
251 read
->IsBound
= EGL_TRUE
;
254 t
->CurrentContext
= ctx
;
261 * This is defined by the EGL_MESA_copy_context extension.
264 _eglCopyContextMESA(_EGLDriver
*drv
, EGLDisplay dpy
, EGLContext source
,
265 EGLContext dest
, EGLint mask
)
267 /* This function will always have to be overridden/implemented in the
268 * device driver. If the driver is based on Mesa, use _mesa_copy_context().