[mutter] MetaEgl: Add EGL procs necessary for EGLDevice based rendering



commit b735bdcf2f1832629a1ffffe3d398b3152e492e8
Author: Jonas Ådahl <jadahl gmail com>
Date:   Thu Aug 18 11:27:45 2016 +0800

    MetaEgl: Add EGL procs necessary for EGLDevice based rendering
    
    https://bugzilla.gnome.org/show_bug.cgi?id=773629

 src/backends/meta-egl-ext.h |   52 ++++++++
 src/backends/meta-egl.c     |  297 +++++++++++++++++++++++++++++++++++++++++++
 src/backends/meta-egl.h     |   73 +++++++++++
 3 files changed, 422 insertions(+), 0 deletions(-)
---
diff --git a/src/backends/meta-egl-ext.h b/src/backends/meta-egl-ext.h
new file mode 100644
index 0000000..eff8508
--- /dev/null
+++ b/src/backends/meta-egl-ext.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef META_EGL_EXT_H
+#define META_EGL_EXT_H
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+/*
+ * FIXME: Remove both EGL_EXT_stream_acquire_mode and
+ *        EGL_NV_output_drm_flip_event definitions below once both extensions
+ *        get published by Khronos and incorportated into Khronos' header files
+ */
+#ifndef EGL_EXT_stream_acquire_mode
+#define EGL_EXT_stream_acquire_mode 1
+#define EGL_CONSUMER_AUTO_ACQUIRE_EXT         0x332B
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREATTRIBEXTPROC) (EGLDisplay dpy, EGLStreamKHR 
stream, const EGLAttrib *attrib_list);
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLBoolean EGLAPIENTRY eglStreamConsumerAcquireAttribEXT (EGLDisplay dpy, EGLStreamKHR stream, const 
EGLAttrib *attrib_list);
+#endif
+#endif /* EGL_EXT_stream_acquire_mode */
+
+#ifndef EGL_NV_output_drm_flip_event
+#define EGL_NV_output_drm_flip_event 1
+#define EGL_DRM_FLIP_EVENT_DATA_NV            0x333E
+#endif /* EGL_NV_output_drm_flip_event */
+
+#endif /* META_EGL_EXT_H */
diff --git a/src/backends/meta-egl.c b/src/backends/meta-egl.c
index 499b04f..a1da5d2 100644
--- a/src/backends/meta-egl.c
+++ b/src/backends/meta-egl.c
@@ -26,6 +26,7 @@
 
 #include "backends/meta-backend-private.h"
 #include "backends/meta-egl.h"
+#include "backends/meta-egl-ext.h"
 #include "meta/util.h"
 
 #include <EGL/egl.h>
@@ -39,6 +40,24 @@ struct _MetaEgl
   GObject parent;
 
   PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT;
+
+  PFNEGLQUERYDEVICESEXTPROC eglQueryDevicesEXT;
+  PFNEGLQUERYDEVICESTRINGEXTPROC eglQueryDeviceStringEXT;
+
+  PFNEGLGETOUTPUTLAYERSEXTPROC eglGetOutputLayersEXT;
+  PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC eglQueryOutputLayerAttribEXT;
+
+  PFNEGLCREATESTREAMKHRPROC eglCreateStreamKHR;
+  PFNEGLDESTROYSTREAMKHRPROC eglDestroyStreamKHR;
+  PFNEGLQUERYSTREAMKHRPROC eglQueryStreamKHR;
+
+  PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC eglCreateStreamProducerSurfaceKHR;
+
+  PFNEGLSTREAMCONSUMEROUTPUTEXTPROC eglStreamConsumerOutputEXT;
+
+  PFNEGLSTREAMCONSUMERACQUIREATTRIBEXTPROC eglStreamConsumerAcquireAttribEXT;
+
+  PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC eglStreamConsumerGLTextureExternalKHR;
 };
 
 G_DEFINE_TYPE (MetaEgl, meta_egl, G_TYPE_OBJECT)
