Revert "egl: drop EGL driver `name`"
[mesa.git] / src / egl / main / eglapi.c
index a4d5f896e6dccefad90f98b29982ea802f3e460a..38fc9311cb8da3ed5f6f7a53ed91f011562fc498 100644 (file)
@@ -88,7 +88,6 @@
 #include <string.h>
 #include "c99_compat.h"
 #include "c11/threads.h"
-#include "GL/mesa_glinterop.h"
 #include "util/macros.h"
 
 #include "eglglobals.h"
 #include "eglimage.h"
 #include "eglsync.h"
 
+#include "GL/mesa_glinterop.h"
 
 /**
  * Macros to help return an API entrypoint.
@@ -274,8 +274,7 @@ _eglSetFuncName(const char *funcName, _EGLDisplay *disp, EGLenum objectType, _EG
       return EGL_TRUE;
    }
 
-   _eglDebugReportFull(EGL_BAD_ALLOC, funcName, funcName,
-                      EGL_DEBUG_MSG_CRITICAL_KHR, NULL, NULL);
+   _eglDebugReport(EGL_BAD_ALLOC, funcName, EGL_DEBUG_MSG_CRITICAL_KHR, NULL);
    return EGL_FALSE;
 }
 
@@ -377,7 +376,7 @@ eglGetDisplay(EGLNativeDisplayType nativeDisplay)
 
 static EGLDisplay
 _eglGetPlatformDisplayCommon(EGLenum platform, void *native_display,
-                            const EGLint *attrib_list)
+                             const EGLint *attrib_list)
 {
    _EGLDisplay *dpy;
 
@@ -488,11 +487,13 @@ _eglCreateExtensionsString(_EGLDisplay *dpy)
    _EGL_CHECK_EXTENSION(EXT_buffer_age);
    _EGL_CHECK_EXTENSION(EXT_create_context_robustness);
    _EGL_CHECK_EXTENSION(EXT_image_dma_buf_import);
+   _EGL_CHECK_EXTENSION(EXT_image_dma_buf_import_modifiers);
    _EGL_CHECK_EXTENSION(EXT_swap_buffers_with_damage);
 
    _EGL_CHECK_EXTENSION(KHR_cl_event2);
    _EGL_CHECK_EXTENSION(KHR_config_attribs);
    _EGL_CHECK_EXTENSION(KHR_create_context);
+   _EGL_CHECK_EXTENSION(KHR_create_context_no_error);
    _EGL_CHECK_EXTENSION(KHR_fence_sync);
    _EGL_CHECK_EXTENSION(KHR_get_all_proc_addresses);
    _EGL_CHECK_EXTENSION(KHR_gl_colorspace);
@@ -505,6 +506,7 @@ _eglCreateExtensionsString(_EGLDisplay *dpy)
    _EGL_CHECK_EXTENSION(KHR_image_base);
    _EGL_CHECK_EXTENSION(KHR_image_pixmap);
    _EGL_CHECK_EXTENSION(KHR_no_config_context);
+   _EGL_CHECK_EXTENSION(KHR_partial_update);
    _EGL_CHECK_EXTENSION(KHR_reusable_sync);
    _EGL_CHECK_EXTENSION(KHR_surfaceless_context);
    if (dpy->Extensions.EXT_swap_buffers_with_damage)
@@ -581,7 +583,7 @@ eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
       RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
 
    if (!disp->Initialized) {
-      if (!_eglMatchDriver(disp, EGL_FALSE))
+      if (!_eglMatchDriver(disp))
          RETURN_EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE);
 
       /* limit to APIs supported by core */
@@ -613,8 +615,8 @@ eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
       _eglCreateExtensionsString(disp);
       _eglCreateAPIsString(disp);
       snprintf(disp->VersionString, sizeof(disp->VersionString),
-              "%d.%d (%s)", disp->Version / 10, disp->Version % 10,
-              disp->Driver->Name);
+               "%d.%d (%s)", disp->Version / 10, disp->Version % 10,
+               disp->Driver->Name);
    }
 
    /* Update applications version of major and minor if not NULL */
