[mutter] cogl: Turn CoglFramebuffer, CoglOffscreen and CoglOnscreen into GObjects



commit eb14da3874fd7044c6ef6bf28bf33b1bfcc7a3a0
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Tue Oct 13 11:35:47 2020 +0200

    cogl: Turn CoglFramebuffer, CoglOffscreen and CoglOnscreen into GObjects
    
    A first step towards abandoning the CoglObject type system: convert
    CoglFramebuffer, CoglOffscreen and CoglOnscreen into GObjects.
    CoglFramebuffer is turned into an abstract GObject, while the two others
    are currently final. The "winsys" and "platform" are still sprinkled
    'void *' in the the non-abstract type instances however.
    
    https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1496

 clutter/clutter/clutter-backend.c                  |   2 +-
 clutter/clutter/clutter-offscreen-effect.c         |  16 +-
 clutter/clutter/clutter-paint-context.c            |   7 +-
 clutter/clutter/clutter-paint-nodes.c              |  13 +-
 clutter/clutter/clutter-pick-context.c             |   4 +-
 clutter/clutter/clutter-stage-view.c               |  54 ++---
 clutter/clutter/clutter-stage.c                    |   2 +-
 clutter/clutter/cogl/clutter-stage-cogl.c          |  10 +-
 cogl/cogl/cogl-blit.c                              |  18 +-
 cogl/cogl/cogl-dma-buf-handle.c                    |   4 +-
 cogl/cogl/cogl-framebuffer-private.h               |  25 +-
 cogl/cogl/cogl-framebuffer.c                       | 265 ++++++++++++++-------
 cogl/cogl/cogl-framebuffer.h                       |  28 +--
 cogl/cogl/cogl-journal.c                           |   4 +-
 cogl/cogl/cogl-offscreen.h                         |  29 +--
 cogl/cogl/cogl-onscreen-private.h                  |   2 +-
 cogl/cogl/cogl-onscreen.c                          |  59 ++---
 cogl/cogl/cogl-onscreen.h                          |  29 +--
 cogl/cogl/cogl-texture.c                           |  22 +-
 cogl/cogl/cogl-types.h                             |   2 +
 cogl/cogl/deprecated/cogl-type-casts.h             |   1 -
 cogl/cogl/driver/gl/cogl-clip-stack-gl.c           |   2 +-
 cogl/cogl/driver/gl/cogl-framebuffer-gl.c          |  24 +-
 cogl/cogl/driver/gl/cogl-pipeline-opengl.c         |   2 +-
 cogl/cogl/driver/gl/cogl-pipeline-progend-glsl.c   |   2 +-
 cogl/cogl/winsys/cogl-winsys-egl-x11.c             |   4 +-
 cogl/cogl/winsys/cogl-winsys-glx.c                 |   6 +-
 cogl/test-fixtures/test-utils.c                    |   2 +-
 cogl/tests/conform/test-backface-culling.c         |   4 +-
 cogl/tests/conform/test-framebuffer-get-bits.c     |   8 +-
 cogl/tests/conform/test-offscreen.c                |  26 +-
 cogl/tests/conform/test-pipeline-shader-state.c    |   4 +-
 cogl/tests/conform/test-readpixels.c               |   2 +-
 cogl/tests/conform/test-viewport.c                 |   2 +-
 src/backends/meta-screen-cast-stream-src.c         |   4 +-
 src/backends/native/meta-renderer-native.c         |  24 +-
 src/backends/x11/meta-stage-x11.c                  |   4 +-
 src/compositor/meta-background.c                   |  14 +-
 src/compositor/meta-compositor-native.c            |   2 +-
 src/compositor/meta-shaped-texture.c               |   4 +-
 src/compositor/meta-texture-tower.c                |   6 +-
 src/compositor/meta-window-actor.c                 |   4 +-
 .../clutter/interactive/test-cogl-offscreen.c      |   2 +-
 43 files changed, 390 insertions(+), 358 deletions(-)
---
diff --git a/clutter/clutter/clutter-backend.c b/clutter/clutter/clutter-backend.c
index d331f9fad8..5e98a2bbe5 100644
--- a/clutter/clutter/clutter-backend.c
+++ b/clutter/clutter/clutter-backend.c
@@ -93,7 +93,7 @@ clutter_backend_dispose (GObject *gobject)
   /* clear the events still in the queue of the main context */
   _clutter_clear_events_queue ();
 
