예제 #1
0
/**
 * 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;
}