[mutter] cogl/onscreen: Use CoglFramebufferClass::allocate() to init



commit 0936d7bd0636b5ad88c032465e95222a1282660a
Author: Jonas Ådahl <jadahl gmail com>
Date:   Sun Oct 18 11:15:49 2020 +0200

    cogl/onscreen: Use CoglFramebufferClass::allocate() to init
    
    Instead of calling "init_onscreen()" on two different separate vtables
    from the allocate() funtion, just have the CoglOnscreen sub types
    themself implement allocate() and initialize in there.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1514>

 cogl/cogl/cogl-onscreen.c                  |  18 ---
 cogl/cogl/winsys/cogl-onscreen-egl.c       |  37 ++----
 cogl/cogl/winsys/cogl-onscreen-egl.h       |  12 +-
 cogl/cogl/winsys/cogl-onscreen-glx.c       | 110 ++++++++--------
 cogl/cogl/winsys/cogl-onscreen-glx.h       |   7 -
 cogl/cogl/winsys/cogl-onscreen-xlib.c      | 204 ++++++++++++++++-------------
 cogl/cogl/winsys/cogl-winsys-egl-private.h |   7 -
 cogl/cogl/winsys/cogl-winsys-egl-x11.c     |   2 -
 cogl/cogl/winsys/cogl-winsys-egl.c         |   2 -
 cogl/cogl/winsys/cogl-winsys-glx.c         |   2 -
 cogl/cogl/winsys/cogl-winsys-private.h     |   6 -
 src/backends/native/meta-onscreen-native.c |  32 +++--
 src/backends/native/meta-onscreen-native.h |   4 -
 src/backends/native/meta-renderer-native.c |   3 -
 14 files changed, 210 insertions(+), 236 deletions(-)
---
diff --git a/cogl/cogl/cogl-onscreen.c b/cogl/cogl/cogl-onscreen.c
index 7ea6db8f29..eff4521dd2 100644
--- a/cogl/cogl/cogl-onscreen.c
+++ b/cogl/cogl/cogl-onscreen.c
@@ -56,8 +56,6 @@ typedef struct _CoglOnscreenPrivate
                                * cogl_onscreen_swap_region() or
                                * cogl_onscreen_swap_buffers() */
   GQueue pending_frame_infos;
-
-  gboolean needs_deinit;
 } CoglOnscreenPrivate;
 
 G_DEFINE_TYPE_WITH_PRIVATE (CoglOnscreen, cogl_onscreen, COGL_TYPE_FRAMEBUFFER)
@@ -92,15 +90,8 @@ cogl_onscreen_allocate (CoglFramebuffer  *framebuffer,
                         GError          **error)
 {
   CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
-  CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen);
-  const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
   CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
 
-  if (!winsys->onscreen_init (onscreen, error))
-    return FALSE;
-
-  priv->needs_deinit = TRUE;
-
   /* If the winsys doesn't support dirty events then we'll report
    * one on allocation so that if the application only paints in
    * response to dirty events then it will at least paint once to
@@ -150,8 +141,6 @@ cogl_onscreen_dispose (GObject *object)
 {
   CoglOnscreen *onscreen = COGL_ONSCREEN (object);
   CoglOnscreenPrivate *priv = cogl_onscreen_get_instance_private (onscreen);
-  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
-  const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
   CoglFrameInfo *frame_info;
 
   _cogl_closure_list_disconnect_all (&priv->resize_closures);
@@ -162,12 +151,6 @@ cogl_onscreen_dispose (GObject *object)
     cogl_object_unref (frame_info);
   g_queue_clear (&priv->pending_frame_infos);
 
-  if (priv->needs_deinit)
-    {
-      winsys->onscreen_deinit (onscreen);
-      priv->needs_deinit = FALSE;
-    }
-
   G_OBJECT_CLASS (cogl_onscreen_parent_class)->dispose (object);
 }
 
@@ -701,4 +684,3 @@ cogl_onscreen_get_frame_counter (CoglOnscreen *onscreen)
 
   return priv->frame_counter;
 }
-
diff --git a/cogl/cogl/winsys/cogl-onscreen-egl.c b/cogl/cogl/winsys/cogl-onscreen-egl.c
index a5710b9b1c..b23b48e297 100644
--- a/cogl/cogl/winsys/cogl-onscreen-egl.c
+++ b/cogl/cogl/winsys/cogl-onscreen-egl.c
@@ -44,13 +44,13 @@ G_DEFINE_TYPE_WITH_PRIVATE (CoglOnscreenEgl, cogl_onscreen_egl,
                             COGL_TYPE_ONSCREEN)
 
 gboolean
-_cogl_winsys_onscreen_egl_init (CoglOnscreen  *onscreen,
-                                GError       **error)
+cogl_onscreen_egl_choose_config (CoglOnscreenEgl  *onscreen_egl,
+                                 EGLConfig        *out_egl_config,
+                                 GError          **error)
 {
-  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen_egl);
   CoglContext *context = cogl_framebuffer_get_context (framebuffer);
   CoglDisplay *display = context->display;
-  CoglDisplayEGL *egl_display = display->winsys;
   CoglRenderer *renderer = display->renderer;
   CoglRendererEGL *egl_renderer = renderer->winsys;
   const CoglFramebufferConfig *config;
@@ -59,8 +59,6 @@ _cogl_winsys_onscreen_egl_init (CoglOnscreen  *onscreen,
   EGLint config_count = 0;
   EGLBoolean status;
 
-  g_return_val_if_fail (egl_display->egl_context, FALSE);
-
   config = cogl_framebuffer_get_config (framebuffer);
   cogl_display_egl_determine_attributes (display, config, attributes);
 
@@ -76,8 +74,6 @@ _cogl_winsys_onscreen_egl_init (CoglOnscreen  *onscreen,
       return FALSE;
     }
 
-  /* Update the real number of samples_per_pixel now that we have
-   * found an egl_config... */
   if (config->samples_per_pixel)
     {
       EGLint samples;
@@ -88,30 +84,23 @@ _cogl_winsys_onscreen_egl_init (CoglOnscreen  *onscreen,
       cogl_framebuffer_update_samples_per_pixel (framebuffer, samples);
     }
 
-  if (egl_renderer->platform_vtable->onscreen_init &&
-      !egl_renderer->platform_vtable->onscreen_init (onscreen,
-                                                     egl_config,
-                                                     error))
-    return FALSE;
-
+  *out_egl_config = egl_config;
   return TRUE;
 }
 
