diff options
Diffstat (limited to 'src/egl/main/eglapi.c')
| -rw-r--r-- | src/egl/main/eglapi.c | 237 | 
1 files changed, 131 insertions, 106 deletions
| diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index 29617b7aff..14cc5fa613 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -9,12 +9,36 @@   * heterogeneous hardware devices in the future.   *   * The EGLDisplay, EGLConfig, EGLContext and EGLSurface types are - * opaque handles implemented with 32-bit unsigned integers. - * It's up to the driver function or fallback function to look up the - * handle and get an object. - * By using opaque handles, we leave open the possibility of having - * indirect rendering in the future, like GLX. + * opaque handles. Internal objects are linked to a display to + * create the handles.   * + * For each public API entry point, the opaque handles are looked up + * before being dispatched to the drivers.  When it fails to look up + * a handle, one of + * + * EGL_BAD_DISPLAY + * EGL_BAD_CONFIG + * EGL_BAD_CONTEXT + * EGL_BAD_SURFACE + * EGL_BAD_SCREEN_MESA + * EGL_BAD_MODE_MESA + * + * is generated and the driver function is not called. An + * uninitialized EGLDisplay has no driver associated with it. When + * such display is detected, + * + * EGL_NOT_INITIALIZED + * + * is generated. + * + * Some of the entry points use current display, context, or surface + * implicitly.  For such entry points, the implicit objects are also + * checked before calling the driver function.  Other than the + * errors listed above, + * + * EGL_BAD_CURRENT_SURFACE + * + * may also be generated.   *   * Notes on naming conventions:   * @@ -92,8 +116,8 @@ eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)        snprintf(disp->Version, sizeof(disp->Version),                 "%d.%d (%s)", major_int, minor_int, drv->Name); -      /* update the global notion of supported APIs */ -      _eglGlobal.ClientAPIsMask |= disp->ClientAPIsMask; +      /* limit to APIs supported by core */ +      disp->ClientAPIsMask &= _EGL_API_ALL_BITS;        disp->Driver = drv;     } else { @@ -496,15 +520,31 @@ eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)  EGLBoolean EGLAPIENTRY  eglSwapInterval(EGLDisplay dpy, EGLint interval)  { +   _EGLContext *ctx = _eglGetCurrentContext(); +   _EGLSurface *surf;     _EGL_DECLARE_DD(dpy); -   return drv->API.SwapInterval(drv, disp, interval); + +   if (!ctx || !_eglIsContextLinked(ctx) || ctx->Display != disp) +      return _eglError(EGL_BAD_CONTEXT, __FUNCTION__); + +   surf = ctx->DrawSurface; +   if (!_eglIsSurfaceLinked(surf)) +      return _eglError(EGL_BAD_SURFACE, __FUNCTION__); + +   return drv->API.SwapInterval(drv, disp, surf, interval);  }  EGLBoolean EGLAPIENTRY  eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)  { +   _EGLContext *ctx = _eglGetCurrentContext();     _EGL_DECLARE_DD_AND_SURFACE(dpy, surface); + +   /* surface must be bound to current context in EGL 1.4 */ +   if (!ctx || !_eglIsContextLinked(ctx) || surf != ctx->DrawSurface) +      return _eglError(EGL_BAD_SURFACE, __FUNCTION__); +     return drv->API.SwapBuffers(drv, disp, surf);  } @@ -518,32 +558,66 @@ eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, NativePixmapType target)  EGLBoolean EGLAPIENTRY -eglWaitGL(void) +eglWaitClient(void)  { -   _EGLDisplay *disp = _eglGetCurrentDisplay(); +   _EGLContext *ctx = _eglGetCurrentContext(); +   _EGLDisplay *disp;     _EGLDriver *drv; -   if (!disp) +   if (!ctx)        return EGL_TRUE; +   /* let bad current context imply bad current surface */ +   if (!_eglIsContextLinked(ctx) || !_eglIsSurfaceLinked(ctx->DrawSurface)) +      return _eglError(EGL_BAD_CURRENT_SURFACE, __FUNCTION__); -   /* a current display is always initialized */ +   /* a valid current context implies an initialized current display */ +   disp = ctx->Display;     drv = disp->Driver; +   assert(drv); + +   return drv->API.WaitClient(drv, disp, ctx); +} + + +EGLBoolean EGLAPIENTRY +eglWaitGL(void) +{ +#ifdef EGL_VERSION_1_2 +   _EGLThreadInfo *t = _eglGetCurrentThread(); +   EGLint api_index = t->CurrentAPIIndex; +   EGLint es_index = _eglConvertApiToIndex(EGL_OPENGL_ES_API); +   EGLBoolean ret; + +   if (api_index != es_index && _eglIsCurrentThreadDummy()) +      return _eglError(EGL_BAD_ALLOC, "eglWaitGL"); -   return drv->API.WaitGL(drv, disp); +   t->CurrentAPIIndex = es_index; +   ret = eglWaitClient(); +   t->CurrentAPIIndex = api_index; +   return ret; +#else +   return eglWaitClient(); +#endif  }  EGLBoolean EGLAPIENTRY  eglWaitNative(EGLint engine)  { -   _EGLDisplay *disp = _eglGetCurrentDisplay(); +   _EGLContext *ctx = _eglGetCurrentContext(); +   _EGLDisplay *disp;     _EGLDriver *drv; -   if (!disp) +   if (!ctx)        return EGL_TRUE; +   /* let bad current context imply bad current surface */ +   if (!_eglIsContextLinked(ctx) || !_eglIsSurfaceLinked(ctx->DrawSurface)) +      return _eglError(EGL_BAD_CURRENT_SURFACE, __FUNCTION__); -   /* a current display is always initialized */ +   /* a valid current context implies an initialized current display */ +   disp = ctx->Display;     drv = disp->Driver; +   assert(drv);     return drv->API.WaitNative(drv, disp, engine);  } @@ -568,8 +642,26 @@ eglGetCurrentContext(void)  EGLSurface EGLAPIENTRY  eglGetCurrentSurface(EGLint readdraw)  { -   _EGLSurface *s = _eglGetCurrentSurface(readdraw); -   return _eglGetSurfaceHandle(s); +   _EGLContext *ctx = _eglGetCurrentContext(); +   _EGLSurface *surf; + +   if (!ctx) +      return EGL_NO_SURFACE; + +   switch (readdraw) { +   case EGL_DRAW: +      surf = ctx->DrawSurface; +      break; +   case EGL_READ: +      surf = ctx->ReadSurface; +      break; +   default: +      _eglError(EGL_BAD_PARAMETER, __FUNCTION__); +      surf = NULL; +      break; +   } + +   return _eglGetSurfaceHandle(surf);  } @@ -586,43 +678,11 @@ eglGetError(void)  void (* EGLAPIENTRY eglGetProcAddress(const char *procname))()  { -   typedef void (*genericFunc)(); -   struct name_function { +   static const struct {        const char *name;        _EGLProc function; -   }; -   static struct name_function egl_functions[] = { -      /* alphabetical order */ -      { "eglBindTexImage", (_EGLProc) eglBindTexImage }, -      { "eglChooseConfig", (_EGLProc) eglChooseConfig }, -      { "eglCopyBuffers", (_EGLProc) eglCopyBuffers }, -      { "eglCreateContext", (_EGLProc) eglCreateContext }, -      { "eglCreatePbufferSurface", (_EGLProc) eglCreatePbufferSurface }, -      { "eglCreatePixmapSurface", (_EGLProc) eglCreatePixmapSurface }, -      { "eglCreateWindowSurface", (_EGLProc) eglCreateWindowSurface }, -      { "eglDestroyContext", (_EGLProc) eglDestroyContext }, -      { "eglDestroySurface", (_EGLProc) eglDestroySurface }, -      { "eglGetConfigAttrib", (_EGLProc) eglGetConfigAttrib }, -      { "eglGetConfigs", (_EGLProc) eglGetConfigs }, -      { "eglGetCurrentContext", (_EGLProc) eglGetCurrentContext }, -      { "eglGetCurrentDisplay", (_EGLProc) eglGetCurrentDisplay }, -      { "eglGetCurrentSurface", (_EGLProc) eglGetCurrentSurface }, -      { "eglGetDisplay", (_EGLProc) eglGetDisplay }, -      { "eglGetError", (_EGLProc) eglGetError }, -      { "eglGetProcAddress", (_EGLProc) eglGetProcAddress }, -      { "eglInitialize", (_EGLProc) eglInitialize }, -      { "eglMakeCurrent", (_EGLProc) eglMakeCurrent }, -      { "eglQueryContext", (_EGLProc) eglQueryContext }, -      { "eglQueryString", (_EGLProc) eglQueryString }, -      { "eglQuerySurface", (_EGLProc) eglQuerySurface }, -      { "eglReleaseTexImage", (_EGLProc) eglReleaseTexImage }, -      { "eglSurfaceAttrib", (_EGLProc) eglSurfaceAttrib }, -      { "eglSwapBuffers", (_EGLProc) eglSwapBuffers }, -      { "eglSwapInterval", (_EGLProc) eglSwapInterval }, -      { "eglTerminate", (_EGLProc) eglTerminate }, -      { "eglWaitGL", (_EGLProc) eglWaitGL }, -      { "eglWaitNative", (_EGLProc) eglWaitNative }, -      /* Extensions */ +   } egl_functions[] = { +      /* extensions only */  #ifdef EGL_MESA_screen_surface        { "eglChooseModeMESA", (_EGLProc) eglChooseModeMESA },        { "eglGetModesMESA", (_EGLProc) eglGetModesMESA }, @@ -637,22 +697,23 @@ void (* EGLAPIENTRY eglGetProcAddress(const char *procname))()        { "eglQueryScreenModeMESA", (_EGLProc) eglQueryScreenModeMESA },        { "eglQueryModeStringMESA", (_EGLProc) eglQueryModeStringMESA },  #endif /* EGL_MESA_screen_surface */ -#ifdef EGL_VERSION_1_2 -      { "eglBindAPI", (_EGLProc) eglBindAPI }, -      { "eglCreatePbufferFromClientBuffer", (_EGLProc) eglCreatePbufferFromClientBuffer }, -      { "eglQueryAPI", (_EGLProc) eglQueryAPI }, -      { "eglReleaseThread", (_EGLProc) eglReleaseThread }, -      { "eglWaitClient", (_EGLProc) eglWaitClient }, -#endif /* EGL_VERSION_1_2 */        { NULL, NULL }     };     EGLint i; -   for (i = 0; egl_functions[i].name; i++) { -      if (strcmp(egl_functions[i].name, procname) == 0) { -         return (genericFunc) egl_functions[i].function; + +   if (!procname) +      return NULL; +   if (strncmp(procname, "egl", 3) == 0) { +      for (i = 0; egl_functions[i].name; i++) { +         if (strcmp(egl_functions[i].name, procname) == 0) +            return egl_functions[i].function;        }     } +   /* preload a driver if there isn't one */ +   if (!_eglGlobal.NumDrivers) +      _eglPreloadDriver(NULL); +     /* now loop over drivers to query their procs */     for (i = 0; i < _eglGlobal.NumDrivers; i++) {        _EGLProc p = _eglGlobal.Drivers[i]->API.GetProcAddress(procname); @@ -664,6 +725,9 @@ void (* EGLAPIENTRY eglGetProcAddress(const char *procname))()  } +#ifdef EGL_MESA_screen_surface + +  /*   * EGL_MESA_screen extension   */ @@ -838,6 +902,9 @@ eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode)  } +#endif /* EGL_MESA_screen_surface */ + +  /**   ** EGL 1.2   **/ @@ -867,33 +934,7 @@ eglBindAPI(EGLenum api)     if (!_eglIsApiValid(api))        return _eglError(EGL_BAD_PARAMETER, "eglBindAPI"); -   switch (api) { -#ifdef EGL_VERSION_1_4 -   case EGL_OPENGL_API: -      if (_eglGlobal.ClientAPIsMask & EGL_OPENGL_BIT) { -         t->CurrentAPIIndex = _eglConvertApiToIndex(api); -         return EGL_TRUE; -      } -      _eglError(EGL_BAD_PARAMETER, "eglBindAPI"); -      return EGL_FALSE; -#endif -   case EGL_OPENGL_ES_API: -      if (_eglGlobal.ClientAPIsMask & (EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT)) { -         t->CurrentAPIIndex = _eglConvertApiToIndex(api); -         return EGL_TRUE; -      } -      _eglError(EGL_BAD_PARAMETER, "eglBindAPI"); -      return EGL_FALSE; -   case EGL_OPENVG_API: -      if (_eglGlobal.ClientAPIsMask & EGL_OPENVG_BIT) { -         t->CurrentAPIIndex = _eglConvertApiToIndex(api); -         return EGL_TRUE; -      } -      _eglError(EGL_BAD_PARAMETER, "eglBindAPI"); -      return EGL_FALSE; -   default: -      return EGL_FALSE; -   } +   t->CurrentAPIIndex = _eglConvertApiToIndex(api);     return EGL_TRUE;  } @@ -951,20 +992,4 @@ eglReleaseThread(void)  } -EGLBoolean -eglWaitClient(void) -{ -   _EGLDisplay *disp = _eglGetCurrentDisplay(); -   _EGLDriver *drv; - -   if (!disp) -      return EGL_TRUE; - -   /* a current display is always initialized */ -   drv = disp->Driver; - -   return drv->API.WaitClient(drv, disp); -} - -  #endif /* EGL_VERSION_1_2 */ | 
