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
);
163 #ifdef EGL_VERSION_1_2
164 case EGL_CONTEXT_CLIENT_TYPE
:
165 *value
= c
->ClientAPI
;
167 #endif /* EGL_VERSION_1_2 */
169 _eglError(EGL_BAD_ATTRIBUTE
, "eglQueryContext");
176 * Drivers will typically call this to do the error checking and
177 * update the various IsBound and DeletePending flags.
178 * Then, the driver will do its device-dependent Make-Current stuff.
181 _eglMakeCurrent(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface d
,
182 EGLSurface r
, EGLContext context
)
184 _EGLThreadInfo
*t
= _eglGetCurrentThread();
185 _EGLContext
*ctx
= _eglLookupContext(context
);
186 _EGLSurface
*draw
= _eglLookupSurface(d
);
187 _EGLSurface
*read
= _eglLookupSurface(r
);
189 _EGLContext
*oldContext
= _eglGetCurrentContext();
190 _EGLSurface
*oldDrawSurface
= _eglGetCurrentSurface(EGL_DRAW
);
191 _EGLSurface
*oldReadSurface
= _eglGetCurrentSurface(EGL_READ
);
195 if (draw
== NULL
|| read
== NULL
) {
196 _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
199 if (draw
->Config
!= ctx
->Config
) {
200 _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
203 if (read
->Config
!= ctx
->Config
) {
204 _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
210 * check if the old context or surfaces need to be deleted
212 if (oldDrawSurface
!= NULL
) {
213 oldDrawSurface
->IsBound
= EGL_FALSE
;
214 if (oldDrawSurface
->DeletePending
) {
215 /* make sure we don't try to rebind a deleted surface */
216 if (draw
== oldDrawSurface
|| draw
== oldReadSurface
) {
219 /* really delete surface now */
220 drv
->API
.DestroySurface(drv
, dpy
, oldDrawSurface
->Handle
);
223 if (oldReadSurface
!= NULL
&& oldReadSurface
!= oldDrawSurface
) {
224 oldReadSurface
->IsBound
= EGL_FALSE
;
225 if (oldReadSurface
->DeletePending
) {
226 /* make sure we don't try to rebind a deleted surface */
227 if (read
== oldDrawSurface
|| read
== oldReadSurface
) {
230 /* really delete surface now */
231 drv
->API
.DestroySurface(drv
, dpy
, oldReadSurface
->Handle
);
234 if (oldContext
!= NULL
) {
235 oldContext
->IsBound
= EGL_FALSE
;
236 if (oldContext
->DeletePending
) {
237 /* make sure we don't try to rebind a deleted context */
238 if (ctx
== oldContext
) {
241 /* really delete context now */
242 drv
->API
.DestroyContext(drv
, dpy
, oldContext
->Handle
);
247 /* check read/draw again, in case we deleted them above */
248 if (draw
== NULL
|| read
== NULL
) {
249 _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
252 ctx
->DrawSurface
= draw
;
253 ctx
->ReadSurface
= read
;
254 ctx
->IsBound
= EGL_TRUE
;
255 draw
->IsBound
= EGL_TRUE
;
256 read
->IsBound
= EGL_TRUE
;
259 t
->CurrentContext
= ctx
;
266 * This is defined by the EGL_MESA_copy_context extension.
269 _eglCopyContextMESA(_EGLDriver
*drv
, EGLDisplay dpy
, EGLContext source
,
270 EGLContext dest
, EGLint mask
)
272 /* This function will always have to be overridden/implemented in the
273 * device driver. If the driver is based on Mesa, use _mesa_copy_context().