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
, _EGLContext
*ctx
,
18 _EGLConfig
*conf
, const EGLint
*attrib_list
)
21 const EGLenum api
= eglQueryAPI();
23 if (api
== EGL_NONE
) {
24 _eglError(EGL_BAD_MATCH
, "eglCreateContext(no client API)");
29 _eglError(EGL_BAD_CONFIG
, "_eglInitContext");
33 memset(ctx
, 0, sizeof(_EGLContext
));
35 ctx
->ClientVersion
= 1; /* the default, per EGL spec */
37 for (i
= 0; attrib_list
&& attrib_list
[i
] != EGL_NONE
; i
++) {
38 switch (attrib_list
[i
]) {
39 case EGL_CONTEXT_CLIENT_VERSION
:
41 ctx
->ClientVersion
= attrib_list
[i
];
44 _eglError(EGL_BAD_ATTRIBUTE
, "_eglInitContext");
50 ctx
->DrawSurface
= EGL_NO_SURFACE
;
51 ctx
->ReadSurface
= EGL_NO_SURFACE
;
59 * Just a placeholder/demo function. Real driver will never use this!
62 _eglCreateContext(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig config
,
63 EGLContext share_list
, const EGLint
*attrib_list
)
65 #if 0 /* example code */
69 conf
= _eglLookupConfig(drv
, dpy
, config
);
71 _eglError(EGL_BAD_CONFIG
, "eglCreateContext");
72 return EGL_NO_CONTEXT
;
75 context
= (_EGLContext
*) calloc(1, sizeof(_EGLContext
));
77 return EGL_NO_CONTEXT
;
79 if (!_eglInitContext(drv
, context
, conf
, attrib_list
)) {
81 return EGL_NO_CONTEXT
;
84 return _eglLinkContext(context
, _eglLookupDisplay(dpy
));
86 return EGL_NO_CONTEXT
;
91 * Default fallback routine - drivers should usually override this.
94 _eglDestroyContext(_EGLDriver
*drv
, EGLDisplay dpy
, EGLContext ctx
)
96 _EGLContext
*context
= _eglLookupContext(ctx
);
98 _eglUnlinkContext(context
);
99 if (!_eglIsContextBound(context
))
104 _eglError(EGL_BAD_CONTEXT
, "eglDestroyContext");
111 _eglQueryContext(_EGLDriver
*drv
, EGLDisplay dpy
, EGLContext ctx
,
112 EGLint attribute
, EGLint
*value
)
114 _EGLContext
*c
= _eglLookupContext(ctx
);
120 _eglError(EGL_BAD_CONTEXT
, "eglQueryContext");
126 *value
= GET_CONFIG_ATTRIB(c
->Config
, EGL_CONFIG_ID
);
128 #ifdef EGL_VERSION_1_2
129 case EGL_CONTEXT_CLIENT_TYPE
:
130 *value
= c
->ClientAPI
;
132 #endif /* EGL_VERSION_1_2 */
133 case EGL_CONTEXT_CLIENT_VERSION
:
134 *value
= c
->ClientVersion
;
137 _eglError(EGL_BAD_ATTRIBUTE
, "eglQueryContext");
144 * Drivers will typically call this to do the error checking and
145 * update the various flags.
146 * Then, the driver will do its device-dependent Make-Current stuff.
149 _eglMakeCurrent(_EGLDriver
*drv
, EGLDisplay display
, EGLSurface d
,
150 EGLSurface r
, EGLContext context
)
152 _EGLThreadInfo
*t
= _eglGetCurrentThread();
153 _EGLDisplay
*dpy
= _eglLookupDisplay(display
);
154 _EGLContext
*ctx
= _eglLookupContext(context
);
155 _EGLSurface
*draw
= _eglLookupSurface(d
);
156 _EGLSurface
*read
= _eglLookupSurface(r
);
157 _EGLContext
*oldContext
= NULL
;
158 _EGLSurface
*oldDrawSurface
= NULL
;
159 _EGLSurface
*oldReadSurface
= NULL
;
162 if (_eglIsCurrentThreadDummy())
163 return _eglError(EGL_BAD_ALLOC
, "eglMakeCurrent");
165 return _eglError(EGL_BAD_DISPLAY
, "eglMakeCurrent");
169 if (ctx
->Binding
&& ctx
->Binding
!= t
)
170 return _eglError(EGL_BAD_ACCESS
, "eglMakeCurrent");
171 if (draw
== NULL
|| read
== NULL
) {
172 EGLint err
= (d
== EGL_NO_SURFACE
|| r
== EGL_NO_SURFACE
)
173 ? EGL_BAD_MATCH
: EGL_BAD_SURFACE
;
174 return _eglError(err
, "eglMakeCurrent");
176 if (draw
->Config
!= ctx
->Config
|| read
->Config
!= ctx
->Config
)
177 return _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
178 if ((draw
->Binding
&& draw
->Binding
->Binding
!= t
) ||
179 (read
->Binding
&& read
->Binding
->Binding
!= t
))
180 return _eglError(EGL_BAD_ACCESS
, "eglMakeCurrent");
182 #ifdef EGL_VERSION_1_4
183 /* OpenGL and OpenGL ES are conflicting */
184 switch (ctx
->ClientAPI
) {
185 case EGL_OPENGL_ES_API
:
186 if (t
->CurrentContexts
[_eglConvertApiToIndex(EGL_OPENGL_API
)])
187 return _eglError(EGL_BAD_ACCESS
, "eglMakeCurrent");
190 if (t
->CurrentContexts
[_eglConvertApiToIndex(EGL_OPENGL_ES_API
)])
191 return _eglError(EGL_BAD_ACCESS
, "eglMakeCurrent");
197 apiIndex
= _eglConvertApiToIndex(ctx
->ClientAPI
);
200 if (context
!= EGL_NO_CONTEXT
)
201 return _eglError(EGL_BAD_CONTEXT
, "eglMakeCurrent");
202 if (draw
!= NULL
|| read
!= NULL
)
203 return _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
204 apiIndex
= t
->CurrentAPIIndex
;
207 oldContext
= t
->CurrentContexts
[apiIndex
];
209 oldDrawSurface
= oldContext
->DrawSurface
;
210 oldReadSurface
= oldContext
->ReadSurface
;
211 assert(oldDrawSurface
);
212 assert(oldReadSurface
);
214 /* break old bindings */
215 t
->CurrentContexts
[apiIndex
] = NULL
;
216 oldContext
->Binding
= NULL
;
217 oldContext
->DrawSurface
= NULL
;
218 oldContext
->ReadSurface
= NULL
;
219 oldDrawSurface
->Binding
= NULL
;
220 oldReadSurface
->Binding
= NULL
;
223 * check if the old context or surfaces need to be deleted
224 * FIXME They are linked so that they can be unlinked. This is ugly.
226 if (!_eglIsSurfaceLinked(oldDrawSurface
)) {
227 assert(draw
!= oldDrawSurface
&& read
!= oldDrawSurface
);
228 drv
->API
.DestroySurface(drv
, display
,
229 _eglLinkSurface(oldDrawSurface
, dpy
));
231 if (oldReadSurface
!= oldDrawSurface
&&
232 !_eglIsSurfaceLinked(oldReadSurface
)) {
233 assert(draw
!= oldReadSurface
&& read
!= oldReadSurface
);
234 drv
->API
.DestroySurface(drv
, display
,
235 _eglLinkSurface(oldReadSurface
, dpy
));
237 if (!_eglIsContextLinked(oldContext
)) {
238 assert(ctx
!= oldContext
);
239 drv
->API
.DestroyContext(drv
, display
,
240 _eglLinkContext(oldContext
, dpy
));
244 /* build new bindings */
246 t
->CurrentContexts
[apiIndex
] = ctx
;
248 ctx
->DrawSurface
= draw
;
249 ctx
->ReadSurface
= read
;
259 * This is defined by the EGL_MESA_copy_context extension.
262 _eglCopyContextMESA(_EGLDriver
*drv
, EGLDisplay dpy
, EGLContext source
,
263 EGLContext dest
, EGLint mask
)
265 /* This function will always have to be overridden/implemented in the
266 * device driver. If the driver is based on Mesa, use _mesa_copy_context().