-  g_clear_pointer (&backend->dummy_onscreen, cogl_object_unref);
+  g_clear_object (&backend->dummy_onscreen);
   if (backend->stage_window)
     {
       g_object_remove_weak_pointer (G_OBJECT (backend->stage_window),
diff --git a/clutter/clutter/clutter-offscreen-effect.c b/clutter/clutter/clutter-offscreen-effect.c
index a4224b60c3..6315caa730 100644
--- a/clutter/clutter/clutter-offscreen-effect.c
+++ b/clutter/clutter/clutter-offscreen-effect.c
@@ -118,7 +118,7 @@ clutter_offscreen_effect_set_actor (ClutterActorMeta *meta,
   meta_class->set_actor (meta, actor);
 
   /* clear out the previous state */
-  g_clear_pointer (&priv->offscreen, cogl_object_unref);
+  g_clear_object (&priv->offscreen);
 
   /* we keep a back pointer here, to avoid going through the ActorMeta */
   priv->actor = clutter_actor_meta_get_actor (meta);
@@ -161,7 +161,7 @@ ensure_pipeline_filter_for_scale (ClutterOffscreenEffect *self,
 static void
 video_memory_purged (ClutterOffscreenEffect *self)
 {
-  g_clear_pointer (&self->priv->offscreen, cogl_object_unref);
+  g_clear_object (&self->priv->offscreen);
 }
 
 static gboolean
@@ -221,7 +221,7 @@ update_fbo (ClutterEffect *effect,
     }
 
   g_clear_pointer (&priv->texture, cogl_object_unref);
-  g_clear_pointer (&priv->offscreen, cogl_object_unref);
+  g_clear_object (&priv->offscreen);
 
   priv->texture =
     clutter_offscreen_effect_create_texture (self, target_width, target_height);
@@ -239,7 +239,7 @@ update_fbo (ClutterEffect *effect,
       g_warning ("Failed to create offscreen effect framebuffer: %s",
                  error->message);
 
-      cogl_object_unref (offscreen);
+      g_object_unref (offscreen);
       cogl_object_unref (priv->pipeline);
       priv->pipeline = NULL;
 
@@ -369,7 +369,7 @@ clutter_offscreen_effect_pre_paint (ClutterEffect       *effect,
   return TRUE;
 
 disable_effect:
-  cogl_clear_object (&priv->offscreen);
+  g_clear_object (&priv->offscreen);
   return FALSE;
 }
 
@@ -476,7 +476,7 @@ clutter_offscreen_effect_paint (ClutterEffect           *effect,
   if (flags & CLUTTER_EFFECT_PAINT_BYPASS_EFFECT)
     {
       clutter_actor_continue_paint (priv->actor, paint_context);
-      cogl_clear_object (&priv->offscreen);
+      g_clear_object (&priv->offscreen);
       return;
     }
 
@@ -503,7 +503,7 @@ clutter_offscreen_effect_set_enabled (ClutterActorMeta *meta,
   ClutterOffscreenEffect *offscreen_effect = CLUTTER_OFFSCREEN_EFFECT (meta);
   ClutterOffscreenEffectPrivate *priv = offscreen_effect->priv;
 
-  g_clear_pointer (&priv->offscreen, cogl_object_unref);
+  g_clear_object (&priv->offscreen);
 
   parent_class->set_enabled (meta, is_enabled);
 }
@@ -514,7 +514,7 @@ clutter_offscreen_effect_finalize (GObject *gobject)
   ClutterOffscreenEffect *self = CLUTTER_OFFSCREEN_EFFECT (gobject);
   ClutterOffscreenEffectPrivate *priv = self->priv;
 
-  g_clear_pointer (&priv->offscreen, cogl_object_unref);
+  g_clear_object (&priv->offscreen);
   g_clear_pointer (&priv->texture, cogl_object_unref);
   g_clear_pointer (&priv->pipeline, cogl_object_unref);
 
diff --git a/clutter/clutter/clutter-paint-context.c b/clutter/clutter/clutter-paint-context.c
index 5981835068..5e348581c1 100644
--- a/clutter/clutter/clutter-paint-context.c
+++ b/clutter/clutter/clutter-paint-context.c
@@ -86,8 +86,7 @@ clutter_paint_context_ref (ClutterPaintContext *paint_context)
 static void
 clutter_paint_context_dispose (ClutterPaintContext *paint_context)
 {
-  g_list_free_full (paint_context->framebuffers,
-                    cogl_object_unref);
+  g_list_free_full (paint_context->framebuffers, g_object_unref);
   paint_context->framebuffers = NULL;
   g_clear_pointer (&paint_context->redraw_clip, cairo_region_destroy);
 }
@@ -114,7 +113,7 @@ clutter_paint_context_push_framebuffer (ClutterPaintContext *paint_context,
                                         CoglFramebuffer     *framebuffer)
 {
   paint_context->framebuffers = g_list_prepend (paint_context->framebuffers,
-                                                cogl_object_ref (framebuffer));
+                                                g_object_ref (framebuffer));
 }
 
 void
@@ -122,7 +121,7 @@ clutter_paint_context_pop_framebuffer (ClutterPaintContext *paint_context)
 {
   g_return_if_fail (paint_context->framebuffers);
 
-  cogl_object_unref (paint_context->framebuffers->data);
+  g_object_unref (paint_context->framebuffers->data);
   paint_context->framebuffers =
     g_list_delete_link (paint_context->framebuffers,
                         paint_context->framebuffers);
diff --git a/clutter/clutter/clutter-paint-nodes.c b/clutter/clutter/clutter-paint-nodes.c
index d44e1a8ab0..41e789a072 100644
--- a/clutter/clutter/clutter-paint-nodes.c
+++ b/clutter/clutter/clutter-paint-nodes.c
@@ -130,7 +130,7 @@ clutter_root_node_finalize (ClutterPaintNode *node)
 {
   ClutterRootNode *rnode = (ClutterRootNode *) node;
 
-  cogl_object_unref (rnode->framebuffer);
+  g_object_unref (rnode->framebuffer);
 
   CLUTTER_PAINT_NODE_CLASS (clutter_root_node_parent_class)->finalize (node);
 }
@@ -177,7 +177,7 @@ clutter_root_node_new (CoglFramebuffer    *framebuffer,
                             clear_color->alpha);
   cogl_color_premultiply (&res->clear_color);
 
-  res->framebuffer = cogl_object_ref (framebuffer);
+  res->framebuffer = g_object_ref (framebuffer);
   res->clear_flags = clear_flags;
 
   return (ClutterPaintNode *) res;
@@ -326,7 +326,7 @@ clutter_dummy_node_finalize (ClutterPaintNode *node)
 {
   ClutterDummyNode *dnode = (ClutterDummyNode *) node;
 
-  cogl_clear_object (&dnode->framebuffer);
+  g_clear_object (&dnode->framebuffer);
 
   CLUTTER_PAINT_NODE_CLASS (clutter_dummy_node_parent_class)->finalize (node);
 }
@@ -358,7 +358,7 @@ _clutter_dummy_node_new (ClutterActor    *actor,
 
   dnode = (ClutterDummyNode *) res;
   dnode->actor = actor;
-  dnode->framebuffer = cogl_object_ref (framebuffer);
+  dnode->framebuffer = g_object_ref (framebuffer);
 
   return res;
 }
@@ -1361,8 +1361,7 @@ clutter_layer_node_finalize (ClutterPaintNode *node)
   if (lnode->pipeline != NULL)
     cogl_object_unref (lnode->pipeline);
 
-  if (lnode->offscreen != NULL)
-    cogl_object_unref (lnode->offscreen);
+  g_clear_object (&lnode->offscreen);
 
   CLUTTER_PAINT_NODE_CLASS (clutter_layer_node_parent_class)->finalize (node);
 }
@@ -1440,7 +1439,7 @@ clutter_layer_node_new (const graphene_matrix_t *projection,
     {
       g_warning ("Unable to create an allocate paint node offscreen: %s",
                  error->message);
-      cogl_object_unref (offscreen);
+      g_object_unref (offscreen);
       goto out;
     }
 
diff --git a/clutter/clutter/clutter-pick-context.c b/clutter/clutter/clutter-pick-context.c
index a02d6e7952..5ecb907b09 100644
--- a/clutter/clutter/clutter-pick-context.c
+++ b/clutter/clutter/clutter-pick-context.c
@@ -38,7 +38,7 @@ clutter_pick_context_new_for_view (ClutterStageView *view)
   pick_context = g_new0 (ClutterPickContext, 1);
   g_ref_count_init (&pick_context->ref_count);
   pick_context->framebuffer =
-    cogl_object_ref (clutter_stage_view_get_framebuffer (view));
+    g_object_ref (clutter_stage_view_get_framebuffer (view));
 
   return pick_context;
 }
@@ -53,7 +53,7 @@ clutter_pick_context_ref (ClutterPickContext *pick_context)
 static void
 clutter_pick_context_dispose (ClutterPickContext *pick_context)
 {
-  g_clear_pointer (&pick_context->framebuffer, cogl_object_unref);
+  g_clear_object (&pick_context->framebuffer);
 }
 
 void
diff --git a/clutter/clutter/clutter-stage-view.c b/clutter/clutter/clutter-stage-view.c
index 6e505bd07e..8123eb7db5 100644
--- a/clutter/clutter/clutter-stage-view.c
+++ b/clutter/clutter/clutter-stage-view.c
@@ -321,7 +321,7 @@ init_dma_buf_shadowfbs (ClutterStageView  *view,
       return FALSE;
     }
 
-  if (!cogl_is_onscreen (priv->framebuffer))
+  if (!COGL_IS_ONSCREEN (priv->framebuffer))
     {
       g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
                    "Tried to use shadow buffer without onscreen");
@@ -348,7 +348,7 @@ init_dma_buf_shadowfbs (ClutterStageView  *view,
 
   initial_shadowfb =
     cogl_dma_buf_handle_get_framebuffer (priv->shadow.dma_buf.handles[0]);
-  priv->shadow.framebuffer = cogl_object_ref (initial_shadowfb);
+  priv->shadow.framebuffer = COGL_OFFSCREEN (g_object_ref (initial_shadowfb));
 
   return TRUE;
 }
@@ -376,7 +376,7 @@ create_offscreen_framebuffer (CoglContext  *context,
   cogl_object_unref (texture);
   if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (framebuffer), error))
     {
-      cogl_object_unref (framebuffer);
+      g_object_unref (framebuffer);
       return FALSE;
     }
 
@@ -631,8 +631,8 @@ swap_dma_buf_framebuffer (ClutterStageView *view)
   next_dma_buf_handle = priv->shadow.dma_buf.handles[next_idx];
   next_framebuffer =
     cogl_dma_buf_handle_get_framebuffer (next_dma_buf_handle);
-  cogl_clear_object (&priv->shadow.framebuffer);
-  priv->shadow.framebuffer = cogl_object_ref (next_framebuffer);
+  g_clear_object (&priv->shadow.framebuffer);
+  priv->shadow.framebuffer = COGL_OFFSCREEN (g_object_ref (next_framebuffer));
 }
 
 static void
@@ -1165,7 +1165,7 @@ clutter_stage_view_set_framebuffer (ClutterStageView *view,
   g_warn_if_fail (!priv->framebuffer);
   if (framebuffer)
     {
-      priv->framebuffer = cogl_object_ref (framebuffer);
+      priv->framebuffer = g_object_ref (framebuffer);
       sanity_check_framebuffer (view);
     }
 }
@@ -1192,10 +1192,10 @@ clutter_stage_view_get_property (GObject    *object,
       g_value_set_boxed (value, &priv->layout);
       break;
     case PROP_FRAMEBUFFER:
-      g_value_set_boxed (value, priv->framebuffer);
+      g_value_set_object (value, priv->framebuffer);
       break;
     case PROP_OFFSCREEN:
-      g_value_set_boxed (value, priv->offscreen);
+      g_value_set_object (value, priv->offscreen);
       break;
     case PROP_USE_SHADOWFB:
       g_value_set_boolean (value, priv->use_shadowfb);
@@ -1235,10 +1235,10 @@ clutter_stage_view_set_property (GObject      *object,
       priv->layout = *layout;
       break;
     case PROP_FRAMEBUFFER:
-      clutter_stage_view_set_framebuffer (view, g_value_get_boxed (value));
+      clutter_stage_view_set_framebuffer (view, g_value_get_object (value));
       break;
     case PROP_OFFSCREEN:
-      priv->offscreen = g_value_dup_boxed (value);
+      priv->offscreen = g_value_dup_object (value);
       break;
     case PROP_USE_SHADOWFB:
       priv->use_shadowfb = g_value_get_boolean (value);
@@ -1281,7 +1281,7 @@ clutter_stage_view_dispose (GObject *object)
 
   g_clear_pointer (&priv->name, g_free);
 
-  g_clear_pointer (&priv->shadow.framebuffer, cogl_object_unref);
+  g_clear_object (&priv->shadow.framebuffer);
   for (i = 0; i < G_N_ELEMENTS (priv->shadow.dma_buf.handles); i++)
     {
       g_clear_pointer (&priv->shadow.dma_buf.handles[i],
@@ -1290,7 +1290,7 @@ clutter_stage_view_dispose (GObject *object)
   g_clear_pointer (&priv->shadow.dma_buf.damage_history,
                    clutter_damage_history_free);
 
-  g_clear_pointer (&priv->offscreen, cogl_object_unref);
+  g_clear_object (&priv->offscreen);
   g_clear_pointer (&priv->offscreen_pipeline, cogl_object_unref);
   g_clear_pointer (&priv->redraw_clip, cairo_region_destroy);
   g_clear_pointer (&priv->frame_clock, clutter_frame_clock_destroy);
@@ -1305,7 +1305,7 @@ clutter_stage_view_finalize (GObject *object)
   ClutterStageViewPrivate *priv =
     clutter_stage_view_get_instance_private (view);
 
-  g_clear_pointer (&priv->framebuffer, cogl_object_unref);
+  g_clear_object (&priv->framebuffer);
 
   G_OBJECT_CLASS (clutter_stage_view_parent_class)->dispose (object);
 }
@@ -1364,22 +1364,22 @@ clutter_stage_view_class_init (ClutterStageViewClass *klass)
                         G_PARAM_STATIC_STRINGS);
 
   obj_props[PROP_FRAMEBUFFER] =
-    g_param_spec_boxed ("framebuffer",
-                        "View framebuffer",
-                        "The front buffer of the view",
-                        COGL_TYPE_HANDLE,
-                        G_PARAM_READWRITE |
-                        G_PARAM_CONSTRUCT |
-                        G_PARAM_STATIC_STRINGS);
+    g_param_spec_object ("framebuffer",
+                         "View framebuffer",
+                         "The front buffer of the view",
+                         COGL_TYPE_FRAMEBUFFER,
+                         G_PARAM_READWRITE |
+                         G_PARAM_CONSTRUCT |
+                         G_PARAM_STATIC_STRINGS);
 
   obj_props[PROP_OFFSCREEN] =
-    g_param_spec_boxed ("offscreen",
-                        "Offscreen buffer",
-                        "Framebuffer used as intermediate buffer",
-                        COGL_TYPE_HANDLE,
-                        G_PARAM_READWRITE |
-                        G_PARAM_CONSTRUCT_ONLY |
-                        G_PARAM_STATIC_STRINGS);
+    g_param_spec_object ("offscreen",
+                         "Offscreen buffer",
+                         "Framebuffer used as intermediate buffer",
+                         COGL_TYPE_OFFSCREEN,
+                         G_PARAM_READWRITE |
+                         G_PARAM_CONSTRUCT_ONLY |
+                         G_PARAM_STATIC_STRINGS);
 
   obj_props[PROP_USE_SHADOWFB] =
     g_param_spec_boolean ("use-shadowfb",
diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c
index c9680388b6..26cc9e0e58 100644
--- a/clutter/clutter/clutter-stage.c
+++ b/clutter/clutter/clutter-stage.c
@@ -3731,7 +3731,7 @@ clutter_stage_paint_to_buffer (ClutterStage                 *stage,
                                             bitmap);
 
   cogl_object_unref (bitmap);
-  cogl_object_unref (framebuffer);
+  g_object_unref (framebuffer);
 
   return TRUE;
 }
diff --git a/clutter/clutter/cogl/clutter-stage-cogl.c b/clutter/clutter/cogl/clutter-stage-cogl.c
index 6483973e40..794960e82a 100644
--- a/clutter/clutter/cogl/clutter-stage-cogl.c
+++ b/clutter/clutter/cogl/clutter-stage-cogl.c
@@ -257,7 +257,7 @@ swap_framebuffer (ClutterStageWindow *stage_window,
 
   clutter_stage_view_before_swap_buffer (view, swap_region);
 
-  if (cogl_is_onscreen (framebuffer))
+  if (COGL_IS_ONSCREEN (framebuffer))
     {
       CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
       int *damage, n_rects, i;
@@ -481,10 +481,10 @@ clutter_stage_cogl_redraw_view_primary (ClutterStageCogl *stage_cogl,
   fb_height = cogl_framebuffer_get_height (fb);
 
   can_blit_sub_buffer =
-    cogl_is_onscreen (onscreen) &&
+    COGL_IS_ONSCREEN (onscreen) &&
     cogl_clutter_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_REGION);
 
-  has_buffer_age = cogl_is_onscreen (onscreen) && is_buffer_age_enabled ();
+  has_buffer_age = COGL_IS_ONSCREEN (onscreen) && is_buffer_age_enabled ();
 
   redraw_clip = clutter_stage_view_take_redraw_clip (view);
   if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DAMAGE_REGION))
@@ -661,7 +661,7 @@ clutter_stage_cogl_scanout_view (ClutterStageCogl  *stage_cogl,
   CoglOnscreen *onscreen;
   CoglFrameInfo *frame_info;
 
-  g_assert (cogl_is_onscreen (framebuffer));
+  g_assert (COGL_IS_ONSCREEN (framebuffer));
 
   onscreen = COGL_ONSCREEN (framebuffer);
 
@@ -807,7 +807,7 @@ clutter_stage_view_cogl_constructed (GObject *object)
   CoglFramebuffer *framebuffer;
 
   framebuffer = clutter_stage_view_get_onscreen (view);
-  if (framebuffer && cogl_is_onscreen (framebuffer))
+  if (framebuffer && COGL_IS_ONSCREEN (framebuffer))
     {
       view_priv->frame_cb_closure =
         cogl_onscreen_add_frame_callback (COGL_ONSCREEN (framebuffer),
diff --git a/cogl/cogl/cogl-blit.c b/cogl/cogl/cogl-blit.c
index 3ddc3eba23..57922f736f 100644
--- a/cogl/cogl/cogl-blit.c
+++ b/cogl/cogl/cogl-blit.c
@@ -62,7 +62,7 @@ _cogl_blit_texture_render_begin (CoglBlitData *data)
   if (!cogl_framebuffer_allocate (fb, &ignore_error))
     {
       g_error_free (ignore_error);
-      cogl_object_unref (fb);
+      g_object_unref (fb);
       return FALSE;
     }
 
@@ -142,7 +142,7 @@ _cogl_blit_texture_render_end (CoglBlitData *data)
   cogl_pipeline_set_layer_texture (ctx->blit_texture_pipeline, 0,
                                    data->dst_tex);
 
-  cogl_object_unref (data->dest_fb);
+  g_object_unref (data->dest_fb);
 }
 
 static gboolean
@@ -190,10 +190,8 @@ _cogl_blit_framebuffer_begin (CoglBlitData *data)
 
 error:
 
-  if (dst_offscreen)
-    cogl_object_unref (dst_offscreen);
-  if (src_offscreen)
-    cogl_object_unref (src_offscreen);
+  g_clear_object (&dst_offscreen);
+  g_clear_object (&src_offscreen);
 
   return FALSE;
 }
@@ -218,8 +216,8 @@ _cogl_blit_framebuffer_blit (CoglBlitData *data,
 static void
 _cogl_blit_framebuffer_end (CoglBlitData *data)
 {
-  cogl_object_unref (data->src_fb);
-  cogl_object_unref (data->dest_fb);
+  g_object_unref (data->src_fb);
+  g_object_unref (data->dest_fb);
 }
 
 static gboolean
@@ -240,7 +238,7 @@ _cogl_blit_copy_tex_sub_image_begin (CoglBlitData *data)
   if (!cogl_framebuffer_allocate (fb, &ignore_error))
     {
       g_error_free (ignore_error);
-      cogl_object_unref (fb);
+      g_object_unref (fb);
       return FALSE;
     }
 
@@ -269,7 +267,7 @@ _cogl_blit_copy_tex_sub_image_blit (CoglBlitData *data,
 static void
 _cogl_blit_copy_tex_sub_image_end (CoglBlitData *data)
 {
-  cogl_object_unref (data->src_fb);
+  g_object_unref (data->src_fb);
 }
 
 static gboolean
diff --git a/cogl/cogl/cogl-dma-buf-handle.c b/cogl/cogl/cogl-dma-buf-handle.c
index 9724ac9c95..5b18f10304 100644
--- a/cogl/cogl/cogl-dma-buf-handle.c
+++ b/cogl/cogl/cogl-dma-buf-handle.c
@@ -71,7 +71,7 @@ cogl_dma_buf_handle_new (CoglFramebuffer *framebuffer,
   g_assert (dmabuf_fd != -1);
 
   dmabuf_handle = g_new0 (CoglDmaBufHandle, 1);
-  dmabuf_handle->framebuffer = cogl_object_ref (framebuffer);
+  dmabuf_handle->framebuffer = g_object_ref (framebuffer);
   dmabuf_handle->dmabuf_fd = dmabuf_fd;
   dmabuf_handle->user_data = user_data;
   dmabuf_handle->destroy_func = destroy_func;
@@ -90,7 +90,7 @@ cogl_dma_buf_handle_free (CoglDmaBufHandle *dmabuf_handle)
 {
   g_return_if_fail (dmabuf_handle != NULL);
 
-  g_clear_pointer (&dmabuf_handle->framebuffer, cogl_object_unref);
+  g_clear_object (&dmabuf_handle->framebuffer);
 
   if (dmabuf_handle->destroy_func)
     g_clear_pointer (&dmabuf_handle->user_data, dmabuf_handle->destroy_func);
diff --git a/cogl/cogl/cogl-framebuffer-private.h b/cogl/cogl/cogl-framebuffer-private.h
index 8d3f2c8732..2f0a05b43a 100644
--- a/cogl/cogl/cogl-framebuffer-private.h
+++ b/cogl/cogl/cogl-framebuffer-private.h
@@ -41,12 +41,6 @@
 #include "cogl-gl-header.h"
 #include "cogl-clip-stack.h"
 
-typedef enum _CoglFramebufferType
-{
-  COGL_FRAMEBUFFER_TYPE_ONSCREEN,
-  COGL_FRAMEBUFFER_TYPE_OFFSCREEN
-} CoglFramebufferType;
-
 typedef struct
 {
   CoglSwapChain *swap_chain;
@@ -116,12 +110,6 @@ typedef struct
   int stencil;
 } CoglFramebufferBits;
 
-struct _CoglFramebuffer
-{
-  CoglObject _parent;
-  gpointer priv;
-};
-
 typedef enum
 {
   COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH_STENCIL    = 1L<<0,
@@ -138,12 +126,12 @@ typedef struct _CoglGLFramebuffer
 
 struct _CoglOffscreen
 {
-  CoglFramebuffer  _parent;
+  CoglFramebuffer parent;
 
   CoglGLFramebuffer gl_framebuffer;
 
-  CoglTexture    *texture;
-  int             texture_level;
+  CoglTexture *texture;
+  int texture_level;
 
   CoglTexture *depth_texture;
 
@@ -155,13 +143,6 @@ struct _CoglOffscreen
   CoglOffscreenFlags create_flags;
 };
 
-void
-_cogl_framebuffer_init (CoglFramebuffer *framebuffer,
-                        CoglContext *ctx,
-                        CoglFramebufferType type,
-                        int width,
-                        int height);
-
 gboolean
 cogl_framebuffer_is_allocated (CoglFramebuffer *framebuffer);
 
diff --git a/cogl/cogl/cogl-framebuffer.c b/cogl/cogl/cogl-framebuffer.c
index f2c4e88798..12e5e122a4 100644
--- a/cogl/cogl/cogl-framebuffer.c
+++ b/cogl/cogl/cogl-framebuffer.c
@@ -53,7 +53,27 @@
 #include "cogl-gtype-private.h"
 #include "winsys/cogl-winsys-private.h"
 
-extern CoglObjectClass _cogl_onscreen_class;
+enum
+{
+  PROP_0,
+
+  PROP_CONTEXT,
+  PROP_WIDTH,
+  PROP_HEIGHT,
+
+  N_PROPS
+};
+
+static GParamSpec *obj_props[N_PROPS];
+
+enum
+{
+  DESTROY,
+
+  N_SIGNALS
+};
+
+static guint signals[N_SIGNALS];
 
 #ifdef COGL_ENABLE_DEBUG
 static CoglUserDataKey wire_pipeline_key;
@@ -62,7 +82,6 @@ static CoglUserDataKey wire_pipeline_key;
 typedef struct _CoglFramebufferPrivate
 {
   CoglContext *context;
-  CoglFramebufferType type;
 
   /* The user configuration before allocation... */
   CoglFramebufferConfig config;
@@ -125,26 +144,11 @@ typedef struct _CoglFramebufferPrivate
   GDestroyNotify driver_private_destroy;
 } CoglFramebufferPrivate;
 
-static void _cogl_offscreen_free (CoglOffscreen *offscreen);
+G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (CoglFramebuffer, cogl_framebuffer,
+                                     G_TYPE_OBJECT)
 
-COGL_OBJECT_DEFINE_WITH_CODE_GTYPE (Offscreen, offscreen,
-                                    _cogl_offscreen_class.virt_unref =
-                                    _cogl_framebuffer_unref);
-COGL_GTYPE_DEFINE_CLASS (Offscreen, offscreen,
-                         COGL_GTYPE_IMPLEMENT_INTERFACE (framebuffer));
-COGL_GTYPE_DEFINE_INTERFACE (Framebuffer, framebuffer);
-
-/* XXX:
- * The CoglObject macros don't support any form of inheritance, so for
- * now we implement the CoglObject support for the CoglFramebuffer
- * abstract class manually.
- */
-
-static CoglFramebufferPrivate *
-cogl_framebuffer_get_instance_private (CoglFramebuffer *framebuffer)
-{
-  return framebuffer->priv;
-}
+G_DEFINE_TYPE (CoglOffscreen, cogl_offscreen,
+               COGL_TYPE_FRAMEBUFFER)
 
 uint32_t
 cogl_framebuffer_error_quark (void)
@@ -155,43 +159,83 @@ cogl_framebuffer_error_quark (void)
 gboolean
 cogl_is_framebuffer (void *object)
 {
-  CoglObject *obj = object;
+  return COGL_IS_FRAMEBUFFER (object);
+}
 
-  if (obj == NULL)
-    return FALSE;
+static void
+cogl_framebuffer_get_property (GObject    *object,
+                               guint       prop_id,
+                               GValue     *value,
+                               GParamSpec *pspec)
+{
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (object);
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
 
-  return (obj->klass == &_cogl_onscreen_class ||
-          obj->klass == &_cogl_offscreen_class);
+  switch (prop_id)
+    {
+    case PROP_CONTEXT:
+      g_value_set_boxed (value, priv->context);
+      break;
+    case PROP_WIDTH:
+      g_value_set_int (value, priv->width);
+      break;
+    case PROP_HEIGHT:
+      g_value_set_int (value, priv->height);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
 }
 
-void
-_cogl_framebuffer_init (CoglFramebuffer *framebuffer,
-                        CoglContext *ctx,
-                        CoglFramebufferType type,
-                        int width,
-                        int height)
+static void
+cogl_framebuffer_set_property (GObject      *object,
+                               guint         prop_id,
+                               const GValue *value,
+                               GParamSpec   *pspec)
 {
-  CoglFramebufferPrivate *priv;
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (object);
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
 
-  framebuffer->priv = priv = g_new0 (CoglFramebufferPrivate, 1);
-  priv->context = ctx;
+  switch (prop_id)
+    {
+    case PROP_CONTEXT:
+      priv->context = g_value_get_boxed (value);
+      break;
+    case PROP_WIDTH:
+      priv->width = g_value_get_int (value);
+      break;
+    case PROP_HEIGHT:
+      priv->height = g_value_get_int (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+cogl_framebuffer_constructed (GObject *object)
+{
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (object);
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
+  g_assert (priv->context);
 
-  priv->type = type;
-  priv->width = width;
-  priv->height = height;
   priv->internal_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE;
   priv->viewport_x = 0;
   priv->viewport_y = 0;
-  priv->viewport_width = width;
-  priv->viewport_height = height;
+  priv->viewport_width = priv->width;
+  priv->viewport_height = priv->height;
   priv->viewport_age = 0;
   priv->viewport_age_for_scissor_workaround = -1;
   priv->dither_enabled = TRUE;
   priv->depth_writing_enabled = TRUE;
   priv->depth_buffer_clear_needed = TRUE;
 
-  priv->modelview_stack = cogl_matrix_stack_new (ctx);
-  priv->projection_stack = cogl_matrix_stack_new (ctx);
+  priv->modelview_stack = cogl_matrix_stack_new (priv->context);
+  priv->projection_stack = cogl_matrix_stack_new (priv->context);
 
   priv->samples_per_pixel = 0;
 
@@ -232,7 +276,8 @@ _cogl_framebuffer_init (CoglFramebuffer *framebuffer,
    * we don't have to worry about retaining references to OpenGL
    * texture coordinates that may later become invalid.
    */
-  ctx->framebuffers = g_list_prepend (ctx->framebuffers, framebuffer);
+  priv->context->framebuffers = g_list_prepend (priv->context->framebuffers,
+                                                framebuffer);
 }
 
 void
@@ -274,15 +319,20 @@ cogl_framebuffer_init_config (CoglFramebuffer             *framebuffer,
   cogl_object_ref (priv->config.swap_chain);
 }
 
-void
-_cogl_framebuffer_free (CoglFramebuffer *framebuffer)
+static void
+cogl_framebuffer_dispose (GObject *object)
 {
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (object);
   CoglFramebufferPrivate *priv =
     cogl_framebuffer_get_instance_private (framebuffer);
   CoglContext *ctx = priv->context;
 
-  _cogl_fence_cancel_fences_for_framebuffer (framebuffer);
+  if (priv->journal)
+    {
+      g_signal_emit (framebuffer, signals[DESTROY], 0);
 
+      _cogl_fence_cancel_fences_for_framebuffer (framebuffer);
+    }
 
   g_clear_pointer (&priv->clip_stack, _cogl_clip_stack_unref);
   cogl_clear_object (&priv->modelview_stack);
@@ -298,10 +348,65 @@ _cogl_framebuffer_free (CoglFramebuffer *framebuffer)
 
   if (priv->driver_private_destroy)
     priv->driver_private_destroy (priv->driver_private);
-  priv->driver_private_destroy = NULL;
   priv->driver_private = NULL;
+  priv->driver_private_destroy = NULL;
+}
+
+static void
+cogl_framebuffer_init (CoglFramebuffer *framebuffer)
+{
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
 
-  g_clear_pointer (&framebuffer->priv, g_free);
+  priv->width = -1;
+  priv->height = -1;
+}
+
+static void
+cogl_framebuffer_class_init (CoglFramebufferClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->dispose = cogl_framebuffer_dispose;
+  object_class->constructed = cogl_framebuffer_constructed;
+  object_class->get_property = cogl_framebuffer_get_property;
+  object_class->set_property = cogl_framebuffer_set_property;
+
+  obj_props[PROP_CONTEXT] =
+    g_param_spec_boxed ("context",
+                        "context",
+                        "CoglContext",
+                        COGL_TYPE_HANDLE,
+                        G_PARAM_READWRITE |
+                        G_PARAM_CONSTRUCT_ONLY |
+                        G_PARAM_STATIC_STRINGS);
+  obj_props[PROP_WIDTH] =
+    g_param_spec_int ("width",
+                      "width",
+                      "framebuffer width",
+                      -1, INT_MAX, -1,
+                      G_PARAM_READWRITE |
+                      G_PARAM_CONSTRUCT |
+                      G_PARAM_STATIC_STRINGS);
+  obj_props[PROP_HEIGHT] =
+    g_param_spec_int ("height",
+                      "height",
+                      "framebuffer height",
+                      -1, INT_MAX, -1,
+                      G_PARAM_READWRITE |
+                      G_PARAM_CONSTRUCT |
+                      G_PARAM_STATIC_STRINGS);
+
+  g_object_class_install_properties (object_class, N_PROPS, obj_props);
+
+  signals[DESTROY] =
+    g_signal_new (I_("destroy"),
+                  G_TYPE_FROM_CLASS (object_class),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE,
+                  0);
 }
 
 const CoglWinsysVtable *
@@ -564,7 +669,7 @@ ensure_size_initialized (CoglFramebuffer *framebuffer)
     {
       /* Currently we assume the size is always initialized for
        * onscreen framebuffers. */
-      g_return_if_fail (cogl_is_offscreen (framebuffer));
+      g_return_if_fail (COGL_IS_OFFSCREEN (framebuffer));
 
       /* We also assume the size would have been initialized if the
        * framebuffer were allocated. */
@@ -765,7 +870,7 @@ _cogl_framebuffer_add_dependency (CoglFramebuffer *framebuffer,
    * cogl_object_set_user_data or for pipeline children as a way to
    * avoid quite a lot of mid-scene micro allocations here... */
   priv->deps =
-    g_list_prepend (priv->deps, cogl_object_ref (dependency));
+    g_list_prepend (priv->deps, g_object_ref (dependency));
 }
 
 void
@@ -787,7 +892,7 @@ _cogl_framebuffer_flush_dependency_journals (CoglFramebuffer *framebuffer)
   for (l = priv->deps; l; l = l->next)
     _cogl_framebuffer_flush_journal (l->data);
   for (l = priv->deps; l; l = l->next)
-    cogl_object_unref (l->data);
+    g_object_unref (l->data);
   g_list_free (priv->deps);
   priv->deps = NULL;
 }
@@ -800,11 +905,12 @@ _cogl_offscreen_new_with_texture_full (CoglTexture *texture,
   CoglContext *ctx = texture->context;
   CoglOffscreen *offscreen;
   CoglFramebuffer *fb;
-  CoglOffscreen *ret;
 
   g_return_val_if_fail (cogl_is_texture (texture), NULL);
 
-  offscreen = g_new0 (CoglOffscreen, 1);
+  offscreen = g_object_new (COGL_TYPE_OFFSCREEN,
+                            "context", ctx,
+                            NULL);
   offscreen->texture = cogl_object_ref (texture);
   offscreen->texture_level = level;
   offscreen->create_flags = create_flags;
@@ -816,17 +922,9 @@ _cogl_offscreen_new_with_texture_full (CoglTexture *texture,
    * texture is being loaded from a file then the file might not
    * have been read yet. */
 
-  _cogl_framebuffer_init (fb,
-                          ctx,
-                          COGL_FRAMEBUFFER_TYPE_OFFSCREEN,
-                          -1, /* unknown width, until allocation */
-                          -1); /* unknown height until allocation */
-
-  ret = _cogl_offscreen_object_new (offscreen);
-
   _cogl_texture_associate_framebuffer (texture, fb);
 
-  return ret;
+  return offscreen;
 }
 
 CoglOffscreen *
@@ -842,25 +940,34 @@ cogl_offscreen_get_texture (CoglOffscreen *offscreen)
 }
 
 static void
-_cogl_offscreen_free (CoglOffscreen *offscreen)
+cogl_offscreen_dispose (GObject *object)
 {
+  CoglOffscreen *offscreen = COGL_OFFSCREEN (object);
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (offscreen);
   CoglFramebufferPrivate *priv =
     cogl_framebuffer_get_instance_private (framebuffer);
   CoglContext *ctx = priv->context;
 
-  ctx->driver_vtable->offscreen_free (offscreen);
+  if (offscreen->texture)
+    ctx->driver_vtable->offscreen_free (offscreen);
+
+  G_OBJECT_CLASS (cogl_offscreen_parent_class)->dispose (object);
 
-  /* Chain up to parent */
-  _cogl_framebuffer_free (framebuffer);
+  cogl_clear_object (&offscreen->texture);
+  cogl_clear_object (&offscreen->depth_texture);
+}
 
-  if (offscreen->texture != NULL)
-    cogl_object_unref (offscreen->texture);
+static void
+cogl_offscreen_init (CoglOffscreen *offscreen)
+{
+}
 
-  if (offscreen->depth_texture != NULL)
-    cogl_object_unref (offscreen->depth_texture);
+static void
+cogl_offscreen_class_init (CoglOffscreenClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-  g_free (offscreen);
+  object_class->dispose = cogl_offscreen_dispose;
 }
 
 gboolean
@@ -878,15 +985,16 @@ cogl_framebuffer_allocate (CoglFramebuffer *framebuffer,
 {
   CoglFramebufferPrivate *priv =
     cogl_framebuffer_get_instance_private (framebuffer);
-  CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
   const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
   CoglContext *ctx = priv->context;
 
   if (priv->allocated)
     return TRUE;
 
-  if (priv->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN)
+  if (COGL_IS_ONSCREEN (framebuffer))
     {
+      CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
+
       if (!winsys->onscreen_init (onscreen, error))
         return FALSE;
 
@@ -948,7 +1056,7 @@ _cogl_framebuffer_compare_viewport_state (CoglFramebuffer *a,
       priv_a->viewport_height != priv_b->viewport_height ||
       /* NB: we render upside down to offscreen framebuffers and that
        * can affect how we setup the GL viewport... */
-      priv_a->type != priv_b->type)
+      G_OBJECT_TYPE (a) != G_OBJECT_TYPE (b))
     return COGL_FRAMEBUFFER_STATE_VIEWPORT;
   else
     return 0;
@@ -1002,10 +1110,7 @@ static unsigned long
 _cogl_framebuffer_compare_front_face_winding_state (CoglFramebuffer *a,
                                                     CoglFramebuffer *b)
 {
-  CoglFramebufferPrivate *priv_a = cogl_framebuffer_get_instance_private (a);
-  CoglFramebufferPrivate *priv_b = cogl_framebuffer_get_instance_private (b);
-
-  if (priv_a->type != priv_b->type)
+  if (G_OBJECT_TYPE (a) != G_OBJECT_TYPE (b))
     return COGL_FRAMEBUFFER_STATE_FRONT_FACE_WINDING;
   else
     return 0;
@@ -1628,7 +1733,7 @@ cogl_blit_framebuffer (CoglFramebuffer *framebuffer,
   /* Offscreens we do the normal way, onscreens need an y-flip. Even if
    * we consider offscreens to be rendered upside-down, the offscreen
    * orientation is in this function's API. */
-  if (cogl_is_offscreen (framebuffer))
+  if (COGL_IS_OFFSCREEN (framebuffer))
     {
       src_x1 = src_x;
       src_y1 = src_y;
@@ -1643,7 +1748,7 @@ cogl_blit_framebuffer (CoglFramebuffer *framebuffer,
       src_y2 = src_y1 - height;
     }
 
-  if (cogl_is_offscreen (dst))
+  if (COGL_IS_OFFSCREEN (dst))
     {
       dst_x1 = dst_x;
       dst_y1 = dst_y;
diff --git a/cogl/cogl/cogl-framebuffer.h b/cogl/cogl/cogl-framebuffer.h
index 1478cc4068..3dc05bba2d 100644
--- a/cogl/cogl/cogl-framebuffer.h
+++ b/cogl/cogl/cogl-framebuffer.h
@@ -35,19 +35,6 @@
 #ifndef __COGL_FRAMEBUFFER_H
 #define __COGL_FRAMEBUFFER_H
 
-/* We forward declare the CoglFramebuffer type here to avoid some circular
- * dependency issues with the following headers.
- */
-#if defined(__COGL_H_INSIDE__) && !defined(COGL_ENABLE_MUTTER_API) && \
-  !defined(COGL_GIR_SCANNING)
-/* For the public C api we typedef interface types as void to avoid needing
- * lots of casting in code and instead we will rely on runtime type checking
- * for these objects. */
-typedef void CoglFramebuffer;
-#else
-typedef struct _CoglFramebuffer CoglFramebuffer;
-#define COGL_FRAMEBUFFER(X) ((CoglFramebuffer *)(X))
-#endif
 
 #include <cogl/cogl-pipeline.h>
 #include <cogl/cogl-indices.h>
@@ -98,13 +85,16 @@ G_BEGIN_DECLS
  * configuration.
  */
 
-/**
- * cogl_framebuffer_get_gtype:
- *
- * Returns: a #GType that can be used with the GLib type system.
- */
+#define COGL_TYPE_FRAMEBUFFER (cogl_framebuffer_get_type ())
 COGL_EXPORT
-GType cogl_framebuffer_get_gtype (void);
+G_DECLARE_DERIVABLE_TYPE (CoglFramebuffer, cogl_framebuffer,
+                          COGL, FRAMEBUFFER, GObject)
+
+struct _CoglFramebufferClass
+{
+  /*< private >*/
+  GObjectClass parent_class;
+};
 
 /**
  * cogl_framebuffer_allocate:
diff --git a/cogl/cogl/cogl-journal.c b/cogl/cogl/cogl-journal.c
index fc11bdc2c3..b567530bd0 100644
--- a/cogl/cogl/cogl-journal.c
+++ b/cogl/cogl/cogl-journal.c
@@ -1272,7 +1272,7 @@ _cogl_journal_discard (CoglJournal *journal)
 
   /* The journal only holds a reference to the framebuffer while the
      journal is not empty */
-  cogl_object_unref (journal->framebuffer);
+  g_object_unref (journal->framebuffer);
 }
 
 /* Note: A return value of FALSE doesn't mean 'no' it means
@@ -1533,7 +1533,7 @@ _cogl_journal_log_quad (CoglJournal  *journal,
      reference to the current framebuffer. This reference will be
      removed when the journal is flushed */
   if (journal->vertices->len == 0)
-    cogl_object_ref (framebuffer);
+    g_object_ref (framebuffer);
 
   /* The vertex data is logged into a separate array. The data needs
      to be copied into a vertex array before it's given to GL so we
diff --git a/cogl/cogl/cogl-offscreen.h b/cogl/cogl/cogl-offscreen.h
index cb6bba90cb..2fa21dcc44 100644
--- a/cogl/cogl/cogl-offscreen.h
+++ b/cogl/cogl/cogl-offscreen.h
@@ -50,19 +50,13 @@ G_BEGIN_DECLS
  * Cogl allows creating and operating on offscreen framebuffers.
  */
 
-typedef struct _CoglOffscreen CoglOffscreen;
-
-#define COGL_OFFSCREEN(X) ((CoglOffscreen *)X)
+/* Offscreen api */
 
-/**
- * cogl_offscreen_get_gtype:
- *
- * Returns: a #GType that can be used with the GLib type system.
- */
+#define COGL_TYPE_OFFSCREEN (cogl_offscreen_get_type ())
 COGL_EXPORT
-GType cogl_offscreen_get_gtype (void);
-
-/* Offscreen api */
+G_DECLARE_FINAL_TYPE (CoglOffscreen, cogl_offscreen,
+                      COGL, OFFSCREEN,
+                      CoglFramebuffer)
 
 /**
  * cogl_offscreen_new_with_texture:
@@ -99,19 +93,6 @@ GType cogl_offscreen_get_gtype (void);
 COGL_EXPORT CoglOffscreen *
 cogl_offscreen_new_with_texture (CoglTexture *texture);
 
-/**
- * cogl_is_offscreen:
- * @object: A pointer to a #CoglObject
- *
- * Determines whether the given #CoglObject references an offscreen
- * framebuffer object.
- *
- * Returns: %TRUE if @object is a #CoglOffscreen framebuffer,
- *          %FALSE otherwise
- */
-COGL_EXPORT gboolean
-cogl_is_offscreen (void *object);
-
 /**
  * cogl_offscreen_get_texture: (skip)
  */
diff --git a/cogl/cogl/cogl-onscreen-private.h b/cogl/cogl/cogl-onscreen-private.h
index 1059018800..ad46273042 100644
--- a/cogl/cogl/cogl-onscreen-private.h
+++ b/cogl/cogl/cogl-onscreen-private.h
@@ -57,7 +57,7 @@ typedef struct _CoglOnscreenQueuedDirty
 
 struct _CoglOnscreen
 {
-  CoglFramebuffer  _parent;
+  CoglFramebuffer parent;
 
   CoglList frame_closures;
 
diff --git a/cogl/cogl/cogl-onscreen.c b/cogl/cogl/cogl-onscreen.c
index c667fe73a9..c81bc80db1 100644
--- a/cogl/cogl/cogl-onscreen.c
+++ b/cogl/cogl/cogl-onscreen.c
@@ -42,13 +42,7 @@
 #include "cogl-poll-private.h"
 #include "cogl-gtype-private.h"
 
-static void _cogl_onscreen_free (CoglOnscreen *onscreen);
-
-COGL_OBJECT_DEFINE_WITH_CODE_GTYPE (Onscreen, onscreen,
-                                    _cogl_onscreen_class.virt_unref =
-                                    _cogl_framebuffer_unref);
-COGL_GTYPE_DEFINE_CLASS (Onscreen, onscreen,
-                         COGL_GTYPE_IMPLEMENT_INTERFACE (framebuffer));
+G_DEFINE_TYPE (CoglOnscreen, cogl_onscreen, COGL_TYPE_FRAMEBUFFER)
 
 static gpointer
 cogl_dummy_copy (gpointer data)
@@ -102,21 +96,21 @@ cogl_onscreen_new (CoglContext *ctx, int width, int height)
      is not premultiplied in case it is being used for some special
      purpose. */
 
-  onscreen = g_new0 (CoglOnscreen, 1);
-  _cogl_framebuffer_init (COGL_FRAMEBUFFER (onscreen),
-                          ctx,
-                          COGL_FRAMEBUFFER_TYPE_ONSCREEN,
-                          width, /* width */
-                          height); /* height */
+  onscreen = g_object_new (COGL_TYPE_ONSCREEN,
+                           "context", ctx,
+                           "width", width,
+                           "height", height,
+                           NULL);
 
   _cogl_onscreen_init_from_template (onscreen, ctx->display->onscreen_template);
 
-  return _cogl_onscreen_object_new (onscreen);
+  return onscreen;
 }
 
 static void
-_cogl_onscreen_free (CoglOnscreen *onscreen)
+cogl_onscreen_dispose (GObject *object)
 {
+  CoglOnscreen *onscreen = COGL_ONSCREEN (object);
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
   const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
   CoglFrameInfo *frame_info;
@@ -129,13 +123,24 @@ _cogl_onscreen_free (CoglOnscreen *onscreen)
     cogl_object_unref (frame_info);
   g_queue_clear (&onscreen->pending_frame_infos);
 
-  winsys->onscreen_deinit (onscreen);
+  if (onscreen->winsys)
+    winsys->onscreen_deinit (onscreen);
   g_return_if_fail (onscreen->winsys == NULL);
 
-  /* Chain up to parent */
-  _cogl_framebuffer_free (framebuffer);
+  G_OBJECT_CLASS (cogl_onscreen_parent_class)->dispose (object);
+}
+
+static void
+cogl_onscreen_init (CoglOnscreen *onscreen)
+{
+}
+
+static void
+cogl_onscreen_class_init (CoglOnscreenClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-  g_free (onscreen);
+  object_class->dispose = cogl_onscreen_dispose;
 }
 
 static void
@@ -172,7 +177,7 @@ _cogl_dispatch_onscreen_cb (CoglContext *context)
 
       notify_event (onscreen, event->type, info);
 
-      cogl_object_unref (onscreen);
+      g_object_unref (onscreen);
       cogl_object_unref (info);
 
       g_slice_free (CoglOnscreenEvent, event);
@@ -192,7 +197,7 @@ _cogl_dispatch_onscreen_cb (CoglContext *context)
                                  qe->onscreen,
                                  &qe->info);
 
-      cogl_object_unref (qe->onscreen);
+      g_object_unref (qe->onscreen);
 
       g_slice_free (CoglOnscreenQueuedDirty, qe);
     }
@@ -223,7 +228,7 @@ _cogl_onscreen_queue_dirty (CoglOnscreen *onscreen,
   CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
   CoglOnscreenQueuedDirty *qe = g_slice_new (CoglOnscreenQueuedDirty);
 
-  qe->onscreen = cogl_object_ref (onscreen);
+  qe->onscreen = g_object_ref (onscreen);
   qe->info = *info;
   _cogl_list_insert (ctx->onscreen_dirty_queue.prev, &qe->link);
 
@@ -254,7 +259,7 @@ _cogl_onscreen_queue_event (CoglOnscreen *onscreen,
 
   CoglOnscreenEvent *event = g_slice_new (CoglOnscreenEvent);
 
-  event->onscreen = cogl_object_ref (onscreen);
+  event->onscreen = g_object_ref (onscreen);
   event->info = cogl_object_ref (info);
   event->type = type;
 
@@ -272,7 +277,7 @@ cogl_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
   const CoglWinsysVtable *winsys;
 
-  g_return_if_fail  (cogl_is_onscreen (framebuffer));
+  g_return_if_fail  (COGL_IS_ONSCREEN (framebuffer));
 
   info->frame_counter = onscreen->frame_counter;
   g_queue_push_tail (&onscreen->pending_frame_infos, info);
@@ -321,7 +326,7 @@ cogl_onscreen_swap_region (CoglOnscreen *onscreen,
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
   const CoglWinsysVtable *winsys;
 
-  g_return_if_fail  (cogl_is_onscreen (framebuffer));
+  g_return_if_fail  (COGL_IS_ONSCREEN (framebuffer));
 
   info->frame_counter = onscreen->frame_counter;
   g_queue_push_tail (&onscreen->pending_frame_infos, info);
@@ -367,7 +372,7 @@ cogl_onscreen_get_buffer_age (CoglOnscreen *onscreen)
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
   const CoglWinsysVtable *winsys;
 
-  g_return_val_if_fail (cogl_is_onscreen (framebuffer), 0);
+  g_return_val_if_fail (COGL_IS_ONSCREEN (framebuffer), 0);
 
   winsys = _cogl_framebuffer_get_winsys (framebuffer);
 
@@ -386,7 +391,7 @@ cogl_onscreen_direct_scanout (CoglOnscreen   *onscreen,
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
   const CoglWinsysVtable *winsys;
 
-  g_warn_if_fail (cogl_is_onscreen (framebuffer));
+  g_warn_if_fail (COGL_IS_ONSCREEN (framebuffer));
   g_warn_if_fail (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT));
 
   info->frame_counter = onscreen->frame_counter;
diff --git a/cogl/cogl/cogl-onscreen.h b/cogl/cogl/cogl-onscreen.h
index 824672f5ef..66f8c82f61 100644
--- a/cogl/cogl/cogl-onscreen.h
+++ b/cogl/cogl/cogl-onscreen.h
@@ -47,19 +47,14 @@
 
 G_BEGIN_DECLS
 
-typedef struct _CoglOnscreen CoglOnscreen;
-#define COGL_ONSCREEN(X) ((CoglOnscreen *)(X))
+#define COGL_TYPE_ONSCREEN (cogl_onscreen_get_type ())
+COGL_EXPORT
+G_DECLARE_FINAL_TYPE (CoglOnscreen, cogl_onscreen,
+                      COGL, ONSCREEN,
+                      CoglFramebuffer)
 
 typedef struct _CoglScanout CoglScanout;
 
-/**
- * cogl_onscreen_get_gtype:
- *
- * Returns: a #GType that can be used with the GLib type system.
- */
-COGL_EXPORT
-GType cogl_onscreen_get_gtype (void);
-
 /**
  * cogl_onscreen_new: (constructor) (skip)
  * @context: A #CoglContext
@@ -750,20 +745,6 @@ COGL_EXPORT void
 cogl_onscreen_remove_dirty_callback (CoglOnscreen *onscreen,
                                      CoglOnscreenDirtyClosure *closure);
 
-/**
- * cogl_is_onscreen:
- * @object: A #CoglObject pointer
- *
- * Gets whether the given object references a #CoglOnscreen.
- *
- * Return value: %TRUE if the object references a #CoglOnscreen
- *   and %FALSE otherwise.
- * Since: 1.10
- * Stability: unstable
- */
-COGL_EXPORT gboolean
-cogl_is_onscreen (void *object);
-
 /**
  * cogl_onscreen_get_frame_counter:
  *
diff --git a/cogl/cogl/cogl-texture.c b/cogl/cogl/cogl-texture.c
index f69dfc1614..8a7ec49b29 100644
--- a/cogl/cogl/cogl-texture.c
+++ b/cogl/cogl/cogl-texture.c
@@ -579,7 +579,7 @@ get_texture_bits_via_offscreen (CoglTexture *meta_texture,
 
   cogl_object_unref (bitmap);
 
-  cogl_object_unref (framebuffer);
+  g_object_unref (framebuffer);
 
   return ret;
 }
@@ -892,31 +892,23 @@ cogl_texture_get_data (CoglTexture *texture,
 }
 
 static void
-_cogl_texture_framebuffer_destroy_cb (void *user_data,
-                                      void *instance)
+on_framebuffer_destroy (CoglFramebuffer *framebuffer,
+                        CoglTexture     *texture)
 {
-  CoglTexture *tex = user_data;
-  CoglFramebuffer *framebuffer = instance;
-
-  tex->framebuffers = g_list_remove (tex->framebuffers, framebuffer);
+  texture->framebuffers = g_list_remove (texture->framebuffers, framebuffer);
 }
 
 void
 _cogl_texture_associate_framebuffer (CoglTexture *texture,
                                      CoglFramebuffer *framebuffer)
 {
-  static CoglUserDataKey framebuffer_destroy_notify_key;
-
   /* Note: we don't take a reference on the framebuffer here because
    * that would introduce a circular reference. */
   texture->framebuffers = g_list_prepend (texture->framebuffers, framebuffer);
 
-  /* Since we haven't taken a reference on the framebuffer we setup
-    * some private data so we will be notified if it is destroyed... */
-  _cogl_object_set_user_data (COGL_OBJECT (framebuffer),
-                              &framebuffer_destroy_notify_key,
-                              texture,
-                              _cogl_texture_framebuffer_destroy_cb);
+  g_signal_connect (framebuffer, "destroy",
+                    G_CALLBACK (on_framebuffer_destroy),
+                    texture);
 }
 
 const GList *
diff --git a/cogl/cogl/cogl-types.h b/cogl/cogl/cogl-types.h
index d6856bd2e9..30c908b640 100644
--- a/cogl/cogl/cogl-types.h
+++ b/cogl/cogl/cogl-types.h
@@ -86,6 +86,8 @@ typedef void * CoglHandle;
 COGL_EXPORT GType
 cogl_handle_get_type (void) G_GNUC_CONST;
 
+typedef struct _CoglFramebuffer CoglFramebuffer;
+
 /**
  * CoglAngle:
  *
diff --git a/cogl/cogl/deprecated/cogl-type-casts.h b/cogl/cogl/deprecated/cogl-type-casts.h
index c35ea056be..4ea8110113 100644
--- a/cogl/cogl/deprecated/cogl-type-casts.h
+++ b/cogl/cogl/deprecated/cogl-type-casts.h
@@ -45,7 +45,6 @@
  */
 
 #if !defined(COGL_ENABLE_MUTTER_API) && !defined(COGL_GIR_SCANNING)
-#define COGL_FRAMEBUFFER(X) (X)
 #define COGL_BUFFER(X) (X)
 #define COGL_TEXTURE(X) (X)
 #define COGL_META_TEXTURE(X) (X)
diff --git a/cogl/cogl/driver/gl/cogl-clip-stack-gl.c b/cogl/cogl/driver/gl/cogl-clip-stack-gl.c
index 365874dfb6..3f2b98ba1a 100644
--- a/cogl/cogl/driver/gl/cogl-clip-stack-gl.c
+++ b/cogl/cogl/driver/gl/cogl-clip-stack-gl.c
@@ -453,7 +453,7 @@ _cogl_clip_stack_gl_flush (CoglClipStack *stack,
        * down so in this case no conversion is needed.
        */
 
-      if (cogl_is_offscreen (framebuffer))
+      if (COGL_IS_OFFSCREEN (framebuffer))
         scissor_y_start = scissor_y0;
       else
         {
diff --git a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c b/cogl/cogl/driver/gl/cogl-framebuffer-gl.c
index c51b99997c..a95991d677 100644
--- a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c
+++ b/cogl/cogl/driver/gl/cogl-framebuffer-gl.c
@@ -153,7 +153,7 @@ _cogl_framebuffer_gl_flush_viewport_state (CoglFramebuffer *framebuffer)
    * left, while Cogl defines them to be top left.
    * NB: We render upside down to offscreen framebuffers so we don't
    * need to convert the y offset in this case. */
-  if (cogl_is_offscreen (framebuffer))
+  if (COGL_IS_OFFSCREEN (framebuffer))
     gl_viewport_y = viewport_y;
   else
     gl_viewport_y =
@@ -255,7 +255,7 @@ _cogl_framebuffer_gl_flush_stereo_mode_state (CoglFramebuffer *framebuffer)
   CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
   GLenum draw_buffer = GL_BACK;
 
-  if (cogl_is_offscreen (framebuffer))
+  if (COGL_IS_OFFSCREEN (framebuffer))
     return;
 
   if (!ctx->glDrawBuffer)
@@ -290,7 +290,7 @@ _cogl_framebuffer_gl_bind (CoglFramebuffer *framebuffer, GLenum target)
 {
   CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
 
-  if (cogl_is_offscreen (framebuffer))
+  if (COGL_IS_OFFSCREEN (framebuffer))
     {
       CoglOffscreen *offscreen = COGL_OFFSCREEN (framebuffer);
       GE (ctx, glBindFramebuffer (target,
@@ -986,11 +986,11 @@ _cogl_framebuffer_init_bits (CoglFramebuffer *framebuffer)
 
 #ifdef HAVE_COGL_GL
   if ((ctx->driver == COGL_DRIVER_GL3 &&
-       cogl_is_onscreen (framebuffer)) ||
+       COGL_IS_ONSCREEN (framebuffer)) ||
       (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS) &&
-       cogl_is_offscreen (framebuffer)))
+       COGL_IS_OFFSCREEN (framebuffer)))
     {
-      gboolean is_offscreen = cogl_is_offscreen (framebuffer);
+      gboolean is_offscreen = COGL_IS_OFFSCREEN (framebuffer);
       const struct {
         GLenum attachment, pname;
         size_t offset;
@@ -1040,7 +1040,7 @@ _cogl_framebuffer_init_bits (CoglFramebuffer *framebuffer)
   /* If we don't have alpha textures then the alpha bits are actually
    * stored in the red component */
   if (!_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_ALPHA_TEXTURES) &&
-      cogl_is_offscreen (framebuffer) &&
+      COGL_IS_OFFSCREEN (framebuffer) &&
       cogl_framebuffer_get_internal_format (framebuffer) == COGL_PIXEL_FORMAT_A_8)
     {
       framebuffer_gl->bits.alpha = framebuffer_gl->bits.red;
@@ -1050,7 +1050,7 @@ _cogl_framebuffer_init_bits (CoglFramebuffer *framebuffer)
   COGL_NOTE (OFFSCREEN,
              "RGBA/D/S Bits for framebuffer[%p, %s]: %d, %d, %d, %d, %d, %d",
              framebuffer,
-             cogl_is_offscreen (framebuffer) ? "offscreen" : "onscreen",
+             COGL_IS_OFFSCREEN (framebuffer) ? "offscreen" : "onscreen",
              framebuffer_gl->bits.red,
              framebuffer_gl->bits.blue,
              framebuffer_gl->bits.green,
@@ -1098,7 +1098,7 @@ _cogl_framebuffer_gl_discard_buffers (CoglFramebuffer *framebuffer,
       GLenum attachments[3];
       int i = 0;
 
-      if (cogl_is_onscreen (framebuffer))
+      if (COGL_IS_ONSCREEN (framebuffer))
         {
           if (buffers & COGL_BUFFER_BIT_COLOR)
             attachments[i++] = GL_COLOR;
@@ -1245,7 +1245,7 @@ _cogl_framebuffer_gl_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
    * NB: all offscreen rendering is done upside down so no conversion
    * is necissary in this case.
    */
-  if (!cogl_is_offscreen (framebuffer))
+  if (!COGL_IS_OFFSCREEN (framebuffer))
     y = framebuffer_height - y - height;
 
   required_format = ctx->driver_vtable->pixel_format_to_gl (ctx,
@@ -1258,7 +1258,7 @@ _cogl_framebuffer_gl_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
    * to flip in this case... */
   if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_MESA_PACK_INVERT) &&
       (source & COGL_READ_PIXELS_NO_FLIP) == 0 &&
-      !cogl_is_offscreen (framebuffer))
+      !COGL_IS_OFFSCREEN (framebuffer))
     {
       if (ctx->driver == COGL_DRIVER_GLES2)
         gl_pack_enum = GL_PACK_REVERSE_ROW_ORDER_ANGLE;
@@ -1415,7 +1415,7 @@ _cogl_framebuffer_gl_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
 
   /* NB: All offscreen rendering is done upside down so there is no need
    * to flip in this case... */
-  if (!cogl_is_offscreen (framebuffer) &&
+  if (!COGL_IS_OFFSCREEN (framebuffer) &&
       (source & COGL_READ_PIXELS_NO_FLIP) == 0 &&
       !pack_invert_set)
     {
diff --git a/cogl/cogl/driver/gl/cogl-pipeline-opengl.c b/cogl/cogl/driver/gl/cogl-pipeline-opengl.c
index bf3dbad9fe..802dd07fee 100644
--- a/cogl/cogl/driver/gl/cogl-pipeline-opengl.c
+++ b/cogl/cogl/driver/gl/cogl-pipeline-opengl.c
@@ -428,7 +428,7 @@ _cogl_pipeline_flush_color_blend_alpha_depth_state (
           /* If we are painting to an offscreen framebuffer then we
              need to invert the winding of the front face because
              everything is painted upside down */
-          invert_winding = cogl_is_offscreen (ctx->current_draw_buffer);
+          invert_winding = COGL_IS_OFFSCREEN (ctx->current_draw_buffer);
 
           switch (cull_face_state->front_winding)
             {
diff --git a/cogl/cogl/driver/gl/cogl-pipeline-progend-glsl.c 
b/cogl/cogl/driver/gl/cogl-pipeline-progend-glsl.c
index 88c0adc770..3064fc4dae 100644
--- a/cogl/cogl/driver/gl/cogl-pipeline-progend-glsl.c
+++ b/cogl/cogl/driver/gl/cogl-pipeline-progend-glsl.c
@@ -1016,7 +1016,7 @@ _cogl_pipeline_progend_glsl_pre_paint (CoglPipeline *pipeline,
   if (modelview_entry == NULL || projection_entry == NULL)
     return;
 
-  needs_flip = cogl_is_offscreen (ctx->current_draw_buffer);
+  needs_flip = COGL_IS_OFFSCREEN (ctx->current_draw_buffer);
 
   projection_changed =
     _cogl_matrix_entry_cache_maybe_update (&program_state->projection_cache,
diff --git a/cogl/cogl/winsys/cogl-winsys-egl-x11.c b/cogl/cogl/winsys/cogl-winsys-egl-x11.c
index f298720388..9ce1fa1085 100644
--- a/cogl/cogl/winsys/cogl-winsys-egl-x11.c
+++ b/cogl/cogl/winsys/cogl-winsys-egl-x11.c
@@ -81,7 +81,7 @@ find_onscreen_for_xid (CoglContext *context, uint32_t xid)
       CoglOnscreenEGL *egl_onscreen;
       CoglOnscreenXlib *xlib_onscreen;
 
-      if (!cogl_is_onscreen (framebuffer))
+      if (!COGL_IS_ONSCREEN (framebuffer))
         continue;
 
       egl_onscreen = COGL_ONSCREEN (framebuffer)->winsys;
@@ -99,7 +99,7 @@ flush_pending_resize_notifications_cb (void *data,
 {
   CoglFramebuffer *framebuffer = data;
 
-  if (cogl_is_onscreen (framebuffer))
+  if (COGL_IS_ONSCREEN (framebuffer))
     {
       CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
       CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
diff --git a/cogl/cogl/winsys/cogl-winsys-glx.c b/cogl/cogl/winsys/cogl-winsys-glx.c
index 5bef8d3951..759a15c715 100644
--- a/cogl/cogl/winsys/cogl-winsys-glx.c
+++ b/cogl/cogl/winsys/cogl-winsys-glx.c
@@ -178,7 +178,7 @@ find_onscreen_for_xid (CoglContext *context, uint32_t xid)
       CoglFramebuffer *framebuffer = l->data;
       CoglOnscreenXlib *xlib_onscreen;
 
-      if (!cogl_is_onscreen (framebuffer))
+      if (!COGL_IS_ONSCREEN (framebuffer))
         continue;
 
       /* Does the GLXEvent have the GLXDrawable or the X Window? */
@@ -331,7 +331,7 @@ flush_pending_notifications_cb (void *data,
 {
   CoglFramebuffer *framebuffer = data;
 
-  if (cogl_is_onscreen (framebuffer))
+  if (COGL_IS_ONSCREEN (framebuffer))
     {
       CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
       CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
@@ -633,7 +633,7 @@ update_all_outputs (CoglRenderer *renderer)
     {
       CoglFramebuffer *framebuffer = l->data;
 
-      if (!cogl_is_onscreen (framebuffer))
+      if (!COGL_IS_ONSCREEN (framebuffer))
         continue;
 
       update_output (COGL_ONSCREEN (framebuffer));
diff --git a/cogl/test-fixtures/test-utils.c b/cogl/test-fixtures/test-utils.c
index a59160f09e..597519d8f1 100644
--- a/cogl/test-fixtures/test-utils.c
+++ b/cogl/test-fixtures/test-utils.c
@@ -164,7 +164,7 @@ void
 test_utils_fini (void)
 {
   if (test_fb)
-    cogl_object_unref (test_fb);
+    g_object_unref (test_fb);
 
   if (test_ctx)
     cogl_object_unref (test_ctx);
diff --git a/cogl/tests/conform/test-backface-culling.c b/cogl/tests/conform/test-backface-culling.c
index 24cce4b946..508d2da912 100644
--- a/cogl/tests/conform/test-backface-culling.c
+++ b/cogl/tests/conform/test-backface-culling.c
@@ -303,12 +303,12 @@ test_backface_culling (void)
                                           state.width, state.height,
                                           TEST_UTILS_TEXTURE_NO_SLICING,
                                           COGL_TEXTURE_COMPONENTS_RGBA);
-  state.offscreen = cogl_offscreen_new_with_texture (tex);
+  state.offscreen = COGL_FRAMEBUFFER (cogl_offscreen_new_with_texture (tex));
   state.offscreen_tex = tex;
 
   paint (&state);
 
-  cogl_object_unref (state.offscreen);
+  g_object_unref (state.offscreen);
   cogl_object_unref (state.offscreen_tex);
   cogl_object_unref (state.texture);
 
diff --git a/cogl/tests/conform/test-framebuffer-get-bits.c b/cogl/tests/conform/test-framebuffer-get-bits.c
index d03f91b992..208b711e84 100644
--- a/cogl/tests/conform/test-framebuffer-get-bits.c
+++ b/cogl/tests/conform/test-framebuffer-get-bits.c
@@ -11,13 +11,13 @@ test_framebuffer_get_bits (void)
                                    16, 16); /* width/height */
   CoglOffscreen *offscreen_a =
     cogl_offscreen_new_with_texture (tex_a);
-  CoglFramebuffer *fb_a = offscreen_a;
+  CoglFramebuffer *fb_a = COGL_FRAMEBUFFER (offscreen_a);
   CoglTexture2D *tex_rgba =
     cogl_texture_2d_new_with_size (test_ctx,
                                    16, 16); /* width/height */
   CoglOffscreen *offscreen_rgba =
     cogl_offscreen_new_with_texture (tex_rgba);
-  CoglFramebuffer *fb_rgba = offscreen_rgba;
+  CoglFramebuffer *fb_rgba = COGL_FRAMEBUFFER (offscreen_rgba);
 
   cogl_texture_set_components (tex_a,
                                COGL_TEXTURE_COMPONENTS_A);
@@ -34,8 +34,8 @@ test_framebuffer_get_bits (void)
   g_assert_cmpint (cogl_framebuffer_get_blue_bits (fb_rgba), >=, 1);
   g_assert_cmpint (cogl_framebuffer_get_alpha_bits (fb_rgba), >=, 1);
 
-  cogl_object_unref (fb_rgba);
+  g_object_unref (fb_rgba);
   cogl_object_unref (tex_rgba);
-  cogl_object_unref (fb_a);
+  g_object_unref (fb_a);
   cogl_object_unref (tex_a);
 }
diff --git a/cogl/tests/conform/test-offscreen.c b/cogl/tests/conform/test-offscreen.c
index a5de870e55..5dfe17e418 100644
--- a/cogl/tests/conform/test-offscreen.c
+++ b/cogl/tests/conform/test-offscreen.c
@@ -44,6 +44,7 @@ test_paint (TestState *state)
   CoglTexture2D *tex_2d;
   CoglTexture *tex;
   CoglOffscreen *offscreen;
+  CoglFramebuffer *framebuffer;
   CoglPipeline *opaque_pipeline;
   CoglPipeline *texture_pipeline;
 
@@ -53,6 +54,7 @@ test_paint (TestState *state)
   tex = tex_2d;
 
   offscreen = cogl_offscreen_new_with_texture (tex);
+  framebuffer = COGL_FRAMEBUFFER (offscreen);
 
   /* Set a scale and translate transform on the window framebuffer
    * before switching to the offscreen framebuffer so we can verify it
@@ -76,20 +78,24 @@ test_paint (TestState *state)
   opaque_pipeline = cogl_pipeline_new (test_ctx);
   /* red, top left */
   cogl_pipeline_set_color4ub (opaque_pipeline, 0xff, 0x00, 0x00, 0xff);
-  cogl_framebuffer_draw_rectangle (offscreen, opaque_pipeline, -0.5, 0.5, 0, 0);
+  cogl_framebuffer_draw_rectangle (framebuffer, opaque_pipeline,
+                                   -0.5, 0.5, 0, 0);
   /* green, top right */
   cogl_pipeline_set_color4ub (opaque_pipeline, 0x00, 0xff, 0x00, 0xff);
-  cogl_framebuffer_draw_rectangle (offscreen, opaque_pipeline, 0, 0.5, 0.5, 0);
+  cogl_framebuffer_draw_rectangle (framebuffer, opaque_pipeline,
+                                   0, 0.5, 0.5, 0);
   /* blue, bottom left */
   cogl_pipeline_set_color4ub (opaque_pipeline, 0x00, 0x00, 0xff, 0xff);
-  cogl_framebuffer_draw_rectangle (offscreen, opaque_pipeline, -0.5, 0, 0, -0.5);
+  cogl_framebuffer_draw_rectangle (framebuffer, opaque_pipeline,
+                                   -0.5, 0, 0, -0.5);
   /* white, bottom right */
   cogl_pipeline_set_color4ub (opaque_pipeline, 0xff, 0xff, 0xff, 0xff);
-  cogl_framebuffer_draw_rectangle (offscreen, opaque_pipeline, 0, 0, 0.5, -0.5);
+  cogl_framebuffer_draw_rectangle (framebuffer, opaque_pipeline,
+                                   0, 0, 0.5, -0.5);
 
   /* Cogl should release the last reference when we call cogl_pop_framebuffer()
    */
-  cogl_object_unref (offscreen);
+  g_object_unref (offscreen);
 
   texture_pipeline = cogl_pipeline_new (test_ctx);
   cogl_pipeline_set_layer_texture (texture_pipeline, 0, tex);
@@ -121,6 +127,7 @@ test_flush (TestState *state)
   CoglTexture2D *tex_2d;
   CoglTexture *tex;
   CoglOffscreen *offscreen;
+  CoglFramebuffer *framebuffer;
   CoglColor clear_color;
   int i;
 
@@ -138,15 +145,16 @@ test_flush (TestState *state)
       tex = tex_2d;
 
       offscreen = cogl_offscreen_new_with_texture (tex);
+      framebuffer = COGL_FRAMEBUFFER (offscreen);
 
       cogl_color_init_from_4ub (&clear_color, 0, 0, 0, 255);
-      cogl_framebuffer_clear (offscreen, COGL_BUFFER_BIT_COLOR, &clear_color);
+      cogl_framebuffer_clear (framebuffer, COGL_BUFFER_BIT_COLOR, &clear_color);
 
-      cogl_framebuffer_draw_rectangle (offscreen, pipeline, -1, -1, 1, 1);
+      cogl_framebuffer_draw_rectangle (framebuffer, pipeline, -1, -1, 1, 1);
 
       if (i == 0)
         /* First time check using read pixels on the offscreen */
-        test_utils_check_region (offscreen,
+        test_utils_check_region (framebuffer,
                                  1, 1, 15, 15, 0xff0000ff);
       else if (i == 1)
         {
@@ -178,7 +186,7 @@ test_flush (TestState *state)
         }
 
       cogl_object_unref (tex_2d);
-      cogl_object_unref (offscreen);
+      g_object_unref (offscreen);
     }
 
   cogl_object_unref (pipeline);
diff --git a/cogl/tests/conform/test-pipeline-shader-state.c b/cogl/tests/conform/test-pipeline-shader-state.c
index 7bf0e72e65..69e6526f67 100644
--- a/cogl/tests/conform/test-pipeline-shader-state.c
+++ b/cogl/tests/conform/test-pipeline-shader-state.c
@@ -25,9 +25,9 @@ test_pipeline_shader_state (void)
 
   tex = cogl_texture_2d_new_with_size (test_ctx, 128, 128);
   offscreen = cogl_offscreen_new_with_texture (tex);
-  fb = offscreen;
+  fb = COGL_FRAMEBUFFER (offscreen);
   cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
-  cogl_object_unref (offscreen);
+  g_object_unref (offscreen);
 
   cogl_framebuffer_clear4f (test_fb, COGL_BUFFER_BIT_COLOR, 1, 1, 0, 1);
 
diff --git a/cogl/tests/conform/test-readpixels.c b/cogl/tests/conform/test-readpixels.c
index 64824b0aa9..8e23ad6183 100644
--- a/cogl/tests/conform/test-readpixels.c
+++ b/cogl/tests/conform/test-readpixels.c
@@ -83,7 +83,7 @@ on_paint (ClutterActor        *actor,
   g_free (pixels);
 
   cogl_pop_framebuffer ();
-  cogl_object_unref (offscreen);
+  g_object_unref (offscreen);
 
   /* Now verify reading back from an onscreen framebuffer...
    */
diff --git a/cogl/tests/conform/test-viewport.c b/cogl/tests/conform/test-viewport.c
index 3b58a2351f..d2961fdff5 100644
--- a/cogl/tests/conform/test-viewport.c
+++ b/cogl/tests/conform/test-viewport.c
@@ -337,7 +337,7 @@ on_paint (ClutterActor        *actor,
   cogl_set_viewport (0, 0, 10, 10);
 
   cogl_pop_framebuffer ();
-  cogl_object_unref (offscreen);
+  g_object_unref (offscreen);
 
   /*
    * Verify that the previous onscreen framebuffer's viewport was restored
diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c
index e0aec91152..cc08bccdbe 100644
--- a/src/backends/meta-screen-cast-stream-src.c
+++ b/src/backends/meta-screen-cast-stream-src.c
@@ -214,7 +214,7 @@ draw_cursor_sprite_via_offscreen (MetaScreenCastStreamSrc  *src,
   cogl_object_unref (bitmap_texture);
   if (!cogl_framebuffer_allocate (fb, error))
     {
-      cogl_object_unref (fb);
+      g_object_unref (fb);
       return FALSE;
     }
 
@@ -234,7 +234,7 @@ draw_cursor_sprite_via_offscreen (MetaScreenCastStreamSrc  *src,
                                 bitmap_width, bitmap_height,
                                 COGL_PIXEL_FORMAT_RGBA_8888_PRE,
                                 bitmap_data);
-  cogl_object_unref (fb);
+  g_object_unref (fb);
 
   return TRUE;
 }
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
index 68656e977d..d28a81f6de 100644
--- a/src/backends/native/meta-renderer-native.c
+++ b/src/backends/native/meta-renderer-native.c
@@ -1278,7 +1278,7 @@ queue_dummy_power_save_page_flip (CoglOnscreen *onscreen)
 
   renderer_native->power_save_page_flip_onscreens =
     g_list_prepend (renderer_native->power_save_page_flip_onscreens,
-                    cogl_object_ref (onscreen));
+                    g_object_ref (onscreen));
 }
 
 static void
@@ -1635,7 +1635,7 @@ create_dma_buf_framebuffer (MetaRendererNative  *renderer_native,
 
   if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (cogl_fbo), error))
     {
-      cogl_object_unref (cogl_fbo);
+      g_object_unref (cogl_fbo);
       return NULL;
     }
 
@@ -1706,11 +1706,11 @@ copy_shared_framebuffer_primary_gpu (CoglOnscreen                        *onscre
                               dumb_fb->height,
                               &error))
     {
-      cogl_object_unref (dmabuf_fb);
+      g_object_unref (dmabuf_fb);
       return FALSE;
     }
 
-  cogl_object_unref (dmabuf_fb);
+  g_object_unref (dmabuf_fb);
 
   g_clear_object (&secondary_gpu_state->gbm.next_fb);
   buffer_dumb = meta_drm_buffer_dumb_new (dumb_fb->fb_id);
@@ -2051,7 +2051,7 @@ meta_renderer_native_create_dma_buf (CoglRenderer  *cogl_renderer,
                                    width, height, stride, offset, bpp,
                                    new_bo,
                                    (GDestroyNotify) gbm_bo_destroy);
-        cogl_object_unref (dmabuf_fb);
+        g_object_unref (dmabuf_fb);
         return dmabuf_handle;
       }
       break;
@@ -2790,7 +2790,7 @@ meta_renderer_native_create_onscreen (MetaRendererNative   *renderer_native,
 
   if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (onscreen), error))
     {
-      cogl_object_unref (onscreen);
+      g_object_unref (onscreen);
       return NULL;
     }
 
@@ -2805,7 +2805,7 @@ meta_renderer_native_create_onscreen (MetaRendererNative   *renderer_native,
     {
       if (!init_secondary_gpu_state (renderer_native, onscreen, error))
         {
-          cogl_object_unref (onscreen);
+          g_object_unref (onscreen);
           return NULL;
         }
     }
@@ -2836,7 +2836,7 @@ meta_renderer_native_create_offscreen (MetaRendererNative    *renderer,
   cogl_object_unref (tex);
   if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (fb), error))
     {
-      cogl_object_unref (fb);
+      g_object_unref (fb);
       return FALSE;
     }
 
@@ -3075,20 +3075,20 @@ meta_renderer_native_create_view (MetaRenderer       *renderer,
                        "transform", view_transform,
                        "refresh-rate", crtc_mode_info->refresh_rate,
                        NULL);
-  g_clear_pointer (&offscreen, cogl_object_unref);
+  g_clear_object (&offscreen);
 
   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 (onscreen);
       g_object_unref (view);
       g_error_free (error);
       return NULL;
     }
 
-  cogl_object_unref (onscreen);
+  g_object_unref (onscreen);
 
   /* Ensure we don't point to stale surfaces when creating the offscreen */
   onscreen_egl = onscreen->winsys;
@@ -3857,7 +3857,7 @@ meta_renderer_native_finalize (GObject *object)
   if (renderer_native->power_save_page_flip_onscreens)
     {
       g_list_free_full (renderer_native->power_save_page_flip_onscreens,
-                        (GDestroyNotify) cogl_object_unref);
+                        g_object_unref);
       g_clear_handle_id (&renderer_native->power_save_page_flip_source_id,
                          g_source_remove);
     }
diff --git a/src/backends/x11/meta-stage-x11.c b/src/backends/x11/meta-stage-x11.c
index 684b711b71..18c64b6ca2 100644
--- a/src/backends/x11/meta-stage-x11.c
+++ b/src/backends/x11/meta-stage-x11.c
@@ -251,7 +251,7 @@ meta_stage_x11_unrealize (ClutterStageWindow *stage_window)
 
   clutter_stage_window_parent_iface->unrealize (stage_window);
 
-  g_clear_pointer (&stage_x11->onscreen, cogl_object_unref);
+  g_clear_object (&stage_x11->onscreen);
 }
 
 static gboolean
@@ -289,7 +289,7 @@ meta_stage_x11_realize (ClutterStageWindow *stage_window)
     {
       g_warning ("Failed to allocate stage: %s", error->message);
       g_error_free (error);
-      cogl_object_unref (stage_x11->onscreen);
+      g_object_unref (stage_x11->onscreen);
       abort();
     }
 
diff --git a/src/compositor/meta-background.c b/src/compositor/meta-background.c
index 71eca7a95e..736f582908 100644
--- a/src/compositor/meta-background.c
+++ b/src/compositor/meta-background.c
@@ -94,11 +94,8 @@ free_fbos (MetaBackground *self)
   for (i = 0; i < self->n_monitors; i++)
     {
       MetaBackgroundMonitor *monitor = &self->monitors[i];
-      if (monitor->fbo)
-        {
-          cogl_object_unref (monitor->fbo);
-          monitor->fbo = NULL;
-        }
+
+      g_clear_object (&monitor->fbo);
       if (monitor->texture)
         {
           cogl_object_unref (monitor->texture);
@@ -698,7 +695,7 @@ ensure_wallpaper_texture (MetaBackground *self,
 
           cogl_object_unref (self->wallpaper_texture);
           self->wallpaper_texture = NULL;
-          cogl_object_unref (fbo);
+          g_object_unref (fbo);
 
           self->wallpaper_allocation_failed = TRUE;
           return FALSE;
@@ -723,7 +720,7 @@ ensure_wallpaper_texture (MetaBackground *self,
           cogl_object_unref (pipeline);
         }
 
-      cogl_object_unref (fbo);
+      g_object_unref (fbo);
     }
 
   return self->wallpaper_texture != NULL;
@@ -860,8 +857,7 @@ meta_background_get_texture (MetaBackground         *self,
            */
           cogl_object_unref (monitor->texture);
           monitor->texture = NULL;
-          cogl_object_unref (monitor->fbo);
-          monitor->fbo = NULL;
+          g_clear_object (&monitor->fbo);
 
           g_error_free (catch_error);
           return NULL;
diff --git a/src/compositor/meta-compositor-native.c b/src/compositor/meta-compositor-native.c
index 92b0aedf9c..00f66b70d4 100644
--- a/src/compositor/meta-compositor-native.c
+++ b/src/compositor/meta-compositor-native.c
@@ -98,7 +98,7 @@ maybe_assign_primary_plane (MetaCompositor *compositor)
     return;
 
   framebuffer = clutter_stage_view_get_framebuffer (CLUTTER_STAGE_VIEW (view));
-  if (!cogl_is_onscreen (framebuffer))
+  if (!COGL_IS_ONSCREEN (framebuffer))
     return;
 
   surface_actor = meta_window_actor_get_surface (window_actor);
diff --git a/src/compositor/meta-shaped-texture.c b/src/compositor/meta-shaped-texture.c
index 2637a63fe4..6271142f2b 100644
--- a/src/compositor/meta-shaped-texture.c
+++ b/src/compositor/meta-shaped-texture.c
@@ -1402,7 +1402,7 @@ get_image_via_offscreen (MetaShapedTexture     *stex,
   if (!cogl_framebuffer_allocate (fb, &error))
     {
       g_error_free (error);
-      cogl_object_unref (fb);
+      g_object_unref (fb);
       return FALSE;
     }
 
@@ -1445,7 +1445,7 @@ get_image_via_offscreen (MetaShapedTexture     *stex,
                                 clip->width, clip->height,
                                 CLUTTER_CAIRO_FORMAT_ARGB32,
                                 cairo_image_surface_get_data (surface));
-  cogl_object_unref (fb);
+  g_object_unref (fb);
 
   cairo_surface_mark_dirty (surface);
 
diff --git a/src/compositor/meta-texture-tower.c b/src/compositor/meta-texture-tower.c
index cb7b997262..ab4d61d26f 100644
--- a/src/compositor/meta-texture-tower.c
+++ b/src/compositor/meta-texture-tower.c
@@ -132,11 +132,7 @@ meta_texture_tower_set_base_texture (MetaTextureTower *tower,
               tower->textures[i] = NULL;
             }
 
-          if (tower->fbos[i] != NULL)
-            {
-              cogl_object_unref (tower->fbos[i]);
-              tower->fbos[i] = NULL;
-            }
+          g_clear_object (&tower->fbos[i]);
         }
 
       cogl_object_unref (tower->textures[0]);
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index 523fff8fb1..5eb37a9e92 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -1486,7 +1486,7 @@ meta_window_actor_get_image (MetaWindowActor *self,
     {
       g_warning ("Failed to allocate framebuffer for screenshot: %s",
                  error->message);
-      cogl_object_unref (framebuffer);
+      g_object_unref (framebuffer);
       cogl_object_unref (texture);
       goto out;
     }
@@ -1533,7 +1533,7 @@ meta_window_actor_get_image (MetaWindowActor *self,
                                 CLUTTER_CAIRO_FORMAT_ARGB32,
                                 cairo_image_surface_get_data (surface));
 
-  cogl_object_unref (framebuffer);
+  g_object_unref (framebuffer);
 
   cairo_surface_mark_dirty (surface);
 
diff --git a/src/tests/clutter/interactive/test-cogl-offscreen.c 
b/src/tests/clutter/interactive/test-cogl-offscreen.c
index 1ce7a1540e..4f2e6bddb1 100644
--- a/src/tests/clutter/interactive/test-cogl-offscreen.c
+++ b/src/tests/clutter/interactive/test-cogl-offscreen.c
@@ -146,7 +146,7 @@ test_coglbox_dispose (GObject *object)
   priv = TEST_COGLBOX_GET_PRIVATE (object);
 
   cogl_object_unref (priv->texture_id);
-  cogl_object_unref (priv->framebuffer);
+  g_object_unref (priv->framebuffer);
 
   G_OBJECT_CLASS (test_coglbox_parent_class)->dispose (object);
 }


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