/** * Bind the context to the current thread and given surfaces. Return the * previously bound context and the surfaces it bound to. Each argument is * both input and output. */ EGLBoolean _eglBindContext(_EGLContext **ctx, _EGLSurface **draw, _EGLSurface **read) { _EGLThreadInfo *t = _eglGetCurrentThread(); _EGLContext *newCtx = *ctx, *oldCtx; if (!_eglCheckMakeCurrent(newCtx, *draw, *read)) return EGL_FALSE; /* bind the new context */ oldCtx = _eglBindContextToThread(newCtx, t); *ctx = oldCtx; if (newCtx) _eglBindContextToSurfaces(newCtx, draw, read); /* unbind the old context from its binding surfaces */ if (oldCtx) { /* * If the new context replaces some old context, the new one should not * be current before the replacement and it should not be bound to any * surface. */ if (newCtx) assert(!*draw && !*read); *draw = oldCtx->DrawSurface; *read = oldCtx->ReadSurface; assert(*draw && *read); _eglBindContextToSurfaces(NULL, draw, read); } return EGL_TRUE; }
/** * Bind the context to the current thread and given surfaces. Return the * 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, _EGLContext **old_ctx, _EGLSurface **old_draw, _EGLSurface **old_read) { _EGLThreadInfo *t = _eglGetCurrentThread(); _EGLContext *prev_ctx; _EGLSurface *prev_draw, *prev_read; if (!_eglCheckMakeCurrent(ctx, draw, read)) return EGL_FALSE; /* increment refcounts before binding */ _eglGetContext(ctx); _eglGetSurface(draw); _eglGetSurface(read); /* bind the new context */ prev_ctx = _eglBindContextToThread(ctx, t); /* break previous bindings */ if (prev_ctx) { prev_draw = prev_ctx->DrawSurface; prev_read = prev_ctx->ReadSurface; if (prev_draw) prev_draw->CurrentContext = NULL; if (prev_read) prev_read->CurrentContext = NULL; prev_ctx->DrawSurface = NULL; prev_ctx->ReadSurface = NULL; } else { prev_draw = prev_read = NULL; } /* establish new bindings */ if (ctx) { if (draw) draw->CurrentContext = ctx; if (read) read->CurrentContext = ctx; ctx->DrawSurface = draw; ctx->ReadSurface = read; } assert(old_ctx && old_draw && old_read); *old_ctx = prev_ctx; *old_draw = prev_draw; *old_read = prev_read; return EGL_TRUE; }