egl: Update to Wayland 1.2 server API
[mesa.git] / src / gallium / state_trackers / egl / common / egl_g3d.c
index e60a56074dd57a5dbec4945482d869495f6ad7a9..7cc4e8f6cba4be90829a65758f27ddc885d1dce6 100644 (file)
@@ -1,6 +1,5 @@
 /*
  * Mesa 3-D graphics library
- * Version:  7.8
  *
  * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org>
  *
@@ -31,6 +30,7 @@
 #include "util/u_memory.h"
 #include "util/u_format.h"
 #include "util/u_string.h"
+#include "util/u_atomic.h"
 
 #include "egl_g3d.h"
 #include "egl_g3d_api.h"
@@ -45,15 +45,9 @@ egl_g3d_invalid_surface(struct native_display *ndpy,
 {
    /* XXX not thread safe? */
    struct egl_g3d_surface *gsurf = egl_g3d_surface(nsurf->user_data);
-   struct egl_g3d_context *gctx;
-   
-   /*
-    * Some functions such as egl_g3d_copy_buffers create a temporary native
-    * surface.  There is no gsurf associated with it.
-    */
-   gctx = (gsurf) ? egl_g3d_context(gsurf->base.CurrentContext) : NULL;
-   if (gctx)
-      gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi, gsurf->stfbi);
+
+   if (gsurf && gsurf->stfbi)
+      p_atomic_inc(&gsurf->stfbi->stamp);
 }
 
 static struct pipe_screen *
@@ -72,10 +66,26 @@ egl_g3d_new_sw_screen(struct native_display *ndpy, struct sw_winsys *ws)
    return gdpy->loader->create_sw_screen(ws);
 }
 
-static struct native_event_handler egl_g3d_native_event_handler = {
+static struct pipe_resource *
+egl_g3d_lookup_egl_image(struct native_display *ndpy, void *egl_image)
+{
+   _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data;
+   struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
+   struct st_egl_image img;
+   struct pipe_resource *resource = NULL;
+
+   memset(&img, 0, sizeof(img));
+   if (gdpy->smapi->get_egl_image(gdpy->smapi, egl_image, &img))
+      resource = img.texture;
+
+   return resource;
+}
+
+static const struct native_event_handler egl_g3d_native_event_handler = {
    egl_g3d_invalid_surface,
    egl_g3d_new_drm_screen,
-   egl_g3d_new_sw_screen
+   egl_g3d_new_sw_screen,
+   egl_g3d_lookup_egl_image
 };
 
 /**
@@ -94,40 +104,50 @@ egl_g3d_get_platform(_EGLDriver *drv, _EGLPlatformType plat)
       case _EGL_PLATFORM_WINDOWS:
          plat_name = "Windows";
 #ifdef HAVE_GDI_BACKEND
-         nplat = native_get_gdi_platform();
+         nplat = native_get_gdi_platform(&egl_g3d_native_event_handler);
 #endif
          break;
       case _EGL_PLATFORM_X11:
          plat_name = "X11";
 #ifdef HAVE_X11_BACKEND
-         nplat = native_get_x11_platform();
+         nplat = native_get_x11_platform(&egl_g3d_native_event_handler);
 #endif
         break;
       case _EGL_PLATFORM_WAYLAND:
          plat_name = "wayland";
 #ifdef HAVE_WAYLAND_BACKEND
-         nplat = native_get_wayland_platform();
+         nplat = native_get_wayland_platform(&egl_g3d_native_event_handler);
 #endif
          break;
       case _EGL_PLATFORM_DRM:
          plat_name = "DRM";
 #ifdef HAVE_DRM_BACKEND
-         nplat = native_get_drm_platform();
+         nplat = native_get_drm_platform(&egl_g3d_native_event_handler);
 #endif
          break;
       case _EGL_PLATFORM_FBDEV:
          plat_name = "FBDEV";
 #ifdef HAVE_FBDEV_BACKEND
-         nplat = native_get_fbdev_platform();
+         nplat = native_get_fbdev_platform(&egl_g3d_native_event_handler);
+#endif
+         break;
+      case _EGL_PLATFORM_NULL:
+         plat_name = "NULL";
+#ifdef HAVE_NULL_BACKEND
+         nplat = native_get_null_platform(&egl_g3d_native_event_handler);
+#endif
+         break;
+      case _EGL_PLATFORM_ANDROID:
+         plat_name = "Android";
+#ifdef HAVE_ANDROID_BACKEND
+         nplat = native_get_android_platform(&egl_g3d_native_event_handler);
 #endif
          break;
       default:
          break;
       }
 
-      if (nplat)
-         nplat->set_event_handler(&egl_g3d_native_event_handler);
-      else
+      if (!nplat)
          _eglLog(_EGL_WARNING, "unsupported platform %s", plat_name);
 
       gdrv->platforms[plat] = nplat;
@@ -148,8 +168,7 @@ egl_g3d_add_screens(_EGLDriver *drv, _EGLDisplay *dpy)
    native_connectors =
       gdpy->native->modeset->get_connectors(gdpy->native, &num_connectors, NULL);
    if (!num_connectors) {
-      if (native_connectors)
-         FREE(native_connectors);
+      FREE(native_connectors);
       return;
    }
 
@@ -163,8 +182,7 @@ egl_g3d_add_screens(_EGLDriver *drv, _EGLDisplay *dpy)
       native_modes =
          gdpy->native->modeset->get_modes(gdpy->native, nconn, &num_modes);
       if (!num_modes) {
-         if (native_modes)
-            FREE(native_modes);
+         FREE(native_modes);
          continue;
       }
 
@@ -205,7 +223,8 @@ egl_g3d_add_screens(_EGLDriver *drv, _EGLDisplay *dpy)
 static EGLBoolean
 init_config_attributes(_EGLConfig *conf, const struct native_config *nconf,
                        EGLint api_mask, enum pipe_format depth_stencil_format,
-                       EGLBoolean preserve_buffer, EGLint max_swap_interval)
+                       EGLint preserve_buffer, EGLint max_swap_interval,
+                       EGLBoolean pre_alpha)
 {
    uint rgba[4], depth_stencil[2], buffer_size;
    EGLint surface_type;
@@ -247,6 +266,15 @@ init_config_attributes(_EGLConfig *conf, const struct native_config *nconf,
       surface_type |= EGL_PBUFFER_BIT;
    }
 
+   if (preserve_buffer)
+      surface_type |= EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
+
+   if (pre_alpha && rgba[3]) {
+      surface_type |= EGL_VG_ALPHA_FORMAT_PRE_BIT;
+      /* st/vega does not support premultiplied alpha yet */
+      api_mask &= ~EGL_OPENVG_BIT;
+   }
+
    conf->Conformant = api_mask;
    conf->RenderableType = api_mask;
 