@@ -712,7 +714,7 @@ eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs,
 
    _EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
    ret = drv->API.ChooseConfig(drv, disp, attrib_list, configs,
-                                config_size, num_config);
+                               config_size, num_config);
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -920,7 +922,7 @@ static void *
 _fixupNativeWindow(_EGLDisplay *disp, void *native_window)
 {
 #ifdef HAVE_X11_PLATFORM
-   if (disp->Platform == _EGL_PLATFORM_X11 && native_window != NULL) {
+   if (disp && disp->Platform == _EGL_PLATFORM_X11 && native_window != NULL) {
       /* The `native_window` parameter for the X11 platform differs between
        * eglCreateWindowSurface() and eglCreatePlatformPixmapSurfaceEXT(). In
        * eglCreateWindowSurface(), the type of `native_window` is an Xlib
@@ -975,14 +977,14 @@ 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)
+   /* 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 && disp->Platform == _EGL_PLATFORM_X11 && native_pixmap != NULL)
       return (void *)(* (Pixmap*) native_pixmap);
 #endif
    return native_pixmap;
@@ -1018,6 +1020,9 @@ _eglCreatePixmapSurfaceCommon(_EGLDisplay *disp, EGLConfig config,
    if ((conf->SurfaceType & EGL_PIXMAP_BIT) == 0)
       RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SURFACE);
 
+   if (native_pixmap == NULL)
+      RETURN_EGL_ERROR(disp, EGL_BAD_NATIVE_PIXMAP, EGL_NO_SURFACE);
+
    surf = drv->API.CreatePixmapSurface(drv, disp, conf, native_pixmap,
                                        attrib_list);
    ret = (surf) ? _eglLinkSurface(surf) : EGL_NO_SURFACE;
@@ -1035,13 +1040,13 @@ eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
    _EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL, EGL_NO_SURFACE);
    STATIC_ASSERT(sizeof(void*) == sizeof(pixmap));
    return _eglCreatePixmapSurfaceCommon(disp, config, (void*) pixmap,
-                                         attrib_list);
+                                        attrib_list);
 }
 
 static EGLSurface EGLAPIENTRY
 eglCreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config,
-                                   void *native_pixmap,
-                                   const EGLint *attrib_list)
+                                  void *native_pixmap,
+                                  const EGLint *attrib_list)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
 
@@ -1198,7 +1203,17 @@ eglSwapInterval(EGLDisplay dpy, EGLint interval)
    if (_eglGetSurfaceHandle(surf) == EGL_NO_SURFACE)
       RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
 
-   ret = drv->API.SwapInterval(drv, disp, surf, interval);
+   interval = CLAMP(interval,
+                    surf->Config->MinSwapInterval,
+                    surf->Config->MaxSwapInterval);
+
+   if (surf->SwapInterval != interval)
+      ret = drv->API.SwapInterval(drv, disp, surf, interval);
+   else
+      ret = EGL_TRUE;
+
+   if (ret)
+      surf->SwapInterval = interval;
 
    RETURN_EGL_EVAL(disp, ret);
 }
@@ -1234,6 +1249,15 @@ eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
 
    ret = drv->API.SwapBuffers(drv, disp, surf);
 
+   /* EGL_KHR_partial_update
+    * Frame boundary successfully reached,
+    * reset damage region and reset BufferAgeRead
+    */
+   if (ret) {
+      surf->SetDamageRegionCalled = EGL_FALSE;
+      surf->BufferAgeRead = EGL_FALSE;
+   }
+
    RETURN_EGL_EVAL(disp, ret);
 }
 
@@ -1258,6 +1282,15 @@ _eglSwapBuffersWithDamageCommon(_EGLDisplay *disp, _EGLSurface *surf,
 
    ret = drv->API.SwapBuffersWithDamageEXT(drv, disp, surf, rects, n_rects);
 
+   /* EGL_KHR_partial_update
+    * Frame boundary successfully reached,
+    * reset damage region and reset BufferAgeRead
+    */
+   if (ret) {
+      surf->SetDamageRegionCalled = EGL_FALSE;
+      surf->BufferAgeRead = EGL_FALSE;
+   }
+
    RETURN_EGL_EVAL(disp, ret);
 }
 
@@ -1281,6 +1314,70 @@ eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface surface,
    return _eglSwapBuffersWithDamageCommon(disp, surf, rects, n_rects);
 }
 
+/**
+ * If the width of the passed rect is greater than the surface's
+ * width then it is clamped to the width of the surface. Same with
+ * height.
+ */
+
+static void
+_eglSetDamageRegionKHRClampRects(_EGLDisplay* disp, _EGLSurface* surf,
+                                 EGLint *rects, EGLint n_rects)
+{
+   EGLint i;
+   EGLint surf_height = surf->Height;
+   EGLint surf_width = surf->Width;
+
+   for (i = 0; i < (4 * n_rects); i += 4) {
+      EGLint x, y, rect_width, rect_height;
+      x = rects[i];
+      y = rects[i + 1];
+      rect_width = rects[i + 2];
+      rect_height = rects[i + 3];
+
+      if (rect_width > surf_width - x)
+         rects[i + 2] = surf_width - x;
+
+      if (rect_height > surf_height - y)
+         rects[i + 3] = surf_height - y;
+   }
+}
+
+static EGLBoolean EGLAPIENTRY
+eglSetDamageRegionKHR(EGLDisplay dpy, EGLSurface surface,
+                      EGLint *rects, EGLint n_rects)
+{
+   _EGLDisplay *disp = _eglLockDisplay(dpy);
+   _EGLSurface *surf = _eglLookupSurface(surface, disp);
+   _EGL_FUNC_START(disp, EGL_OBJECT_SURFACE_KHR, surf, EGL_FALSE);
+   _EGLContext *ctx = _eglGetCurrentContext();
+   _EGLDriver *drv;
+   EGLBoolean ret;
+   _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE, drv);
+
+   if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
+       surf->Type != EGL_WINDOW_BIT ||
+       ctx->DrawSurface != surf ||
+       surf->SwapBehavior != EGL_BUFFER_DESTROYED)
+      RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
+
+   /* If the damage region is already set or
+    * buffer age is not queried between
+    * frame boundaries, throw bad access error
+    */
+
+   if (surf->SetDamageRegionCalled || !surf->BufferAgeRead)
+      RETURN_EGL_ERROR(disp, EGL_BAD_ACCESS, EGL_FALSE);
+
+   _eglSetDamageRegionKHRClampRects(disp, surf, rects, n_rects);
+   ret = drv->API.SetDamageRegion(drv, disp, surf, rects, n_rects);
+
+   if (ret)
+      surf->SetDamageRegionCalled = EGL_TRUE;
+
+   RETURN_EGL_EVAL(disp, ret);
+}
+
 EGLBoolean EGLAPIENTRY
 eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
 {
@@ -1546,7 +1643,7 @@ eglReleaseThread(void)
 
 static EGLImage
 _eglCreateImageCommon(_EGLDisplay *disp, EGLContext ctx, EGLenum target,
-                  EGLClientBuffer buffer, const EGLint *attr_list)
+                      EGLClientBuffer buffer, const EGLint *attr_list)
 {
    _EGLContext *context = _eglLookupContext(ctx, disp);
    _EGLDriver *drv;
@@ -1564,8 +1661,8 @@ _eglCreateImageCommon(_EGLDisplay *disp, EGLContext ctx, EGLenum target,
    if (ctx != EGL_NO_CONTEXT && target == EGL_LINUX_DMA_BUF_EXT)
       RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
 
-   img = drv->API.CreateImageKHR(drv,
-         disp, context, target, buffer, attr_list);
+   img = drv->API.CreateImageKHR(drv, disp, context, target,
+                                 buffer, attr_list);
    ret = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR;
 
    RETURN_EGL_EVAL(disp, ret);
@@ -1673,7 +1770,7 @@ _eglCreateSync(_EGLDisplay *disp, EGLenum type, const EGLAttrib *attrib_list,
 
    /* return an error if the client API doesn't support GL_OES_EGL_sync */
    if (ctx && (ctx->Resource.Display != disp ||
-       ctx->ClientAPI != EGL_OPENGL_ES_API))
+               ctx->ClientAPI != EGL_OPENGL_ES_API))
       RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
 
    switch (type) {
@@ -1988,7 +2085,7 @@ eglDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSync sync)
 
 static EGLBoolean EGLAPIENTRY
 eglSwapBuffersRegionNOK(EGLDisplay dpy, EGLSurface surface,
-                       EGLint numRects, const EGLint *rects)
+                        EGLint numRects, const EGLint *rects)
 {
    _EGLContext *ctx = _eglGetCurrentContext();
    _EGLDisplay *disp = _eglLockDisplay(dpy);
@@ -2036,7 +2133,7 @@ eglCreateDRMImageMESA(EGLDisplay dpy, const EGLint *attr_list)
 
 static EGLBoolean EGLAPIENTRY
 eglExportDRMImageMESA(EGLDisplay dpy, EGLImage image,
-                     EGLint *name, EGLint *handle, EGLint *stride)
+                      EGLint *name, EGLint *handle, EGLint *stride)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
    _EGLImage *img = _eglLookupImage(image, disp);
