egl: Factor out _eglWaitSyncCommon
[mesa.git] / src / egl / main / eglapi.c
index 4700dbe42f672984026d6ff9e6548b886ff80e0e..dd4fd2cbbbc568a813b078582914a4821549a71f 100644 (file)
@@ -295,9 +295,9 @@ eglGetDisplay(EGLNativeDisplayType nativeDisplay)
    return _eglGetDisplayHandle(dpy);
 }
 
-static EGLDisplay EGLAPIENTRY
-eglGetPlatformDisplayEXT(EGLenum platform, void *native_display,
-                         const EGLint *attrib_list)
+static EGLDisplay
+_eglGetPlatformDisplayCommon(EGLenum platform, void *native_display,
+                            const EGLint *attrib_list)
 {
    _EGLDisplay *dpy;
 
@@ -326,17 +326,25 @@ eglGetPlatformDisplayEXT(EGLenum platform, void *native_display,
    return _eglGetDisplayHandle(dpy);
 }
 
+static EGLDisplay EGLAPIENTRY
+eglGetPlatformDisplayEXT(EGLenum platform, void *native_display,
+                         const EGLint *attrib_list)
+{
+   return _eglGetPlatformDisplayCommon(platform, native_display, attrib_list);
+}
+
 EGLDisplay EGLAPIENTRY
 eglGetPlatformDisplay(EGLenum platform, void *native_display,
                       const EGLAttrib *attrib_list)
 {
    EGLDisplay display;
-   EGLint *int_attribs = _eglConvertAttribsToInt(attrib_list);
+   EGLint *int_attribs;
 
+   int_attribs = _eglConvertAttribsToInt(attrib_list);
    if (attrib_list && !int_attribs)
       RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, NULL);
 
-   display = eglGetPlatformDisplayEXT(platform, native_display, int_attribs);
+   display = _eglGetPlatformDisplayCommon(platform, native_display, int_attribs);
    free(int_attribs);
    return display;
 }
@@ -406,11 +414,13 @@ _eglCreateExtensionsString(_EGLDisplay *dpy)
       _eglAppendExtension(&exts, "EGL_KHR_image");
    _EGL_CHECK_EXTENSION(KHR_image_base);
    _EGL_CHECK_EXTENSION(KHR_image_pixmap);
+   _EGL_CHECK_EXTENSION(KHR_no_config_context);
    _EGL_CHECK_EXTENSION(KHR_reusable_sync);
    _EGL_CHECK_EXTENSION(KHR_surfaceless_context);
    _EGL_CHECK_EXTENSION(KHR_wait_sync);
 
-   _EGL_CHECK_EXTENSION(MESA_configless_context);
+   if (dpy->Extensions.KHR_no_config_context)
+      _eglAppendExtension(&exts, "EGL_MESA_configless_context");
    _EGL_CHECK_EXTENSION(MESA_drm_image);
    _EGL_CHECK_EXTENSION(MESA_image_dma_buf_export);
 
@@ -627,7 +637,7 @@ eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
 
    _EGL_CHECK_DISPLAY(disp, EGL_NO_CONTEXT, drv);
 
-   if (!config && !disp->Extensions.MESA_configless_context)
+   if (!config && !disp->Extensions.KHR_no_config_context)
       RETURN_EGL_ERROR(disp, EGL_BAD_CONFIG, EGL_NO_CONTEXT);
 
    if (!share && share_list != EGL_NO_CONTEXT)
@@ -752,14 +762,9 @@ eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
                                         attrib_list);
 }
 