@@ -305,6 +324,266 @@ meta_egl_get_platform_display (MetaEgl      *egl,
   return display;
 }
 
+gboolean
+meta_egl_query_devices (MetaEgl      *egl,
+                        EGLint        max_devices,
+                        EGLDeviceEXT *devices,
+                        EGLint       *num_devices,
+                        GError      **error)
+{
+  if (!is_egl_proc_valid (egl->eglQueryDevicesEXT, error))
+    return FALSE;
+
+  if (!egl->eglQueryDevicesEXT (max_devices,
+                                devices,
+                                num_devices))
+    {
+      set_egl_error (error);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+const char *
+meta_egl_query_device_string (MetaEgl     *egl,
+                              EGLDeviceEXT device,
+                              EGLint       name,
+                              GError     **error)
+{
+  const char *device_string;
+
+  if (!is_egl_proc_valid (egl->eglQueryDeviceStringEXT, error))
+    return NULL;
+
+  device_string = egl->eglQueryDeviceStringEXT (device, name);
+  if (!device_string)
+    {
+      set_egl_error (error);
+      return NULL;
+    }
+
+  return device_string;
+}
+
+gboolean
+meta_egl_egl_device_has_extensions (MetaEgl     *egl,
+                                    EGLDeviceEXT device,
+                                    char      ***missing_extensions,
+                                    char        *first_extension,
+                                    ...)
+{
+  va_list var_args;
+  const char *extensions_str;
+  gboolean has_extensions;
+  GError *error = NULL;
+
+  extensions_str = meta_egl_query_device_string (egl, device, EGL_EXTENSIONS,
+                                                 &error);
+  if (!extensions_str)
+    {
+      g_warning ("Failed to query device string: %s", error->message);
+      g_error_free (error);
+      return FALSE;
+    }
+
+  va_start (var_args, first_extension);
+  has_extensions = extensions_string_has_extensions_valist (extensions_str,
+                                                            missing_extensions,
+                                                            first_extension,
+                                                            var_args);
+  va_end (var_args);
+
+  return has_extensions;
+}
+
+gboolean
+meta_egl_get_output_layers (MetaEgl           *egl,
+                            EGLDisplay         display,
+                            const EGLAttrib   *attrib_list,
+                            EGLOutputLayerEXT *layers,
+                            EGLint             max_layers,
+                            EGLint            *num_layers,
+                            GError           **error)
+{
+  if (!is_egl_proc_valid (egl->eglGetOutputLayersEXT, error))
+    return FALSE;
+
+  if (!egl->eglGetOutputLayersEXT (display,
+                                   attrib_list,
+                                   layers,
+                                   max_layers,
+                                   num_layers))
+    {
+      set_egl_error (error);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+gboolean
+meta_egl_query_output_layer_attrib (MetaEgl          *egl,
+                                    EGLDisplay        display,
+                                    EGLOutputLayerEXT layer,
+                                    EGLint            attribute,
+                                    EGLAttrib        *value,
+                                    GError          **error)
+{
+  if (!is_egl_proc_valid (egl->eglQueryOutputLayerAttribEXT, error))
+    return FALSE;
+
+  if (!egl->eglQueryOutputLayerAttribEXT (display, layer,
+                                          attribute, value))
+    {
+      set_egl_error (error);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+EGLStreamKHR
+meta_egl_create_stream (MetaEgl      *egl,
+                        EGLDisplay    display,
+                        const EGLint *attrib_list,
+                        GError      **error)
+{
+  EGLStreamKHR stream;
+
+  if (!is_egl_proc_valid (egl->eglCreateStreamKHR, error))
+    return EGL_NO_STREAM_KHR;
+
+  stream = egl->eglCreateStreamKHR (display, attrib_list);
+  if (stream == EGL_NO_STREAM_KHR)
+    {
+      set_egl_error (error);
+      return EGL_NO_STREAM_KHR;
+    }
+
+  return stream;
+}
+
+gboolean
+meta_egl_destroy_stream (MetaEgl     *egl,
+                         EGLDisplay   display,
+                         EGLStreamKHR stream,
+                         GError     **error)
+{
+  if (!is_egl_proc_valid (egl->eglDestroyStreamKHR, error))
+    return FALSE;
+
+  if (!egl->eglDestroyStreamKHR (display, stream))
+    {
+      set_egl_error (error);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+gboolean
+meta_egl_query_stream (MetaEgl     *egl,
+                       EGLDisplay   display,
+                       EGLStreamKHR stream,
+                       EGLenum      attribute,
+                       EGLint      *value,
+                       GError     **error)
+{
+  if (!is_egl_proc_valid (egl->eglQueryStreamKHR, error))
+    return FALSE;
+
+  if (!egl->eglQueryStreamKHR (display, stream, attribute, value))
+    {
+      set_egl_error (error);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+EGLSurface
+meta_egl_create_stream_producer_surface (MetaEgl     *egl,
+                                         EGLDisplay   display,
+                                         EGLConfig    config,
+                                         EGLStreamKHR stream,
+                                         const EGLint *attrib_list,
+                                         GError      **error)
+{
+  EGLSurface surface;
+
+  if (!is_egl_proc_valid (egl->eglCreateStreamProducerSurfaceKHR, error))
+    return EGL_NO_SURFACE;
+
+  surface = egl->eglCreateStreamProducerSurfaceKHR (display,
+                                                    config,
+                                                    stream,
+                                                    attrib_list);
+  if (surface == EGL_NO_SURFACE)
+    {
+      set_egl_error (error);
+      return EGL_NO_SURFACE;
+    }
+
+  return surface;
+}
+
+gboolean
+meta_egl_stream_consumer_output (MetaEgl          *egl,
+                                 EGLDisplay        display,
+                                 EGLStreamKHR      stream,
+                                 EGLOutputLayerEXT layer,
+                                 GError          **error)
+{
+  if (!is_egl_proc_valid (egl->eglStreamConsumerOutputEXT, error))
+    return FALSE;
+
+  if (!egl->eglStreamConsumerOutputEXT (display, stream, layer))
+    {
+      set_egl_error (error);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+gboolean
+meta_egl_stream_consumer_acquire_attrib (MetaEgl     *egl,
+                                         EGLDisplay   display,
+                                         EGLStreamKHR stream,
+                                         EGLAttrib   *attrib_list,
+                                         GError     **error)
+{
+  if (!is_egl_proc_valid (egl->eglStreamConsumerAcquireAttribEXT, error))
+    return FALSE;
+
+  if (!egl->eglStreamConsumerAcquireAttribEXT (display, stream, attrib_list))
+    {
+      set_egl_error (error);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+gboolean
+meta_egl_stream_consumer_gl_texture_external (MetaEgl     *egl,
+                                              EGLDisplay   display,
+                                              EGLStreamKHR stream,
+                                              GError     **error)
+{
+  if (!is_egl_proc_valid (egl->eglStreamConsumerGLTextureExternalKHR, error))
+    return FALSE;
+
+  if (!egl->eglStreamConsumerGLTextureExternalKHR (display, stream))
+    {
+      set_egl_error (error);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
 #define GET_EGL_PROC_ADDR(proc) \
   egl->proc = (void *) eglGetProcAddress (#proc);
 
@@ -321,6 +600,24 @@ meta_egl_constructed (GObject *object)
   MetaEgl *egl = META_EGL (object);
 
   GET_EGL_PROC_ADDR_REQUIRED (eglGetPlatformDisplayEXT);
+
+  GET_EGL_PROC_ADDR (eglQueryDevicesEXT);
+  GET_EGL_PROC_ADDR (eglQueryDeviceStringEXT);
+
+  GET_EGL_PROC_ADDR (eglGetOutputLayersEXT);
+  GET_EGL_PROC_ADDR (eglQueryOutputLayerAttribEXT);
+
+  GET_EGL_PROC_ADDR (eglCreateStreamKHR);
+  GET_EGL_PROC_ADDR (eglDestroyStreamKHR);
+  GET_EGL_PROC_ADDR (eglQueryStreamKHR);
+
+  GET_EGL_PROC_ADDR (eglCreateStreamProducerSurfaceKHR);
+
+  GET_EGL_PROC_ADDR (eglStreamConsumerOutputEXT);
+
+  GET_EGL_PROC_ADDR (eglStreamConsumerAcquireAttribEXT);
+
+  GET_EGL_PROC_ADDR (eglStreamConsumerGLTextureExternalKHR);
 }
 
 #undef GET_EGL_PROC_ADDR
diff --git a/src/backends/meta-egl.h b/src/backends/meta-egl.h
index 40db950..aa38a5c 100644
--- a/src/backends/meta-egl.h
+++ b/src/backends/meta-egl.h
@@ -60,4 +60,77 @@ EGLDisplay meta_egl_get_platform_display (MetaEgl      *egl,
                                           const EGLint *attrib_list,
                                           GError      **error);
 
+gboolean meta_egl_query_devices (MetaEgl      *egl,
+                                 EGLint        max_devices,
+                                 EGLDeviceEXT *devices,
+                                 EGLint       *num_devices,
+                                 GError      **error);
+
+const char * meta_egl_query_device_string (MetaEgl     *egl,
+                                           EGLDeviceEXT device,
+                                           EGLint       name,
+                                           GError     **error);
+
+gboolean meta_egl_egl_device_has_extensions (MetaEgl      *egl,
+                                             EGLDeviceEXT device,
+                                             char      ***missing_extensions,
+                                             char        *first_extension,
+                                             ...);
+
+gboolean meta_egl_get_output_layers (MetaEgl           *egl,
+                                     EGLDisplay         display,
+                                     const EGLAttrib   *attrib_list,
+                                     EGLOutputLayerEXT *layers,
+                                     EGLint             max_layers,
+                                     EGLint            *num_layers,
+                                     GError           **error);
+
+gboolean meta_egl_query_output_layer_attrib (MetaEgl          *egl,
+                                             EGLDisplay        display,
+                                             EGLOutputLayerEXT layer,
+                                             EGLint            attribute,
+                                             EGLAttrib        *value,
+                                             GError          **error);
+
+EGLStreamKHR meta_egl_create_stream (MetaEgl      *egl,
+                                     EGLDisplay    display,
+                                     const EGLint *attrib_list,
+                                     GError      **error);
+
+gboolean meta_egl_destroy_stream (MetaEgl     *egl,
+                                  EGLDisplay   display,
+                                  EGLStreamKHR stream,
+                                  GError      **error);
+
+gboolean meta_egl_query_stream (MetaEgl     *egl,
+                                EGLDisplay   display,
+                                EGLStreamKHR stream,
+                                EGLenum      attribute,
+                                EGLint      *value,
+                                GError     **error);
+
+EGLSurface meta_egl_create_stream_producer_surface (MetaEgl     *egl,
+                                                    EGLDisplay   display,
+                                                    EGLConfig    config,
+                                                    EGLStreamKHR stream,
+                                                    const EGLint *attrib_list,
+                                                    GError      **error);
+
+gboolean meta_egl_stream_consumer_output (MetaEgl          *egl,
+                                          EGLDisplay        display,
+                                          EGLStreamKHR      stream,
+                                          EGLOutputLayerEXT layer,
+                                          GError          **error);
+
+gboolean meta_egl_stream_consumer_acquire_attrib (MetaEgl     *egl,
+                                                  EGLDisplay   display,
+                                                  EGLStreamKHR stream,
+                                                  EGLAttrib   *attrib_list,
+                                                  GError     **error);
+
+gboolean meta_egl_stream_consumer_gl_texture_external (MetaEgl     *egl,
+                                                       EGLDisplay   display,
+                                                       EGLStreamKHR stream,
+                                                       GError     **error);
+
 #endif /* META_EGL_H */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]