@@ -259,6 +287,10 @@ init_config_attributes(_EGLConfig *conf, const struct native_config *nconf,
    conf->DepthSize = depth_stencil[0];
    conf->StencilSize = depth_stencil[1];
 
+   /* st/vega will allocate the mask on demand */
+   if (api_mask & EGL_OPENVG_BIT)
+      conf->AlphaMaskSize = 8;
+
    conf->SurfaceType = surface_type;
 
    conf->NativeRenderable = EGL_TRUE;
@@ -288,8 +320,6 @@ init_config_attributes(_EGLConfig *conf, const struct native_config *nconf,
 
    conf->MinSwapInterval = 0;
    conf->MaxSwapInterval = max_swap_interval;
-   if (preserve_buffer)
-      conf->SurfaceType |= EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
 
    return _eglValidateConfig(conf, EGL_FALSE);
 }
@@ -301,7 +331,8 @@ static EGLBoolean
 egl_g3d_init_config(_EGLDriver *drv, _EGLDisplay *dpy,
                     _EGLConfig *conf, const struct native_config *nconf,
                     enum pipe_format depth_stencil_format,
-                    int preserve_buffer, int max_swap_interval)
+                    int preserve_buffer, int max_swap_interval,
+                    int pre_alpha)
 {
    struct egl_g3d_config *gconf = egl_g3d_config(conf);
    EGLint buffer_mask;
@@ -329,7 +360,7 @@ egl_g3d_init_config(_EGLDriver *drv, _EGLDisplay *dpy,
 
    valid = init_config_attributes(&gconf->base,
          nconf, dpy->ClientAPIs, depth_stencil_format,
-         preserve_buffer, max_swap_interval);
+         preserve_buffer, max_swap_interval, pre_alpha);
    if (!valid) {
       _eglLog(_EGL_DEBUG, "skip invalid config 0x%x", nconf->native_visual_id);
       return EGL_FALSE;
@@ -352,7 +383,7 @@ egl_g3d_fill_depth_stencil_formats(_EGLDisplay *dpy,
    const EGLint candidates[] = {
       1, PIPE_FORMAT_Z16_UNORM,
       1, PIPE_FORMAT_Z32_UNORM,
-      2, PIPE_FORMAT_Z24_UNORM_S8_USCALED, PIPE_FORMAT_S8_USCALED_Z24_UNORM,
+      2, PIPE_FORMAT_Z24_UNORM_S8_UINT, PIPE_FORMAT_S8_UINT_Z24_UNORM,
       2, PIPE_FORMAT_Z24X8_UNORM, PIPE_FORMAT_X8Z24_UNORM,
       0
    };
@@ -368,7 +399,7 @@ egl_g3d_fill_depth_stencil_formats(_EGLDisplay *dpy,
       /* pick the first supported format */
       for (i = 0; i < n; i++) {
          if (screen->is_format_supported(screen, fmt[i],
-                  PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL, 0)) {
+                  PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL)) {
             formats[count++] = fmt[i];
             break;
          }
@@ -390,12 +421,11 @@ egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id)
    const struct native_config **native_configs;
    enum pipe_format depth_stencil_formats[8];
    int num_formats, num_configs, i, j;
-   int preserve_buffer, max_swap_interval;
+   int preserve_buffer, max_swap_interval, premultiplied_alpha;
 
    native_configs = gdpy->native->get_configs(gdpy->native, &num_configs);
    if (!num_configs) {
-      if (native_configs)
-         FREE(native_configs);
+      FREE(native_configs);
       return id;
    }
 
@@ -403,6 +433,8 @@ egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id)
       gdpy->native->get_param(gdpy->native, NATIVE_PARAM_PRESERVE_BUFFER);
    max_swap_interval =
       gdpy->native->get_param(gdpy->native, NATIVE_PARAM_MAX_SWAP_INTERVAL);
+   premultiplied_alpha =
+      gdpy->native->get_param(gdpy->native, NATIVE_PARAM_PREMULTIPLIED_ALPHA);
 
    num_formats = egl_g3d_fill_depth_stencil_formats(dpy,
          depth_stencil_formats);
@@ -416,7 +448,8 @@ egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id)
             _eglInitConfig(&gconf->base, dpy, id);
             if (!egl_g3d_init_config(drv, dpy, &gconf->base,
                      native_configs[i], depth_stencil_formats[j],
-                     preserve_buffer, max_swap_interval)) {
+                     preserve_buffer, max_swap_interval,
+                     premultiplied_alpha)) {
                FREE(gconf);
                break;
             }
