summaryrefslogtreecommitdiffstats
path: root/src/egl/main/eglcontext.c
diff options
context:
space:
mode:
authorKristian Høgsberg <[email protected]>2010-06-02 22:48:06 -0400
committerKristian Høgsberg <[email protected]>2010-07-28 23:07:00 -0400
commitb90a3e7d8b1bcd412ddbf2a4803de2756dacd436 (patch)
treed9e9721b568da63059507953b985dcf3faeed76d /src/egl/main/eglcontext.c
parentaa44bd9189848b91619335207b8ec3be5679f982 (diff)
egl: EGL_KHR_surfaceless_* extensions
These extensions allow an application to make a context current by passing EGL_NO_SURFACE for the write and read surface in the call to eglMakeCurrent. The motivation is that applications that only want to render to client API targets (such as OpenGL framebuffer objects) should not need to create a throw-away EGL surface just to get a current context.
Diffstat (limited to 'src/egl/main/eglcontext.c')
-rw-r--r--src/egl/main/eglcontext.c90
1 files changed, 55 insertions, 35 deletions
diff --git a/src/egl/main/eglcontext.c b/src/egl/main/eglcontext.c
index d5a1e79a994..74a5a632eba 100644
--- a/src/egl/main/eglcontext.c
+++ b/src/egl/main/eglcontext.c
@@ -83,7 +83,7 @@ _eglParseContextAttribList(_EGLContext *ctx, const EGLint *attrib_list)
}
}
- if (err == EGL_SUCCESS) {
+ if (err == EGL_SUCCESS && ctx->Config) {
EGLint renderable_type, api_bit;
renderable_type = GET_CONFIG_ATTRIB(ctx->Config, EGL_RENDERABLE_TYPE);
@@ -220,45 +220,49 @@ _eglBindContextToSurfaces(_EGLContext *newCtx,
* surface (oldDraw), the old bindings are broken first and the new one is
* created.
*/
- oldCtx = newDraw->CurrentContext;
- if (newCtx != oldCtx) {
- if (oldCtx) {
- assert(oldCtx->DrawSurface == newDraw);
- oldCtx->DrawSurface = NULL;
+ if (newDraw) {
+ oldCtx = newDraw->CurrentContext;
+ if (newCtx != oldCtx) {
+ if (oldCtx) {
+ assert(oldCtx->DrawSurface == newDraw);
+ oldCtx->DrawSurface = NULL;
+ }
+
+ newDraw->CurrentContext = newCtx;
}
+ }
- if (newCtx) {
- _EGLSurface *oldDraw = newCtx->DrawSurface;
- if (oldDraw)
- oldDraw->CurrentContext = NULL;
-
- newCtx->DrawSurface = newDraw;
- *draw = oldDraw;
- }
+ if (newCtx) {
+ _EGLSurface *oldDraw = newCtx->DrawSurface;
+ if (oldDraw)
+ oldDraw->CurrentContext = NULL;
- newDraw->CurrentContext = newCtx;
+ newCtx->DrawSurface = newDraw;
+ *draw = oldDraw;
}
/* likewise */
- if (newRead != newDraw)
+ if (newRead && newRead != newDraw) {
oldCtx = newRead->CurrentContext;
- if (newCtx != oldCtx) {
- if (oldCtx) {
- assert(oldCtx->ReadSurface == newRead);
- oldCtx->ReadSurface = NULL;
- }
+ if (newCtx != oldCtx) {
+ if (oldCtx) {
+ assert(oldCtx->ReadSurface == newRead);
+ oldCtx->ReadSurface = NULL;
+ }
- if (newCtx) {
- _EGLSurface *oldRead = newCtx->ReadSurface;
- if (oldRead)
- oldRead->CurrentContext = NULL;
-
- newCtx->ReadSurface = newRead;
- *read = oldRead;
+ newRead->CurrentContext = newCtx;
}
+ }
- newRead->CurrentContext = newCtx;
+ if (newCtx) {
+ _EGLSurface *oldRead = newCtx->ReadSurface;
+ if (oldRead)
+ oldRead->CurrentContext = NULL;
+
+ newCtx->ReadSurface = newRead;
+ *read = oldRead;
}
+
}
@@ -297,7 +301,9 @@ static EGLBoolean
_eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read)
{
_EGLThreadInfo *t = _eglGetCurrentThread();
+ _EGLDisplay *dpy = ctx->Resource.Display;
EGLint conflict_api;
+ EGLBoolean surfaceless;
if (_eglIsCurrentThreadDummy())
return _eglError(EGL_BAD_ALLOC, "eglMakeCurrent");
@@ -309,8 +315,22 @@ _eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read)
return EGL_TRUE;
}
- /* ctx/draw/read must be all given */
- if (draw == NULL || read == NULL)
+ switch (_eglGetContextAPIBit(ctx)) {
+ case EGL_OPENGL_ES_BIT:
+ surfaceless = dpy->Extensions.KHR_surfaceless_gles1;
+ break;
+ case EGL_OPENGL_ES2_BIT:
+ surfaceless = dpy->Extensions.KHR_surfaceless_gles2;
+ break;
+ case EGL_OPENGL_BIT:
+ surfaceless = dpy->Extensions.KHR_surfaceless_opengl;
+ break;
+ default:
+ surfaceless = EGL_FALSE;
+ break;
+ }
+
+ if (!surfaceless && (draw == NULL || read == NULL))
return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
/* context stealing from another thread is not allowed */
@@ -331,12 +351,13 @@ _eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read)
*
* The latter is more restrictive so we can check only the latter case.
*/
- if ((draw->CurrentContext && draw->CurrentContext != ctx) ||
- (read->CurrentContext && read->CurrentContext != ctx))
+ if ((draw && draw->CurrentContext && draw->CurrentContext != ctx) ||
+ (read && read->CurrentContext && read->CurrentContext != ctx))
return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
/* simply require the configs to be equal */
- if (draw->Config != ctx->Config || read->Config != ctx->Config)
+ if ((draw && draw->Config != ctx->Config) ||
+ (read && read->Config != ctx->Config))
return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
switch (ctx->ClientAPI) {
@@ -387,7 +408,6 @@ _eglBindContext(_EGLContext **ctx, _EGLSurface **draw, _EGLSurface **read)
*draw = oldCtx->DrawSurface;
*read = oldCtx->ReadSurface;
- assert(*draw && *read);
_eglBindContextToSurfaces(NULL, draw, read);
}