-void
-_cogl_winsys_onscreen_egl_deinit (CoglOnscreen *onscreen)
+static void
+cogl_onscreen_egl_dispose (GObject *object)
 {
-  CoglOnscreenEgl *onscreen_egl = COGL_ONSCREEN_EGL (onscreen);
+  CoglOnscreenEgl *onscreen_egl = COGL_ONSCREEN_EGL (object);
   CoglOnscreenEglPrivate *priv =
     cogl_onscreen_egl_get_instance_private (onscreen_egl);
-  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (object);
   CoglContext *context = cogl_framebuffer_get_context (framebuffer);
   CoglDisplayEGL *egl_display = context->display->winsys;
   CoglRenderer *renderer = context->display->renderer;
   CoglRendererEGL *egl_renderer = renderer->winsys;
 
-  /* If we never successfully allocated then there's nothing to do */
-  if (onscreen_egl == NULL)
-    return;
+  G_OBJECT_CLASS (cogl_onscreen_egl_parent_class)->dispose (object);
 
   if (priv->egl_surface != EGL_NO_SURFACE)
     {
@@ -135,9 +124,6 @@ _cogl_winsys_onscreen_egl_deinit (CoglOnscreen *onscreen)
         g_warning ("Failed to destroy EGL surface");
       priv->egl_surface = EGL_NO_SURFACE;
     }
-
-  if (egl_renderer->platform_vtable->onscreen_deinit)
-    egl_renderer->platform_vtable->onscreen_deinit (onscreen);
 }
 
 static gboolean
@@ -365,4 +351,7 @@ cogl_onscreen_egl_init (CoglOnscreenEgl *onscreen_egl)
 static void
 cogl_onscreen_egl_class_init (CoglOnscreenEglClass *klass)
 {
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->dispose = cogl_onscreen_egl_dispose;
 }
diff --git a/cogl/cogl/winsys/cogl-onscreen-egl.h b/cogl/cogl/winsys/cogl-onscreen-egl.h
index 4f2ae458dc..fab854a693 100644
--- a/cogl/cogl/winsys/cogl-onscreen-egl.h
+++ b/cogl/cogl/winsys/cogl-onscreen-egl.h
@@ -41,13 +41,6 @@ struct _CoglOnscreenEglClass
   CoglOnscreenClass parent_class;
 };
 
-gboolean
-_cogl_winsys_onscreen_egl_init (CoglOnscreen  *onscreen,
-                                GError       **error);
-
-void
-_cogl_winsys_onscreen_egl_deinit (CoglOnscreen *onscreen);
-
 void
 _cogl_winsys_onscreen_egl_bind (CoglOnscreen *onscreen);
 
