Ejemplo n.º 1
0
/**
 * Return true if the given context and surfaces can be made current.
 */
static EGLBoolean
_eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read)
{
   _EGLThreadInfo *t = _eglGetCurrentThread();
   _EGLDisplay *dpy;
   EGLint conflict_api;

   if (_eglIsCurrentThreadDummy())
      return _eglError(EGL_BAD_ALLOC, "eglMakeCurrent");

   /* this is easy */
   if (!ctx) {
      if (draw || read)
         return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
      return EGL_TRUE;
   }

   dpy = ctx->Resource.Display;
   if (!dpy->Extensions.KHR_surfaceless_context
       && (draw == NULL || read == NULL))
      return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");

   /*
    * The spec says
    *
    * "If ctx is current to some other thread, or if either draw or read are
    * bound to contexts in another thread, an EGL_BAD_ACCESS error is
    * generated."
    *
    * and
    *
    * "at most one context may be bound to a particular surface at a given
    * time"
    */
   if (ctx->Binding && ctx->Binding != t)
      return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
   if (draw && draw->CurrentContext && draw->CurrentContext != ctx) {
      if (draw->CurrentContext->Binding != t ||
          draw->CurrentContext->ClientAPI != ctx->ClientAPI)
         return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
   }
   if (read && read->CurrentContext && read->CurrentContext != ctx) {
      if (read->CurrentContext->Binding != t ||
          read->CurrentContext->ClientAPI != ctx->ClientAPI)
         return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
   }

   /* If the context has a config then it must match that of the two
    * surfaces */
   if (ctx->Config) {
      if ((draw && draw->Config != ctx->Config) ||
          (read && read->Config != ctx->Config))
         return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
   } else {
      /* Otherwise we must be using the EGL_MESA_configless_context
       * extension */
      assert(dpy->Extensions.MESA_configless_context);

      /* The extension doesn't permit binding draw and read buffers with
       * differing contexts */
      if (draw && read && draw->Config != read->Config)
         return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
   }

   switch (ctx->ClientAPI) {
   /* OpenGL and OpenGL ES are conflicting */
   case EGL_OPENGL_ES_API:
      conflict_api = EGL_OPENGL_API;
      break;
   case EGL_OPENGL_API:
      conflict_api = EGL_OPENGL_ES_API;
      break;
   default:
      conflict_api = -1;
      break;
   }

   if (conflict_api >= 0 && _eglGetAPIContext(conflict_api))
      return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");

   return EGL_TRUE;
}
Ejemplo n.º 2
0
/**
 * Return true if the given context and surfaces can be made current.
 */
static EGLBoolean
_eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read)
{
   _EGLThreadInfo *t = _eglGetCurrentThread();
   _EGLDisplay *dpy;
   EGLint conflict_api;

   if (_eglIsCurrentThreadDummy())
      return _eglError(EGL_BAD_ALLOC, "eglMakeCurrent");

   /* this is easy */
   if (!ctx) {
      if (draw || read)
         return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
      return EGL_TRUE;
   }

   dpy = ctx->Resource.Display;
   if (!dpy->Extensions.KHR_surfaceless_context
       && (draw == NULL || read == NULL))
      return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");

   /*
    * The spec says
    *
    * "If ctx is current to some other thread, or if either draw or read are
    * bound to contexts in another thread, an EGL_BAD_ACCESS error is
    * generated."
    *
    * and
    *
    * "at most one context may be bound to a particular surface at a given
    * time"
    */
   if (ctx->Binding && ctx->Binding != t)
      return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
   if (draw && draw->CurrentContext && draw->CurrentContext != ctx) {
      if (draw->CurrentContext->Binding != t ||
          draw->CurrentContext->ClientAPI != ctx->ClientAPI)
         return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
   }
   if (read && read->CurrentContext && read->CurrentContext != ctx) {
      if (read->CurrentContext->Binding != t ||
          read->CurrentContext->ClientAPI != ctx->ClientAPI)
         return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
   }

   /* simply require the configs to be equal */
   if ((draw && draw->Config != ctx->Config) ||
       (read && read->Config != ctx->Config))
      return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");

   switch (ctx->ClientAPI) {
   /* OpenGL and OpenGL ES are conflicting */
   case EGL_OPENGL_ES_API:
      conflict_api = EGL_OPENGL_API;
      break;
   case EGL_OPENGL_API:
      conflict_api = EGL_OPENGL_ES_API;
      break;
   default:
      conflict_api = -1;
      break;
   }

   if (conflict_api >= 0 && _eglGetAPIContext(conflict_api))
      return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");

   return EGL_TRUE;
}
/**
 * Drivers will typically call this to do the error checking and
 * update the various IsBound and DeletePending flags.
 * Then, the driver will do its device-dependent Make-Current stuff.
 */