-
-static EGLSurface EGLAPIENTRY
-eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config,
-                                  void *native_window,
-                                  const EGLint *attrib_list)
+static void *
+fixupNativeWindow(_EGLDisplay *disp, void *native_window)
 {
-   _EGLDisplay *disp = _eglLockDisplay(dpy);
-
 #ifdef HAVE_X11_PLATFORM
    if (disp->Platform == _EGL_PLATFORM_X11 && native_window != NULL) {
       /* The `native_window` parameter for the X11 platform differs between
@@ -769,9 +774,20 @@ eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config,
        * `Window*`.  Convert `Window*` to `Window` because that's what
        * dri2_x11_create_window_surface() expects.
        */
-      native_window = (void*) (* (Window*) native_window);
+      return (void *)(* (Window*) native_window);
    }
 #endif
+   return native_window;
+}
+
+static EGLSurface EGLAPIENTRY
+eglCreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config,
+                                  void *native_window,
+                                  const EGLint *attrib_list)
+{
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+
+   native_window = fixupNativeWindow(disp, native_window);
 
    return _eglCreateWindowSurfaceCommon(disp, config, native_window,
                                         attrib_list);
@@ -783,18 +799,36 @@ eglCreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config,
                                void *native_window,
                                const EGLAttrib *attrib_list)
 {
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
    EGLSurface surface;
    EGLint *int_attribs = _eglConvertAttribsToInt(attrib_list);
 
    if (attrib_list && !int_attribs)
       RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_NO_SURFACE);
 
-   surface = eglCreatePlatformWindowSurfaceEXT(dpy, config, native_window,
-                                               int_attribs);
+   native_window = fixupNativeWindow(disp, native_window);
+   surface = _eglCreateWindowSurfaceCommon(disp, config, native_window,
+                                           int_attribs);
    free(int_attribs);
    return surface;
 }
 
+static void *
+fixupNativePixmap(_EGLDisplay *disp, void *native_pixmap)
+{
+#ifdef HAVE_X11_PLATFORM
+      /* The `native_pixmap` parameter for the X11 platform differs between
+       * eglCreatePixmapSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
+       * eglCreatePixmapSurface(), the type of `native_pixmap` is an Xlib
+       * `Pixmap`. In eglCreatePlatformPixmapSurfaceEXT(), the type is
+       * `Pixmap*`.  Convert `Pixmap*` to `Pixmap` because that's what
+       * dri2_x11_create_pixmap_surface() expects.
+       */
+   if (disp->Platform == _EGL_PLATFORM_X11 && native_pixmap != NULL)
+      return (void *)(* (Pixmap*) native_pixmap);
+#endif
+   return native_pixmap;
+}
 
 static EGLSurface
 _eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
@@ -831,19 +865,7 @@ eglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config,
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
 
-#ifdef HAVE_X11_PLATFORM
-      /* The `native_pixmap` parameter for the X11 platform differs between
-       * eglCreatePixmapSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
-       * eglCreatePixmapSurface(), the type of `native_pixmap` is an Xlib
-       * `Pixmap`. In eglCreatePlatformPixmapSurfaceEXT(), the type is
-       * `Pixmap*`.  Convert `Pixmap*` to `Pixmap` because that's what
-       * dri2_x11_create_pixmap_surface() expects.
-       */
-   if (disp->Platform == _EGL_PLATFORM_X11 && native_pixmap != NULL) {
-      native_pixmap = (void*) (* (Pixmap*) native_pixmap);
-   }
-#endif
-
+   native_pixmap = fixupNativePixmap(disp, native_pixmap);
    return _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap,
                                         attrib_list);
 }
@@ -854,14 +876,16 @@ eglCreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config,
                                void *native_pixmap,
                                const EGLAttrib *attrib_list)
 {
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
    EGLSurface surface;
    EGLint *int_attribs = _eglConvertAttribsToInt(attrib_list);
 
    if (attrib_list && !int_attribs)
       RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_NO_SURFACE);
 
-   surface = eglCreatePlatformPixmapSurfaceEXT(dpy, config, native_pixmap,
-                                               int_attribs);
+   native_pixmap = fixupNativePixmap(disp, native_pixmap);
+   surface = _eglCreatePixmapSurfaceCommon(disp, config, native_pixmap,
+                                           int_attribs);
    free(int_attribs);
    return surface;
 }
@@ -1057,8 +1081,8 @@ eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
 }
 
 
