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 /* XXX this should be per-thread someday */
91 return _eglGlobal
.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 _EGLContext
*ctx
= _eglLookupContext(context
);
180 _EGLSurface
*draw
= _eglLookupSurface(d
);
181 _EGLSurface
*read
= _eglLookupSurface(r
);
183 _EGLContext
*oldContext
= _eglGetCurrentContext();
184 _EGLSurface
*oldDrawSurface
= _eglGetCurrentSurface(EGL_DRAW
);
185 _EGLSurface
*oldReadSurface
= _eglGetCurrentSurface(EGL_READ
);
189 if (draw
== NULL
|| read
== NULL
) {
190 _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
193 if (draw
->Config
!= ctx
->Config
) {
194 _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
197 if (read
->Config
!= ctx
->Config
) {
198 _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
204 * check if the old context or surfaces need to be deleted
206 if (oldDrawSurface
!= NULL
) {
207 oldDrawSurface
->IsBound
= EGL_FALSE
;
208 if (oldDrawSurface
->DeletePending
) {
209 /* make sure we don't try to rebind a deleted surface */
210 if (draw
== oldDrawSurface
|| draw
== oldReadSurface
) {
213 /* really delete surface now */
214 drv
->API
.DestroySurface(drv
, dpy
, oldDrawSurface
->Handle
);
217 if (oldReadSurface
!= NULL
&& oldReadSurface
!= oldDrawSurface
) {
218 oldReadSurface
->IsBound
= EGL_FALSE
;
219 if (oldReadSurface
->DeletePending
) {
220 /* make sure we don't try to rebind a deleted surface */
221 if (read
== oldDrawSurface
|| read
== oldReadSurface
) {
224 /* really delete surface now */
225 drv
->API
.DestroySurface(drv
, dpy
, oldReadSurface
->Handle
);
228 if (oldContext
!= NULL
) {
229 oldContext
->IsBound
= EGL_FALSE
;
230 if (oldContext
->DeletePending
) {
231 /* make sure we don't try to rebind a deleted context */
232 if (ctx
== oldContext
) {
235 /* really delete context now */
236 drv
->API
.DestroyContext(drv
, dpy
, oldContext
->Handle
);
241 /* check read/draw again, in case we deleted them above */
242 if (draw
== NULL
|| read
== NULL
) {
243 _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
246 ctx
->DrawSurface
= draw
;
247 ctx
->ReadSurface
= read
;
248 ctx
->IsBound
= EGL_TRUE
;
249 draw
->IsBound
= EGL_TRUE
;
250 read
->IsBound
= EGL_TRUE
;
253 _eglGlobal
.CurrentContext
= ctx
;
260 * This is defined by the EGL_MESA_copy_context extension.
263 _eglCopyContextMESA(_EGLDriver
*drv
, EGLDisplay dpy
, EGLContext source
,
264 EGLContext dest
, EGLint mask
)
266 /* This function will always have to be overridden/implemented in the
267 * device driver. If the driver is based on Mesa, use _mesa_copy_context().