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().