[mutter] MetaOnscreenNative: Allocate for real after cogl_framebuffer_allocate



commit b1597b4291c00d6eee991fbea1b60e56a71b9561
Author: Jonas Ådahl <jadahl gmail com>
Date:   Thu Sep 29 22:46:34 2016 +0800

    MetaOnscreenNative: Allocate for real after cogl_framebuffer_allocate
    
    There is no way to pass any backend specific parameters to a
    CoglFramebuffer until after it has been allocated by
    cogl_framebuffer_allocate() (since this is where the winsys/platform
    fields are initialized). This can make it hard to actually allocate
    anything, if the platform depends on some backend specific data.
    
    A proper solution would be to refactor the onscreens and framebuffers to
    use a GObject based type system instead of the home baked Cogl one, but
    that'll be left for another day. For now, allocate in two steps, one to
    allocate the backend specific parts (MetaOnscreenNative), and one to
    allocate the actual onscreen framebuffer (via
    meta_onscreen_native_allocate()).
    
    So far there is nothing that forces this separation, but in the future
    there will, for example EGLDevice's need to know about the CRTC in
    order to create the EGLSurface.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=773629

 src/backends/native/meta-renderer-native.c |   77 ++++++++++++++++++++++------
 1 files changed, 61 insertions(+), 16 deletions(-)
---
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
index 21f786f..05497d1 100644
--- a/src/backends/native/meta-renderer-native.c
+++ b/src/backends/native/meta-renderer-native.c
@@ -757,15 +757,8 @@ meta_renderer_native_init_onscreen (CoglOnscreen *onscreen,
   CoglContext *cogl_context = framebuffer->context;
   CoglDisplay *cogl_display = cogl_context->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;
   CoglOnscreenEGL *egl_onscreen;
   MetaOnscreenNative *onscreen_native;
-  struct gbm_surface *gbm_surface;
-  EGLSurface egl_surface;
-  int width;
-  int height;
 
   _COGL_RETURN_VAL_IF_FAIL (egl_display->egl_context, FALSE);
 
@@ -775,6 +768,36 @@ meta_renderer_native_init_onscreen (CoglOnscreen *onscreen,
   onscreen_native = g_slice_new0 (MetaOnscreenNative);
   egl_onscreen->platform = onscreen_native;
 
+  /*
+   * Don't actually initialize anything here, since we may not have the
+   * information available yet, and there is no way to pass it at this stage.
+   * To properly allocate a MetaOnscreenNative, the caller must call
+   * meta_onscreen_native_allocate() after cogl_framebuffer_allocate().
+   *
+   * TODO: Turn CoglFramebuffer/CoglOnscreen into GObjects, so it's possible
+   * to add backend specific properties.
+   */
+
+  return TRUE;
+}
+
+static gboolean
+meta_onscreen_native_allocate (CoglOnscreen *onscreen,
+                               GError      **error)
+{
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  CoglContext *cogl_context = framebuffer->context;
+  CoglDisplay *cogl_display = cogl_context->display;
+  CoglRenderer *cogl_renderer = cogl_display->renderer;
+  CoglRendererEGL *egl_renderer = cogl_renderer->winsys;
+  MetaRendererNative *renderer_native = egl_renderer->platform;
+  CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
+  MetaOnscreenNative *onscreen_native = egl_onscreen->platform;
+  struct gbm_surface *gbm_surface;
+  EGLSurface egl_surface;
+  int width;
+  int height;
+
   onscreen_native->pending_set_crtc = TRUE;
 
   /* If a kms_fd is set then the display width and height
@@ -1129,6 +1152,7 @@ meta_renderer_native_create_legacy_view (MetaRendererNative *renderer_native)
   CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
   cairo_rectangle_int_t view_layout = { 0 };
   MetaRendererView *view;
+  GError *error = NULL;
 
   if (!monitor_manager)
     return NULL;
@@ -1150,10 +1174,20 @@ meta_renderer_native_create_legacy_view (MetaRendererNative *renderer_native)
                        "layout", &view_layout,
                        "framebuffer", onscreen,
                        NULL);
-  cogl_object_unref (onscreen);
 
   meta_onscreen_native_set_view (onscreen, view);
 
+  if (!meta_onscreen_native_allocate (onscreen, &error))
+    {
+      g_warning ("Could not create onscreen: %s", error->message);
+      cogl_object_unref (onscreen);
+      g_object_unref (view);
+      g_error_free (error);
+      return NULL;
+    }
+
+  cogl_object_unref (onscreen);
+
   return view;
 }
 
@@ -1171,6 +1205,7 @@ meta_renderer_native_create_view (MetaRenderer    *renderer,
   CoglOnscreen *onscreen = NULL;
   CoglOffscreen *offscreen = NULL;
   MetaRendererView *view;
+  GError *error = NULL;
 
   transform = meta_renderer_native_get_monitor_info_transform (renderer,
                                                                monitor_info);
@@ -1183,13 +1218,6 @@ meta_renderer_native_create_view (MetaRenderer    *renderer,
   if (!onscreen)
     meta_fatal ("Failed to allocate onscreen framebuffer\n");
 
-  /* Ensure we don't point to stale surfaces when creating the offscreen */
-  egl_onscreen = onscreen->winsys;
-  _cogl_winsys_egl_make_current (cogl_display,
-                                 egl_onscreen->egl_surface,
-                                 egl_onscreen->egl_surface,
-                                 egl_display->egl_context);
-
   if (transform != META_MONITOR_TRANSFORM_NORMAL)
     {
       offscreen = meta_renderer_native_create_offscreen (META_RENDERER_NATIVE (renderer),
@@ -1208,11 +1236,28 @@ meta_renderer_native_create_view (MetaRenderer    *renderer,
                        "monitor-info", monitor_info,
                        "transform", transform,
                        NULL);
-  cogl_object_unref (onscreen);
   g_clear_pointer (&offscreen, cogl_object_unref);
 
   meta_onscreen_native_set_view (onscreen, view);
 
+  if (!meta_onscreen_native_allocate (onscreen, &error))
+    {
+      g_warning ("Could not create onscreen: %s", error->message);
+      cogl_object_unref (onscreen);
+      g_object_unref (view);
+      g_error_free (error);
+      return NULL;
+    }
+
+  cogl_object_unref (onscreen);
+
+  /* Ensure we don't point to stale surfaces when creating the offscreen */
+  egl_onscreen = onscreen->winsys;
+  _cogl_winsys_egl_make_current (cogl_display,
+                                 egl_onscreen->egl_surface,
+                                 egl_onscreen->egl_surface,
+                                 egl_display->egl_context);
+
   return view;
 }
 


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