EGLBoolean
_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
                EGLSurface r, EGLContext context)
{
   _EGLThreadInfo *t = _eglGetCurrentThread();
   _EGLContext *ctx = _eglLookupContext(context);
   _EGLSurface *draw = _eglLookupSurface(d);
   _EGLSurface *read = _eglLookupSurface(r);

   _EGLContext *oldContext = _eglGetCurrentContext();
   _EGLSurface *oldDrawSurface = _eglGetCurrentSurface(EGL_DRAW);
   _EGLSurface *oldReadSurface = _eglGetCurrentSurface(EGL_READ);

   /* error checking */
   if (ctx) {
      if (draw == NULL || read == NULL) {
         _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
         return EGL_FALSE;
      }
      if (draw->Config != ctx->Config) {
         _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
         return EGL_FALSE;
      }
      if (read->Config != ctx->Config) {
         _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
         return EGL_FALSE;
      }
   }

   /*
    * check if the old context or surfaces need to be deleted
    */
   if (oldDrawSurface != NULL) {
      oldDrawSurface->IsBound = EGL_FALSE;
      if (oldDrawSurface->DeletePending) {
         /* make sure we don't try to rebind a deleted surface */
         if (draw == oldDrawSurface || draw == oldReadSurface) {
            draw = NULL;
         }
         /* really delete surface now */
         drv->API.DestroySurface(drv, dpy, oldDrawSurface->Handle);
      }
   }
   if (oldReadSurface != NULL && oldReadSurface != oldDrawSurface) {
      oldReadSurface->IsBound = EGL_FALSE;
      if (oldReadSurface->DeletePending) {
         /* make sure we don't try to rebind a deleted surface */
         if (read == oldDrawSurface || read == oldReadSurface) {
            read = NULL;
         }
         /* really delete surface now */
         drv->API.DestroySurface(drv, dpy, oldReadSurface->Handle);
      }
   }
   if (oldContext != NULL) {
      oldContext->IsBound = EGL_FALSE;
      if (oldContext->DeletePending) {
         /* make sure we don't try to rebind a deleted context */
         if (ctx == oldContext) {
            ctx = NULL;
         }
         /* really delete context now */
         drv->API.DestroyContext(drv, dpy, oldContext->Handle);
      }
   }

   if (ctx) {
      /* check read/draw again, in case we deleted them above */
      if (draw == NULL || read == NULL) {
         _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
         return EGL_FALSE;
      }
      ctx->DrawSurface = draw;
      ctx->ReadSurface = read;
      ctx->IsBound = EGL_TRUE;
      draw->IsBound = EGL_TRUE;
      read->IsBound = EGL_TRUE;
   }

   t->CurrentContext = ctx;

   return EGL_TRUE;
}
/**
 * Return the currently bound _EGLContext object, or NULL.
 */
_EGLContext *
_eglGetCurrentContext(void)
{
   _EGLThreadInfo *t = _eglGetCurrentThread();
   return t->CurrentContext;
}
Ejemplo n.º 5
0
/**
 * Returns the label set for the current thread.
 */
EGLLabelKHR
_eglGetThreadLabel(void)
{
   _EGLThreadInfo *t = _eglGetCurrentThread();
   return t->Label;
}
Ejemplo n.º 6
0
/**
 * Drivers will typically call this to do the error checking and
 * update the various flags.
 * Then, the driver will do its device-dependent Make-Current stuff.
 */