@@ -2238,7 +2335,7 @@ eglExportDMABUFImageMESA(EGLDisplay dpy, EGLImage image,
 
 static EGLint EGLAPIENTRY
 eglLabelObjectKHR(EGLDisplay dpy, EGLenum objectType, EGLObjectKHR object,
-                 EGLLabelKHR label)
+                  EGLLabelKHR label)
 {
    _EGLDisplay *disp = NULL;
    _EGLResourceType type;
@@ -2296,16 +2393,9 @@ eglLabelObjectKHR(EGLDisplay dpy, EGLenum objectType, EGLObjectKHR object,
    RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_BAD_PARAMETER);
 }
 
-static EGLBoolean
-_validDebugMessageLevel(EGLAttrib level)
-{
-   return (level >= EGL_DEBUG_MSG_CRITICAL_KHR &&
-           level <= EGL_DEBUG_MSG_INFO_KHR);
-}
-
 static EGLint EGLAPIENTRY
 eglDebugMessageControlKHR(EGLDEBUGPROCKHR callback,
-                         const EGLAttrib *attrib_list)
+                          const EGLAttrib *attrib_list)
 {
    unsigned int newEnabled;
 
@@ -2318,20 +2408,24 @@ eglDebugMessageControlKHR(EGLDEBUGPROCKHR callback,
       int i;
 
       for (i = 0; attrib_list[i] != EGL_NONE; i += 2) {
-         if (_validDebugMessageLevel(attrib_list[i])) {
+         switch (attrib_list[i]) {
+         case EGL_DEBUG_MSG_CRITICAL_KHR:
+         case EGL_DEBUG_MSG_ERROR_KHR:
+         case EGL_DEBUG_MSG_WARN_KHR:
+         case EGL_DEBUG_MSG_INFO_KHR:
             if (attrib_list[i + 1])
                newEnabled |= DebugBitFromType(attrib_list[i]);
             else
                newEnabled &= ~DebugBitFromType(attrib_list[i]);
-            continue;
+            break;
+         default:
+            // On error, set the last error code, call the current
+            // debug callback, and return the error code.
+            mtx_unlock(_eglGlobal.Mutex);
+            _eglReportError(EGL_BAD_ATTRIBUTE, NULL,
+                  "Invalid attribute 0x%04lx", (unsigned long) attrib_list[i]);
+            return EGL_BAD_ATTRIBUTE;
          }
-
-         // On error, set the last error code, call the current
-         // debug callback, and return the error code.
-         mtx_unlock(_eglGlobal.Mutex);
-         _eglReportError(EGL_BAD_ATTRIBUTE, NULL,
-               "Invalid attribute 0x%04lx", (unsigned long) attrib_list[i]);
-         return EGL_BAD_ATTRIBUTE;
       }
    }
 
@@ -2354,25 +2448,25 @@ eglQueryDebugKHR(EGLint attribute, EGLAttrib *value)
 
    mtx_lock(_eglGlobal.Mutex);
 
-   do {
-      if (_validDebugMessageLevel(attribute)) {
-         if (_eglGlobal.debugTypesEnabled & DebugBitFromType(attribute))
-            *value = EGL_TRUE;
-         else
-            *value = EGL_FALSE;
-         break;
-      }
-
-      if (attribute == EGL_DEBUG_CALLBACK_KHR) {
-         *value = (EGLAttrib) _eglGlobal.debugCallback;
-         break;
-      }
-
+   switch (attribute) {
+   case EGL_DEBUG_MSG_CRITICAL_KHR:
+   case EGL_DEBUG_MSG_ERROR_KHR:
+   case EGL_DEBUG_MSG_WARN_KHR:
+   case EGL_DEBUG_MSG_INFO_KHR:
+      if (_eglGlobal.debugTypesEnabled & DebugBitFromType(attribute))
+         *value = EGL_TRUE;
+      else
+         *value = EGL_FALSE;
+      break;
+   case EGL_DEBUG_CALLBACK_KHR:
+      *value = (EGLAttrib) _eglGlobal.debugCallback;
+      break;
+   default:
       mtx_unlock(_eglGlobal.Mutex);
       _eglReportError(EGL_BAD_ATTRIBUTE, NULL,
-              "Invalid attribute 0x%04lx", (unsigned long) attribute);
+                      "Invalid attribute 0x%04lx", (unsigned long) attribute);
       return EGL_FALSE;
-   } while (0);
+   }
 
    mtx_unlock(_eglGlobal.Mutex);
    return EGL_TRUE;