summaryrefslogtreecommitdiffstats
path: root/src/egl/main/eglcontext.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/egl/main/eglcontext.c')
-rw-r--r--src/egl/main/eglcontext.c75
1 files changed, 43 insertions, 32 deletions
diff --git a/src/egl/main/eglcontext.c b/src/egl/main/eglcontext.c
index b4cc7439583..3266a758249 100644
--- a/src/egl/main/eglcontext.c
+++ b/src/egl/main/eglcontext.c
@@ -300,54 +300,65 @@ _eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read)
/**
* Bind the context to the current thread and given surfaces. Return the
- * "orphaned" context and surfaces. Each argument is both input and output.
+ * previous bound context and surfaces. The caller should unreference the
+ * returned context and surfaces.
+ *
+ * Making a second call with the resources returned by the first call
+ * unsurprisingly undoes the first call, except for the resouce reference
+ * counts.
*/
EGLBoolean
-_eglBindContext(_EGLContext **ctx, _EGLSurface **draw, _EGLSurface **read)
+_eglBindContext(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read,
+ _EGLContext **old_ctx,
+ _EGLSurface **old_draw, _EGLSurface **old_read)
{
_EGLThreadInfo *t = _eglGetCurrentThread();
- _EGLContext *newCtx = *ctx, *oldCtx;
- _EGLSurface *newDraw = *draw, *newRead = *read;
+ _EGLContext *prev_ctx;
+ _EGLSurface *prev_draw, *prev_read;
- if (!_eglCheckMakeCurrent(newCtx, newDraw, newRead))
+ if (!_eglCheckMakeCurrent(ctx, draw, read))
return EGL_FALSE;
+ /* increment refcounts before binding */
+ _eglGetContext(ctx);
+ _eglGetSurface(draw);
+ _eglGetSurface(read);
+
/* bind the new context */
- oldCtx = _eglBindContextToThread(newCtx, t);
+ prev_ctx = _eglBindContextToThread(ctx, t);
- /* break old bindings */
- if (oldCtx) {
- *ctx = oldCtx;
- *draw = oldCtx->DrawSurface;
- *read = oldCtx->ReadSurface;
+ /* break previous bindings */
+ if (prev_ctx) {
+ prev_draw = prev_ctx->DrawSurface;
+ prev_read = prev_ctx->ReadSurface;
- if (*draw)
- (*draw)->CurrentContext = NULL;
- if (*read)
- (*read)->CurrentContext = NULL;
+ if (prev_draw)
+ prev_draw->CurrentContext = NULL;
+ if (prev_read)
+ prev_read->CurrentContext = NULL;
- oldCtx->DrawSurface = NULL;
- oldCtx->ReadSurface = NULL;
+ prev_ctx->DrawSurface = NULL;
+ prev_ctx->ReadSurface = NULL;
+ }
+ else {
+ prev_draw = prev_read = NULL;
}
/* establish new bindings */
- if (newCtx) {
- if (newDraw)
- newDraw->CurrentContext = newCtx;
- if (newRead)
- newRead->CurrentContext = newCtx;
-
- newCtx->DrawSurface = newDraw;
- newCtx->ReadSurface = newRead;
+ if (ctx) {
+ if (draw)
+ draw->CurrentContext = ctx;
+ if (read)
+ read->CurrentContext = ctx;
+
+ ctx->DrawSurface = draw;
+ ctx->ReadSurface = read;
}
- /* an old context or surface is not orphaned if it is still bound */
- if (*ctx == newCtx)
- *ctx = NULL;
- if (*draw == newDraw || *draw == newRead)
- *draw = NULL;
- if (*read == newDraw || *read == newRead)
- *read = NULL;
+ assert(old_ctx && old_draw && old_read);
+ *old_ctx = prev_ctx;
+ *old_draw = prev_draw;
+ *old_read = prev_read;
return EGL_TRUE;
}