[mutter] cogl: Init framebuffer driver up front



commit d136c6510bcc6db1c76ac9843d0fa22b016b9806
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Mon Oct 19 17:53:56 2020 +0200

    cogl: Init framebuffer driver up front
    
    The framebuffer driver was lazilly initialized on demand in some cases
    (onscreen), and up front other (offscreen). Replace this with a more
    predictable up front initialization, done at framebuffer allocation.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1514>

 cogl/cogl/cogl-driver.h                            |  12 +-
 cogl/cogl/cogl-framebuffer-private.h               |  15 ++-
 cogl/cogl/cogl-framebuffer.c                       |  75 +++++++----
 cogl/cogl/cogl-framebuffer.h                       |   2 +
 cogl/cogl/cogl-offscreen.c                         |  29 ++---
 cogl/cogl/driver/gl/cogl-framebuffer-gl-private.h  |   3 -
 cogl/cogl/driver/gl/cogl-framebuffer-gl.c          | 141 ++++++++++-----------
 cogl/cogl/driver/gl/cogl-util-gl-private.h         |   6 +
 cogl/cogl/driver/gl/cogl-util-gl.c                 |   3 +-
 cogl/cogl/driver/gl/gl/cogl-driver-gl.c            |   3 +-
 cogl/cogl/driver/gl/gles/cogl-driver-gles.c        |   3 +-
 cogl/cogl/driver/nop/cogl-driver-nop.c             |  15 ++-
 .../cogl/driver/nop/cogl-framebuffer-nop-private.h |   8 --
 cogl/cogl/driver/nop/cogl-framebuffer-nop.c        |  13 --
 cogl/cogl/driver/nop/cogl-nop-framebuffer.c        |  46 +++++++
 cogl/cogl/driver/nop/cogl-nop-framebuffer.h        |  36 ++++++
 cogl/cogl/meson.build                              |   2 +
 17 files changed, 250 insertions(+), 162 deletions(-)
---
diff --git a/cogl/cogl/cogl-driver.h b/cogl/cogl/cogl-driver.h
index 5e07eb5b87..e2cf989279 100644
--- a/cogl/cogl/cogl-driver.h
+++ b/cogl/cogl/cogl-driver.h
@@ -73,13 +73,11 @@ struct _CoglDriverVtable
   (* update_features) (CoglContext *context,
                        GError **error);
 