@@ -82,4 +75,9 @@ cogl_onscreen_egl_set_egl_surface (CoglOnscreenEgl *onscreen_egl,
 COGL_EXPORT EGLSurface
 cogl_onscreen_egl_get_egl_surface (CoglOnscreenEgl *onscreen_egl);
 
+gboolean
+cogl_onscreen_egl_choose_config (CoglOnscreenEgl  *onscreen_egl,
+                                 EGLConfig        *out_egl_config,
+                                 GError          **error);
+
 #endif /* COGL_ONSCREEN_EGL_H */
diff --git a/cogl/cogl/winsys/cogl-onscreen-glx.c b/cogl/cogl/winsys/cogl-onscreen-glx.c
index 5331e828e4..7f9e566a08 100644
--- a/cogl/cogl/winsys/cogl-onscreen-glx.c
+++ b/cogl/cogl/winsys/cogl-onscreen-glx.c
@@ -58,12 +58,11 @@ G_DEFINE_TYPE (CoglOnscreenGlx, cogl_onscreen_glx,
 
 #define COGL_ONSCREEN_X11_EVENT_MASK (StructureNotifyMask | ExposureMask)
 
-gboolean
-_cogl_winsys_onscreen_glx_init (CoglOnscreen  *onscreen,
-                                GError       **error)
+static gboolean
+cogl_onscreen_glx_allocate (CoglFramebuffer  *framebuffer,
+                            GError          **error)
 {
-  CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen);
-  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (framebuffer);
   CoglContext *context = cogl_framebuffer_get_context (framebuffer);
   CoglDisplay *display = context->display;
   CoglGLXDisplay *glx_display = display->winsys;
@@ -205,11 +204,11 @@ _cogl_winsys_onscreen_glx_init (CoglOnscreen  *onscreen,
   return TRUE;
 }
 
-void
-_cogl_winsys_onscreen_glx_deinit (CoglOnscreen *onscreen)
+static void
+cogl_onscreen_glx_dispose (GObject *object)
 {
-  CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (onscreen);
-  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  CoglOnscreenGlx *onscreen_glx = COGL_ONSCREEN_GLX (object);
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (object);
   CoglContext *context = cogl_framebuffer_get_context (framebuffer);
   CoglGLXDisplay *glx_display = context->display->winsys;
   CoglXlibRenderer *xlib_renderer =
@@ -218,56 +217,59 @@ _cogl_winsys_onscreen_glx_deinit (CoglOnscreen *onscreen)
   CoglXlibTrapState old_state;
   GLXDrawable drawable;
 
-  /* If we never successfully allocated then there's nothing to do */
-  if (onscreen_glx == NULL)
-    return;
+  G_OBJECT_CLASS (cogl_onscreen_glx_parent_class)->dispose (object);
 
   cogl_clear_object (&onscreen_glx->output);
 
-  _cogl_xlib_renderer_trap_errors (context->display->renderer, &old_state);
-
-  drawable =
-    onscreen_glx->glxwin == None ? onscreen_glx->xwin : onscreen_glx->glxwin;
-
-  /* Cogl always needs a valid context bound to something so if we are
-   * destroying the onscreen that is currently bound we'll switch back
-   * to the dummy drawable. Although the documentation for
-   * glXDestroyWindow states that a currently bound window won't
-   * actually be destroyed until it is unbound, it looks like this
-   * doesn't work if the X window itself is destroyed */
-  if (drawable == cogl_context_glx_get_current_drawable (context))
+  if (onscreen_glx->glxwin != None ||
+      onscreen_glx->xwin != None)
     {
-      GLXDrawable dummy_drawable = (glx_display->dummy_glxwin == None ?
-                                    glx_display->dummy_xwin :
-                                    glx_display->dummy_glxwin);
-
-      glx_renderer->glXMakeContextCurrent (xlib_renderer->xdpy,
-                                           dummy_drawable,
-                                           dummy_drawable,
-                                           glx_display->glx_context);
-      cogl_context_glx_set_current_drawable (context, dummy_drawable);
-    }
+      _cogl_xlib_renderer_trap_errors (context->display->renderer, &old_state);
 
-  if (onscreen_glx->glxwin != None)
-    {
-      glx_renderer->glXDestroyWindow (xlib_renderer->xdpy,
-                                      onscreen_glx->glxwin);
-      onscreen_glx->glxwin = None;
-    }
+      drawable =
+        onscreen_glx->glxwin == None ? onscreen_glx->xwin : onscreen_glx->glxwin;
+
+      /* Cogl always needs a valid context bound to something so if we are
+       * destroying the onscreen that is currently bound we'll switch back
+       * to the dummy drawable. Although the documentation for
+       * glXDestroyWindow states that a currently bound window won't
+       * actually be destroyed until it is unbound, it looks like this
+       * doesn't work if the X window itself is destroyed */
+      if (drawable == cogl_context_glx_get_current_drawable (context))
+        {
+          GLXDrawable dummy_drawable = (glx_display->dummy_glxwin == None ?
+                                        glx_display->dummy_xwin :
+                                        glx_display->dummy_glxwin);
+
+          glx_renderer->glXMakeContextCurrent (xlib_renderer->xdpy,
+                                               dummy_drawable,
+                                               dummy_drawable,
+                                               glx_display->glx_context);
+          cogl_context_glx_set_current_drawable (context, dummy_drawable);
+        }
 
-  if (onscreen_glx->xwin != None)
-    {
-      XDestroyWindow (xlib_renderer->xdpy, onscreen_glx->xwin);
-      onscreen_glx->xwin = None;
-    }
-  else
-    {
-      onscreen_glx->xwin = None;
-    }
+      if (onscreen_glx->glxwin != None)
+        {
+          glx_renderer->glXDestroyWindow (xlib_renderer->xdpy,
+                                          onscreen_glx->glxwin);
+          onscreen_glx->glxwin = None;
+        }
 
-  XSync (xlib_renderer->xdpy, False);
+      if (onscreen_glx->xwin != None)
+        {
+          XDestroyWindow (xlib_renderer->xdpy, onscreen_glx->xwin);
+          onscreen_glx->xwin = None;
+        }
+      else
+        {
+          onscreen_glx->xwin = None;
+        }
+
+      XSync (xlib_renderer->xdpy, False);
 
-  _cogl_xlib_renderer_untrap_errors (context->display->renderer, &old_state);
+      _cogl_xlib_renderer_untrap_errors (context->display->renderer,
+                                         &old_state);
+    }
 }
 
 void
@@ -1142,4 +1144,10 @@ cogl_onscreen_glx_init (CoglOnscreenGlx *onscreen_glx)
 static void
 cogl_onscreen_glx_class_init (CoglOnscreenGlxClass *klass)
 {
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  CoglFramebufferClass *framebuffer_class = COGL_FRAMEBUFFER_CLASS (klass);
+
+  object_class->dispose = cogl_onscreen_glx_dispose;
+
+  framebuffer_class->allocate = cogl_onscreen_glx_allocate;
 }
diff --git a/cogl/cogl/winsys/cogl-onscreen-glx.h b/cogl/cogl/winsys/cogl-onscreen-glx.h
index 75454ae926..8b10e39692 100644
--- a/cogl/cogl/winsys/cogl-onscreen-glx.h
+++ b/cogl/cogl/winsys/cogl-onscreen-glx.h
@@ -41,13 +41,6 @@ cogl_onscreen_glx_new (CoglContext *context,
                        int          width,
                        int          height);
 
-gboolean
-_cogl_winsys_onscreen_glx_init (CoglOnscreen  *onscreen,
-                                GError       **error);
-
-void
-_cogl_winsys_onscreen_glx_deinit (CoglOnscreen *onscreen);
-
 void
 _cogl_winsys_onscreen_glx_bind (CoglOnscreen *onscreen);
 
diff --git a/cogl/cogl/winsys/cogl-onscreen-xlib.c b/cogl/cogl/winsys/cogl-onscreen-xlib.c
index b1d1aac6c6..97540639a1 100644
--- a/cogl/cogl/winsys/cogl-onscreen-xlib.c
+++ b/cogl/cogl/winsys/cogl-onscreen-xlib.c
@@ -48,94 +48,109 @@ G_DEFINE_TYPE (CoglOnscreenXlib, cogl_onscreen_xlib,
 
 #define COGL_ONSCREEN_X11_EVENT_MASK (StructureNotifyMask | ExposureMask)
 
-gboolean
-_cogl_winsys_egl_onscreen_xlib_init (CoglOnscreen  *onscreen,
-                                     EGLConfig      egl_config,
-                                     GError       **error)
+
+static Window
+create_xwindow (CoglOnscreenXlib  *onscreen_xlib,
+                EGLConfig          egl_config,
+                GError           **error)
 {
-  CoglOnscreenXlib *onscreen_xlib = COGL_ONSCREEN_XLIB (onscreen);;
+  CoglOnscreen *onscreen = COGL_ONSCREEN (onscreen_xlib);
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
   CoglContext *context = cogl_framebuffer_get_context (framebuffer);
   CoglDisplay *display = context->display;
   CoglRenderer *renderer = display->renderer;
-  CoglRendererEGL *egl_renderer = renderer->winsys;
   CoglXlibRenderer *xlib_renderer =
     _cogl_xlib_renderer_get_data (renderer);
-  CoglOnscreenEgl *onscreen_egl = COGL_ONSCREEN_EGL (onscreen);
   Window xwin;
-  EGLSurface egl_surface;
+  int width;
+  int height;
+  CoglXlibTrapState state;
+  XVisualInfo *xvisinfo;
+  XSetWindowAttributes xattr;
+  unsigned long mask;
+  int xerror;
+
+  width = cogl_framebuffer_get_width (framebuffer);
+  height = cogl_framebuffer_get_height (framebuffer);
 
-  /* FIXME: We need to explicitly Select for ConfigureNotify events.
-   * We need to document that for windows we create then toolkits
-   * must be careful not to clear event mask bits that we select.
-   */
+  _cogl_xlib_renderer_trap_errors (display->renderer, &state);
 
+  xvisinfo = cogl_display_xlib_get_visual_info (display, egl_config);
+  if (xvisinfo == NULL)
     {
-      int width;
-      int height;
-      CoglXlibTrapState state;
-      XVisualInfo *xvisinfo;
-      XSetWindowAttributes xattr;
-      unsigned long mask;
-      int xerror;
+      g_set_error (error, COGL_WINSYS_ERROR,
+                   COGL_WINSYS_ERROR_CREATE_ONSCREEN,
+                   "Unable to retrieve the X11 visual of context's "
+                   "fbconfig");
+      return None;
+    }
 
-      width = cogl_framebuffer_get_width (framebuffer);
-      height = cogl_framebuffer_get_height (framebuffer);
+  /* window attributes */
+  xattr.background_pixel =
+    WhitePixel (xlib_renderer->xdpy,
+                DefaultScreen (xlib_renderer->xdpy));
+  xattr.border_pixel = 0;
+  /* XXX: is this an X resource that we are leaking‽... */
+  xattr.colormap =
+    XCreateColormap (xlib_renderer->xdpy,
+                     DefaultRootWindow (xlib_renderer->xdpy),
+                     xvisinfo->visual,
+                     AllocNone);
+  xattr.event_mask = COGL_ONSCREEN_X11_EVENT_MASK;
+
+  mask = CWBorderPixel | CWColormap | CWEventMask;
+
+  xwin = XCreateWindow (xlib_renderer->xdpy,
+                        DefaultRootWindow (xlib_renderer->xdpy),
+                        0, 0,
+                        width, height,
+                        0,
+                        xvisinfo->depth,
+                        InputOutput,
+                        xvisinfo->visual,
+                        mask, &xattr);
+
+  XFree (xvisinfo);
 
-      _cogl_xlib_renderer_trap_errors (display->renderer, &state);
+  XSync (xlib_renderer->xdpy, False);
+  xerror =
+    _cogl_xlib_renderer_untrap_errors (display->renderer, &state);
+  if (xerror)
+    {
+      char message[1000];
+      XGetErrorText (xlib_renderer->xdpy, xerror,
+                     message, sizeof (message));
+      g_set_error (error, COGL_WINSYS_ERROR,
+                   COGL_WINSYS_ERROR_CREATE_ONSCREEN,
+                   "X error while creating Window for CoglOnscreen: %s",
+                   message);
+      return None;
+    }
 
-      xvisinfo = cogl_display_xlib_get_visual_info (display, egl_config);
-      if (xvisinfo == NULL)
-        {
-          g_set_error (error, COGL_WINSYS_ERROR,
-                       COGL_WINSYS_ERROR_CREATE_ONSCREEN,
-                       "Unable to retrieve the X11 visual of context's "
-                       "fbconfig");
-          return FALSE;
-        }
+  return xwin;
+}
 
-      /* window attributes */
-      xattr.background_pixel =
-        WhitePixel (xlib_renderer->xdpy,
-                    DefaultScreen (xlib_renderer->xdpy));
-      xattr.border_pixel = 0;
-      /* XXX: is this an X resource that we are leaking‽... */
-      xattr.colormap =
-        XCreateColormap (xlib_renderer->xdpy,
-                         DefaultRootWindow (xlib_renderer->xdpy),
-                         xvisinfo->visual,
-                         AllocNone);
-      xattr.event_mask = COGL_ONSCREEN_X11_EVENT_MASK;
-
-      mask = CWBorderPixel | CWColormap | CWEventMask;
-
-      xwin = XCreateWindow (xlib_renderer->xdpy,
-                            DefaultRootWindow (xlib_renderer->xdpy),
-                            0, 0,
-                            width, height,
-                            0,
-                            xvisinfo->depth,
-                            InputOutput,
-                            xvisinfo->visual,
-                            mask, &xattr);
-
-      XFree (xvisinfo);
+static gboolean
+cogl_onscreen_xlib_allocate (CoglFramebuffer  *framebuffer,
+                             GError          **error)
+{
+  CoglOnscreenXlib *onscreen_xlib = COGL_ONSCREEN_XLIB (framebuffer);
+  CoglOnscreenEgl *onscreen_egl = COGL_ONSCREEN_EGL (framebuffer);
+  CoglContext *context = cogl_framebuffer_get_context (framebuffer);
+  CoglDisplay *display = context->display;
+  CoglRenderer *renderer = display->renderer;
+  CoglRendererEGL *egl_renderer = renderer->winsys;
+  EGLConfig egl_config;
+  Window xwin;
+  EGLSurface egl_surface;
+  CoglFramebufferClass *parent_class;
 
-      XSync (xlib_renderer->xdpy, False);
-      xerror =
-        _cogl_xlib_renderer_untrap_errors (display->renderer, &state);
-      if (xerror)
-        {
-          char message[1000];
-          XGetErrorText (xlib_renderer->xdpy, xerror,
-                         message, sizeof (message));
-          g_set_error (error, COGL_WINSYS_ERROR,
-                       COGL_WINSYS_ERROR_CREATE_ONSCREEN,
-                       "X error while creating Window for CoglOnscreen: %s",
-                       message);
-          return FALSE;
-        }
-    }
+  if (!cogl_onscreen_egl_choose_config (onscreen_egl, &egl_config, error))
+    return FALSE;
+
+  xwin = create_xwindow (onscreen_xlib, egl_config, error);
+  if (xwin == None)
+    return FALSE;
 
   onscreen_xlib->xwin = xwin;
 
@@ -147,35 +162,38 @@ _cogl_winsys_egl_onscreen_xlib_init (CoglOnscreen  *onscreen,
   cogl_onscreen_egl_set_egl_surface (onscreen_egl,
                                      egl_surface);
 
-  return TRUE;
+  parent_class = COGL_FRAMEBUFFER_CLASS (cogl_onscreen_xlib_parent_class);
+  return parent_class->allocate (framebuffer, error);
 }
 
-void
-_cogl_winsys_egl_onscreen_xlib_deinit (CoglOnscreen *onscreen)
+static void
+cogl_onscreen_xlib_dispose (GObject *object)
 {
-  CoglOnscreenXlib *onscreen_xlib = COGL_ONSCREEN_XLIB (onscreen);
-  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
-  CoglContext *context = cogl_framebuffer_get_context (framebuffer);
-  CoglRenderer *renderer = context->display->renderer;
-  CoglXlibRenderer *xlib_renderer =
-    _cogl_xlib_renderer_get_data (renderer);
-  CoglXlibTrapState old_state;
+  CoglOnscreenXlib *onscreen_xlib = COGL_ONSCREEN_XLIB (object);
 
-  _cogl_xlib_renderer_trap_errors (renderer, &old_state);
+  G_OBJECT_CLASS (cogl_onscreen_xlib_parent_class)->dispose (object);
 
   if (onscreen_xlib->xwin != None)
     {
+      CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (object);
+      CoglContext *context = cogl_framebuffer_get_context (framebuffer);
+      CoglRenderer *renderer = context->display->renderer;
+      CoglXlibRenderer *xlib_renderer =
+        _cogl_xlib_renderer_get_data (renderer);
+      CoglXlibTrapState old_state;
+
+      _cogl_xlib_renderer_trap_errors (renderer, &old_state);
+
       XDestroyWindow (xlib_renderer->xdpy, onscreen_xlib->xwin);
       onscreen_xlib->xwin = None;
-    }
-  else
-    onscreen_xlib->xwin = None;
+      XSync (xlib_renderer->xdpy, False);
 
-  XSync (xlib_renderer->xdpy, False);
+      if (_cogl_xlib_renderer_untrap_errors (renderer,
+                                             &old_state) != Success)
+        g_warning ("X Error while destroying X window");
 
-  if (_cogl_xlib_renderer_untrap_errors (renderer,
-                                         &old_state) != Success)
-    g_warning ("X Error while destroying X window");
+      onscreen_xlib->xwin = None;
+    }
 }
 
 void
@@ -335,4 +353,10 @@ cogl_onscreen_xlib_init (CoglOnscreenXlib *onscreen_xlib)
 static void
 cogl_onscreen_xlib_class_init (CoglOnscreenXlibClass *klass)
 {
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  CoglFramebufferClass *framebuffer_class = COGL_FRAMEBUFFER_CLASS (klass);
+
+  object_class->dispose = cogl_onscreen_xlib_dispose;
+
+  framebuffer_class->allocate = cogl_onscreen_xlib_allocate;
 }
diff --git a/cogl/cogl/winsys/cogl-winsys-egl-private.h b/cogl/cogl/winsys/cogl-winsys-egl-private.h
index 7f8b550502..9d6fa5cfb2 100644
--- a/cogl/cogl/winsys/cogl-winsys-egl-private.h
+++ b/cogl/cogl/winsys/cogl-winsys-egl-private.h
@@ -79,13 +79,6 @@ typedef struct _CoglWinsysEGLVtable
   void
   (* context_deinit) (CoglContext *context);
 
-  gboolean
-  (* onscreen_init) (CoglOnscreen *onscreen,
-                     EGLConfig config,
-                     GError **error);
-  void
-  (* onscreen_deinit) (CoglOnscreen *onscreen);
-
   int
   (* add_config_attributes) (CoglDisplay                 *display,
                              const CoglFramebufferConfig *config,
diff --git a/cogl/cogl/winsys/cogl-winsys-egl-x11.c b/cogl/cogl/winsys/cogl-winsys-egl-x11.c
index 63871d7085..1113fb1999 100644
--- a/cogl/cogl/winsys/cogl-winsys-egl-x11.c
+++ b/cogl/cogl/winsys/cogl-winsys-egl-x11.c
@@ -567,8 +567,6 @@ _cogl_winsys_egl_vtable =
     .cleanup_context = _cogl_winsys_egl_cleanup_context,
     .context_init = _cogl_winsys_egl_context_init,
     .context_deinit = _cogl_winsys_egl_context_deinit,
-    .onscreen_init = _cogl_winsys_egl_onscreen_xlib_init,
-    .onscreen_deinit = _cogl_winsys_egl_onscreen_xlib_deinit
   };
 
 COGL_EXPORT const CoglWinsysVtable *
diff --git a/cogl/cogl/winsys/cogl-winsys-egl.c b/cogl/cogl/winsys/cogl-winsys-egl.c
index 87ea8bb067..8a563aca35 100644
--- a/cogl/cogl/winsys/cogl-winsys-egl.c
+++ b/cogl/cogl/winsys/cogl-winsys-egl.c
@@ -636,8 +636,6 @@ static CoglWinsysVtable _cogl_winsys_vtable =
     .display_destroy = _cogl_winsys_display_destroy,
     .context_init = _cogl_winsys_context_init,
     .context_deinit = _cogl_winsys_context_deinit,
-    .onscreen_init = _cogl_winsys_onscreen_egl_init,
-    .onscreen_deinit = _cogl_winsys_onscreen_egl_deinit,
     .onscreen_bind = _cogl_winsys_onscreen_egl_bind,
     .onscreen_swap_buffers_with_damage =
       _cogl_winsys_onscreen_egl_swap_buffers_with_damage,
diff --git a/cogl/cogl/winsys/cogl-winsys-glx.c b/cogl/cogl/winsys/cogl-winsys-glx.c
index 160cf71e52..97d92e0cdd 100644
--- a/cogl/cogl/winsys/cogl-winsys-glx.c
+++ b/cogl/cogl/winsys/cogl-winsys-glx.c
@@ -1469,8 +1469,6 @@ static CoglWinsysVtable _cogl_winsys_vtable =
     .context_init = _cogl_winsys_context_init,
     .context_deinit = _cogl_winsys_context_deinit,
     .context_get_clock_time = _cogl_winsys_get_clock_time,
-    .onscreen_init = _cogl_winsys_onscreen_glx_init,
-    .onscreen_deinit = _cogl_winsys_onscreen_glx_deinit,
     .onscreen_bind = _cogl_winsys_onscreen_glx_bind,
     .onscreen_swap_buffers_with_damage =
       _cogl_winsys_onscreen_glx_swap_buffers_with_damage,
diff --git a/cogl/cogl/winsys/cogl-winsys-private.h b/cogl/cogl/winsys/cogl-winsys-private.h
index 9af682bc88..95ff65237b 100644
--- a/cogl/cogl/winsys/cogl-winsys-private.h
+++ b/cogl/cogl/winsys/cogl-winsys-private.h
@@ -104,12 +104,6 @@ typedef struct _CoglWinsysVtable
   void
   (*context_deinit) (CoglContext *context);
 
-  gboolean
-  (*onscreen_init) (CoglOnscreen *onscreen, GError **error);
-
-  void
-  (*onscreen_deinit) (CoglOnscreen *onscreen);
-
   void
   (*onscreen_bind) (CoglOnscreen *onscreen);
 
diff --git a/src/backends/native/meta-onscreen-native.c b/src/backends/native/meta-onscreen-native.c
index 8f7b11d7c4..45bd769bcb 100644
--- a/src/backends/native/meta-onscreen-native.c
+++ b/src/backends/native/meta-onscreen-native.c
@@ -1667,13 +1667,13 @@ meta_onscreen_native_set_view (CoglOnscreen     *onscreen,
   onscreen_native->view = view;
 }
 
-gboolean
-meta_renderer_native_init_onscreen (CoglOnscreen *onscreen,
-                                    GError      **error)
+static gboolean
+meta_onscreen_native_allocate (CoglFramebuffer  *framebuffer,
+                               GError          **error)
 {
+  CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
   MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (onscreen);
   CoglOnscreenEgl *onscreen_egl = COGL_ONSCREEN_EGL (onscreen);
-  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
   MetaRendererNativeGpuData *renderer_gpu_data;
   struct gbm_surface *gbm_surface;
   EGLSurface egl_surface;
@@ -1683,6 +1683,7 @@ meta_renderer_native_init_onscreen (CoglOnscreen *onscreen,
   MetaKmsDevice *render_kms_device;
   EGLStreamKHR egl_stream;
 #endif
+  CoglFramebufferClass *parent_class;
 
   if (META_GPU_KMS (meta_crtc_get_gpu (onscreen_native->crtc)) !=
       onscreen_native->render_gpu)
@@ -1736,7 +1737,8 @@ meta_renderer_native_init_onscreen (CoglOnscreen *onscreen,
 #endif /* HAVE_EGL_DEVICE */
     }
 
-  return TRUE;
+  parent_class = COGL_FRAMEBUFFER_CLASS (meta_onscreen_native_parent_class);
+  return parent_class->allocate (framebuffer, error);
 }
 
 static gboolean
@@ -2017,10 +2019,11 @@ destroy_egl_surface (CoglOnscreen *onscreen)
     }
 }
 
