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)");
28 memset(ctx
, 0, sizeof(_EGLContext
));
30 ctx
->ClientVersion
= 1; /* the default, per EGL spec */
32 for (i
= 0; attrib_list
&& attrib_list
[i
] != EGL_NONE
; i
++) {
33 switch (attrib_list
[i
]) {
34 case EGL_CONTEXT_CLIENT_VERSION
:
36 ctx
->ClientVersion
= attrib_list
[i
];
39 _eglError(EGL_BAD_ATTRIBUTE
, "_eglInitContext");
45 ctx
->DrawSurface
= EGL_NO_SURFACE
;
46 ctx
->ReadSurface
= EGL_NO_SURFACE
;
48 ctx
->WindowRenderBuffer
= EGL_NONE
;
55 * Just a placeholder/demo function. Real driver will never use this!
58 _eglCreateContext(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLConfig
*conf
,
59 _EGLContext
*share_list
, const EGLint
*attrib_list
)
61 #if 0 /* example code */
64 context
= (_EGLContext
*) calloc(1, sizeof(_EGLContext
));
68 if (!_eglInitContext(drv
, context
, conf
, attrib_list
)) {
80 * Default fallback routine - drivers should usually override this.
83 _eglDestroyContext(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLContext
*ctx
)
85 if (!_eglIsContextBound(ctx
))
91 #ifdef EGL_VERSION_1_2
93 _eglQueryContextRenderBuffer(_EGLContext
*ctx
)
95 _EGLSurface
*surf
= ctx
->DrawSurface
;
100 if (surf
->Type
== EGL_WINDOW_BIT
&& ctx
->WindowRenderBuffer
!= EGL_NONE
)
101 rb
= ctx
->WindowRenderBuffer
;
103 rb
= surf
->RenderBuffer
;
106 #endif /* EGL_VERSION_1_2 */
110 _eglQueryContext(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLContext
*c
,
111 EGLint attribute
, EGLint
*value
)
117 return _eglError(EGL_BAD_PARAMETER
, "eglQueryContext");
121 *value
= GET_CONFIG_ATTRIB(c
->Config
, EGL_CONFIG_ID
);
123 case EGL_CONTEXT_CLIENT_VERSION
:
124 *value
= c
->ClientVersion
;
126 #ifdef EGL_VERSION_1_2
127 case EGL_CONTEXT_CLIENT_TYPE
:
128 *value
= c
->ClientAPI
;
130 case EGL_RENDER_BUFFER
:
131 *value
= _eglQueryContextRenderBuffer(c
);
133 #endif /* EGL_VERSION_1_2 */
135 return _eglError(EGL_BAD_ATTRIBUTE
, "eglQueryContext");
143 * Drivers will typically call this to do the error checking and
144 * update the various flags.
145 * Then, the driver will do its device-dependent Make-Current stuff.
148 _eglMakeCurrent(_EGLDriver
*drv
, _EGLDisplay
*dpy
, _EGLSurface
*draw
,
149 _EGLSurface
*read
, _EGLContext
*ctx
)
151 _EGLThreadInfo
*t
= _eglGetCurrentThread();
152 _EGLContext
*oldContext
= NULL
;
153 _EGLSurface
*oldDrawSurface
= NULL
;
154 _EGLSurface
*oldReadSurface
= NULL
;
157 if (_eglIsCurrentThreadDummy())
158 return _eglError(EGL_BAD_ALLOC
, "eglMakeCurrent");
162 if (ctx
->Binding
&& ctx
->Binding
!= t
)
163 return _eglError(EGL_BAD_ACCESS
, "eglMakeCurrent");
164 if (draw
== NULL
|| read
== NULL
)
165 return _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
166 if (draw
->Config
!= ctx
->Config
|| read
->Config
!= ctx
->Config
)
167 return _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
168 if ((draw
->Binding
&& draw
->Binding
->Binding
!= t
) ||
169 (read
->Binding
&& read
->Binding
->Binding
!= t
))
170 return _eglError(EGL_BAD_ACCESS
, "eglMakeCurrent");
172 #ifdef EGL_VERSION_1_4
173 /* OpenGL and OpenGL ES are conflicting */
174 switch (ctx
->ClientAPI
) {
175 case EGL_OPENGL_ES_API
:
176 if (t
->CurrentContexts
[_eglConvertApiToIndex(EGL_OPENGL_API
)])
177 return _eglError(EGL_BAD_ACCESS
, "eglMakeCurrent");
180 if (t
->CurrentContexts
[_eglConvertApiToIndex(EGL_OPENGL_ES_API
)])
181 return _eglError(EGL_BAD_ACCESS
, "eglMakeCurrent");
187 apiIndex
= _eglConvertApiToIndex(ctx
->ClientAPI
);
190 if (draw
!= NULL
|| read
!= NULL
)
191 return _eglError(EGL_BAD_MATCH
, "eglMakeCurrent");
192 apiIndex
= t
->CurrentAPIIndex
;
195 oldContext
= t
->CurrentContexts
[apiIndex
];
197 oldDrawSurface
= oldContext
->DrawSurface
;
198 oldReadSurface
= oldContext
->ReadSurface
;
199 assert(oldDrawSurface
);
200 assert(oldReadSurface
);
202 /* break old bindings */
203 t
->CurrentContexts
[apiIndex
] = NULL
;
204 oldContext
->Binding
= NULL
;
205 oldContext
->DrawSurface
= NULL
;
206 oldContext
->ReadSurface
= NULL
;
207 oldDrawSurface
->Binding
= NULL
;
208 oldReadSurface
->Binding
= NULL
;
211 * check if the old context or surfaces need to be deleted
213 if (!_eglIsSurfaceLinked(oldDrawSurface
)) {
214 assert(draw
!= oldDrawSurface
&& read
!= oldDrawSurface
);
215 drv
->API
.DestroySurface(drv
, dpy
, oldDrawSurface
);
217 if (oldReadSurface
!= oldDrawSurface
&&
218 !_eglIsSurfaceLinked(oldReadSurface
)) {
219 assert(draw
!= oldReadSurface
&& read
!= oldReadSurface
);
220 drv
->API
.DestroySurface(drv
, dpy
, oldReadSurface
);
222 if (!_eglIsContextLinked(oldContext
)) {
223 assert(ctx
!= oldContext
);
224 drv
->API
.DestroyContext(drv
, dpy
, oldContext
);
228 /* build new bindings */
230 t
->CurrentContexts
[apiIndex
] = ctx
;
232 ctx
->DrawSurface
= draw
;
233 ctx
->ReadSurface
= read
;
243 * This is defined by the EGL_MESA_copy_context extension.
246 _eglCopyContextMESA(_EGLDriver
*drv
, EGLDisplay dpy
, EGLContext source
,
247 EGLContext dest
, EGLint mask
)
249 /* This function will always have to be overridden/implemented in the
250 * device driver. If the driver is based on Mesa, use _mesa_copy_context().