-EGLBoolean EGLAPIENTRY
-eglWaitClient(void)
+static EGLBoolean
+_eglWaitClientCommon(void)
 {
    _EGLContext *ctx = _eglGetCurrentContext();
    _EGLDisplay *disp;
@@ -1084,22 +1108,17 @@ eglWaitClient(void)
    RETURN_EGL_EVAL(disp, ret);
 }
 
+EGLBoolean EGLAPIENTRY
+eglWaitClient(void)
+{
+   return _eglWaitClientCommon();
+}
 
 EGLBoolean EGLAPIENTRY
 eglWaitGL(void)
 {
-   _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_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE);
-
-   t->CurrentAPIIndex = es_index;
-   ret = eglWaitClient();
-   t->CurrentAPIIndex = api_index;
-   return ret;
+   /* Since we only support OpenGL and GLES, eglWaitGL is equivalent to eglWaitClient. */
+   return _eglWaitClientCommon();
 }
 
 
@@ -1222,7 +1241,7 @@ eglBindAPI(EGLenum api)
    if (!_eglIsApiValid(api))
       RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE);
 
-   t->CurrentAPIIndex = _eglConvertApiToIndex(api);
+   t->CurrentAPI = api;
 
    RETURN_EGL_SUCCESS(NULL, EGL_TRUE);
 }
@@ -1238,7 +1257,7 @@ eglQueryAPI(void)
    EGLenum ret;
 
    /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
-   ret = _eglConvertApiFromIndex(t->CurrentAPIIndex);
+   ret = t->CurrentAPI;
 
    RETURN_EGL_SUCCESS(NULL, ret);
 }
@@ -1271,25 +1290,17 @@ eglReleaseThread(void)
    /* unbind current contexts */
    if (!_eglIsCurrentThreadDummy()) {
       _EGLThreadInfo *t = _eglGetCurrentThread();
-      EGLint api_index = t->CurrentAPIIndex;
-      EGLint i;
 
-      for (i = 0; i < _EGL_API_NUM_APIS; i++) {
-         _EGLContext *ctx = t->CurrentContexts[i];
-         if (ctx) {
-            _EGLDisplay *disp = ctx->Resource.Display;
-            _EGLDriver *drv;
+      _EGLContext *ctx = t->CurrentContext;
+      if (ctx) {
+         _EGLDisplay *disp = ctx->Resource.Display;
+         _EGLDriver *drv;
 
-            t->CurrentAPIIndex = i;
-
-            mtx_lock(&disp->Mutex);
-            drv = disp->Driver;
-            (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
-            mtx_unlock(&disp->Mutex);
-         }
+         mtx_lock(&disp->Mutex);
+         drv = disp->Driver;
+         (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
+         mtx_unlock(&disp->Mutex);
       }
-
-      t->CurrentAPIIndex = api_index;
    }
 
    _eglDestroyCurrentThread();
@@ -1298,11 +1309,10 @@ eglReleaseThread(void)
 }
 
 
-static EGLImage EGLAPIENTRY
-eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
+static EGLImage
+_eglCreateImageCommon(_EGLDisplay *disp, EGLContext ctx, EGLenum target,
                   EGLClientBuffer buffer, const EGLint *attr_list)
 {
-   _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLContext *context = _eglLookupContext(ctx, disp);
    _EGLDriver *drv;
    _EGLImage *img;
@@ -1326,18 +1336,27 @@ eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
    RETURN_EGL_EVAL(disp, ret);
 }
 
+static EGLImage EGLAPIENTRY
+eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
+                  EGLClientBuffer buffer, const EGLint *attr_list)
+{
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   return _eglCreateImageCommon(disp, ctx, target, buffer, attr_list);
+}
+
 
 EGLImage EGLAPIENTRY
 eglCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target,
                EGLClientBuffer buffer, const EGLAttrib *attr_list)
 {
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
    EGLImage image;
    EGLint *int_attribs = _eglConvertAttribsToInt(attr_list);
 
    if (attr_list && !int_attribs)
-      RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_NO_IMAGE);
+      RETURN_EGL_ERROR(disp, EGL_BAD_ALLOC, EGL_NO_IMAGE);
 