-  gboolean
-  (* offscreen_allocate) (CoglOffscreen       *offscreen,
-                          CoglOffscreenFlags   flags,
-                          GError             **error);
-
-  void
-  (* offscreen_free) (CoglOffscreen *offscreen);
+  CoglFramebufferDriver *
+  (* create_framebuffer_driver) (CoglContext                        *context,
+                                 CoglFramebuffer                    *framebuffer,
+                                 const CoglFramebufferDriverConfig  *driver_config,
+                                 GError                            **error);
 
   void
   (* flush_framebuffer_state) (CoglContext          *context,
diff --git a/cogl/cogl/cogl-framebuffer-private.h b/cogl/cogl/cogl-framebuffer-private.h
index 1d8f471d3d..f00a5bc4b8 100644
--- a/cogl/cogl/cogl-framebuffer-private.h
+++ b/cogl/cogl/cogl-framebuffer-private.h
@@ -32,6 +32,7 @@
 #ifndef __COGL_FRAMEBUFFER_PRIVATE_H
 #define __COGL_FRAMEBUFFER_PRIVATE_H
 
+#include "cogl-framebuffer-driver.h"
 #include "cogl-object-private.h"
 #include "cogl-matrix-stack-private.h"
 #include "cogl-journal-private.h"
@@ -39,6 +40,11 @@
 #include "cogl-attribute-private.h"
 #include "cogl-clip-stack.h"
 
+struct _CoglFramebufferDriverConfig
+{
+  gboolean disable_depth_and_stencil;
+};
+
 typedef struct
 {
   CoglSwapChain *swap_chain;
@@ -293,12 +299,7 @@ _cogl_framebuffer_get_stencil_bits (CoglFramebuffer *framebuffer);
 CoglJournal *
 cogl_framebuffer_get_journal (CoglFramebuffer *framebuffer);
 
-gpointer
-cogl_framebuffer_get_driver_private (CoglFramebuffer *framebuffer);
-
-void
-cogl_framebuffer_set_driver_private (CoglFramebuffer *framebuffer,
-                                     gpointer         driver_private,
-                                     GDestroyNotify   desrtoy_notify);
+CoglFramebufferDriver *
+cogl_framebuffer_get_driver (CoglFramebuffer *framebuffer);
 
 #endif /* __COGL_FRAMEBUFFER_PRIVATE_H */
diff --git a/cogl/cogl/cogl-framebuffer.c b/cogl/cogl/cogl-framebuffer.c
index cf73551033..b83c3c19af 100644
--- a/cogl/cogl/cogl-framebuffer.c
+++ b/cogl/cogl/cogl-framebuffer.c
@@ -58,6 +58,7 @@ enum
   PROP_0,
 
   PROP_CONTEXT,
+  PROP_DRIVER_CONFIG,
   PROP_WIDTH,
   PROP_HEIGHT,
 
@@ -86,6 +87,9 @@ typedef struct _CoglFramebufferPrivate
   /* The user configuration before allocation... */
   CoglFramebufferConfig config;
 
+  CoglFramebufferDriverConfig driver_config;
+  CoglFramebufferDriver *driver;
+
   int width;
   int height;
   /* Format of the pixels in the framebuffer (including the expected
@@ -139,9 +143,6 @@ typedef struct _CoglFramebufferPrivate
  * usually means it needs to be cleared before being reused next.
  */
   gboolean depth_buffer_clear_needed;
-
-  gpointer driver_private;
-  GDestroyNotify driver_private_destroy;
 } CoglFramebufferPrivate;
 
 G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (CoglFramebuffer, cogl_framebuffer,
@@ -174,6 +175,9 @@ cogl_framebuffer_get_property (GObject    *object,
     case PROP_CONTEXT:
       g_value_set_boxed (value, priv->context);
       break;
+    case PROP_DRIVER_CONFIG:
+      g_value_set_pointer (value, &priv->driver_config);
+      break;
     case PROP_WIDTH:
       g_value_set_int (value, priv->width);
       break;
@@ -194,12 +198,18 @@ cogl_framebuffer_set_property (GObject      *object,
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (object);
   CoglFramebufferPrivate *priv =
     cogl_framebuffer_get_instance_private (framebuffer);
+  CoglFramebufferDriverConfig *driver_config;
 
   switch (prop_id)
     {
     case PROP_CONTEXT:
       priv->context = g_value_get_boxed (value);
       break;
+    case PROP_DRIVER_CONFIG:
+      driver_config = g_value_get_pointer (value);
+      if (driver_config)
+        priv->driver_config = *driver_config;
+      break;
     case PROP_WIDTH:
       priv->width = g_value_get_int (value);
       break;
@@ -343,10 +353,7 @@ cogl_framebuffer_dispose (GObject *object)
   if (ctx->current_read_buffer == framebuffer)
     ctx->current_read_buffer = NULL;
 
-  if (priv->driver_private_destroy)
-    priv->driver_private_destroy (priv->driver_private);
-  priv->driver_private = NULL;
-  priv->driver_private_destroy = NULL;
+  g_clear_object (&priv->driver);
 }
 
 static void
@@ -377,6 +384,13 @@ cogl_framebuffer_class_init (CoglFramebufferClass *klass)
                         G_PARAM_READWRITE |
                         G_PARAM_CONSTRUCT_ONLY |
                         G_PARAM_STATIC_STRINGS);
+  obj_props[PROP_DRIVER_CONFIG] =
+    g_param_spec_pointer ("driver-config",
+                          "driver-config",
+                          "CoglFramebufferDriverConfig",
+                          G_PARAM_READWRITE |
+                          G_PARAM_CONSTRUCT_ONLY |
+                          G_PARAM_STATIC_STRINGS);
   obj_props[PROP_WIDTH] =
     g_param_spec_int ("width",
                       "width",
@@ -901,17 +915,42 @@ cogl_framebuffer_is_allocated (CoglFramebuffer *framebuffer)
   return priv->allocated;
 }
 
+static gboolean
+cogl_framebuffer_init_driver (CoglFramebuffer  *framebuffer,
+                              GError          **error)
+
+{
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+  const CoglDriverVtable *driver_vtable = priv->context->driver_vtable;
+  CoglFramebufferDriver *driver;
+
+  driver = driver_vtable->create_framebuffer_driver (priv->context,
+                                                     framebuffer,
+                                                     &priv->driver_config,
+                                                     error);
+  if (!driver)
+    return FALSE;
+
+  priv->driver = driver;
+  return TRUE;
+}
+
 gboolean
 cogl_framebuffer_allocate (CoglFramebuffer *framebuffer,
                            GError **error)
 {
   CoglFramebufferPrivate *priv =
     cogl_framebuffer_get_instance_private (framebuffer);
+  CoglFramebufferClass *klass = COGL_FRAMEBUFFER_GET_CLASS (framebuffer);
 
   if (priv->allocated)
     return TRUE;
 
-  if (!COGL_FRAMEBUFFER_GET_CLASS (framebuffer)->allocate (framebuffer, error))
+  if (!klass->allocate (framebuffer, error))
+    return FALSE;
+
+  if (!cogl_framebuffer_init_driver (framebuffer, error))
     return FALSE;
 
   priv->allocated = TRUE;
@@ -2652,25 +2691,11 @@ cogl_framebuffer_draw_textured_rectangles (CoglFramebuffer *framebuffer,
                                                    n_rectangles);
 }
 
-gpointer
-cogl_framebuffer_get_driver_private (CoglFramebuffer *framebuffer)
-{
-  CoglFramebufferPrivate *priv =
-    cogl_framebuffer_get_instance_private (framebuffer);
-
-  return priv->driver_private;
-}
-
-void
-cogl_framebuffer_set_driver_private (CoglFramebuffer *framebuffer,
-                                     gpointer         driver_private,
-                                     GDestroyNotify   destroy_notify)
+CoglFramebufferDriver *
+cogl_framebuffer_get_driver (CoglFramebuffer *framebuffer)
 {
   CoglFramebufferPrivate *priv =
     cogl_framebuffer_get_instance_private (framebuffer);
 
-  g_warn_if_fail (!priv->driver_private);
-
-  priv->driver_private = driver_private;
-  priv->driver_private_destroy = destroy_notify;
+  return priv->driver;
 }
diff --git a/cogl/cogl/cogl-framebuffer.h b/cogl/cogl/cogl-framebuffer.h
index fab99ef2c0..993de7a25f 100644
--- a/cogl/cogl/cogl-framebuffer.h
+++ b/cogl/cogl/cogl-framebuffer.h
@@ -85,6 +85,8 @@ G_BEGIN_DECLS
  * configuration.
  */
 
+typedef struct _CoglFramebufferDriverConfig CoglFramebufferDriverConfig;
+
 #define COGL_TYPE_FRAMEBUFFER (cogl_framebuffer_get_type ())
 COGL_EXPORT
 G_DECLARE_DERIVABLE_TYPE (CoglFramebuffer, cogl_framebuffer,
diff --git a/cogl/cogl/cogl-offscreen.c b/cogl/cogl/cogl-offscreen.c
index bc4ecf0dfe..ae05f73433 100644
--- a/cogl/cogl/cogl-offscreen.c
+++ b/cogl/cogl/cogl-offscreen.c
@@ -38,33 +38,33 @@ struct _CoglOffscreen
 
   CoglTexture *texture;
   int texture_level;
-
-  /* FIXME: _cogl_offscreen_new_with_texture_full should be made to use
-   * fb->config to configure if we want a depth or stencil buffer so
-   * we can get rid of these flags */
-  CoglOffscreenFlags create_flags;
 };
 
 G_DEFINE_TYPE (CoglOffscreen, cogl_offscreen,
                COGL_TYPE_FRAMEBUFFER)
 
 CoglOffscreen *
-_cogl_offscreen_new_with_texture_full (CoglTexture        *texture,
-                                       CoglOffscreenFlags  create_flags,
-                                       int                 level)
+_cogl_offscreen_new_with_texture_full (CoglTexture       *texture,
+                                       CoglOffscreenFlags flags,
+                                       int                level)
 {
   CoglContext *ctx = texture->context;
+  CoglFramebufferDriverConfig driver_config;
   CoglOffscreen *offscreen;
   CoglFramebuffer *fb;
 
   g_return_val_if_fail (cogl_is_texture (texture), NULL);
 
+  driver_config = (CoglFramebufferDriverConfig) {
+    .disable_depth_and_stencil =
+      !!(flags & COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL),
+  };
   offscreen = g_object_new (COGL_TYPE_OFFSCREEN,
                             "context", ctx,
+                            "driver-config", &driver_config,
                             NULL);
   offscreen->texture = cogl_object_ref (texture);
   offscreen->texture_level = level;
-  offscreen->create_flags = create_flags;
 
   fb = COGL_FRAMEBUFFER (offscreen);
 
@@ -101,7 +101,6 @@ cogl_offscreen_allocate (CoglFramebuffer  *framebuffer,
                          GError          **error)
 {
   CoglOffscreen *offscreen = COGL_OFFSCREEN (framebuffer);
-  CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
   CoglPixelFormat texture_format;
   int width, height;
 
@@ -125,11 +124,6 @@ cogl_offscreen_allocate (CoglFramebuffer  *framebuffer,
   texture_format = _cogl_texture_get_format (offscreen->texture);
   _cogl_framebuffer_set_internal_format (framebuffer, texture_format);
 
-  if (!ctx->driver_vtable->offscreen_allocate (offscreen,
-                                               offscreen->create_flags,
-                                               error))
-    return FALSE;
-
   return TRUE;
 }
 
@@ -143,11 +137,6 @@ static void
 cogl_offscreen_dispose (GObject *object)
 {
   CoglOffscreen *offscreen = COGL_OFFSCREEN (object);
-  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (offscreen);
-  CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
-
-  if (offscreen->texture)
-    ctx->driver_vtable->offscreen_free (offscreen);
 
   G_OBJECT_CLASS (cogl_offscreen_parent_class)->dispose (object);
 
diff --git a/cogl/cogl/driver/gl/cogl-framebuffer-gl-private.h 
b/cogl/cogl/driver/gl/cogl-framebuffer-gl-private.h
index 6fe059d30d..2f96f6f8f7 100644
--- a/cogl/cogl/driver/gl/cogl-framebuffer-gl-private.h
+++ b/cogl/cogl/driver/gl/cogl-framebuffer-gl-private.h
@@ -41,9 +41,6 @@ G_DECLARE_FINAL_TYPE (CoglGlFramebuffer, cogl_gl_framebuffer,
                       COGL, GL_FRAMEBUFFER,
                       CoglFramebufferDriver)
 
-CoglGlFramebuffer *
-cogl_gl_framebuffer_from_framebuffer (CoglFramebuffer *framebuffer);
-
 gboolean
 _cogl_offscreen_gl_allocate (CoglOffscreen       *offscreen,
                              CoglOffscreenFlags   flags,
diff --git a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c b/cogl/cogl/driver/gl/cogl-framebuffer-gl.c
index 4ac0ae7c40..95e4a39b6c 100644
--- a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c
+++ b/cogl/cogl/driver/gl/cogl-framebuffer-gl.c
@@ -151,9 +151,6 @@ struct _CoglGlFramebuffer
 G_DEFINE_TYPE_WITH_PRIVATE (CoglGlFramebuffer, cogl_gl_framebuffer,
                             COGL_TYPE_FRAMEBUFFER_DRIVER)
 
-static CoglGlFramebuffer *
-ensure_gl_framebuffer (CoglFramebuffer *framebuffer);
-
 static void
 _cogl_framebuffer_gl_flush_viewport_state (CoglFramebuffer *framebuffer)
 {
@@ -355,6 +352,16 @@ cogl_gl_framebuffer_flush_state_differences (CoglGlFramebuffer *gl_framebuffer,
   COGL_FLAGS_FOREACH_END;
 }
 
+static CoglGlFramebuffer *
+cogl_gl_framebuffer_from_framebuffer (CoglFramebuffer *framebuffer)
+{
+  CoglFramebufferDriver *driver = cogl_framebuffer_get_driver (framebuffer);
+
+  g_assert (driver);
+
+  return COGL_GL_FRAMEBUFFER (driver);
+}
+
 void
 _cogl_framebuffer_gl_bind (CoglFramebuffer *framebuffer, GLenum target)
 {
@@ -362,11 +369,11 @@ _cogl_framebuffer_gl_bind (CoglFramebuffer *framebuffer, GLenum target)
 
   if (COGL_IS_OFFSCREEN (framebuffer))
     {
-      CoglGlFramebuffer *gl_framebuffer;
-      CoglGlFramebufferPrivate *priv;
+      CoglGlFramebuffer *gl_framebuffer =
+        cogl_gl_framebuffer_from_framebuffer (framebuffer);
+      CoglGlFramebufferPrivate *priv =
+        cogl_gl_framebuffer_get_instance_private (gl_framebuffer);
 
-      gl_framebuffer = ensure_gl_framebuffer (framebuffer);
-      priv = cogl_gl_framebuffer_get_instance_private (gl_framebuffer);
       GE (ctx, glBindFramebuffer (target, priv->gl_fbo.fbo_handle));
     }
   else
@@ -633,14 +640,14 @@ try_creating_fbo (CoglContext                 *ctx,
   return TRUE;
 }
 
-gboolean
-_cogl_offscreen_gl_allocate (CoglOffscreen       *offscreen,
-                             CoglOffscreenFlags   flags,
-                             GError             **error)
+CoglFramebufferDriver *
+_cogl_driver_gl_create_framebuffer_driver (CoglContext                        *context,
+                                           CoglFramebuffer                    *framebuffer,
+                                           const CoglFramebufferDriverConfig  *driver_config,
+                                           GError                            **error)
 {
-  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (offscreen);
-  CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
   CoglOffscreenAllocateFlags allocate_flags;
+  CoglOffscreen *offscreen;
   CoglGlFramebuffer *gl_framebuffer;
   CoglGlFramebufferPrivate *priv;
   CoglGlFbo *gl_fbo;
@@ -650,6 +657,14 @@ _cogl_offscreen_gl_allocate (CoglOffscreen       *offscreen,
   int level_width;
   int level_height;
 
+  if (COGL_IS_ONSCREEN (framebuffer))
+    {
+      return g_object_new (COGL_TYPE_GL_FRAMEBUFFER,
+                           "framebuffer", framebuffer,
+                           NULL);
+    }
+
+  offscreen = COGL_OFFSCREEN (framebuffer);
   texture = cogl_offscreen_get_texture (offscreen);
   texture_level = cogl_offscreen_get_texture_level (offscreen);
 
@@ -677,12 +692,14 @@ _cogl_offscreen_gl_allocate (CoglOffscreen       *offscreen,
 
   config = cogl_framebuffer_get_config (framebuffer);
 
-  gl_framebuffer = ensure_gl_framebuffer (framebuffer);
+  gl_framebuffer = g_object_new (COGL_TYPE_GL_FRAMEBUFFER,
+                                 "framebuffer", framebuffer,
+                                 NULL);
   priv = cogl_gl_framebuffer_get_instance_private (gl_framebuffer);
   gl_fbo = &priv->gl_fbo;
 
-  if (((flags & COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL) &&
-       try_creating_fbo (ctx,
+  if ((driver_config->disable_depth_and_stencil &&
+       try_creating_fbo (context,
                          texture,
                          texture_level,
                          level_width,
@@ -691,24 +708,24 @@ _cogl_offscreen_gl_allocate (CoglOffscreen       *offscreen,
                          allocate_flags = 0,
                          gl_fbo)) ||
 
-      (ctx->have_last_offscreen_allocate_flags &&
-       try_creating_fbo (ctx,
+      (context->have_last_offscreen_allocate_flags &&
+       try_creating_fbo (context,
                          texture,
                          texture_level,
                          level_width,
                          level_height,
                          config,
-                         allocate_flags = ctx->last_offscreen_allocate_flags,
+                         allocate_flags = context->last_offscreen_allocate_flags,
                          gl_fbo)) ||
 
       (
        /* NB: WebGL introduces a DEPTH_STENCIL_ATTACHMENT and doesn't
         * need an extension to handle _FLAG_DEPTH_STENCIL */
        (_cogl_has_private_feature
-        (ctx, COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL) ||
+        (context, COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL) ||
         _cogl_has_private_feature
-        (ctx, COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL)) &&
-       try_creating_fbo (ctx,
+        (context, COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL)) &&
+       try_creating_fbo (context,
                          texture,
                          texture_level,
                          level_width,
@@ -717,7 +734,7 @@ _cogl_offscreen_gl_allocate (CoglOffscreen       *offscreen,
                          allocate_flags = COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH_STENCIL,
                          gl_fbo)) ||
 
-      try_creating_fbo (ctx,
+      try_creating_fbo (context,
                         texture,
                         texture_level,
                         level_width,
@@ -727,7 +744,7 @@ _cogl_offscreen_gl_allocate (CoglOffscreen       *offscreen,
                         COGL_OFFSCREEN_ALLOCATE_FLAG_STENCIL,
                         gl_fbo) ||
 
-      try_creating_fbo (ctx,
+      try_creating_fbo (context,
                         texture,
                         texture_level,
                         level_width,
@@ -736,7 +753,7 @@ _cogl_offscreen_gl_allocate (CoglOffscreen       *offscreen,
                         allocate_flags = COGL_OFFSCREEN_ALLOCATE_FLAG_STENCIL,
                         gl_fbo) ||
 
-      try_creating_fbo (ctx,
+      try_creating_fbo (context,
                         texture,
                         texture_level,
                         level_width,
@@ -745,7 +762,7 @@ _cogl_offscreen_gl_allocate (CoglOffscreen       *offscreen,
                         allocate_flags = COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH,
                         gl_fbo) ||
 
-      try_creating_fbo (ctx,
+      try_creating_fbo (context,
                         texture,
                         texture_level,
                         level_width,
@@ -757,35 +774,38 @@ _cogl_offscreen_gl_allocate (CoglOffscreen       *offscreen,
       cogl_framebuffer_update_samples_per_pixel (framebuffer,
                                                  gl_fbo->samples_per_pixel);
 
-      if (!(flags & COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL))
+      if (!driver_config->disable_depth_and_stencil)
         {
           /* Record that the last set of flags succeeded so that we can
              try that set first next time */
-          ctx->last_offscreen_allocate_flags = allocate_flags;
-          ctx->have_last_offscreen_allocate_flags = TRUE;
+          context->last_offscreen_allocate_flags = allocate_flags;
+          context->have_last_offscreen_allocate_flags = TRUE;
         }
 
-      return TRUE;
+      return COGL_FRAMEBUFFER_DRIVER (gl_framebuffer);
     }
   else
     {
+      g_object_unref (gl_framebuffer);
       g_set_error (error, COGL_FRAMEBUFFER_ERROR,
                    COGL_FRAMEBUFFER_ERROR_ALLOCATE,
                    "Failed to create an OpenGL framebuffer object");
-      return FALSE;
+      return NULL;
     }
 }
 
-void
-_cogl_offscreen_gl_free (CoglOffscreen *offscreen)
+static void
+cogl_gl_framebuffer_dispose (GObject *object)
 {
-  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (offscreen);
+  CoglGlFramebuffer *gl_framebuffer = COGL_GL_FRAMEBUFFER (object);
+  CoglGlFramebufferPrivate *priv =
+    cogl_gl_framebuffer_get_instance_private (gl_framebuffer);
+  CoglFramebufferDriver *driver = COGL_FRAMEBUFFER_DRIVER (object);
+  CoglFramebuffer *framebuffer =
+    cogl_framebuffer_driver_get_framebuffer (driver);
   CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
-  CoglGlFramebuffer *gl_framebuffer;
-  CoglGlFramebufferPrivate *priv;
 
-  gl_framebuffer = ensure_gl_framebuffer (framebuffer);
-  priv = cogl_gl_framebuffer_get_instance_private (gl_framebuffer);
+  G_OBJECT_CLASS (cogl_gl_framebuffer_parent_class)->dispose (object);
 
   delete_renderbuffers (ctx, priv->gl_fbo.renderbuffers);
 
@@ -837,40 +857,14 @@ _cogl_framebuffer_gl_clear (CoglFramebuffer *framebuffer,
   GE (ctx, glClear (gl_buffers));
 }
 
-CoglGlFramebuffer *
-cogl_gl_framebuffer_from_framebuffer (CoglFramebuffer *framebuffer)
-{
-  return ensure_gl_framebuffer (framebuffer);
-}
-
-static CoglGlFramebuffer *
-ensure_gl_framebuffer (CoglFramebuffer *framebuffer)
-{
-  CoglGlFramebuffer *gl_framebuffer;
-
-  gl_framebuffer = cogl_framebuffer_get_driver_private (framebuffer);
-  if (!gl_framebuffer)
-    {
-      gl_framebuffer = g_object_new (COGL_TYPE_GL_FRAMEBUFFER,
-                                     "framebuffer", framebuffer,
-                                     NULL);
-      cogl_framebuffer_set_driver_private (framebuffer,
-                                           gl_framebuffer,
-                                           g_object_unref);
-    }
-
-  return gl_framebuffer;
-}
-
 static inline void
 _cogl_framebuffer_init_bits (CoglFramebuffer *framebuffer)
 {
+  CoglGlFramebuffer *gl_framebuffer =
+    cogl_gl_framebuffer_from_framebuffer (framebuffer);
+  CoglGlFramebufferPrivate *priv =
+    cogl_gl_framebuffer_get_instance_private (gl_framebuffer);
   CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
-  CoglGlFramebuffer *gl_framebuffer;
-  CoglGlFramebufferPrivate *priv;
-
-  gl_framebuffer = ensure_gl_framebuffer (framebuffer);
-  priv = cogl_gl_framebuffer_get_instance_private (gl_framebuffer);
 
   if (!priv->dirty_bitmasks)
     return;
@@ -963,15 +957,15 @@ void
 _cogl_framebuffer_gl_query_bits (CoglFramebuffer *framebuffer,
                                  CoglFramebufferBits *bits)
 {
-  CoglGlFramebuffer *gl_framebuffer;
-  CoglGlFramebufferPrivate *priv;
+  CoglGlFramebuffer *gl_framebuffer =
+    cogl_gl_framebuffer_from_framebuffer (framebuffer);
+  CoglGlFramebufferPrivate *priv =
+    cogl_gl_framebuffer_get_instance_private (gl_framebuffer);
 
   _cogl_framebuffer_init_bits (framebuffer);
 
   /* TODO: cache these in some driver specific location not
    * directly as part of CoglFramebuffer. */
-  gl_framebuffer = ensure_gl_framebuffer (framebuffer);
-  priv = cogl_gl_framebuffer_get_instance_private (gl_framebuffer);
   *bits = priv->bits;
 }
 
@@ -1380,4 +1374,7 @@ cogl_gl_framebuffer_init (CoglGlFramebuffer *gl_framebuffer)
 static void
 cogl_gl_framebuffer_class_init (CoglGlFramebufferClass *klass)
 {
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->dispose = cogl_gl_framebuffer_dispose;
 }
diff --git a/cogl/cogl/driver/gl/cogl-util-gl-private.h b/cogl/cogl/driver/gl/cogl-util-gl-private.h
index f72c741942..6bada2cd02 100644
--- a/cogl/cogl/driver/gl/cogl-util-gl-private.h
+++ b/cogl/cogl/driver/gl/cogl-util-gl-private.h
@@ -100,6 +100,12 @@ _cogl_driver_gl_flush_framebuffer_state (CoglContext          *context,
                                          CoglFramebuffer      *read_buffer,
                                          CoglFramebufferState  state);
 
+CoglFramebufferDriver *
+_cogl_driver_gl_create_framebuffer_driver (CoglContext                        *context,
+                                           CoglFramebuffer                    *framebuffer,
+                                           const CoglFramebufferDriverConfig  *driver_config,
+                                           GError                            **error);
+
 GLenum
 _cogl_gl_util_get_error (CoglContext *ctx);
 
diff --git a/cogl/cogl/driver/gl/cogl-util-gl.c b/cogl/cogl/driver/gl/cogl-util-gl.c
index 1ca513e8d7..2c1c4e5441 100644
--- a/cogl/cogl/driver/gl/cogl-util-gl.c
+++ b/cogl/cogl/driver/gl/cogl-util-gl.c
@@ -214,7 +214,8 @@ _cogl_driver_gl_flush_framebuffer_state (CoglContext          *ctx,
       differences &= ~COGL_FRAMEBUFFER_STATE_BIND;
     }
 
-  draw_gl_framebuffer = cogl_gl_framebuffer_from_framebuffer (draw_buffer);
+  draw_gl_framebuffer =
+    COGL_GL_FRAMEBUFFER (cogl_framebuffer_get_driver (draw_buffer));
   cogl_gl_framebuffer_flush_state_differences (draw_gl_framebuffer,
                                                differences);
 
diff --git a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c
index 77c7bbcf83..31f6c898f7 100644
--- a/cogl/cogl/driver/gl/gl/cogl-driver-gl.c
+++ b/cogl/cogl/driver/gl/gl/cogl-driver-gl.c
@@ -569,8 +569,7 @@ _cogl_driver_gl =
     _cogl_driver_pixel_format_from_gl_internal,
     _cogl_driver_pixel_format_to_gl,
     _cogl_driver_update_features,
-    _cogl_offscreen_gl_allocate,
-    _cogl_offscreen_gl_free,
+    _cogl_driver_gl_create_framebuffer_driver,
     _cogl_driver_gl_flush_framebuffer_state,
     _cogl_framebuffer_gl_clear,
     _cogl_framebuffer_gl_query_bits,
diff --git a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c
index 3c652486e2..506d5250b6 100644
--- a/cogl/cogl/driver/gl/gles/cogl-driver-gles.c
+++ b/cogl/cogl/driver/gl/gles/cogl-driver-gles.c
@@ -457,8 +457,7 @@ _cogl_driver_gles =
     _cogl_driver_pixel_format_from_gl_internal,
     _cogl_driver_pixel_format_to_gl,
     _cogl_driver_update_features,
-    _cogl_offscreen_gl_allocate,
-    _cogl_offscreen_gl_free,
+    _cogl_driver_gl_create_framebuffer_driver,
     _cogl_driver_gl_flush_framebuffer_state,
     _cogl_framebuffer_gl_clear,
     _cogl_framebuffer_gl_query_bits,
diff --git a/cogl/cogl/driver/nop/cogl-driver-nop.c b/cogl/cogl/driver/nop/cogl-driver-nop.c
index 8c6aab47c2..7dfc1c5bcc 100644
--- a/cogl/cogl/driver/nop/cogl-driver-nop.c
+++ b/cogl/cogl/driver/nop/cogl-driver-nop.c
@@ -40,6 +40,7 @@
 #include "cogl-texture-2d-nop-private.h"
 #include "cogl-attribute-nop-private.h"
 #include "cogl-clip-stack-nop-private.h"
+#include "driver/nop/cogl-nop-framebuffer.h"
 
 static gboolean
 _cogl_driver_update_features (CoglContext *ctx,
@@ -67,6 +68,17 @@ _cogl_driver_nop_is_hardware_accelerated (CoglContext *context)
   return FALSE;
 }
 
+static CoglFramebufferDriver *
+_cogl_driver_nop_create_framebuffer_driver (CoglContext                        *context,
+                                            CoglFramebuffer                    *framebuffer,
+                                            const CoglFramebufferDriverConfig  *driver_config,
+                                            GError                            **error)
+{
+  return g_object_new (COGL_TYPE_NOP_FRAMEBUFFER,
+                       "framebuffer", framebuffer,
+                       NULL);
+}
+
 static void
 _cogl_driver_nop_flush_framebuffer_state (CoglContext          *ctx,
                                           CoglFramebuffer      *draw_buffer,
@@ -85,8 +97,7 @@ _cogl_driver_nop =
     NULL, /* pixel_format_from_gl_internal */
     NULL, /* pixel_format_to_gl */
     _cogl_driver_update_features,
-    _cogl_offscreen_nop_allocate,
-    _cogl_offscreen_nop_free,
+    _cogl_driver_nop_create_framebuffer_driver,
     _cogl_driver_nop_flush_framebuffer_state,
     _cogl_framebuffer_nop_clear,
     _cogl_framebuffer_nop_query_bits,
diff --git a/cogl/cogl/driver/nop/cogl-framebuffer-nop-private.h 
b/cogl/cogl/driver/nop/cogl-framebuffer-nop-private.h
index 788bde6cc4..19013c7528 100644
--- a/cogl/cogl/driver/nop/cogl-framebuffer-nop-private.h
+++ b/cogl/cogl/driver/nop/cogl-framebuffer-nop-private.h
@@ -37,14 +37,6 @@
 #include "cogl-types.h"
 #include "cogl-context-private.h"
 
-gboolean
-_cogl_offscreen_nop_allocate (CoglOffscreen       *offscreen,
-                              CoglOffscreenFlags   flags,
-                              GError             **error);
-
-void
-_cogl_offscreen_nop_free (CoglOffscreen *offscreen);
-
 void
 _cogl_framebuffer_nop_clear (CoglFramebuffer *framebuffer,
                             unsigned long buffers,
diff --git a/cogl/cogl/driver/nop/cogl-framebuffer-nop.c b/cogl/cogl/driver/nop/cogl-framebuffer-nop.c
index 6dc5e7e91c..d7fc293f23 100644
--- a/cogl/cogl/driver/nop/cogl-framebuffer-nop.c
+++ b/cogl/cogl/driver/nop/cogl-framebuffer-nop.c
@@ -35,19 +35,6 @@
 #include <glib.h>
 #include <string.h>
 
-gboolean
-_cogl_offscreen_nop_allocate (CoglOffscreen       *offscreen,
-                              CoglOffscreenFlags   flags,
-                              GError             **error)
-{
-  return TRUE;
-}
-
-void
-_cogl_offscreen_nop_free (CoglOffscreen *offscreen)
-{
-}
-
 void
 _cogl_framebuffer_nop_clear (CoglFramebuffer *framebuffer,
                              unsigned long buffers,
diff --git a/cogl/cogl/driver/nop/cogl-nop-framebuffer.c b/cogl/cogl/driver/nop/cogl-nop-framebuffer.c
new file mode 100644
index 0000000000..85bed95a7c
--- /dev/null
+++ b/cogl/cogl/driver/nop/cogl-nop-framebuffer.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2020 Red Hat
+ *
+ * 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 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.
+ *
+ */
+
+#include "cogl-config.h"
+
+#include "cogl-nop-framebuffer.h"
+
+struct _CoglNopFramebuffer
+{
+  CoglFramebufferDriver parent;
+};
+
+G_DEFINE_TYPE (CoglNopFramebuffer, cogl_nop_framebuffer,
+               COGL_TYPE_FRAMEBUFFER_DRIVER)
+
+static void
+cogl_nop_framebuffer_init (CoglNopFramebuffer *nop_framebuffer)
+{
+}
+
+static void
+cogl_nop_framebuffer_class_init (CoglNopFramebufferClass *klass)
+{
+}
diff --git a/cogl/cogl/driver/nop/cogl-nop-framebuffer.h b/cogl/cogl/driver/nop/cogl-nop-framebuffer.h
new file mode 100644
index 0000000000..7c9f729a66
--- /dev/null
+++ b/cogl/cogl/driver/nop/cogl-nop-framebuffer.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2020 Red Hat
+ *
+ * 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 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 COGL_NOP_FRAMEBUFFER_H
+#define COGL_NOP_FRAMEBUFFER_H
+
+#include "cogl-framebuffer-driver.h"
+
+#define COGL_TYPE_NOP_FRAMEBUFFER (cogl_nop_framebuffer_get_type ())
+G_DECLARE_FINAL_TYPE (CoglNopFramebuffer, cogl_nop_framebuffer,
+                      COGL, NOP_FRAMEBUFFER_DRIVER,
+                      CoglFramebufferDriver)
+
+#endif /* COGL_NOP_FRAMEBUFFER_H */
diff --git a/cogl/cogl/meson.build b/cogl/cogl/meson.build
index 5a361b42d7..638f5a8273 100644
--- a/cogl/cogl/meson.build
+++ b/cogl/cogl/meson.build
@@ -132,6 +132,8 @@ cogl_noop_driver_sources = [
   'driver/nop/cogl-driver-nop.c',
   'driver/nop/cogl-framebuffer-nop-private.h',
   'driver/nop/cogl-framebuffer-nop.c',
+  'driver/nop/cogl-nop-framebuffer.c',
+  'driver/nop/cogl-nop-framebuffer.h',
   'driver/nop/cogl-attribute-nop-private.h',
   'driver/nop/cogl-attribute-nop.c',
   'driver/nop/cogl-clip-stack-nop-private.h',


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