EGLBoolean
_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw,
                _EGLSurface *read, _EGLContext *ctx)
{
   _EGLThreadInfo *t = _eglGetCurrentThread();
   _EGLContext *oldContext = NULL;
   _EGLSurface *oldDrawSurface = NULL;
   _EGLSurface *oldReadSurface = NULL;
   EGLint apiIndex;

   if (_eglIsCurrentThreadDummy())
      return _eglError(EGL_BAD_ALLOC, "eglMakeCurrent");

   if (ctx) {
      /* error checking */
      if (ctx->Binding && ctx->Binding != t)
         return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
      if (draw == NULL || read == NULL)
         return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
      if (draw->Config != ctx->Config || read->Config != ctx->Config)
         return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
      if ((draw->Binding && draw->Binding->Binding != t) ||
          (read->Binding && read->Binding->Binding != t))
         return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");

#ifdef EGL_VERSION_1_4
      /* OpenGL and OpenGL ES are conflicting */
      switch (ctx->ClientAPI) {
      case EGL_OPENGL_ES_API:
         if (t->CurrentContexts[_eglConvertApiToIndex(EGL_OPENGL_API)])
            return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
         break;
      case EGL_OPENGL_API:
         if (t->CurrentContexts[_eglConvertApiToIndex(EGL_OPENGL_ES_API)])
            return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
         break;
      default:
         break;
      }
#endif
      apiIndex = _eglConvertApiToIndex(ctx->ClientAPI);
   }
   else {
      if (draw != NULL || read != NULL)
         return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
      apiIndex = t->CurrentAPIIndex;
   }

   oldContext = t->CurrentContexts[apiIndex];
   if (oldContext) {
      oldDrawSurface = oldContext->DrawSurface;
      oldReadSurface = oldContext->ReadSurface;
      assert(oldDrawSurface);
      assert(oldReadSurface);

      /* break old bindings */
      t->CurrentContexts[apiIndex] = NULL;
      oldContext->Binding = NULL;
      oldContext->DrawSurface = NULL;
      oldContext->ReadSurface = NULL;
      oldDrawSurface->Binding = NULL;
      oldReadSurface->Binding = NULL;

      /*
       * check if the old context or surfaces need to be deleted
       */
      if (!_eglIsSurfaceLinked(oldDrawSurface)) {
         assert(draw != oldDrawSurface && read != oldDrawSurface);
         drv->API.DestroySurface(drv, dpy, oldDrawSurface);
      }
      if (oldReadSurface != oldDrawSurface &&
          !_eglIsSurfaceLinked(oldReadSurface)) {
         assert(draw != oldReadSurface && read != oldReadSurface);
         drv->API.DestroySurface(drv, dpy, oldReadSurface);
      }
      if (!_eglIsContextLinked(oldContext)) {
         assert(ctx != oldContext);
         drv->API.DestroyContext(drv, dpy, oldContext);
      }
   }

   /* build new bindings */
   if (ctx) {
      t->CurrentContexts[apiIndex] = ctx;
      ctx->Binding = t;
      ctx->DrawSurface = draw;
      ctx->ReadSurface = read;
      draw->Binding = ctx;
      read->Binding = ctx;
   }

   return EGL_TRUE;
}
Ejemplo n.º 7
0
/**
 * Record EGL error code and return EGL_FALSE.
 */
static EGLBoolean
_eglInternalError(EGLint errCode, const char *msg)
{
   _EGLThreadInfo *t = _eglGetCurrentThread();

   if (t == &dummy_thread)
      return EGL_FALSE;

   t->LastError = errCode;

   if (errCode != EGL_SUCCESS) {
      const char *s;

      switch (errCode) {
      case EGL_BAD_ACCESS:
         s = "EGL_BAD_ACCESS";
         break;
      case EGL_BAD_ALLOC:
         s = "EGL_BAD_ALLOC";
         break;
      case EGL_BAD_ATTRIBUTE:
         s = "EGL_BAD_ATTRIBUTE";
         break;
      case EGL_BAD_CONFIG:
         s = "EGL_BAD_CONFIG";
         break;
      case EGL_BAD_CONTEXT:
         s = "EGL_BAD_CONTEXT";
         break;
      case EGL_BAD_CURRENT_SURFACE:
         s = "EGL_BAD_CURRENT_SURFACE";
         break;
      case EGL_BAD_DISPLAY:
         s = "EGL_BAD_DISPLAY";
         break;
      case EGL_BAD_MATCH:
         s = "EGL_BAD_MATCH";
         break;
      case EGL_BAD_NATIVE_PIXMAP:
         s = "EGL_BAD_NATIVE_PIXMAP";
         break;
      case EGL_BAD_NATIVE_WINDOW:
         s = "EGL_BAD_NATIVE_WINDOW";
         break;
      case EGL_BAD_PARAMETER:
         s = "EGL_BAD_PARAMETER";
         break;
      case EGL_BAD_SURFACE:
         s = "EGL_BAD_SURFACE";
         break;
      case EGL_NOT_INITIALIZED:
         s = "EGL_NOT_INITIALIZED";
         break;
      default:
         s = "other EGL error";
      }
      _eglLog(_EGL_DEBUG, "EGL user error 0x%x (%s) in %s\n", errCode, s, msg);
   }

   return EGL_FALSE;
}
Ejemplo n.º 8
0
/**
 * Record EGL error code and return EGL_FALSE.
 */