-   image = eglCreateImageKHR(dpy, ctx, target, buffer, int_attribs);
+   image = _eglCreateImageCommon(disp, ctx, target, buffer, int_attribs);
    free(int_attribs);
    return image;
 }
@@ -1365,11 +1384,10 @@ eglDestroyImage(EGLDisplay dpy, EGLImage image)
 
 
 static EGLSync
-_eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list,
+_eglCreateSync(_EGLDisplay *disp, EGLenum type, const EGLint *attrib_list,
                const EGLAttrib *attrib_list64, EGLBoolean is64,
                EGLenum invalid_type_error)
 {
-   _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLContext *ctx = _eglGetCurrentContext();
    _EGLDriver *drv;
    _EGLSync *sync;
@@ -1381,7 +1399,7 @@ _eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list,
       RETURN_EGL_EVAL(disp, EGL_NO_SYNC_KHR);
 
    /* return an error if the client API doesn't support GL_OES_EGL_sync */
-   if (!ctx || ctx->Resource.Display != dpy ||
+   if (!ctx || ctx->Resource.Display != disp ||
        ctx->ClientAPI != EGL_OPENGL_ES_API)
       RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
 
@@ -1412,7 +1430,8 @@ _eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list,
 static EGLSync EGLAPIENTRY
 eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
 {
-   return _eglCreateSync(dpy, type, attrib_list, NULL, EGL_FALSE,
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   return _eglCreateSync(disp, type, attrib_list, NULL, EGL_FALSE,
                          EGL_BAD_ATTRIBUTE);
 }
 
@@ -1420,7 +1439,8 @@ eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list)
 static EGLSync EGLAPIENTRY
 eglCreateSync64KHR(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
 {
-   return _eglCreateSync(dpy, type, NULL, attrib_list, EGL_TRUE,
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   return _eglCreateSync(disp, type, NULL, attrib_list, EGL_TRUE,
                          EGL_BAD_ATTRIBUTE);
 }
 
@@ -1428,7 +1448,8 @@ eglCreateSync64KHR(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
 EGLSync EGLAPIENTRY
 eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
 {
-   return _eglCreateSync(dpy, type, NULL, attrib_list, EGL_TRUE,
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   return _eglCreateSync(disp, type, NULL, attrib_list, EGL_TRUE,
                          EGL_BAD_PARAMETER);
 }
 
@@ -1488,11 +1509,9 @@ eglClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout)
 }
 
 
-static EGLint EGLAPIENTRY
-eglWaitSyncKHR(EGLDisplay dpy, EGLSync sync, EGLint flags)
+static EGLint
+_eglWaitSyncCommon(_EGLDisplay *disp, _EGLSync *s, EGLint flags)
 {
-   _EGLDisplay *disp = _eglLockDisplay(dpy);
-   _EGLSync *s = _eglLookupSync(sync, disp);
    _EGLContext *ctx = _eglGetCurrentContext();
    _EGLDriver *drv;
    EGLint ret;
@@ -1513,6 +1532,14 @@ eglWaitSyncKHR(EGLDisplay dpy, EGLSync sync, EGLint flags)
    RETURN_EGL_EVAL(disp, ret);
 }
 
+static EGLint EGLAPIENTRY
+eglWaitSyncKHR(EGLDisplay dpy, EGLSync sync, EGLint flags)
+{
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGLSync *s = _eglLookupSync(sync, disp);
+   return _eglWaitSyncCommon(disp, s, flags);
+}
+
 
 EGLBoolean EGLAPIENTRY
 eglWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags)
@@ -1521,7 +1548,9 @@ eglWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags)
     * EGLBoolean. In both cases, the return values can only be EGL_FALSE and
     * EGL_TRUE.
     */
-   return eglWaitSyncKHR(dpy, sync, flags);
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGLSync *s = _eglLookupSync(sync, disp);
+   return _eglWaitSyncCommon(disp, s, flags);
 }