5 #include "eglcontext.h"
6 #include "egldisplay.h"
8 #include "eglglobals.h"
9 #include "eglsurface.h"
13 * Initialize the given _EGLContext object to defaults and/or the values
17 _eglInitContext(_EGLDriver
*drv
, EGLDisplay dpy
, _EGLContext
*ctx
,
18 EGLConfig config
, const EGLint
*attrib_list
)
21 _EGLDisplay
*display
= _eglLookupDisplay(dpy
);
23 const EGLenum api
= eglQueryAPI();
25 if (api
== EGL_NONE
) {
26 _eglError(EGL_BAD_MATCH
, "eglCreateContext(no client API)");
30 conf
= _eglLookupConfig(drv
, dpy
, config
);
32 _eglError(EGL_BAD_CONFIG
, "_eglInitContext");
36 memset(ctx
, 0, sizeof(_EGLContext
));
38 ctx
->ClientVersion
= 1; /* the default, per EGL spec */
40 for (i
= 0; attrib_list
&& attrib_list
[i
] != EGL_NONE
; i
++) {
41 switch (attrib_list
[i
]) {
42 case EGL_CONTEXT_CLIENT_VERSION
:
44 ctx
->ClientVersion
= attrib_list
[i
];
47 _eglError(EGL_BAD_ATTRIBUTE
, "_eglInitContext");
52 ctx
->Display
= display
;
54 ctx
->DrawSurface
= EGL_NO_SURFACE
;
55 ctx
->ReadSurface
= EGL_NO_SURFACE
;
63 * Save a new _EGLContext into the hash table.
66 _eglSaveContext(_EGLContext
*ctx
)
69 * Public EGLContext handle and private _EGLContext are the same.
75 * Remove the given _EGLContext object from the hash table.
78 _eglRemoveContext(_EGLContext
*ctx
)
81 * Public EGLContext handle and private _EGLContext are the same.
87 * Return the public handle for the given private context ptr.
88 * This is the inverse of _eglLookupContext().
91 _eglGetContextHandle(_EGLContext
*ctx
)
94 return (EGLContext
) ctx
;
99 * Return the _EGLContext object that corresponds to the given
101 * This is the inverse of _eglGetContextHandle().
104 _eglLookupContext(EGLContext ctx
)
106 /* just a cast since EGLContext is just a void ptr */
107 return (_EGLContext
*) ctx
;
112 * Return the currently bound _EGLContext object, or NULL.
115 _eglGetCurrentContext(void)
117 _EGLThreadInfo
*t
= _eglGetCurrentThread();
118 return t
->CurrentContext
;
123 * Just a placeholder/demo function. Real driver will never use this!
126 _eglCreateContext(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig config
,
127 EGLContext share_list
, const EGLint
*attrib_list
)
129 #if 0 /* example code */
130 _EGLContext
*context
;
132 context
= (_EGLContext
*) calloc(1, sizeof(_EGLContext
));
134 return EGL_NO_CONTEXT
;
136 if (!_eglInitContext(drv
, dpy
, context
, config
, attrib_list
)) {
138 return EGL_NO_CONTEXT
;
141 _eglSaveContext(context
);
142 return (EGLContext
) context
;
144 return EGL_NO_CONTEXT
;
149 * Default fallback routine - drivers should usually override this.
152 _eglDestroyContext(_EGLDriver
*drv
, EGLDisplay dpy
, EGLContext ctx
)
154 _EGLContext
*context
= _eglLookupContext(ctx
);
156 if (context
->IsBound
) {
157 context
->DeletePending
= EGL_TRUE
;
165 _eglError(EGL_BAD_CONTEXT
, "eglDestroyContext");
172 _eglQueryContext(_EGLDriver
*drv
, EGLDisplay dpy
, EGLContext ctx
,
173 EGLint attribute
, EGLint
*value
)
175 _EGLContext
*c
= _eglLookupContext(ctx
);
181 _eglError(EGL_BAD_CONTEXT
, "eglQueryContext");
187 *value
= GET_CONFIG_ATTRIB(c
->Config
, EGL_CONFIG_ID
);
189 #ifdef EGL_VERSION_1_2
190 case EGL_CONTEXT_CLIENT_TYPE
:
191 *value
= c
->ClientAPI
;
193 #endif /* EGL_VERSION_1_2 */
194 case EGL_CONTEXT_CLIENT_VERSION
:
195 *value
= c
->ClientVersion
;
198 _eglError(EGL_BAD_ATTRIBUTE
, "eglQueryContext");
205 * Drivers will typically call this to do the error checking and
206 * update the various IsBound and DeletePending flags.
207 * Then, the driver will do its device-dependent Make-Current stuff.
210 _eglMakeCurrent(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface d
,
211 EGLSurface r
, EGLContext context
)
213 _EGLThreadInfo
*t
= _eglGetCurrentThread();
214 _EGLContext
*ctx
= _eglLookupContext(context
);
215 _EGLSurface
*draw
= _eglLookupSurface(d
);
216 _EGLSurface
*read
= _eglLookupSurface(r
);
218 _EGLContext
*oldContext
= _eglGetCurrentContext();
219 _EGLSurface
*oldDrawSurface
= _eglGetCurrentSurface(EGL_DRAW
);
220 _EGLSurface
*oldReadSurface
= _eglGetCurrentSurface(EGL_READ
);
224 if (draw
== NULL
|| read
== NULL
) {
225 _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
228 if (draw
->Config
!= ctx
->Config
) {
229 _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
232 if (read
->Config
!= ctx
->Config
) {
233 _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
239 * check if the old context or surfaces need to be deleted
241 if (oldDrawSurface
!= NULL
) {
242 oldDrawSurface
->IsBound
= EGL_FALSE
;
243 if (oldDrawSurface
->DeletePending
) {
244 /* make sure we don't try to rebind a deleted surface */
245 if (draw
== oldDrawSurface
|| draw
== oldReadSurface
) {
248 /* really delete surface now */
249 drv
->API
.DestroySurface(drv
, dpy
, oldDrawSurface
->Handle
);
252 if (oldReadSurface
!= NULL
&& oldReadSurface
!= oldDrawSurface
) {
253 oldReadSurface
->IsBound
= EGL_FALSE
;
254 if (oldReadSurface
->DeletePending
) {
255 /* make sure we don't try to rebind a deleted surface */
256 if (read
== oldDrawSurface
|| read
== oldReadSurface
) {
259 /* really delete surface now */
260 drv
->API
.DestroySurface(drv
, dpy
, oldReadSurface
->Handle
);
263 if (oldContext
!= NULL
) {
264 oldContext
->IsBound
= EGL_FALSE
;
265 if (oldContext
->DeletePending
) {
266 /* make sure we don't try to rebind a deleted context */
267 if (ctx
== oldContext
) {
270 /* really delete context now */
271 drv
->API
.DestroyContext(drv
, dpy
, _eglGetContextHandle(oldContext
));
276 /* check read/draw again, in case we deleted them above */
277 if (draw
== NULL
|| read
== NULL
) {
278 _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
281 ctx
->DrawSurface
= draw
;
282 ctx
->ReadSurface
= read
;
283 ctx
->IsBound
= EGL_TRUE
;
284 draw
->IsBound
= EGL_TRUE
;
285 read
->IsBound
= EGL_TRUE
;
288 t
->CurrentContext
= ctx
;
295 * This is defined by the EGL_MESA_copy_context extension.
298 _eglCopyContextMESA(_EGLDriver
*drv
, EGLDisplay dpy
, EGLContext source
,
299 EGLContext dest
, EGLint mask
)
301 /* This function will always have to be overridden/implemented in the
302 * device driver. If the driver is based on Mesa, use _mesa_copy_context().