EGLBoolean
_eglError(EGLint errCode, const char *msg)
{
   _EGLThreadInfo *t = _eglGetCurrentThread();

   if (t == &dummy_thread)
      return EGL_FALSE;

   t->LastError = errCode;

   if (errCode != EGL_SUCCESS) {
      const char *s;

      switch (errCode) {
      case EGL_BAD_ACCESS:
         s = "EGL_BAD_ACCESS";
         break;
      case EGL_BAD_ALLOC:
         s = "EGL_BAD_ALLOC";
         break;
      case EGL_BAD_ATTRIBUTE:
         s = "EGL_BAD_ATTRIBUTE";
         break;
      case EGL_BAD_CONFIG:
         s = "EGL_BAD_CONFIG";
         break;
      case EGL_BAD_CONTEXT:
         s = "EGL_BAD_CONTEXT";
         break;
      case EGL_BAD_CURRENT_SURFACE:
         s = "EGL_BAD_CURRENT_SURFACE";
         break;
      case EGL_BAD_DISPLAY:
         s = "EGL_BAD_DISPLAY";
         break;
      case EGL_BAD_MATCH:
         s = "EGL_BAD_MATCH";
         break;
      case EGL_BAD_NATIVE_PIXMAP:
         s = "EGL_BAD_NATIVE_PIXMAP";
         break;
      case EGL_BAD_NATIVE_WINDOW:
         s = "EGL_BAD_NATIVE_WINDOW";
         break;
      case EGL_BAD_PARAMETER:
         s = "EGL_BAD_PARAMETER";
         break;
      case EGL_BAD_SURFACE:
         s = "EGL_BAD_SURFACE";
         break;
#ifdef EGL_MESA_screen_surface
      case EGL_BAD_SCREEN_MESA:
         s = "EGL_BAD_SCREEN_MESA";
         break;
      case EGL_BAD_MODE_MESA:
         s = "EGL_BAD_MODE_MESA";
         break;
#endif
      default:
         s = "other";
      }
      _eglLog(_EGL_DEBUG, "EGL user error 0x%x (%s) in %s\n", errCode, s, msg);
   }

   return EGL_FALSE;
}
Ejemplo n.º 9
0
/**
 * Return the currently bound context of the current API, or NULL.
 */
_EGLContext *
_eglGetCurrentContext(void)
{
   _EGLThreadInfo *t = _eglGetCurrentThread();
   return t->CurrentContexts[t->CurrentAPIIndex];
}
Ejemplo n.º 10
0
/**
 * Return the currently bound context of the given API, or NULL.
 */
PUBLIC _EGLContext *
_eglGetAPIContext(EGLenum api)
{
   _EGLThreadInfo *t = _eglGetCurrentThread();
   return t->CurrentContexts[_eglConvertApiToIndex(api)];
}
Ejemplo n.º 11
0
/**
 * Return true if the given context and surfaces can be made current.
 */
static EGLBoolean
_eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read)
{
   _EGLThreadInfo *t = _eglGetCurrentThread();
   EGLint conflict_api;

   if (_eglIsCurrentThreadDummy())
      return _eglError(EGL_BAD_ALLOC, "eglMakeCurrent");

   /* this is easy */
   if (!ctx) {
      if (draw || read)
         return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
      return EGL_TRUE;
   }

   /* ctx/draw/read must be all given */
   if (draw == NULL || read == NULL)
      return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");

   /* context stealing from another thread is not allowed */
   if (ctx->Binding && ctx->Binding != t)
      return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");

   /*
    * The spec says
    *
    * "If ctx is current to some other thread, or if either draw or read are
    * bound to contexts in another thread, an EGL_BAD_ACCESS error is
    * generated."
    *
    * But it also says
    *
    * "at most one context may be bound to a particular surface at a given
    * time"
    *
    * The latter is more restrictive so we can check only the latter case.
    */
   if ((draw->CurrentContext && draw->CurrentContext != ctx) ||
       (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)
      return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");

   switch (ctx->ClientAPI) {
#ifdef EGL_VERSION_1_4
   /* OpenGL and OpenGL ES are conflicting */
   case EGL_OPENGL_ES_API:
      conflict_api = EGL_OPENGL_API;
      break;
   case EGL_OPENGL_API:
      conflict_api = EGL_OPENGL_ES_API;
      break;
#endif
   default:
      conflict_api = -1;
      break;
   }

   if (conflict_api >= 0 && _eglGetAPIContext(conflict_api))
      return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");

   return EGL_TRUE;
}