@@ -500,13 +533,20 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy)
    gdpy->loader = gdrv->loader;
    dpy->DriverData = gdpy;
 
-   _eglLog(_EGL_INFO, "use %s for display %p", nplat->name, dpy->PlatformDisplay);
-   gdpy->native = nplat->create_display(dpy->PlatformDisplay,
-         dpy->Options.UseFallback, (void *) dpy);
+   _eglLog(_EGL_INFO, "use %s for display %p",
+         nplat->name, dpy->PlatformDisplay);
+   gdpy->native =
+      nplat->create_display(dpy->PlatformDisplay, dpy->Options.UseFallback);
    if (!gdpy->native) {
       _eglError(EGL_NOT_INITIALIZED, "eglInitialize(no usable display)");
       goto fail;
    }
+   gdpy->native->user_data = (void *) dpy;
+   if (!gdpy->native->init_screen(gdpy->native)) {
+      _eglError(EGL_NOT_INITIALIZED,
+            "eglInitialize(failed to initialize screen)");
+      goto fail;
+   }
 
    if (gdpy->loader->profile_masks[ST_API_OPENGL] & ST_PROFILE_DEFAULT_MASK)
       dpy->ClientAPIs |= EGL_OPENGL_BIT;
@@ -539,9 +579,7 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy)
    dpy->Extensions.KHR_reusable_sync = EGL_TRUE;
    dpy->Extensions.KHR_fence_sync = EGL_TRUE;
 
-   dpy->Extensions.KHR_surfaceless_gles1 = EGL_TRUE;
-   dpy->Extensions.KHR_surfaceless_gles2 = EGL_TRUE;
-   dpy->Extensions.KHR_surfaceless_opengl = EGL_TRUE;
+   dpy->Extensions.KHR_surfaceless_context = EGL_TRUE;
 
    if (dpy->Platform == _EGL_PLATFORM_DRM) {
       dpy->Extensions.MESA_drm_display = EGL_TRUE;
@@ -552,6 +590,24 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy)
    if (dpy->Platform == _EGL_PLATFORM_WAYLAND && gdpy->native->buffer)
       dpy->Extensions.MESA_drm_image = EGL_TRUE;
 
+#ifdef EGL_ANDROID_image_native_buffer
+   if (dpy->Platform == _EGL_PLATFORM_ANDROID && gdpy->native->buffer)
+      dpy->Extensions.ANDROID_image_native_buffer = EGL_TRUE;
+#endif
+
+#ifdef EGL_WL_bind_wayland_display
+   if (gdpy->native->wayland_bufmgr)
+      dpy->Extensions.WL_bind_wayland_display = EGL_TRUE;
+#endif
+
+   if (gdpy->native->get_param(gdpy->native, NATIVE_PARAM_PRESENT_REGION) &&
+       gdpy->native->get_param(gdpy->native, NATIVE_PARAM_PRESERVE_BUFFER)) {
+#ifdef EGL_NOK_swap_region
+      dpy->Extensions.NOK_swap_region = EGL_TRUE;
+#endif
+      dpy->Extensions.NV_post_sub_buffer = EGL_TRUE;
+   }
+
    if (egl_g3d_add_configs(drv, dpy, 1) == 1) {
       _eglError(EGL_NOT_INITIALIZED, "eglInitialize(unable to add configs)");
       goto fail;