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 * Just a placeholder/demo function. Real driver will never use this!
90 _eglCreateContext(_EGLDriver
*drv
, EGLDisplay dpy
, EGLConfig config
,
91 EGLContext share_list
, const EGLint
*attrib_list
)
93 #if 0 /* example code */
96 context
= (_EGLContext
*) calloc(1, sizeof(_EGLContext
));
98 return EGL_NO_CONTEXT
;
100 if (!_eglInitContext(drv
, dpy
, context
, config
, attrib_list
)) {
102 return EGL_NO_CONTEXT
;
105 _eglSaveContext(context
);
106 return (EGLContext
) context
;
108 return EGL_NO_CONTEXT
;
113 * Default fallback routine - drivers should usually override this.
116 _eglDestroyContext(_EGLDriver
*drv
, EGLDisplay dpy
, EGLContext ctx
)
118 _EGLContext
*context
= _eglLookupContext(ctx
);
120 if (context
->IsBound
) {
121 context
->DeletePending
= EGL_TRUE
;
129 _eglError(EGL_BAD_CONTEXT
, "eglDestroyContext");
136 _eglQueryContext(_EGLDriver
*drv
, EGLDisplay dpy
, EGLContext ctx
,
137 EGLint attribute
, EGLint
*value
)
139 _EGLContext
*c
= _eglLookupContext(ctx
);
145 _eglError(EGL_BAD_CONTEXT
, "eglQueryContext");
151 *value
= GET_CONFIG_ATTRIB(c
->Config
, EGL_CONFIG_ID
);
153 #ifdef EGL_VERSION_1_2
154 case EGL_CONTEXT_CLIENT_TYPE
:
155 *value
= c
->ClientAPI
;
157 #endif /* EGL_VERSION_1_2 */
158 case EGL_CONTEXT_CLIENT_VERSION
:
159 *value
= c
->ClientVersion
;
162 _eglError(EGL_BAD_ATTRIBUTE
, "eglQueryContext");
169 * Drivers will typically call this to do the error checking and
170 * update the various IsBound and DeletePending flags.
171 * Then, the driver will do its device-dependent Make-Current stuff.
174 _eglMakeCurrent(_EGLDriver
*drv
, EGLDisplay dpy
, EGLSurface d
,
175 EGLSurface r
, EGLContext context
)
177 _EGLThreadInfo
*t
= _eglGetCurrentThread();
178 _EGLContext
*ctx
= _eglLookupContext(context
);
179 _EGLSurface
*draw
= _eglLookupSurface(d
);
180 _EGLSurface
*read
= _eglLookupSurface(r
);
181 _EGLContext
*oldContext
= NULL
;
182 _EGLSurface
*oldDrawSurface
= NULL
;
183 _EGLSurface
*oldReadSurface
= NULL
;
186 if (_eglIsCurrentThreadDummy())
187 return _eglError(EGL_BAD_ALLOC
, "eglMakeCurrent");
191 if (draw
== NULL
|| read
== NULL
) {
192 _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
195 if (draw
->Config
!= ctx
->Config
) {
196 _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
199 if (read
->Config
!= ctx
->Config
) {
200 _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
204 #ifdef EGL_VERSION_1_4
205 /* OpenGL and OpenGL ES are conflicting */
206 switch (ctx
->ClientAPI
) {
207 case EGL_OPENGL_ES_API
:
208 if (t
->CurrentContexts
[_eglConvertApiToIndex(EGL_OPENGL_API
)])
209 return _eglError(EGL_BAD_ACCESS
, "eglMakeCurrent");
212 if (t
->CurrentContexts
[_eglConvertApiToIndex(EGL_OPENGL_ES_API
)])
213 return _eglError(EGL_BAD_ACCESS
, "eglMakeCurrent");
219 apiIndex
= _eglConvertApiToIndex(ctx
->ClientAPI
);
222 apiIndex
= t
->CurrentAPIIndex
;
225 oldContext
= t
->CurrentContexts
[apiIndex
];
227 oldDrawSurface
= oldContext
->DrawSurface
;
228 oldReadSurface
= oldContext
->ReadSurface
;
232 * check if the old context or surfaces need to be deleted
234 if (oldDrawSurface
!= NULL
) {
235 oldDrawSurface
->IsBound
= EGL_FALSE
;
236 if (oldDrawSurface
->DeletePending
) {
237 /* make sure we don't try to rebind a deleted surface */
238 if (draw
== oldDrawSurface
|| draw
== oldReadSurface
) {
241 /* really delete surface now */
242 drv
->API
.DestroySurface(drv
, dpy
, oldDrawSurface
->Handle
);
245 if (oldReadSurface
!= NULL
&& oldReadSurface
!= oldDrawSurface
) {
246 oldReadSurface
->IsBound
= EGL_FALSE
;
247 if (oldReadSurface
->DeletePending
) {
248 /* make sure we don't try to rebind a deleted surface */
249 if (read
== oldDrawSurface
|| read
== oldReadSurface
) {
252 /* really delete surface now */
253 drv
->API
.DestroySurface(drv
, dpy
, oldReadSurface
->Handle
);
256 if (oldContext
!= NULL
) {
257 oldContext
->IsBound
= EGL_FALSE
;
258 if (oldContext
->DeletePending
) {
259 /* make sure we don't try to rebind a deleted context */
260 if (ctx
== oldContext
) {
263 /* really delete context now */
264 drv
->API
.DestroyContext(drv
, dpy
, _eglGetContextHandle(oldContext
));
269 /* check read/draw again, in case we deleted them above */
270 if (draw
== NULL
|| read
== NULL
) {
271 _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
274 ctx
->DrawSurface
= draw
;
275 ctx
->ReadSurface
= read
;
276 ctx
->IsBound
= EGL_TRUE
;
277 draw
->IsBound
= EGL_TRUE
;
278 read
->IsBound
= EGL_TRUE
;
279 t
->CurrentContexts
[apiIndex
] = ctx
;
282 t
->CurrentContexts
[apiIndex
] = NULL
;
290 * This is defined by the EGL_MESA_copy_context extension.
293 _eglCopyContextMESA(_EGLDriver
*drv
, EGLDisplay dpy
, EGLContext source
,
294 EGLContext dest
, EGLint mask
)
296 /* This function will always have to be overridden/implemented in the
297 * device driver. If the driver is based on Mesa, use _mesa_copy_context().