-void
-meta_renderer_native_release_onscreen (CoglOnscreen *onscreen)
+static void
+meta_onscreen_native_dispose (GObject *object)
 {
-  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (object);
+  CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
   CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer);
   CoglDisplay *cogl_display = cogl_context_get_display (cogl_context);
   CoglDisplayEGL *cogl_display_egl = cogl_display->winsys;
@@ -2030,6 +2033,7 @@ meta_renderer_native_release_onscreen (CoglOnscreen *onscreen)
   MetaRendererNativeGpuData *renderer_gpu_data;
   EGLSurface egl_surface;
 
+  G_OBJECT_CLASS (meta_onscreen_native_parent_class)->dispose (object);
 
   egl_surface = cogl_onscreen_egl_get_egl_surface (onscreen_egl);
   if (egl_surface != EGL_NO_SURFACE &&
@@ -2057,11 +2061,7 @@ meta_renderer_native_release_onscreen (CoglOnscreen *onscreen)
 
       destroy_egl_surface (onscreen);
 
-      if (onscreen_native->gbm.surface)
-        {
-          gbm_surface_destroy (onscreen_native->gbm.surface);
-          onscreen_native->gbm.surface = NULL;
-        }
+      g_clear_pointer (&onscreen_native->gbm.surface, gbm_surface_destroy);
       break;
 #ifdef HAVE_EGL_DEVICE
     case META_RENDERER_NATIVE_MODE_EGL_DEVICE:
@@ -2097,4 +2097,10 @@ meta_onscreen_native_init (MetaOnscreenNative *onscreen_native)
 static void
 meta_onscreen_native_class_init (MetaOnscreenNativeClass *klass)
 {
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  CoglFramebufferClass *framebuffer_class = COGL_FRAMEBUFFER_CLASS (klass);
+
+  object_class->dispose = meta_onscreen_native_dispose;
+
+  framebuffer_class->allocate = meta_onscreen_native_allocate;
 }
diff --git a/src/backends/native/meta-onscreen-native.h b/src/backends/native/meta-onscreen-native.h
index f47355431a..92892d63dc 100644
--- a/src/backends/native/meta-onscreen-native.h
+++ b/src/backends/native/meta-onscreen-native.h
@@ -33,10 +33,6 @@ G_DECLARE_FINAL_TYPE (MetaOnscreenNative, meta_onscreen_native,
                       META, ONSCREEN_NATIVE,
                       CoglOnscreenEgl)
 
-gboolean
-meta_renderer_native_init_onscreen (CoglOnscreen *onscreen,
-                                    GError      **error);
-
 void meta_renderer_native_release_onscreen (CoglOnscreen *onscreen);
 
 void meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen  *onscreen,
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
index c67dd0de13..eda59a69cc 100644
--- a/src/backends/native/meta-renderer-native.c
+++ b/src/backends/native/meta-renderer-native.c
@@ -940,9 +940,6 @@ get_native_cogl_winsys_vtable (CoglRenderer *cogl_renderer)
       vtable.renderer_disconnect = meta_renderer_native_disconnect;
       vtable.renderer_create_dma_buf = meta_renderer_native_create_dma_buf;
 
-      vtable.onscreen_init = meta_renderer_native_init_onscreen;
-      vtable.onscreen_deinit = meta_renderer_native_release_onscreen;
-
       /* The KMS winsys doesn't support swap region */
       vtable.onscreen_swap_region = NULL;
       vtable.onscreen_swap_buffers_with_damage =


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