[mutter] MetaRendererNative: Use pbuffer surface as dummy surface



commit da1c1d9c22fbd1cf0ea4fc8fd6b433522cbe938e
Author: Jonas Ådahl <jadahl gmail com>
Date:   Wed Aug 31 11:25:45 2016 +0800

    MetaRendererNative: Use pbuffer surface as dummy surface
    
    Lets use a pbuffer surface as a dummy surface instead of a gbm based
    one, so that we don't need to rely on the availability of gbm to create
    a dummy surface when there is no need for it.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=773629

 src/backends/meta-egl.c                    |   63 ++++++++++++++++++++++++++++
 src/backends/meta-egl.h                    |   12 +++++
 src/backends/native/meta-renderer-native.c |   61 ++++++++++++++------------
 3 files changed, 108 insertions(+), 28 deletions(-)
---
diff --git a/src/backends/meta-egl.c b/src/backends/meta-egl.c
index 65e627e..d605a79 100644
--- a/src/backends/meta-egl.c
+++ b/src/backends/meta-egl.c
@@ -200,6 +200,69 @@ meta_egl_get_display (MetaEgl             *egl,
   return display;
 }
 
+gboolean
+meta_egl_choose_config (MetaEgl      *egl,
+                        EGLDisplay    display,
+                        const EGLint *attrib_list,
+                        EGLConfig    *chosen_config,
+                        GError      **error)
+{
+  EGLint num_configs;
+  EGLConfig *configs;
+  EGLint num_matches;
+
+  if (!eglGetConfigs (display, NULL, 0, &num_configs))
+    {
+      set_egl_error (error);
+      return FALSE;
+    }
+
+  if (num_configs < 1)
+    {
+      g_set_error (error, G_IO_ERROR,
+                   G_IO_ERROR_FAILED,
+                   "No EGL configurations available");
+      return FALSE;
+    }
+
+  configs = g_new0 (EGLConfig, num_configs);
+
+  if (!eglChooseConfig (display, attrib_list, configs, num_configs, &num_matches))
+    {
+      g_free (configs);
+      set_egl_error (error);
+      return FALSE;
+    }
+
+  /*
+   * We don't have any preference specified yet, so lets choose the first one.
+   */
+  *chosen_config = configs[0];
+
+  g_free (configs);
+
+  return TRUE;
+}
+
+EGLSurface
+meta_egl_create_pbuffer_surface (MetaEgl      *egl,
+                                 EGLDisplay    display,
+                                 EGLConfig     config,
+                                 const EGLint *attrib_list,
+                                 GError      **error)
+{
+  EGLSurface surface;
+
+  surface = eglCreatePbufferSurface (display, config, attrib_list);
+  if (surface == EGL_NO_SURFACE)
+    {
+      set_egl_error (error);
+      return EGL_NO_SURFACE;
+    }
+
+  return surface;
+}
+
 static gboolean
 is_egl_proc_valid_real (void       *proc,
                         const char *proc_name,
diff --git a/src/backends/meta-egl.h b/src/backends/meta-egl.h
index f8a7a94..ac176d5 100644
--- a/src/backends/meta-egl.h
+++ b/src/backends/meta-egl.h
@@ -42,6 +42,18 @@ EGLDisplay meta_egl_get_display (MetaEgl             *egl,
                                  EGLNativeDisplayType display_id,
                                  GError             **error);
 
+gboolean meta_egl_choose_config (MetaEgl      *egl,
+                                 EGLDisplay    display,
+                                 const EGLint *attrib_list,
+                                 EGLConfig    *chosen_config,
+                                 GError      **error);
+
+EGLSurface meta_egl_create_pbuffer_surface (MetaEgl      *egl,
+                                            EGLDisplay    display,
+                                            EGLConfig     config,
+                                            const EGLint *attrib_list,
+                                            GError      **error);
+
 EGLDisplay meta_egl_get_platform_display (MetaEgl      *egl,
                                           EGLenum       platform,
                                           void         *native_display,
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
index 273a34e..9ec423f 100644
--- a/src/backends/native/meta-renderer-native.c
+++ b/src/backends/native/meta-renderer-native.c
@@ -95,8 +95,6 @@ struct _MetaRendererNative
   CoglClosure *swap_notify_idle;
 
   int64_t frame_counter;
-
-  struct gbm_surface *dummy_gbm_surface;
 };
 
 static void
@@ -281,6 +279,37 @@ meta_renderer_native_destroy_egl_display (CoglDisplay *cogl_display)
 {
 }
 
+static EGLSurface
+create_dummy_pbuffer_surface (EGLDisplay egl_display,
+                              GError   **error)
+{
+  MetaBackend *backend = meta_get_backend ();
+  MetaEgl *egl = meta_backend_get_egl (backend);
+  EGLConfig pbuffer_config;
+  static const EGLint pbuffer_config_attribs[] = {
+    EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
+    EGL_RED_SIZE, 1,
+    EGL_GREEN_SIZE, 1,
+    EGL_BLUE_SIZE, 1,
+    EGL_ALPHA_SIZE, 0,
+    EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+    EGL_NONE
+  };
+  static const EGLint pbuffer_attribs[] = {
+    EGL_WIDTH, 16,
+    EGL_HEIGHT, 16,
+    EGL_NONE
+  };
+
+  if (!meta_egl_choose_config (egl, egl_display, pbuffer_config_attribs,
+                               &pbuffer_config, error))
+    return EGL_NO_SURFACE;
+
+  return meta_egl_create_pbuffer_surface (egl, egl_display,
+                                          pbuffer_config, pbuffer_attribs,
+                                          error);
+}
+
 static gboolean
 meta_renderer_native_egl_context_created (CoglDisplay *cogl_display,
                                           GError     **error)
@@ -288,37 +317,14 @@ meta_renderer_native_egl_context_created (CoglDisplay *cogl_display,
   CoglDisplayEGL *egl_display = cogl_display->winsys;
   CoglRenderer *cogl_renderer = cogl_display->renderer;
   CoglRendererEGL *egl_renderer = cogl_renderer->winsys;
-  MetaRendererNative *renderer_native = egl_renderer->platform;
 
   if ((egl_renderer->private_features &
        COGL_EGL_WINSYS_FEATURE_SURFACELESS_CONTEXT) == 0)
     {
-      renderer_native->dummy_gbm_surface =
-        gbm_surface_create (renderer_native->gbm.device,
-                            16, 16,
-                            GBM_FORMAT_XRGB8888,
-                            GBM_BO_USE_RENDERING);
-      if (!renderer_native->dummy_gbm_surface)
-        {
-          _cogl_set_error (error, COGL_WINSYS_ERROR,
-                           COGL_WINSYS_ERROR_CREATE_CONTEXT,
-                           "Failed to create dummy GBM surface");
-          return FALSE;
-        }
-
       egl_display->dummy_surface =
-        eglCreateWindowSurface (egl_renderer->edpy,
-                                egl_display->egl_config,
-                                (EGLNativeWindowType)
-                                renderer_native->dummy_gbm_surface,
-                                NULL);
+        create_dummy_pbuffer_surface (egl_renderer->edpy, error);
       if (egl_display->dummy_surface == EGL_NO_SURFACE)
-        {
-          _cogl_set_error (error, COGL_WINSYS_ERROR,
-                           COGL_WINSYS_ERROR_CREATE_CONTEXT,
-                           "Failed to create dummy EGL surface");
-          return FALSE;
-        }
+        return FALSE;
     }
 
   if (!_cogl_winsys_egl_make_current (cogl_display,
@@ -1228,7 +1234,6 @@ meta_renderer_native_finalize (GObject *object)
 {
   MetaRendererNative *renderer_native = META_RENDERER_NATIVE (object);
 
-  g_clear_pointer (&renderer_native->dummy_gbm_surface, gbm_surface_destroy);
   g_clear_pointer (&renderer_native->gbm.device, gbm_device_destroy);
 
   G_OBJECT_CLASS (meta_renderer_native_parent_class)->finalize (object);


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