[mutter] cogl/framebuffer: Move public struct fields to private struct



commit aa99e505adf96865fc54c11db643c2924a73835f
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Mon Oct 12 23:31:38 2020 +0200

    cogl/framebuffer: Move public struct fields to private struct
    
    This will limit accidental manipulation of the framebuffer struct
    fields, while also paving the way to change to GObject type hierarchy.
    
    https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1496

 cogl/cogl-pango/cogl-pango-display-list.c  |   2 +-
 cogl/cogl/cogl-attribute.c                 |   4 +-
 cogl/cogl/cogl-clip-stack.c                |   2 +-
 cogl/cogl/cogl-fence.c                     |  21 +-
 cogl/cogl/cogl-framebuffer-private.h       |  99 ++--
 cogl/cogl/cogl-framebuffer.c               | 907 +++++++++++++++++++++--------
 cogl/cogl/cogl-journal.c                   |  13 +-
 cogl/cogl/cogl-onscreen.c                  |  44 +-
 cogl/cogl/cogl-primitives.c                |   8 +-
 cogl/cogl/driver/gl/cogl-attribute-gl.c    |   2 +-
 cogl/cogl/driver/gl/cogl-clip-stack-gl.c   |  10 +-
 cogl/cogl/driver/gl/cogl-framebuffer-gl.c  | 171 +++---
 cogl/cogl/driver/gl/cogl-pipeline-opengl.c |   7 +-
 cogl/cogl/winsys/cogl-winsys-egl-private.h |   6 +-
 cogl/cogl/winsys/cogl-winsys-egl-x11.c     |  19 +-
 cogl/cogl/winsys/cogl-winsys-egl.c         |  44 +-
 cogl/cogl/winsys/cogl-winsys-glx.c         |  58 +-
 src/backends/native/meta-renderer-native.c |  27 +-
 18 files changed, 934 insertions(+), 510 deletions(-)
---
diff --git a/cogl/cogl-pango/cogl-pango-display-list.c b/cogl/cogl-pango/cogl-pango-display-list.c
index caf202d06e..2e5b6414fc 100644
--- a/cogl/cogl-pango/cogl-pango-display-list.c
+++ b/cogl/cogl-pango/cogl-pango-display-list.c
@@ -259,7 +259,7 @@ emit_vertex_buffer_geometry (CoglFramebuffer *fb,
                              CoglPipeline *pipeline,
                              CoglPangoDisplayListNode *node)
 {
-  CoglContext *ctx = fb->context;
+  CoglContext *ctx = cogl_framebuffer_get_context (fb);
 
   /* It's expensive to go through the Cogl journal for large runs
    * of text in part because the journal transforms the quads in software
diff --git a/cogl/cogl/cogl-attribute.c b/cogl/cogl/cogl-attribute.c
index f42bc9f9b6..a31906739a 100644
--- a/cogl/cogl/cogl-attribute.c
+++ b/cogl/cogl/cogl-attribute.c
@@ -587,12 +587,12 @@ _cogl_flush_attributes_state (CoglFramebuffer *framebuffer,
                               CoglAttribute **attributes,
                               int n_attributes)
 {
-  CoglContext *ctx = framebuffer->context;
+  CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
   CoglFlushLayerState layers_state;
   CoglPipeline *copy = NULL;
 
   if (!(flags & COGL_DRAW_SKIP_JOURNAL_FLUSH))
-    _cogl_journal_flush (framebuffer->journal);
+    _cogl_framebuffer_flush_journal (framebuffer);
 
   layers_state.unit = 0;
   layers_state.options.flags = 0;
diff --git a/cogl/cogl/cogl-clip-stack.c b/cogl/cogl/cogl-clip-stack.c
index e158187213..66adfae364 100644
--- a/cogl/cogl/cogl-clip-stack.c
+++ b/cogl/cogl/cogl-clip-stack.c
@@ -428,7 +428,7 @@ void
 _cogl_clip_stack_flush (CoglClipStack *stack,
                         CoglFramebuffer *framebuffer)
 {
-  CoglContext *ctx = framebuffer->context;
+  CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
 
   ctx->driver_vtable->clip_stack_flush (stack, framebuffer);
 }
diff --git a/cogl/cogl/cogl-fence.c b/cogl/cogl/cogl-fence.c
index eb40978b12..ff1a7dfcac 100644
--- a/cogl/cogl/cogl-fence.c
+++ b/cogl/cogl/cogl-fence.c
@@ -45,7 +45,7 @@ cogl_fence_closure_get_user_data (CoglFenceClosure *closure)
 static void
 _cogl_fence_check (CoglFenceClosure *fence)
 {
-  CoglContext *context = fence->framebuffer->context;
+  CoglContext *context = cogl_framebuffer_get_context (fence->framebuffer);
 
   if (fence->type == FENCE_TYPE_WINSYS)
     {
@@ -95,10 +95,11 @@ _cogl_fence_poll_prepare (void *source)
    * hit and the main loop might block forever */
   for (l = context->framebuffers; l; l = l->next)
     {
-      CoglFramebuffer *fb = l->data;
+      CoglFramebuffer *framebuffer = l->data;
+      CoglJournal *journal = cogl_framebuffer_get_journal (framebuffer);
 
-      if (!_cogl_list_empty (&fb->journal->pending_fences))
-        _cogl_framebuffer_flush_journal (fb);
+      if (!_cogl_list_empty (&journal->pending_fences))
+        _cogl_framebuffer_flush_journal (framebuffer);
     }
 
   if (!_cogl_list_empty (&context->fences))
@@ -110,7 +111,7 @@ _cogl_fence_poll_prepare (void *source)
 void
 _cogl_fence_submit (CoglFenceClosure *fence)
 {
-  CoglContext *context = fence->framebuffer->context;
+  CoglContext *context = cogl_framebuffer_get_context (fence->framebuffer);
   const CoglWinsysVtable *winsys = _cogl_context_get_winsys (context);
 
   fence->type = FENCE_TYPE_ERROR;
@@ -156,8 +157,8 @@ cogl_framebuffer_add_fence_callback (CoglFramebuffer *framebuffer,
                                      CoglFenceCallback callback,
                                      void *user_data)
 {
-  CoglContext *context = framebuffer->context;
-  CoglJournal *journal = framebuffer->journal;
+  CoglContext *context = cogl_framebuffer_get_context (framebuffer);
+  CoglJournal *journal = cogl_framebuffer_get_journal (framebuffer);
   CoglFenceClosure *fence;
 
   if (!COGL_FLAGS_GET (context->features, COGL_FEATURE_ID_FENCE))
@@ -184,7 +185,7 @@ void
 cogl_framebuffer_cancel_fence_callback (CoglFramebuffer *framebuffer,
                                         CoglFenceClosure *fence)
 {
-  CoglContext *context = framebuffer->context;
+  CoglContext *context = cogl_framebuffer_get_context (framebuffer);
 
   if (fence->type == FENCE_TYPE_PENDING)
     {
@@ -214,8 +215,8 @@ cogl_framebuffer_cancel_fence_callback (CoglFramebuffer *framebuffer,
 void
 _cogl_fence_cancel_fences_for_framebuffer (CoglFramebuffer *framebuffer)
 {
-  CoglJournal *journal = framebuffer->journal;
-  CoglContext *context = framebuffer->context;
+  CoglJournal *journal = cogl_framebuffer_get_journal (framebuffer);
+  CoglContext *context = cogl_framebuffer_get_context (framebuffer);
   CoglFenceClosure *fence, *tmp;
 
   while (!_cogl_list_empty (&journal->pending_fences))
diff --git a/cogl/cogl/cogl-framebuffer-private.h b/cogl/cogl/cogl-framebuffer-private.h
index 4250897a6a..8d3f2c8732 100644
--- a/cogl/cogl/cogl-framebuffer-private.h
+++ b/cogl/cogl/cogl-framebuffer-private.h
@@ -119,69 +119,7 @@ typedef struct
 struct _CoglFramebuffer
 {
   CoglObject _parent;
-
-  CoglContext *context;
-  CoglFramebufferType type;
-
-  /* The user configuration before allocation... */
-  CoglFramebufferConfig config;
-
-  int width;
-  int height;
-  /* Format of the pixels in the framebuffer (including the expected
-     premult state) */
-  CoglPixelFormat internal_format;
-  gboolean allocated;
-
-  CoglMatrixStack *modelview_stack;
-  CoglMatrixStack *projection_stack;
-  float viewport_x;
-  float viewport_y;
-  float viewport_width;
-  float viewport_height;
-  int viewport_age;
-  int viewport_age_for_scissor_workaround;
-
-  CoglClipStack *clip_stack;
-
-  gboolean dither_enabled;
-  gboolean depth_writing_enabled;
-  CoglStereoMode stereo_mode;
-
-  /* We journal the textured rectangles we want to submit to OpenGL so
-   * we have an opportunity to batch them together into less draw
-   * calls. */
-  CoglJournal *journal;
-
-  /* The scene of a given framebuffer may depend on images in other
-   * framebuffers... */
-  GList *deps;
-
-  /* As part of an optimization for reading-back single pixels from a
-   * framebuffer in some simple cases where the geometry is still
-   * available in the journal we need to track the bounds of the last
-   * region cleared, its color and we need to track when something
-   * does in fact draw to that region so it is no longer clear.
-   */
-  float clear_color_red;
-  float clear_color_green;
-  float clear_color_blue;
-  float clear_color_alpha;
-  int clear_clip_x0;
-  int clear_clip_y0;
-  int clear_clip_x1;
-  int clear_clip_y1;
-  gboolean clear_clip_dirty;
-
-  int samples_per_pixel;
-
-  /* Whether the depth buffer was enabled for this framebuffer,
- * usually means it needs to be cleared before being reused next.
- */
-  gboolean depth_buffer_clear_needed;
-
-  gpointer driver_private;
-  GDestroyNotify driver_private_destroy;
+  gpointer priv;
 };
 
 typedef enum
@@ -224,6 +162,25 @@ _cogl_framebuffer_init (CoglFramebuffer *framebuffer,
                         int width,
                         int height);
 
+gboolean
+cogl_framebuffer_is_allocated (CoglFramebuffer *framebuffer);
+
+void
+cogl_framebuffer_init_config (CoglFramebuffer             *framebuffer,
+                              const CoglFramebufferConfig *config);
+
+const CoglFramebufferConfig *
+cogl_framebuffer_get_config (CoglFramebuffer *framebuffer);
+
+void
+cogl_framebuffer_update_samples_per_pixel (CoglFramebuffer *framebuffer,
+                                           int              samples_per_pixel);
+
+void
+cogl_framebuffer_update_size (CoglFramebuffer *framebuffer,
+                              int              width,
+                              int              height);
+
 /* XXX: For a public api we might instead want a way to explicitly
  * set the _premult status of a framebuffer or what components we
  * care about instead of exposing the CoglPixelFormat
@@ -240,6 +197,9 @@ void
 _cogl_framebuffer_set_internal_format (CoglFramebuffer *framebuffer,
                                        CoglPixelFormat internal_format);
 
+CoglPixelFormat
+cogl_framebuffer_get_internal_format (CoglFramebuffer *framebuffer);
+
 void _cogl_framebuffer_free (CoglFramebuffer *framebuffer);
 
 const CoglWinsysVtable *
@@ -256,6 +216,9 @@ _cogl_framebuffer_clear_without_flush4f (CoglFramebuffer *framebuffer,
 void
 _cogl_framebuffer_mark_clear_clip_dirty (CoglFramebuffer *framebuffer);
 
+void
+cogl_framebuffer_set_depth_buffer_clear_needed (CoglFramebuffer *framebuffer);
+
 /*
  * _cogl_framebuffer_get_clip_stack:
  * @framebuffer: A #CoglFramebuffer
@@ -354,6 +317,13 @@ void
 cogl_framebuffer_set_viewport4fv (CoglFramebuffer *framebuffer,
                                   float *viewport);
 
+void
+cogl_framebuffer_get_viewport4f (CoglFramebuffer *framebuffer,
+                                 float           *viewport_x,
+                                 float           *viewport_y,
+                                 float           *viewport_width,
+                                 float           *viewport_height);
+
 unsigned long
 _cogl_framebuffer_compare (CoglFramebuffer *a,
                            CoglFramebuffer *b,
@@ -397,6 +367,9 @@ _cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
 COGL_EXPORT int
 _cogl_framebuffer_get_stencil_bits (CoglFramebuffer *framebuffer);
 
+CoglJournal *
+cogl_framebuffer_get_journal (CoglFramebuffer *framebuffer);
+
 gpointer
 cogl_framebuffer_get_driver_private (CoglFramebuffer *framebuffer);
 
diff --git a/cogl/cogl/cogl-framebuffer.c b/cogl/cogl/cogl-framebuffer.c
index 32b0240cdb..b89f84fa47 100644
--- a/cogl/cogl/cogl-framebuffer.c
+++ b/cogl/cogl/cogl-framebuffer.c
@@ -59,6 +59,72 @@ extern CoglObjectClass _cogl_onscreen_class;
 static CoglUserDataKey wire_pipeline_key;
 #endif
 
+typedef struct _CoglFramebufferPrivate
+{
+  CoglContext *context;
+  CoglFramebufferType type;
+
+  /* The user configuration before allocation... */
+  CoglFramebufferConfig config;
+
+  int width;
+  int height;
+  /* Format of the pixels in the framebuffer (including the expected
+     premult state) */
+  CoglPixelFormat internal_format;
+  gboolean allocated;
+
+  CoglMatrixStack *modelview_stack;
+  CoglMatrixStack *projection_stack;
+  float viewport_x;
+  float viewport_y;
+  float viewport_width;
+  float viewport_height;
+  int viewport_age;
+  int viewport_age_for_scissor_workaround;
+
+  CoglClipStack *clip_stack;
+
+  gboolean dither_enabled;
+  gboolean depth_writing_enabled;
+  CoglStereoMode stereo_mode;
+
+  /* We journal the textured rectangles we want to submit to OpenGL so
+   * we have an opportunity to batch them together into less draw
+   * calls. */
+  CoglJournal *journal;
+
+  /* The scene of a given framebuffer may depend on images in other
+   * framebuffers... */
+  GList *deps;
+
+  /* As part of an optimization for reading-back single pixels from a
+   * framebuffer in some simple cases where the geometry is still
+   * available in the journal we need to track the bounds of the last
+   * region cleared, its color and we need to track when something
+   * does in fact draw to that region so it is no longer clear.
+   */
+  float clear_color_red;
+  float clear_color_green;
+  float clear_color_blue;
+  float clear_color_alpha;
+  int clear_clip_x0;
+  int clear_clip_y0;
+  int clear_clip_x1;
+  int clear_clip_y1;
+  gboolean clear_clip_dirty;
+
+  int samples_per_pixel;
+
+  /* Whether the depth buffer was enabled for this framebuffer,
+ * usually means it needs to be cleared before being reused next.
+ */
+  gboolean depth_buffer_clear_needed;
+
+  gpointer driver_private;
+  GDestroyNotify driver_private_destroy;
+} CoglFramebufferPrivate;
+
 static void _cogl_offscreen_free (CoglOffscreen *offscreen);
 
 COGL_OBJECT_DEFINE_WITH_CODE_GTYPE (Offscreen, offscreen,
@@ -74,6 +140,12 @@ COGL_GTYPE_DEFINE_INTERFACE (Framebuffer, framebuffer);
  * abstract class manually.
  */
 
+static CoglFramebufferPrivate *
+cogl_framebuffer_get_instance_private (CoglFramebuffer *framebuffer)
+{
+  return framebuffer->priv;
+}
+
 uint32_t
 cogl_framebuffer_error_quark (void)
 {
@@ -99,37 +171,40 @@ _cogl_framebuffer_init (CoglFramebuffer *framebuffer,
                         int width,
                         int height)
 {
-  framebuffer->context = ctx;
+  CoglFramebufferPrivate *priv;
 
-  framebuffer->type = type;
-  framebuffer->width = width;
-  framebuffer->height = height;
-  framebuffer->internal_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE;
-  framebuffer->viewport_x = 0;
-  framebuffer->viewport_y = 0;
-  framebuffer->viewport_width = width;
-  framebuffer->viewport_height = height;
-  framebuffer->viewport_age = 0;
-  framebuffer->viewport_age_for_scissor_workaround = -1;
-  framebuffer->dither_enabled = TRUE;
-  framebuffer->depth_writing_enabled = TRUE;
-  framebuffer->depth_buffer_clear_needed = TRUE;
+  framebuffer->priv = priv = g_new0 (CoglFramebufferPrivate, 1);
+  priv->context = ctx;
 
-  framebuffer->modelview_stack = cogl_matrix_stack_new (ctx);
-  framebuffer->projection_stack = cogl_matrix_stack_new (ctx);
+  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_age = 0;
+  priv->viewport_age_for_scissor_workaround = -1;
+  priv->dither_enabled = TRUE;
+  priv->depth_writing_enabled = TRUE;
+  priv->depth_buffer_clear_needed = TRUE;
 
-  framebuffer->samples_per_pixel = 0;
+  priv->modelview_stack = cogl_matrix_stack_new (ctx);
+  priv->projection_stack = cogl_matrix_stack_new (ctx);
 
-  framebuffer->clip_stack = NULL;
+  priv->samples_per_pixel = 0;
 
-  framebuffer->journal = _cogl_journal_new (framebuffer);
+  priv->clip_stack = NULL;
+
+  priv->journal = _cogl_journal_new (framebuffer);
 
   /* Ensure we know the framebuffer->clear_color* members can't be
    * referenced for our fast-path read-pixel optimization (see
    * _cogl_journal_try_read_pixel()) until some region of the
    * framebuffer is initialized.
    */
-  framebuffer->clear_clip_dirty = TRUE;
+  priv->clear_clip_dirty = TRUE;
 
   /* XXX: We have to maintain a central list of all framebuffers
    * because at times we need to be able to flush all known journals.
@@ -164,25 +239,59 @@ void
 _cogl_framebuffer_set_internal_format (CoglFramebuffer *framebuffer,
                                        CoglPixelFormat internal_format)
 {
-  framebuffer->internal_format = internal_format;
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
+  priv->internal_format = internal_format;
+}
+
+CoglPixelFormat
+cogl_framebuffer_get_internal_format (CoglFramebuffer *framebuffer)
+{
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
+  return priv->internal_format;
+}
+
+const CoglFramebufferConfig *
+cogl_framebuffer_get_config (CoglFramebuffer *framebuffer)
+{
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
+  return &priv->config;
+}
+
+void
+cogl_framebuffer_init_config (CoglFramebuffer             *framebuffer,
+                              const CoglFramebufferConfig *config)
+{
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
+  priv->config = *config;
+  cogl_object_ref (priv->config.swap_chain);
 }
 
 void
 _cogl_framebuffer_free (CoglFramebuffer *framebuffer)
 {
-  CoglContext *ctx = framebuffer->context;
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+  CoglContext *ctx = priv->context;
 
   _cogl_fence_cancel_fences_for_framebuffer (framebuffer);
 
-  _cogl_clip_stack_unref (framebuffer->clip_stack);
+  _cogl_clip_stack_unref (priv->clip_stack);
 
-  cogl_object_unref (framebuffer->modelview_stack);
-  framebuffer->modelview_stack = NULL;
+  cogl_object_unref (priv->modelview_stack);
+  priv->modelview_stack = NULL;
 
-  cogl_object_unref (framebuffer->projection_stack);
-  framebuffer->projection_stack = NULL;
+  cogl_object_unref (priv->projection_stack);
+  priv->projection_stack = NULL;
 
-  cogl_object_unref (framebuffer->journal);
+  cogl_object_unref (priv->journal);
 
   ctx->framebuffers = g_list_remove (ctx->framebuffers, framebuffer);
 
@@ -191,16 +300,21 @@ _cogl_framebuffer_free (CoglFramebuffer *framebuffer)
   if (ctx->current_read_buffer == framebuffer)
     ctx->current_read_buffer = NULL;
 
-  if (framebuffer->driver_private_destroy)
-    framebuffer->driver_private_destroy (framebuffer->driver_private);
-  framebuffer->driver_private_destroy = NULL;
-  framebuffer->driver_private = NULL;
+  if (priv->driver_private_destroy)
+    priv->driver_private_destroy (priv->driver_private);
+  priv->driver_private_destroy = NULL;
+  priv->driver_private = NULL;
+
+  g_clear_pointer (&framebuffer->priv, g_free);
 }
 
 const CoglWinsysVtable *
 _cogl_framebuffer_get_winsys (CoglFramebuffer *framebuffer)
 {
-  return framebuffer->context->display->renderer->winsys_vtable;
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
+  return priv->context->display->renderer->winsys_vtable;
 }
 
 /* This version of cogl_clear can be used internally as an alternative
@@ -215,7 +329,9 @@ _cogl_framebuffer_clear_without_flush4f (CoglFramebuffer *framebuffer,
                                          float blue,
                                          float alpha)
 {
-  CoglContext *ctx = framebuffer->context;
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+  CoglContext *ctx = priv->context;
 
   if (!buffers)
     {
@@ -238,7 +354,19 @@ _cogl_framebuffer_clear_without_flush4f (CoglFramebuffer *framebuffer,
 void
 _cogl_framebuffer_mark_clear_clip_dirty (CoglFramebuffer *framebuffer)
 {
-  framebuffer->clear_clip_dirty = TRUE;
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
+  priv->clear_clip_dirty = TRUE;
+}
+
+void
+cogl_framebuffer_set_depth_buffer_clear_needed (CoglFramebuffer *framebuffer)
+{
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
+  priv->depth_buffer_clear_needed = TRUE;
 }
 
 void
@@ -249,6 +377,8 @@ cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer,
                           float blue,
                           float alpha)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
   CoglClipStack *clip_stack = _cogl_framebuffer_get_clip_stack (framebuffer);
   gboolean had_depth_and_color_buffer_bits;
   int scissor_x0;
@@ -260,7 +390,7 @@ cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer,
     (buffers & COGL_BUFFER_BIT_DEPTH) &&
     (buffers & COGL_BUFFER_BIT_COLOR);
 
-  if (!framebuffer->depth_buffer_clear_needed &&
+  if (!priv->depth_buffer_clear_needed &&
       (buffers & COGL_BUFFER_BIT_DEPTH))
     buffers &= ~(COGL_BUFFER_BIT_DEPTH);
 
@@ -306,15 +436,15 @@ cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer,
    * appropriate here.
    */
   if (had_depth_and_color_buffer_bits &&
-      !framebuffer->clear_clip_dirty &&
-      framebuffer->clear_color_red == red &&
-      framebuffer->clear_color_green == green &&
-      framebuffer->clear_color_blue == blue &&
-      framebuffer->clear_color_alpha == alpha &&
-      scissor_x0 == framebuffer->clear_clip_x0 &&
-      scissor_y0 == framebuffer->clear_clip_y0 &&
-      scissor_x1 == framebuffer->clear_clip_x1 &&
-      scissor_y1 == framebuffer->clear_clip_y1)
+      !priv->clear_clip_dirty &&
+      priv->clear_color_red == red &&
+      priv->clear_color_green == green &&
+      priv->clear_color_blue == blue &&
+      priv->clear_color_alpha == alpha &&
+      scissor_x0 == priv->clear_clip_x0 &&
+      scissor_y0 == priv->clear_clip_y0 &&
+      scissor_x1 == priv->clear_clip_x1 &&
+      scissor_y1 == priv->clear_clip_y1)
     {
       /* NB: We only have to consider the clip state of journal
        * entries if the current clear is clipped since otherwise we
@@ -333,17 +463,17 @@ cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer,
            * it's possible for some false negatives here but that will
            * just result in us falling back to a real clear.
            */
-          if (_cogl_journal_all_entries_within_bounds (framebuffer->journal,
+          if (_cogl_journal_all_entries_within_bounds (priv->journal,
                                                        scissor_x0, scissor_y0,
                                                        scissor_x1, scissor_y1))
             {
-              _cogl_journal_discard (framebuffer->journal);
+              _cogl_journal_discard (priv->journal);
               goto cleared;
             }
         }
       else
         {
-          _cogl_journal_discard (framebuffer->journal);
+          _cogl_journal_discard (priv->journal);
           goto cleared;
         }
     }
@@ -368,7 +498,7 @@ cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer,
   if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_RECTANGLES)) &&
       buffers & COGL_BUFFER_BIT_COLOR)
     {
-      framebuffer->context->journal_rectangles_color = 1;
+      priv->context->journal_rectangles_color = 1;
     }
 
   COGL_NOTE (DRAW, "Clear end");
@@ -378,7 +508,7 @@ cleared:
   _cogl_framebuffer_mark_clear_clip_dirty (framebuffer);
 
   if (buffers & COGL_BUFFER_BIT_DEPTH)
-    framebuffer->depth_buffer_clear_needed = FALSE;
+    priv->depth_buffer_clear_needed = FALSE;
 
   if (had_depth_and_color_buffer_bits)
     {
@@ -386,19 +516,19 @@ cleared:
        * scenes where the whole frame is in the journal we need to
        * track the cleared color of the framebuffer in case the point
        * read doesn't intersect any of the journal rectangles. */
-      framebuffer->clear_clip_dirty = FALSE;
-      framebuffer->clear_color_red = red;
-      framebuffer->clear_color_green = green;
-      framebuffer->clear_color_blue = blue;
-      framebuffer->clear_color_alpha = alpha;
+      priv->clear_clip_dirty = FALSE;
+      priv->clear_color_red = red;
+      priv->clear_color_green = green;
+      priv->clear_color_blue = blue;
+      priv->clear_color_alpha = alpha;
 
       /* NB: A clear may be scissored so we need to track the extents
        * that the clear is applicable too... */
       _cogl_clip_stack_get_bounds (clip_stack,
-                                   &framebuffer->clear_clip_x0,
-                                   &framebuffer->clear_clip_y0,
-                                   &framebuffer->clear_clip_x1,
-                                   &framebuffer->clear_clip_y1);
+                                   &priv->clear_clip_x0,
+                                   &priv->clear_clip_y0,
+                                   &priv->clear_clip_x1,
+                                   &priv->clear_clip_y1);
     }
 }
 
@@ -428,10 +558,13 @@ cogl_framebuffer_clear (CoglFramebuffer *framebuffer,
 static void
 ensure_size_initialized (CoglFramebuffer *framebuffer)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
   /* In the case of offscreen framebuffers backed by a texture then
    * until that texture has been allocated we might not know the size
    * of the framebuffer */
-  if (framebuffer->width < 0)
+  if (priv->width < 0)
     {
       /* Currently we assume the size is always initialized for
        * onscreen framebuffers. */
@@ -439,47 +572,73 @@ ensure_size_initialized (CoglFramebuffer *framebuffer)
 
       /* We also assume the size would have been initialized if the
        * framebuffer were allocated. */
-      g_return_if_fail (!framebuffer->allocated);
+      g_return_if_fail (!priv->allocated);
 
       cogl_framebuffer_allocate (framebuffer, NULL);
     }
 }
 
+void
+cogl_framebuffer_update_size (CoglFramebuffer *framebuffer,
+                              int              width,
+                              int              height)
+{
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
+  priv->width = width;
+  priv->height = height;
+
+  cogl_framebuffer_set_viewport (framebuffer, 0, 0, width, height);
+}
+
 int
 cogl_framebuffer_get_width (CoglFramebuffer *framebuffer)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
   ensure_size_initialized (framebuffer);
-  return framebuffer->width;
+  return priv->width;
 }
 
 int
 cogl_framebuffer_get_height (CoglFramebuffer *framebuffer)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
   ensure_size_initialized (framebuffer);
-  return framebuffer->height;
+  return priv->height;
 }
 
 CoglClipStack *
 _cogl_framebuffer_get_clip_stack (CoglFramebuffer *framebuffer)
 {
-  return framebuffer->clip_stack;
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
+  return priv->clip_stack;
 }
 
 void
 cogl_framebuffer_set_viewport4fv (CoglFramebuffer *framebuffer,
                                   float *viewport)
 {
-  if (framebuffer->viewport_x == viewport[0] &&
-      framebuffer->viewport_y == viewport[1] &&
-      framebuffer->viewport_width == viewport[2] &&
-      framebuffer->viewport_height == viewport[3])
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
+  if (priv->viewport_x == viewport[0] &&
+      priv->viewport_y == viewport[1] &&
+      priv->viewport_width == viewport[2] &&
+      priv->viewport_height == viewport[3])
     return;
 
-  framebuffer->viewport_x = viewport[0];
-  framebuffer->viewport_y = viewport[1];
-  framebuffer->viewport_width = viewport[2];
-  framebuffer->viewport_height = viewport[3];
-  framebuffer->viewport_age++;
+  priv->viewport_x = viewport[0];
+  priv->viewport_y = viewport[1];
+  priv->viewport_width = viewport[2];
+  priv->viewport_height = viewport[3];
+  priv->viewport_age++;
 }
 
 void
@@ -489,77 +648,117 @@ cogl_framebuffer_set_viewport (CoglFramebuffer *framebuffer,
                                float width,
                                float height)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
   g_return_if_fail (width > 0 && height > 0);
 
-  if (framebuffer->viewport_x == x &&
-      framebuffer->viewport_y == y &&
-      framebuffer->viewport_width == width &&
-      framebuffer->viewport_height == height)
+  if (priv->viewport_x == x &&
+      priv->viewport_y == y &&
+      priv->viewport_width == width &&
+      priv->viewport_height == height)
     return;
 
-  framebuffer->viewport_x = x;
-  framebuffer->viewport_y = y;
-  framebuffer->viewport_width = width;
-  framebuffer->viewport_height = height;
+  priv->viewport_x = x;
+  priv->viewport_y = y;
+  priv->viewport_width = width;
+  priv->viewport_height = height;
 }
 
 float
 cogl_framebuffer_get_viewport_x (CoglFramebuffer *framebuffer)
 {
-  return framebuffer->viewport_x;
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
+  return priv->viewport_x;
 }
 
 float
 cogl_framebuffer_get_viewport_y (CoglFramebuffer *framebuffer)
 {
-  return framebuffer->viewport_y;
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
+  return priv->viewport_y;
 }
 
 float
 cogl_framebuffer_get_viewport_width (CoglFramebuffer *framebuffer)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
   ensure_size_initialized (framebuffer);
-  return framebuffer->viewport_width;
+  return priv->viewport_width;
 }
 
 float
 cogl_framebuffer_get_viewport_height (CoglFramebuffer *framebuffer)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
   ensure_size_initialized (framebuffer);
-  return framebuffer->viewport_height;
+  return priv->viewport_height;
 }
 
 void
-cogl_framebuffer_get_viewport4fv (CoglFramebuffer *framebuffer,
-                                  float *viewport)
+cogl_framebuffer_get_viewport4f (CoglFramebuffer *framebuffer,
+                                 float           *viewport_x,
+                                 float           *viewport_y,
+                                 float           *viewport_width,
+                                 float           *viewport_height)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
   ensure_size_initialized (framebuffer);
 
-  viewport[0] = framebuffer->viewport_x;
-  viewport[1] = framebuffer->viewport_y;
-  viewport[2] = framebuffer->viewport_width;
-  viewport[3] = framebuffer->viewport_height;
+  *viewport_x = priv->viewport_x;
+  *viewport_y = priv->viewport_y;
+  *viewport_width = priv->viewport_width;
+  *viewport_height = priv->viewport_height;
+}
+
+void
+cogl_framebuffer_get_viewport4fv (CoglFramebuffer *framebuffer,
+                                  float *viewport)
+{
+  cogl_framebuffer_get_viewport4f (framebuffer,
+                                   &viewport[0],
+                                   &viewport[1],
+                                   &viewport[2],
+                                   &viewport[3]);
 }
 
 CoglMatrixStack *
 _cogl_framebuffer_get_modelview_stack (CoglFramebuffer *framebuffer)
 {
-  return framebuffer->modelview_stack;
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
+  return priv->modelview_stack;
 }
 
 CoglMatrixStack *
 _cogl_framebuffer_get_projection_stack (CoglFramebuffer *framebuffer)
 {
-  return framebuffer->projection_stack;
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
+  return priv->projection_stack;
 }
 
 void
 _cogl_framebuffer_add_dependency (CoglFramebuffer *framebuffer,
                                   CoglFramebuffer *dependency)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
   GList *l;
 
-  for (l = framebuffer->deps; l; l = l->next)
+  for (l = priv->deps; l; l = l->next)
     {
       CoglFramebuffer *existing_dep = l->data;
       if (existing_dep == dependency)
@@ -569,26 +768,32 @@ _cogl_framebuffer_add_dependency (CoglFramebuffer *framebuffer,
   /* TODO: generalize the primed-array type structure we e.g. use for
    * cogl_object_set_user_data or for pipeline children as a way to
    * avoid quite a lot of mid-scene micro allocations here... */
-  framebuffer->deps =
-    g_list_prepend (framebuffer->deps, cogl_object_ref (dependency));
+  priv->deps =
+    g_list_prepend (priv->deps, cogl_object_ref (dependency));
 }
 
 void
 _cogl_framebuffer_flush_journal (CoglFramebuffer *framebuffer)
 {
-  _cogl_journal_flush (framebuffer->journal);
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
+  _cogl_journal_flush (priv->journal);
 }
 
 void
 _cogl_framebuffer_flush_dependency_journals (CoglFramebuffer *framebuffer)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
   GList *l;
-  for (l = framebuffer->deps; l; l = l->next)
+
+  for (l = priv->deps; l; l = l->next)
     _cogl_framebuffer_flush_journal (l->data);
-  for (l = framebuffer->deps; l; l = l->next)
+  for (l = priv->deps; l; l = l->next)
     cogl_object_unref (l->data);
-  g_list_free (framebuffer->deps);
-  framebuffer->deps = NULL;
+  g_list_free (priv->deps);
+  priv->deps = NULL;
 }
 
 CoglOffscreen *
@@ -661,7 +866,9 @@ static void
 _cogl_offscreen_free (CoglOffscreen *offscreen)
 {
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (offscreen);
-  CoglContext *ctx = framebuffer->context;
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+  CoglContext *ctx = priv->context;
 
   ctx->driver_vtable->offscreen_free (offscreen);
 
@@ -677,18 +884,29 @@ _cogl_offscreen_free (CoglOffscreen *offscreen)
   g_free (offscreen);
 }
 
+gboolean
+cogl_framebuffer_is_allocated (CoglFramebuffer *framebuffer)
+{
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
+  return priv->allocated;
+}
+
 gboolean
 cogl_framebuffer_allocate (CoglFramebuffer *framebuffer,
                            GError **error)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
   CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
   const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
-  CoglContext *ctx = framebuffer->context;
+  CoglContext *ctx = priv->context;
 
-  if (framebuffer->allocated)
+  if (priv->allocated)
     return TRUE;
 
-  if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN)
+  if (priv->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN)
     {
       if (!winsys->onscreen_init (onscreen, error))
         return FALSE;
@@ -719,21 +937,21 @@ cogl_framebuffer_allocate (CoglFramebuffer *framebuffer,
 
       /* Now that the texture has been allocated we can determine a
        * size for the framebuffer... */
-      framebuffer->width = cogl_texture_get_width (offscreen->texture);
-      framebuffer->height = cogl_texture_get_height (offscreen->texture);
-      framebuffer->viewport_width = framebuffer->width;
-      framebuffer->viewport_height = framebuffer->height;
+      priv->width = cogl_texture_get_width (offscreen->texture);
+      priv->height = cogl_texture_get_height (offscreen->texture);
+      priv->viewport_width = priv->width;
+      priv->viewport_height = priv->height;
 
       /* Forward the texture format as the internal format of the
        * framebuffer */
-      framebuffer->internal_format =
+      priv->internal_format =
         _cogl_texture_get_format (offscreen->texture);
 
       if (!ctx->driver_vtable->offscreen_allocate (offscreen, error))
         return FALSE;
     }
 
-  framebuffer->allocated = TRUE;
+  priv->allocated = TRUE;
 
   return TRUE;
 }
@@ -742,13 +960,16 @@ static unsigned long
 _cogl_framebuffer_compare_viewport_state (CoglFramebuffer *a,
                                           CoglFramebuffer *b)
 {
-  if (a->viewport_x != b->viewport_x ||
-      a->viewport_y != b->viewport_y ||
-      a->viewport_width != b->viewport_width ||
-      a->viewport_height != b->viewport_height ||
+  CoglFramebufferPrivate *priv_a = cogl_framebuffer_get_instance_private (a);
+  CoglFramebufferPrivate *priv_b = cogl_framebuffer_get_instance_private (b);
+
+  if (priv_a->viewport_x != priv_b->viewport_x ||
+      priv_a->viewport_y != priv_b->viewport_y ||
+      priv_a->viewport_width != priv_b->viewport_width ||
+      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... */
-      a->type != b->type)
+      priv_a->type != priv_b->type)
     return COGL_FRAMEBUFFER_STATE_VIEWPORT;
   else
     return 0;
@@ -758,7 +979,10 @@ static unsigned long
 _cogl_framebuffer_compare_clip_state (CoglFramebuffer *a,
                                       CoglFramebuffer *b)
 {
-  if (a->clip_stack != b->clip_stack)
+  CoglFramebufferPrivate *priv_a = cogl_framebuffer_get_instance_private (a);
+  CoglFramebufferPrivate *priv_b = cogl_framebuffer_get_instance_private (b);
+
+  if (priv_a->clip_stack != priv_b->clip_stack)
     return COGL_FRAMEBUFFER_STATE_CLIP;
   else
     return 0;
@@ -768,7 +992,10 @@ static unsigned long
 _cogl_framebuffer_compare_dither_state (CoglFramebuffer *a,
                                         CoglFramebuffer *b)
 {
-  return a->dither_enabled != b->dither_enabled ?
+  CoglFramebufferPrivate *priv_a = cogl_framebuffer_get_instance_private (a);
+  CoglFramebufferPrivate *priv_b = cogl_framebuffer_get_instance_private (b);
+
+  return priv_a->dither_enabled != priv_b->dither_enabled ?
     COGL_FRAMEBUFFER_STATE_DITHER : 0;
 }
 
@@ -796,7 +1023,10 @@ static unsigned long
 _cogl_framebuffer_compare_front_face_winding_state (CoglFramebuffer *a,
                                                     CoglFramebuffer *b)
 {
-  if (a->type != b->type)
+  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)
     return COGL_FRAMEBUFFER_STATE_FRONT_FACE_WINDING;
   else
     return 0;
@@ -806,7 +1036,10 @@ static unsigned long
 _cogl_framebuffer_compare_depth_write_state (CoglFramebuffer *a,
                                              CoglFramebuffer *b)
 {
-  return a->depth_writing_enabled != b->depth_writing_enabled ?
+  CoglFramebufferPrivate *priv_a = cogl_framebuffer_get_instance_private (a);
+  CoglFramebufferPrivate *priv_b = cogl_framebuffer_get_instance_private (b);
+
+  return priv_a->depth_writing_enabled != priv_b->depth_writing_enabled ?
     COGL_FRAMEBUFFER_STATE_DEPTH_WRITE : 0;
 }
 
@@ -814,7 +1047,10 @@ static unsigned long
 _cogl_framebuffer_compare_stereo_mode (CoglFramebuffer *a,
                                       CoglFramebuffer *b)
 {
-  return a->stereo_mode != b->stereo_mode ?
+  CoglFramebufferPrivate *priv_a = cogl_framebuffer_get_instance_private (a);
+  CoglFramebufferPrivate *priv_b = cogl_framebuffer_get_instance_private (b);
+
+  return priv_a->stereo_mode != priv_b->stereo_mode ?
     COGL_FRAMEBUFFER_STATE_STEREO_MODE : 0;
 }
 
@@ -884,7 +1120,7 @@ _cogl_framebuffer_flush_state (CoglFramebuffer *draw_buffer,
                                CoglFramebuffer *read_buffer,
                                CoglFramebufferState state)
 {
-  CoglContext *ctx = draw_buffer->context;
+  CoglContext *ctx = cogl_framebuffer_get_context (draw_buffer);
 
   ctx->driver_vtable->framebuffer_flush_state (draw_buffer,
                                                read_buffer,
@@ -894,7 +1130,9 @@ _cogl_framebuffer_flush_state (CoglFramebuffer *draw_buffer,
 int
 cogl_framebuffer_get_red_bits (CoglFramebuffer *framebuffer)
 {
-  CoglContext *ctx = framebuffer->context;
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+  CoglContext *ctx = priv->context;
   CoglFramebufferBits bits;
 
   ctx->driver_vtable->framebuffer_query_bits (framebuffer, &bits);
@@ -905,7 +1143,9 @@ cogl_framebuffer_get_red_bits (CoglFramebuffer *framebuffer)
 int
 cogl_framebuffer_get_green_bits (CoglFramebuffer *framebuffer)
 {
-  CoglContext *ctx = framebuffer->context;
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+  CoglContext *ctx = priv->context;
   CoglFramebufferBits bits;
 
   ctx->driver_vtable->framebuffer_query_bits (framebuffer, &bits);
@@ -916,7 +1156,9 @@ cogl_framebuffer_get_green_bits (CoglFramebuffer *framebuffer)
 int
 cogl_framebuffer_get_blue_bits (CoglFramebuffer *framebuffer)
 {
-  CoglContext *ctx = framebuffer->context;
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+  CoglContext *ctx = priv->context;
   CoglFramebufferBits bits;
 
   ctx->driver_vtable->framebuffer_query_bits (framebuffer, &bits);
@@ -927,7 +1169,9 @@ cogl_framebuffer_get_blue_bits (CoglFramebuffer *framebuffer)
 int
 cogl_framebuffer_get_alpha_bits (CoglFramebuffer *framebuffer)
 {
-  CoglContext *ctx = framebuffer->context;
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+  CoglContext *ctx = priv->context;
   CoglFramebufferBits bits;
 
   ctx->driver_vtable->framebuffer_query_bits (framebuffer, &bits);
@@ -938,7 +1182,9 @@ cogl_framebuffer_get_alpha_bits (CoglFramebuffer *framebuffer)
 int
 cogl_framebuffer_get_depth_bits (CoglFramebuffer *framebuffer)
 {
-  CoglContext *ctx = framebuffer->context;
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+  CoglContext *ctx = priv->context;
   CoglFramebufferBits bits;
 
   ctx->driver_vtable->framebuffer_query_bits (framebuffer, &bits);
@@ -949,7 +1195,9 @@ cogl_framebuffer_get_depth_bits (CoglFramebuffer *framebuffer)
 int
 _cogl_framebuffer_get_stencil_bits (CoglFramebuffer *framebuffer)
 {
-  CoglContext *ctx = framebuffer->context;
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+  CoglContext *ctx = priv->context;
   CoglFramebufferBits bits;
 
   ctx->driver_vtable->framebuffer_query_bits (framebuffer, &bits);
@@ -960,96 +1208,136 @@ _cogl_framebuffer_get_stencil_bits (CoglFramebuffer *framebuffer)
 gboolean
 cogl_framebuffer_get_is_stereo (CoglFramebuffer *framebuffer)
 {
-  return framebuffer->config.stereo_enabled;
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
+  return priv->config.stereo_enabled;
 }
 
 CoglStereoMode
 cogl_framebuffer_get_stereo_mode (CoglFramebuffer *framebuffer)
 {
-  return framebuffer->stereo_mode;
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
+  return priv->stereo_mode;
 }
 
 void
 cogl_framebuffer_set_stereo_mode (CoglFramebuffer *framebuffer,
                                  CoglStereoMode   stereo_mode)
 {
-  if (framebuffer->stereo_mode == stereo_mode)
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
+  if (priv->stereo_mode == stereo_mode)
     return;
 
   /* Stereo mode changes don't go through the journal */
   _cogl_framebuffer_flush_journal (framebuffer);
 
-  framebuffer->stereo_mode = stereo_mode;
+  priv->stereo_mode = stereo_mode;
 
-  if (framebuffer->context->current_draw_buffer == framebuffer)
-    framebuffer->context->current_draw_buffer_changes |=
+  if (priv->context->current_draw_buffer == framebuffer)
+    priv->context->current_draw_buffer_changes |=
       COGL_FRAMEBUFFER_STATE_STEREO_MODE;
 }
 
 gboolean
 cogl_framebuffer_get_depth_write_enabled (CoglFramebuffer *framebuffer)
 {
-  return framebuffer->depth_writing_enabled;
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
+  return priv->depth_writing_enabled;
 }
 
 void
 cogl_framebuffer_set_depth_write_enabled (CoglFramebuffer *framebuffer,
                                           gboolean depth_write_enabled)
 {
-  if (framebuffer->depth_writing_enabled == depth_write_enabled)
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
+  if (priv->depth_writing_enabled == depth_write_enabled)
     return;
 
   /* XXX: Currently depth write changes don't go through the journal */
   _cogl_framebuffer_flush_journal (framebuffer);
 
-  framebuffer->depth_writing_enabled = depth_write_enabled;
+  priv->depth_writing_enabled = depth_write_enabled;
 
-  if (framebuffer->context->current_draw_buffer == framebuffer)
-    framebuffer->context->current_draw_buffer_changes |=
+  if (priv->context->current_draw_buffer == framebuffer)
+    priv->context->current_draw_buffer_changes |=
       COGL_FRAMEBUFFER_STATE_DEPTH_WRITE;
 }
 
 gboolean
 cogl_framebuffer_get_dither_enabled (CoglFramebuffer *framebuffer)
 {
-  return framebuffer->dither_enabled;
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
+  return priv->dither_enabled;
 }
 
 void
 cogl_framebuffer_set_dither_enabled (CoglFramebuffer *framebuffer,
                                      gboolean dither_enabled)
 {
-  if (framebuffer->dither_enabled == dither_enabled)
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
+  if (priv->dither_enabled == dither_enabled)
     return;
 
-  framebuffer->dither_enabled = dither_enabled;
+  priv->dither_enabled = dither_enabled;
 }
 
 int
 cogl_framebuffer_get_samples_per_pixel (CoglFramebuffer *framebuffer)
 {
-  if (framebuffer->allocated)
-    return framebuffer->samples_per_pixel;
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
+  if (priv->allocated)
+    return priv->samples_per_pixel;
   else
-    return framebuffer->config.samples_per_pixel;
+    return priv->config.samples_per_pixel;
 }
 
 void
 cogl_framebuffer_set_samples_per_pixel (CoglFramebuffer *framebuffer,
                                         int samples_per_pixel)
 {
-  g_return_if_fail (!framebuffer->allocated);
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
+  g_return_if_fail (!priv->allocated);
+
+  priv->config.samples_per_pixel = samples_per_pixel;
+}
+
+void
+cogl_framebuffer_update_samples_per_pixel (CoglFramebuffer *framebuffer,
+                                           int              samples_per_pixel)
+{
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
 
-  framebuffer->config.samples_per_pixel = samples_per_pixel;
+  priv->samples_per_pixel = samples_per_pixel;
 }
 
 void
 cogl_framebuffer_resolve_samples (CoglFramebuffer *framebuffer)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
   cogl_framebuffer_resolve_samples_region (framebuffer,
                                            0, 0,
-                                           framebuffer->width,
-                                           framebuffer->height);
+                                           priv->width,
+                                           priv->height);
 
   /* TODO: Make this happen implicitly when the resolve texture next gets used
    * as a source, either via cogl_texture_get_data(), via cogl_read_pixels() or
@@ -1092,9 +1380,21 @@ cogl_framebuffer_resolve_samples_region (CoglFramebuffer *framebuffer,
 CoglContext *
 cogl_framebuffer_get_context (CoglFramebuffer *framebuffer)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
   g_return_val_if_fail (framebuffer != NULL, NULL);
 
-  return framebuffer->context;
+  return priv->context;
+}
+
+CoglJournal *
+cogl_framebuffer_get_journal (CoglFramebuffer *framebuffer)
+{
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
+  return priv->journal;
 }
 
 static gboolean
@@ -1104,6 +1404,8 @@ _cogl_framebuffer_try_fast_read_pixel (CoglFramebuffer *framebuffer,
                                        CoglReadPixelsFlags source,
                                        CoglBitmap *bitmap)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
   gboolean found_intersection;
   CoglPixelFormat format;
 
@@ -1119,7 +1421,7 @@ _cogl_framebuffer_try_fast_read_pixel (CoglFramebuffer *framebuffer,
       format != COGL_PIXEL_FORMAT_RGBA_8888)
     return FALSE;
 
-  if (!_cogl_journal_try_read_pixel (framebuffer->journal,
+  if (!_cogl_journal_try_read_pixel (priv->journal,
                                      x, y, bitmap,
                                      &found_intersection))
     return FALSE;
@@ -1137,20 +1439,20 @@ _cogl_framebuffer_try_fast_read_pixel (CoglFramebuffer *framebuffer,
 
   /* If the framebuffer has been rendered too since it was last
    * cleared then we can't return the last known clear color. */
-  if (framebuffer->clear_clip_dirty)
+  if (priv->clear_clip_dirty)
     return FALSE;
 
-  if (x >= framebuffer->clear_clip_x0 &&
-      x < framebuffer->clear_clip_x1 &&
-      y >= framebuffer->clear_clip_y0 &&
-      y < framebuffer->clear_clip_y1)
+  if (x >= priv->clear_clip_x0 &&
+      x < priv->clear_clip_x1 &&
+      y >= priv->clear_clip_y0 &&
+      y < priv->clear_clip_y1)
     {
       uint8_t *pixel;
       GError *ignore_error = NULL;
 
       /* we currently only care about cases where the premultiplied or
        * unpremultipled colors are equivalent... */
-      if (framebuffer->clear_color_alpha != 1.0)
+      if (priv->clear_color_alpha != 1.0)
         return FALSE;
 
       pixel = _cogl_bitmap_map (bitmap,
@@ -1163,10 +1465,10 @@ _cogl_framebuffer_try_fast_read_pixel (CoglFramebuffer *framebuffer,
           return FALSE;
         }
 
-      pixel[0] = framebuffer->clear_color_red * 255.0;
-      pixel[1] = framebuffer->clear_color_green * 255.0;
-      pixel[2] = framebuffer->clear_color_blue * 255.0;
-      pixel[3] = framebuffer->clear_color_alpha * 255.0;
+      pixel[0] = priv->clear_color_red * 255.0;
+      pixel[1] = priv->clear_color_green * 255.0;
+      pixel[2] = priv->clear_color_blue * 255.0;
+      pixel[3] = priv->clear_color_alpha * 255.0;
 
       _cogl_bitmap_unmap (bitmap);
 
@@ -1184,6 +1486,8 @@ _cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
                                            CoglBitmap *bitmap,
                                            GError **error)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
   CoglContext *ctx;
   int width;
   int height;
@@ -1197,7 +1501,7 @@ _cogl_framebuffer_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
   width = cogl_bitmap_get_width (bitmap);
   height = cogl_bitmap_get_height (bitmap);
 
-  if (width == 1 && height == 1 && !framebuffer->clear_clip_dirty)
+  if (width == 1 && height == 1 && !priv->clear_clip_dirty)
     {
       /* If everything drawn so far for this frame is still in the
        * Journal then if all of the rectangles only have a flat
@@ -1251,6 +1555,8 @@ cogl_framebuffer_read_pixels (CoglFramebuffer *framebuffer,
                               CoglPixelFormat format,
                               uint8_t *pixels)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
   int bpp;
   CoglBitmap *bitmap;
   gboolean ret;
@@ -1258,7 +1564,7 @@ cogl_framebuffer_read_pixels (CoglFramebuffer *framebuffer,
   g_return_val_if_fail (cogl_pixel_format_get_n_planes (format) == 1, FALSE);
 
   bpp = cogl_pixel_format_get_bytes_per_pixel (format, 0);
-  bitmap = cogl_bitmap_new_for_data (framebuffer->context,
+  bitmap = cogl_bitmap_new_for_data (priv->context,
                                      width, height,
                                      format,
                                      bpp * width, /* rowstride */
@@ -1290,7 +1596,11 @@ cogl_blit_framebuffer (CoglFramebuffer *framebuffer,
                        int height,
                        GError **error)
 {
-  CoglContext *ctx = framebuffer->context;
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+  CoglFramebufferPrivate *dst_priv =
+    cogl_framebuffer_get_instance_private (dst);
+  CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
   int src_x1, src_y1, src_x2, src_y2;
   int dst_x1, dst_y1, dst_x2, dst_y2;
 
@@ -1303,8 +1613,8 @@ cogl_blit_framebuffer (CoglFramebuffer *framebuffer,
     }
 
   /* The buffers must use the same premult convention */
-  if ((framebuffer->internal_format & COGL_PREMULT_BIT) !=
-      (dst->internal_format & COGL_PREMULT_BIT))
+  if ((priv->internal_format & COGL_PREMULT_BIT) !=
+      (dst_priv->internal_format & COGL_PREMULT_BIT))
     {
       g_set_error_literal (error, COGL_SYSTEM_ERROR,
                            COGL_SYSTEM_ERROR_UNSUPPORTED,
@@ -1381,7 +1691,9 @@ void
 cogl_framebuffer_discard_buffers (CoglFramebuffer *framebuffer,
                                   unsigned long buffers)
 {
-  CoglContext *ctx = framebuffer->context;
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+  CoglContext *ctx = priv->context;
 
   g_return_if_fail (buffers & COGL_BUFFER_BIT_COLOR);
 
@@ -1391,7 +1703,9 @@ cogl_framebuffer_discard_buffers (CoglFramebuffer *framebuffer,
 void
 cogl_framebuffer_finish (CoglFramebuffer *framebuffer)
 {
-  CoglContext *ctx = framebuffer->context;
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+  CoglContext *ctx = priv->context;
 
   _cogl_framebuffer_flush_journal (framebuffer);
 
@@ -1401,8 +1715,9 @@ cogl_framebuffer_finish (CoglFramebuffer *framebuffer)
 void
 cogl_framebuffer_flush (CoglFramebuffer *framebuffer)
 {
-
-  CoglContext *ctx = framebuffer->context;
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+  CoglContext *ctx = priv->context;
 
   _cogl_framebuffer_flush_journal (framebuffer);
 
@@ -1412,37 +1727,49 @@ cogl_framebuffer_flush (CoglFramebuffer *framebuffer)
 void
 cogl_framebuffer_push_matrix (CoglFramebuffer *framebuffer)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
   CoglMatrixStack *modelview_stack =
     _cogl_framebuffer_get_modelview_stack (framebuffer);
   cogl_matrix_stack_push (modelview_stack);
 
-  if (framebuffer->context->current_draw_buffer == framebuffer)
-    framebuffer->context->current_draw_buffer_changes |=
-      COGL_FRAMEBUFFER_STATE_MODELVIEW;
+  if (priv->context->current_draw_buffer == framebuffer)
+    {
+      priv->context->current_draw_buffer_changes |=
+        COGL_FRAMEBUFFER_STATE_MODELVIEW;
+    }
 }
 
 void
 cogl_framebuffer_pop_matrix (CoglFramebuffer *framebuffer)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
   CoglMatrixStack *modelview_stack =
     _cogl_framebuffer_get_modelview_stack (framebuffer);
   cogl_matrix_stack_pop (modelview_stack);
 
-  if (framebuffer->context->current_draw_buffer == framebuffer)
-    framebuffer->context->current_draw_buffer_changes |=
-      COGL_FRAMEBUFFER_STATE_MODELVIEW;
+  if (priv->context->current_draw_buffer == framebuffer)
+    {
+      priv->context->current_draw_buffer_changes |=
+        COGL_FRAMEBUFFER_STATE_MODELVIEW;
+    }
 }
 
 void
 cogl_framebuffer_identity_matrix (CoglFramebuffer *framebuffer)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
   CoglMatrixStack *modelview_stack =
     _cogl_framebuffer_get_modelview_stack (framebuffer);
   cogl_matrix_stack_load_identity (modelview_stack);
 
-  if (framebuffer->context->current_draw_buffer == framebuffer)
-    framebuffer->context->current_draw_buffer_changes |=
-      COGL_FRAMEBUFFER_STATE_MODELVIEW;
+  if (priv->context->current_draw_buffer == framebuffer)
+    {
+      priv->context->current_draw_buffer_changes |=
+        COGL_FRAMEBUFFER_STATE_MODELVIEW;
+    }
 }
 
 void
@@ -1451,13 +1778,17 @@ cogl_framebuffer_scale (CoglFramebuffer *framebuffer,
                         float y,
                         float z)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
   CoglMatrixStack *modelview_stack =
     _cogl_framebuffer_get_modelview_stack (framebuffer);
   cogl_matrix_stack_scale (modelview_stack, x, y, z);
 
-  if (framebuffer->context->current_draw_buffer == framebuffer)
-    framebuffer->context->current_draw_buffer_changes |=
-      COGL_FRAMEBUFFER_STATE_MODELVIEW;
+  if (priv->context->current_draw_buffer == framebuffer)
+    {
+      priv->context->current_draw_buffer_changes |=
+        COGL_FRAMEBUFFER_STATE_MODELVIEW;
+    }
 }
 
 void
@@ -1466,13 +1797,17 @@ cogl_framebuffer_translate (CoglFramebuffer *framebuffer,
                             float y,
                             float z)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
   CoglMatrixStack *modelview_stack =
     _cogl_framebuffer_get_modelview_stack (framebuffer);
   cogl_matrix_stack_translate (modelview_stack, x, y, z);
 
-  if (framebuffer->context->current_draw_buffer == framebuffer)
-    framebuffer->context->current_draw_buffer_changes |=
-      COGL_FRAMEBUFFER_STATE_MODELVIEW;
+  if (priv->context->current_draw_buffer == framebuffer)
+    {
+      priv->context->current_draw_buffer_changes |=
+        COGL_FRAMEBUFFER_STATE_MODELVIEW;
+    }
 }
 
 void
@@ -1482,39 +1817,51 @@ cogl_framebuffer_rotate (CoglFramebuffer *framebuffer,
                          float y,
                          float z)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
   CoglMatrixStack *modelview_stack =
     _cogl_framebuffer_get_modelview_stack (framebuffer);
   cogl_matrix_stack_rotate (modelview_stack, angle, x, y, z);
 
-  if (framebuffer->context->current_draw_buffer == framebuffer)
-    framebuffer->context->current_draw_buffer_changes |=
-      COGL_FRAMEBUFFER_STATE_MODELVIEW;
+  if (priv->context->current_draw_buffer == framebuffer)
+    {
+      priv->context->current_draw_buffer_changes |=
+        COGL_FRAMEBUFFER_STATE_MODELVIEW;
+    }
 }
 
 void
 cogl_framebuffer_rotate_euler (CoglFramebuffer *framebuffer,
                                const graphene_euler_t *euler)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
   CoglMatrixStack *modelview_stack =
     _cogl_framebuffer_get_modelview_stack (framebuffer);
   cogl_matrix_stack_rotate_euler (modelview_stack, euler);
 
-  if (framebuffer->context->current_draw_buffer == framebuffer)
-    framebuffer->context->current_draw_buffer_changes |=
-      COGL_FRAMEBUFFER_STATE_MODELVIEW;
+  if (priv->context->current_draw_buffer == framebuffer)
+    {
+      priv->context->current_draw_buffer_changes |=
+        COGL_FRAMEBUFFER_STATE_MODELVIEW;
+    }
 }
 
 void
 cogl_framebuffer_transform (CoglFramebuffer         *framebuffer,
                             const graphene_matrix_t *matrix)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
   CoglMatrixStack *modelview_stack =
     _cogl_framebuffer_get_modelview_stack (framebuffer);
   cogl_matrix_stack_multiply (modelview_stack, matrix);
 
-  if (framebuffer->context->current_draw_buffer == framebuffer)
-    framebuffer->context->current_draw_buffer_changes |=
-      COGL_FRAMEBUFFER_STATE_MODELVIEW;
+  if (priv->context->current_draw_buffer == framebuffer)
+    {
+      priv->context->current_draw_buffer_changes |=
+        COGL_FRAMEBUFFER_STATE_MODELVIEW;
+    }
 }
 
 void
@@ -1524,6 +1871,8 @@ cogl_framebuffer_perspective (CoglFramebuffer *framebuffer,
                               float z_near,
                               float z_far)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
   float ymax = z_near * tanf (fov_y * G_PI / 360.0);
 
   cogl_framebuffer_frustum (framebuffer,
@@ -1534,9 +1883,11 @@ cogl_framebuffer_perspective (CoglFramebuffer *framebuffer,
                             z_near,
                             z_far);
 
-  if (framebuffer->context->current_draw_buffer == framebuffer)
-    framebuffer->context->current_draw_buffer_changes |=
-      COGL_FRAMEBUFFER_STATE_PROJECTION;
+  if (priv->context->current_draw_buffer == framebuffer)
+    {
+      priv->context->current_draw_buffer_changes |=
+        COGL_FRAMEBUFFER_STATE_PROJECTION;
+    }
 }
 
 void
@@ -1548,6 +1899,8 @@ cogl_framebuffer_frustum (CoglFramebuffer *framebuffer,
                           float z_near,
                           float z_far)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
   CoglMatrixStack *projection_stack =
     _cogl_framebuffer_get_projection_stack (framebuffer);
 
@@ -1565,9 +1918,11 @@ cogl_framebuffer_frustum (CoglFramebuffer *framebuffer,
                              z_near,
                              z_far);
 
-  if (framebuffer->context->current_draw_buffer == framebuffer)
-    framebuffer->context->current_draw_buffer_changes |=
-      COGL_FRAMEBUFFER_STATE_PROJECTION;
+  if (priv->context->current_draw_buffer == framebuffer)
+    {
+      priv->context->current_draw_buffer_changes |=
+        COGL_FRAMEBUFFER_STATE_PROJECTION;
+    }
 }
 
 void
@@ -1579,6 +1934,8 @@ cogl_framebuffer_orthographic (CoglFramebuffer *framebuffer,
                                float near,
                                float far)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
   graphene_matrix_t ortho;
   CoglMatrixStack *projection_stack =
     _cogl_framebuffer_get_projection_stack (framebuffer);
@@ -1590,9 +1947,11 @@ cogl_framebuffer_orthographic (CoglFramebuffer *framebuffer,
   graphene_matrix_init_ortho (&ortho, x_1, x_2, y_2, y_1, near, far);
   cogl_matrix_stack_set (projection_stack, &ortho);
 
-  if (framebuffer->context->current_draw_buffer == framebuffer)
-    framebuffer->context->current_draw_buffer_changes |=
-      COGL_FRAMEBUFFER_STATE_PROJECTION;
+  if (priv->context->current_draw_buffer == framebuffer)
+    {
+      priv->context->current_draw_buffer_changes |=
+        COGL_FRAMEBUFFER_STATE_PROJECTION;
+    }
 }
 
 void
@@ -1601,6 +1960,7 @@ cogl_framebuffer_get_modelview_matrix (CoglFramebuffer   *framebuffer,
 {
   CoglMatrixEntry *modelview_entry =
     _cogl_framebuffer_get_modelview_entry (framebuffer);
+
   cogl_matrix_entry_get (modelview_entry, matrix);
 }
 
@@ -1608,13 +1968,17 @@ void
 cogl_framebuffer_set_modelview_matrix (CoglFramebuffer         *framebuffer,
                                        const graphene_matrix_t *matrix)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
   CoglMatrixStack *modelview_stack =
     _cogl_framebuffer_get_modelview_stack (framebuffer);
   cogl_matrix_stack_set (modelview_stack, matrix);
 
-  if (framebuffer->context->current_draw_buffer == framebuffer)
-    framebuffer->context->current_draw_buffer_changes |=
-      COGL_FRAMEBUFFER_STATE_MODELVIEW;
+  if (priv->context->current_draw_buffer == framebuffer)
+    {
+      priv->context->current_draw_buffer_changes |=
+        COGL_FRAMEBUFFER_STATE_MODELVIEW;
+    }
 }
 
 void
@@ -1623,6 +1987,7 @@ cogl_framebuffer_get_projection_matrix (CoglFramebuffer   *framebuffer,
 {
   CoglMatrixEntry *projection_entry =
     _cogl_framebuffer_get_projection_entry (framebuffer);
+
   cogl_matrix_entry_get (projection_entry, matrix);
 }
 
@@ -1630,6 +1995,8 @@ void
 cogl_framebuffer_set_projection_matrix (CoglFramebuffer         *framebuffer,
                                         const graphene_matrix_t *matrix)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
   CoglMatrixStack *projection_stack =
     _cogl_framebuffer_get_projection_stack (framebuffer);
 
@@ -1639,9 +2006,11 @@ cogl_framebuffer_set_projection_matrix (CoglFramebuffer         *framebuffer,
 
   cogl_matrix_stack_set (projection_stack, matrix);
 
-  if (framebuffer->context->current_draw_buffer == framebuffer)
-    framebuffer->context->current_draw_buffer_changes |=
-      COGL_FRAMEBUFFER_STATE_PROJECTION;
+  if (priv->context->current_draw_buffer == framebuffer)
+    {
+      priv->context->current_draw_buffer_changes |=
+        COGL_FRAMEBUFFER_STATE_PROJECTION;
+    }
 }
 
 void
@@ -1651,13 +2020,18 @@ cogl_framebuffer_push_scissor_clip (CoglFramebuffer *framebuffer,
                                     int width,
                                     int height)
 {
-  framebuffer->clip_stack =
-    _cogl_clip_stack_push_window_rectangle (framebuffer->clip_stack,
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
+  priv->clip_stack =
+    _cogl_clip_stack_push_window_rectangle (priv->clip_stack,
                                             x, y, width, height);
 
-  if (framebuffer->context->current_draw_buffer == framebuffer)
-    framebuffer->context->current_draw_buffer_changes |=
-      COGL_FRAMEBUFFER_STATE_CLIP;
+  if (priv->context->current_draw_buffer == framebuffer)
+    {
+      priv->context->current_draw_buffer_changes |=
+        COGL_FRAMEBUFFER_STATE_CLIP;
+    }
 }
 
 void
@@ -1667,6 +2041,8 @@ cogl_framebuffer_push_rectangle_clip (CoglFramebuffer *framebuffer,
                                       float x_2,
                                       float y_2)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
   CoglMatrixEntry *modelview_entry =
     _cogl_framebuffer_get_modelview_entry (framebuffer);
   CoglMatrixEntry *projection_entry =
@@ -1674,22 +2050,24 @@ cogl_framebuffer_push_rectangle_clip (CoglFramebuffer *framebuffer,
   /* XXX: It would be nicer if we stored the private viewport as a
    * vec4 so we could avoid this redundant copy. */
   float viewport[] = {
-      framebuffer->viewport_x,
-      framebuffer->viewport_y,
-      framebuffer->viewport_width,
-      framebuffer->viewport_height
+    priv->viewport_x,
+    priv->viewport_y,
+    priv->viewport_width,
+    priv->viewport_height
   };
 
-  framebuffer->clip_stack =
-    _cogl_clip_stack_push_rectangle (framebuffer->clip_stack,
+  priv->clip_stack =
+    _cogl_clip_stack_push_rectangle (priv->clip_stack,
                                      x_1, y_1, x_2, y_2,
                                      modelview_entry,
                                      projection_entry,
                                      viewport);
 
-  if (framebuffer->context->current_draw_buffer == framebuffer)
-    framebuffer->context->current_draw_buffer_changes |=
-      COGL_FRAMEBUFFER_STATE_CLIP;
+  if (priv->context->current_draw_buffer == framebuffer)
+    {
+      priv->context->current_draw_buffer_changes |=
+        COGL_FRAMEBUFFER_STATE_CLIP;
+    }
 }
 
 void
@@ -1700,6 +2078,8 @@ cogl_framebuffer_push_primitive_clip (CoglFramebuffer *framebuffer,
                                       float bounds_x2,
                                       float bounds_y2)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
   CoglMatrixEntry *modelview_entry =
     _cogl_framebuffer_get_modelview_entry (framebuffer);
   CoglMatrixEntry *projection_entry =
@@ -1707,14 +2087,14 @@ cogl_framebuffer_push_primitive_clip (CoglFramebuffer *framebuffer,
   /* XXX: It would be nicer if we stored the private viewport as a
    * vec4 so we could avoid this redundant copy. */
   float viewport[] = {
-      framebuffer->viewport_x,
-      framebuffer->viewport_y,
-      framebuffer->viewport_width,
-      framebuffer->viewport_height
+    priv->viewport_x,
+    priv->viewport_y,
+    priv->viewport_width,
+    priv->viewport_height
   };
 
-  framebuffer->clip_stack =
-    _cogl_clip_stack_push_primitive (framebuffer->clip_stack,
+  priv->clip_stack =
+    _cogl_clip_stack_push_primitive (priv->clip_stack,
                                      primitive,
                                      bounds_x1, bounds_y1,
                                      bounds_x2, bounds_y2,
@@ -1722,37 +2102,52 @@ cogl_framebuffer_push_primitive_clip (CoglFramebuffer *framebuffer,
                                      projection_entry,
                                      viewport);
 
-  if (framebuffer->context->current_draw_buffer == framebuffer)
-    framebuffer->context->current_draw_buffer_changes |=
-      COGL_FRAMEBUFFER_STATE_CLIP;
+  if (priv->context->current_draw_buffer == framebuffer)
+    {
+      priv->context->current_draw_buffer_changes |=
+        COGL_FRAMEBUFFER_STATE_CLIP;
+    }
 }
 
 void
 cogl_framebuffer_push_region_clip (CoglFramebuffer *framebuffer,
                                    cairo_region_t  *region)
 {
-  framebuffer->clip_stack =
-    cogl_clip_stack_push_region (framebuffer->clip_stack,
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
+  priv->clip_stack =
+    cogl_clip_stack_push_region (priv->clip_stack,
                                  region);
 
-  if (framebuffer->context->current_draw_buffer == framebuffer)
-    framebuffer->context->current_draw_buffer_changes |=
-      COGL_FRAMEBUFFER_STATE_CLIP;
+  if (priv->context->current_draw_buffer == framebuffer)
+    {
+      priv->context->current_draw_buffer_changes |=
+        COGL_FRAMEBUFFER_STATE_CLIP;
+    }
 }
 
 void
 cogl_framebuffer_pop_clip (CoglFramebuffer *framebuffer)
 {
-  framebuffer->clip_stack = _cogl_clip_stack_pop (framebuffer->clip_stack);
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
 
-  if (framebuffer->context->current_draw_buffer == framebuffer)
-    framebuffer->context->current_draw_buffer_changes |=
-      COGL_FRAMEBUFFER_STATE_CLIP;
+  priv->clip_stack = _cogl_clip_stack_pop (priv->clip_stack);
+
+  if (priv->context->current_draw_buffer == framebuffer)
+    {
+      priv->context->current_draw_buffer_changes |=
+        COGL_FRAMEBUFFER_STATE_CLIP;
+    }
 }
 
 void
 _cogl_framebuffer_unref (CoglFramebuffer *framebuffer)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
   /* The journal holds a reference to the framebuffer whenever it is
      non-empty. Therefore if the journal is non-empty and we will have
      exactly one reference then we know the journal is the only thing
@@ -1760,7 +2155,7 @@ _cogl_framebuffer_unref (CoglFramebuffer *framebuffer)
      journal and let the framebuffer die. It is fine at this point if
      flushing the journal causes something else to take a reference to
      it and it comes back to life */
-  if (framebuffer->journal->entries->len > 0)
+  if (priv->journal->entries->len > 0)
     {
       unsigned int ref_count = ((CoglObject *) framebuffer)->ref_count;
 
@@ -2067,13 +2462,16 @@ _cogl_framebuffer_draw_attributes (CoglFramebuffer *framebuffer,
                                    int n_attributes,
                                    CoglDrawFlags flags)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
 #ifdef COGL_ENABLE_DEBUG
   if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_WIREFRAME) &&
                   (flags & COGL_DRAW_SKIP_DEBUG_WIREFRAME) == 0) &&
       mode != COGL_VERTICES_MODE_LINES &&
       mode != COGL_VERTICES_MODE_LINE_LOOP &&
       mode != COGL_VERTICES_MODE_LINE_STRIP)
-    draw_wireframe (framebuffer->context,
+    draw_wireframe (priv->context,
                     framebuffer, pipeline,
                     mode, first_vertex, n_vertices,
                     attributes, n_attributes, NULL,
@@ -2081,7 +2479,7 @@ _cogl_framebuffer_draw_attributes (CoglFramebuffer *framebuffer,
   else
 #endif
     {
-      CoglContext *ctx = framebuffer->context;
+      CoglContext *ctx = priv->context;
 
       ctx->driver_vtable->framebuffer_draw_attributes (framebuffer,
                                                        pipeline,
@@ -2105,13 +2503,16 @@ _cogl_framebuffer_draw_indexed_attributes (CoglFramebuffer *framebuffer,
                                            int n_attributes,
                                            CoglDrawFlags flags)
 {
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
 #ifdef COGL_ENABLE_DEBUG
   if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_WIREFRAME) &&
                   (flags & COGL_DRAW_SKIP_DEBUG_WIREFRAME) == 0) &&
       mode != COGL_VERTICES_MODE_LINES &&
       mode != COGL_VERTICES_MODE_LINE_LOOP &&
       mode != COGL_VERTICES_MODE_LINE_STRIP)
-    draw_wireframe (framebuffer->context,
+    draw_wireframe (priv->context,
                     framebuffer, pipeline,
                     mode, first_vertex, n_vertices,
                     attributes, n_attributes, indices,
@@ -2119,7 +2520,7 @@ _cogl_framebuffer_draw_indexed_attributes (CoglFramebuffer *framebuffer,
   else
 #endif
     {
-      CoglContext *ctx = framebuffer->context;
+      CoglContext *ctx = priv->context;
 
       ctx->driver_vtable->framebuffer_draw_indexed_attributes (framebuffer,
                                                                pipeline,
@@ -2287,7 +2688,10 @@ cogl_framebuffer_draw_textured_rectangles (CoglFramebuffer *framebuffer,
 gpointer
 cogl_framebuffer_get_driver_private (CoglFramebuffer *framebuffer)
 {
-  return framebuffer->driver_private;
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
+  return priv->driver_private;
 }
 
 void
@@ -2295,8 +2699,11 @@ cogl_framebuffer_set_driver_private (CoglFramebuffer *framebuffer,
                                      gpointer         driver_private,
                                      GDestroyNotify   destroy_notify)
 {
-  g_warn_if_fail (!framebuffer->driver_private);
+  CoglFramebufferPrivate *priv =
+    cogl_framebuffer_get_instance_private (framebuffer);
+
+  g_warn_if_fail (!priv->driver_private);
 
-  framebuffer->driver_private = driver_private;
-  framebuffer->driver_private_destroy = destroy_notify;
+  priv->driver_private = driver_private;
+  priv->driver_private_destroy = destroy_notify;
 }
diff --git a/cogl/cogl/cogl-journal.c b/cogl/cogl/cogl-journal.c
index 498e4d877b..fc11bdc2c3 100644
--- a/cogl/cogl/cogl-journal.c
+++ b/cogl/cogl/cogl-journal.c
@@ -567,7 +567,8 @@ _cogl_journal_flush_vbo_offsets_and_entries (CoglJournalEntry *batch_start,
                                              void             *data)
 {
   CoglJournalFlushState *state = data;
-  CoglContext *ctx = state->journal->framebuffer->context;
+  CoglFramebuffer *framebuffer = state->journal->framebuffer;
+  CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
   size_t stride;
   int i;
   CoglAttribute **attribute_entry;
@@ -688,7 +689,7 @@ _cogl_journal_flush_clip_stacks_and_entries (CoglJournalEntry *batch_start,
 {
   CoglJournalFlushState *state = data;
   CoglFramebuffer *framebuffer = state->journal->framebuffer;
-  CoglContext *ctx = framebuffer->context;
+  CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
   CoglMatrixStack *projection_stack;
 
   COGL_STATIC_TIMER (time_flush_clip_stack_pipeline_entries,
@@ -1032,7 +1033,7 @@ _cogl_journal_flush_dither_and_entries (CoglJournalEntry *batch_start,
 {
   CoglJournalFlushState *state = data;
   CoglFramebuffer *framebuffer = state->journal->framebuffer;
-  CoglContext *ctx = framebuffer->context;
+  CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
 
   COGL_STATIC_TIMER (time_flush_dither_and_entries,
                      "Journal Flush", /* parent */
@@ -1075,7 +1076,7 @@ _cogl_journal_flush_viewport_and_entries (CoglJournalEntry *batch_start,
 {
   CoglJournalFlushState *state = data;
   CoglFramebuffer *framebuffer = state->journal->framebuffer;
-  CoglContext *ctx = framebuffer->context;
+  CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
   float current_viewport[4];
 
   COGL_STATIC_TIMER (time_flush_viewport_and_entries,
@@ -1123,8 +1124,8 @@ static CoglAttributeBuffer *
 create_attribute_buffer (CoglJournal *journal,
                          size_t n_bytes)
 {
+  CoglContext *ctx = cogl_framebuffer_get_context (journal->framebuffer);
   CoglAttributeBuffer *vbo;
-  CoglContext *ctx = journal->framebuffer->context;
 
   vbo = journal->vbo_pool[journal->next_vbo_in_pool];
 
@@ -1383,7 +1384,7 @@ _cogl_journal_flush (CoglJournal *journal)
     }
 
   framebuffer = journal->framebuffer;
-  ctx = framebuffer->context;
+  ctx = cogl_framebuffer_get_context (framebuffer);
 
   /* The entries in this journal may depend on images in other
    * framebuffers which may require that we flush the journals
diff --git a/cogl/cogl/cogl-onscreen.c b/cogl/cogl/cogl-onscreen.c
index 3b3f2585ba..c667fe73a9 100644
--- a/cogl/cogl/cogl-onscreen.c
+++ b/cogl/cogl/cogl-onscreen.c
@@ -83,8 +83,7 @@ _cogl_onscreen_init_from_template (CoglOnscreen *onscreen,
   _cogl_list_init (&onscreen->resize_closures);
   _cogl_list_init (&onscreen->dirty_closures);
 
-  framebuffer->config = onscreen_template->config;
-  cogl_object_ref (framebuffer->config.swap_chain);
+  cogl_framebuffer_init_config (framebuffer, &onscreen_template->config);
 }
 
 CoglOnscreen *
@@ -202,7 +201,8 @@ _cogl_dispatch_onscreen_cb (CoglContext *context)
 static void
 _cogl_onscreen_queue_dispatch_idle (CoglOnscreen *onscreen)
 {
-  CoglContext *ctx = COGL_FRAMEBUFFER (onscreen)->context;
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
 
   if (!ctx->onscreen_dispatch_idle)
     {
@@ -219,7 +219,8 @@ void
 _cogl_onscreen_queue_dirty (CoglOnscreen *onscreen,
                             const CoglOnscreenDirtyInfo *info)
 {
-  CoglContext *ctx = COGL_FRAMEBUFFER (onscreen)->context;
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
   CoglOnscreenQueuedDirty *qe = g_slice_new (CoglOnscreenQueuedDirty);
 
   qe->onscreen = cogl_object_ref (onscreen);
@@ -237,8 +238,8 @@ _cogl_onscreen_queue_full_dirty (CoglOnscreen *onscreen)
 
   info.x = 0;
   info.y = 0;
-  info.width = framebuffer->width;
-  info.height = framebuffer->height;
+  info.width = cogl_framebuffer_get_width (framebuffer);
+  info.height = cogl_framebuffer_get_height (framebuffer);
 
   _cogl_onscreen_queue_dirty (onscreen, &info);
 }
@@ -248,7 +249,8 @@ _cogl_onscreen_queue_event (CoglOnscreen *onscreen,
                             CoglFrameEvent type,
                             CoglFrameInfo *info)
 {
-  CoglContext *ctx = COGL_FRAMEBUFFER (onscreen)->context;
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
 
   CoglOnscreenEvent *event = g_slice_new (CoglOnscreenEvent);
 
@@ -270,7 +272,7 @@ cogl_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
   const CoglWinsysVtable *winsys;
 
-  g_return_if_fail  (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN);
+  g_return_if_fail  (cogl_is_onscreen (framebuffer));
 
   info->frame_counter = onscreen->frame_counter;
   g_queue_push_tail (&onscreen->pending_frame_infos, info);
@@ -319,7 +321,7 @@ cogl_onscreen_swap_region (CoglOnscreen *onscreen,
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
   const CoglWinsysVtable *winsys;
 
-  g_return_if_fail  (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN);
+  g_return_if_fail  (cogl_is_onscreen (framebuffer));
 
   info->frame_counter = onscreen->frame_counter;
   g_queue_push_tail (&onscreen->pending_frame_infos, info);
@@ -365,7 +367,7 @@ cogl_onscreen_get_buffer_age (CoglOnscreen *onscreen)
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
   const CoglWinsysVtable *winsys;
 
-  g_return_val_if_fail  (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN, 0);
+  g_return_val_if_fail (cogl_is_onscreen (framebuffer), 0);
 
   winsys = _cogl_framebuffer_get_winsys (framebuffer);
 
@@ -384,7 +386,7 @@ cogl_onscreen_direct_scanout (CoglOnscreen   *onscreen,
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
   const CoglWinsysVtable *winsys;
 
-  g_warn_if_fail (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN);
+  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;
@@ -442,7 +444,7 @@ cogl_onscreen_show (CoglOnscreen *onscreen)
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
   const CoglWinsysVtable *winsys;
 
-  if (!framebuffer->allocated)
+  if (!cogl_framebuffer_is_allocated (framebuffer))
     {
       if (!cogl_framebuffer_allocate (framebuffer, NULL))
         return;
@@ -458,7 +460,7 @@ cogl_onscreen_hide (CoglOnscreen *onscreen)
 {
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
 
-  if (framebuffer->allocated)
+  if (cogl_framebuffer_is_allocated (framebuffer))
     {
       const CoglWinsysVtable *winsys =
         _cogl_framebuffer_get_winsys (framebuffer);
@@ -487,23 +489,21 @@ _cogl_onscreen_notify_resize (CoglOnscreen *onscreen)
   _cogl_closure_list_invoke (&onscreen->resize_closures,
                              CoglOnscreenResizeCallback,
                              onscreen,
-                             framebuffer->width,
-                             framebuffer->height);
+                             cogl_framebuffer_get_width (framebuffer),
+                             cogl_framebuffer_get_height (framebuffer));
 }
 
 void
 _cogl_framebuffer_winsys_update_size (CoglFramebuffer *framebuffer,
                                       int width, int height)
 {
-  if (framebuffer->width == width && framebuffer->height == height)
+  if (cogl_framebuffer_get_width (framebuffer) == width &&
+      cogl_framebuffer_get_height (framebuffer) == height)
     return;
 
-  framebuffer->width = width;
-  framebuffer->height = height;
-
-  cogl_framebuffer_set_viewport (framebuffer, 0, 0, width, height);
+  cogl_framebuffer_update_size (framebuffer, width, height);
 
-  if (!_cogl_has_private_feature (framebuffer->context,
+  if (!_cogl_has_private_feature (cogl_framebuffer_get_context (framebuffer),
                                   COGL_PRIVATE_FEATURE_DIRTY_EVENTS))
     _cogl_onscreen_queue_full_dirty (COGL_ONSCREEN (framebuffer));
 }
@@ -521,7 +521,7 @@ cogl_onscreen_set_resizable (CoglOnscreen *onscreen,
   onscreen->resizable = resizable;
 
   framebuffer = COGL_FRAMEBUFFER (onscreen);
-  if (framebuffer->allocated)
+  if (cogl_framebuffer_is_allocated (framebuffer))
     {
       winsys = _cogl_framebuffer_get_winsys (COGL_FRAMEBUFFER (onscreen));
 
diff --git a/cogl/cogl/cogl-primitives.c b/cogl/cogl/cogl-primitives.c
index 71a7ca5d20..03e1d54c49 100644
--- a/cogl/cogl/cogl-primitives.c
+++ b/cogl/cogl/cogl-primitives.c
@@ -123,7 +123,7 @@ log_quad_sub_textures_cb (CoglTexture *texture,
   else
     texture_override = texture;
 
-  _cogl_journal_log_quad (framebuffer->journal,
+  _cogl_journal_log_quad (cogl_framebuffer_get_journal (framebuffer),
                           quad_coords,
                           state->pipeline,
                           1, /* one layer */
@@ -458,7 +458,7 @@ _cogl_multitexture_quad_single_primitive (CoglFramebuffer *framebuffer,
   if (state.override_pipeline)
     pipeline = state.override_pipeline;
 
-  _cogl_journal_log_quad (framebuffer->journal,
+  _cogl_journal_log_quad (cogl_framebuffer_get_journal (framebuffer),
                           position,
                           pipeline,
                           n_layers,
@@ -631,7 +631,7 @@ _cogl_framebuffer_draw_multitextured_rectangles (
                                         CoglMultiTexturedRect *rects,
                                         int n_rects)
 {
-  CoglContext *ctx = framebuffer->context;
+  CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
   CoglPipeline *original_pipeline;
   ValidateLayerState state;
   int i;
@@ -714,7 +714,7 @@ cogl_2d_primitives_immediate (CoglFramebuffer *framebuffer,
                               const CoglVertexP2 *vertices,
                               unsigned int n_vertices)
 {
-  CoglContext *ctx = framebuffer->context;
+  CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
   CoglAttributeBuffer *attribute_buffer;
   CoglAttribute *attributes[1];
   size_t vertices_size = sizeof (CoglVertexP2) * n_vertices;
diff --git a/cogl/cogl/driver/gl/cogl-attribute-gl.c b/cogl/cogl/driver/gl/cogl-attribute-gl.c
index 620992dfb1..3475569ffa 100644
--- a/cogl/cogl/driver/gl/cogl-attribute-gl.c
+++ b/cogl/cogl/driver/gl/cogl-attribute-gl.c
@@ -186,7 +186,7 @@ _cogl_gl_flush_attributes_state (CoglFramebuffer *framebuffer,
                                  CoglAttribute **attributes,
                                  int n_attributes)
 {
-  CoglContext *ctx = framebuffer->context;
+  CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
   int i;
   gboolean with_color_attrib = FALSE;
   gboolean unknown_color_alpha = FALSE;
diff --git a/cogl/cogl/driver/gl/cogl-clip-stack-gl.c b/cogl/cogl/driver/gl/cogl-clip-stack-gl.c
index c528365979..365874dfb6 100644
--- a/cogl/cogl/driver/gl/cogl-clip-stack-gl.c
+++ b/cogl/cogl/driver/gl/cogl-clip-stack-gl.c
@@ -153,14 +153,14 @@ add_stencil_clip_region (CoglFramebuffer *framebuffer,
    * the default [-1, -1, 1, 1] range.
    */
   graphene_point3d_init (&p,
-                         - framebuffer->viewport_x,
-                         - framebuffer->viewport_y,
+                         - cogl_framebuffer_get_viewport_x (framebuffer),
+                         - cogl_framebuffer_get_viewport_y (framebuffer),
                          0);
 
   graphene_matrix_init_translate (&matrix, &p);
   graphene_matrix_scale (&matrix,
-                         2.0 / framebuffer->viewport_width,
-                         - 2.0 / framebuffer->viewport_height,
+                         2.0 / cogl_framebuffer_get_viewport_width (framebuffer),
+                         - 2.0 / cogl_framebuffer_get_viewport_height (framebuffer),
                          1);
   graphene_matrix_translate (&matrix, &GRAPHENE_POINT3D_INIT (-1.f, 1.f, 0.f));
 
@@ -398,7 +398,7 @@ void
 _cogl_clip_stack_gl_flush (CoglClipStack *stack,
                            CoglFramebuffer *framebuffer)
 {
-  CoglContext *ctx = framebuffer->context;
+  CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
   gboolean using_stencil_buffer = FALSE;
   int scissor_x0;
   int scissor_y0;
diff --git a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c b/cogl/cogl/driver/gl/cogl-framebuffer-gl.c
index 82a6af4cf9..c51b99997c 100644
--- a/cogl/cogl/driver/gl/cogl-framebuffer-gl.c
+++ b/cogl/cogl/driver/gl/cogl-framebuffer-gl.c
@@ -33,6 +33,7 @@
 
 #include "cogl-context-private.h"
 #include "cogl-framebuffer-private.h"
+#include "cogl-framebuffer.h"
 #include "cogl-texture-private.h"
 #include "driver/gl/cogl-util-gl-private.h"
 #include "driver/gl/cogl-framebuffer-gl-private.h"
@@ -135,10 +136,17 @@ typedef struct _CoglFramebufferGl
 static void
 _cogl_framebuffer_gl_flush_viewport_state (CoglFramebuffer *framebuffer)
 {
+  float viewport_x, viewport_y, viewport_width, viewport_height;
   float gl_viewport_y;
 
-  g_return_if_fail (framebuffer->viewport_width >= 0);
-  g_return_if_fail (framebuffer->viewport_height >= 0);
+  cogl_framebuffer_get_viewport4f (framebuffer,
+                                   &viewport_x,
+                                   &viewport_y,
+                                   &viewport_width,
+                                   &viewport_height);
+
+  g_return_if_fail (viewport_width >= 0);
+  g_return_if_fail (viewport_height >= 0);
 
   /* Convert the Cogl viewport y offset to an OpenGL viewport y offset
    * NB: OpenGL defines its window and viewport origins to be bottom
@@ -146,67 +154,73 @@ _cogl_framebuffer_gl_flush_viewport_state (CoglFramebuffer *framebuffer)
    * 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))
-    gl_viewport_y = framebuffer->viewport_y;
+    gl_viewport_y = viewport_y;
   else
-    gl_viewport_y = framebuffer->height -
-      (framebuffer->viewport_y + framebuffer->viewport_height);
+    gl_viewport_y =
+      cogl_framebuffer_get_height (framebuffer) -
+      (viewport_y + viewport_height);
 
   COGL_NOTE (OPENGL, "Calling glViewport(%f, %f, %f, %f)",
-             framebuffer->viewport_x,
+             viewport_x,
              gl_viewport_y,
-             framebuffer->viewport_width,
-             framebuffer->viewport_height);
+             viewport_width,
+             viewport_height);
 
-  GE (framebuffer->context,
-      glViewport (framebuffer->viewport_x,
+  GE (cogl_framebuffer_get_context (framebuffer),
+      glViewport (viewport_x,
                   gl_viewport_y,
-                  framebuffer->viewport_width,
-                  framebuffer->viewport_height));
+                  viewport_width,
+                  viewport_height));
 }
 
 static void
 _cogl_framebuffer_gl_flush_clip_state (CoglFramebuffer *framebuffer)
 {
-  _cogl_clip_stack_flush (framebuffer->clip_stack, framebuffer);
+  _cogl_clip_stack_flush (_cogl_framebuffer_get_clip_stack (framebuffer),
+                          framebuffer);
 }
 
 static void
 _cogl_framebuffer_gl_flush_dither_state (CoglFramebuffer *framebuffer)
 {
-  CoglContext *ctx = framebuffer->context;
+  CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
+  gboolean is_dither_enabled =
+    cogl_framebuffer_get_dither_enabled (framebuffer);
 
-  if (ctx->current_gl_dither_enabled != framebuffer->dither_enabled)
+  if (ctx->current_gl_dither_enabled != is_dither_enabled)
     {
-      if (framebuffer->dither_enabled)
+      if (is_dither_enabled)
         GE (ctx, glEnable (GL_DITHER));
       else
         GE (ctx, glDisable (GL_DITHER));
-      ctx->current_gl_dither_enabled = framebuffer->dither_enabled;
+      ctx->current_gl_dither_enabled = is_dither_enabled;
     }
 }
 
 static void
 _cogl_framebuffer_gl_flush_modelview_state (CoglFramebuffer *framebuffer)
 {
+  CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
   CoglMatrixEntry *modelview_entry =
     _cogl_framebuffer_get_modelview_entry (framebuffer);
-  _cogl_context_set_current_modelview_entry (framebuffer->context,
-                                             modelview_entry);
+
+  _cogl_context_set_current_modelview_entry (ctx, modelview_entry);
 }
 
 static void
 _cogl_framebuffer_gl_flush_projection_state (CoglFramebuffer *framebuffer)
 {
+  CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
   CoglMatrixEntry *projection_entry =
     _cogl_framebuffer_get_projection_entry (framebuffer);
-  _cogl_context_set_current_projection_entry (framebuffer->context,
-                                             projection_entry);
+
+  _cogl_context_set_current_projection_entry (ctx, projection_entry);
 }
 
 static void
 _cogl_framebuffer_gl_flush_front_face_winding_state (CoglFramebuffer *framebuffer)
 {
-  CoglContext *context = framebuffer->context;
+  CoglContext *context = cogl_framebuffer_get_context (framebuffer);
   CoglPipelineCullFaceMode mode;
 
   /* NB: The face winding state is actually owned by the current
@@ -238,10 +252,10 @@ _cogl_framebuffer_gl_flush_front_face_winding_state (CoglFramebuffer *framebuffe
 static void
 _cogl_framebuffer_gl_flush_stereo_mode_state (CoglFramebuffer *framebuffer)
 {
-  CoglContext *ctx = framebuffer->context;
+  CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
   GLenum draw_buffer = GL_BACK;
 
-  if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN)
+  if (cogl_is_offscreen (framebuffer))
     return;
 
   if (!ctx->glDrawBuffer)
@@ -251,7 +265,7 @@ _cogl_framebuffer_gl_flush_stereo_mode_state (CoglFramebuffer *framebuffer)
    * must have already happened. If not it would override what we set here. */
   g_assert (ctx->was_bound_to_onscreen);
 
-  switch (framebuffer->stereo_mode)
+  switch (cogl_framebuffer_get_stereo_mode (framebuffer))
     {
     case COGL_STEREO_BOTH:
       draw_buffer = GL_BACK;
@@ -274,9 +288,9 @@ _cogl_framebuffer_gl_flush_stereo_mode_state (CoglFramebuffer *framebuffer)
 void
 _cogl_framebuffer_gl_bind (CoglFramebuffer *framebuffer, GLenum target)
 {
-  CoglContext *ctx = framebuffer->context;
+  CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
 
-  if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN)
+  if (cogl_is_offscreen (framebuffer))
     {
       CoglOffscreen *offscreen = COGL_OFFSCREEN (framebuffer);
       GE (ctx, glBindFramebuffer (target,
@@ -325,7 +339,7 @@ _cogl_framebuffer_gl_flush_state (CoglFramebuffer *draw_buffer,
                                   CoglFramebuffer *read_buffer,
                                   CoglFramebufferState state)
 {
-  CoglContext *ctx = draw_buffer->context;
+  CoglContext *ctx = cogl_framebuffer_get_context (draw_buffer);
   unsigned long differences;
   int bit;
 
@@ -377,9 +391,9 @@ _cogl_framebuffer_gl_flush_state (CoglFramebuffer *draw_buffer,
     return;
 
   /* Lazily ensure the framebuffers have been allocated */
-  if (G_UNLIKELY (!draw_buffer->allocated))
+  if (G_UNLIKELY (!cogl_framebuffer_is_allocated (draw_buffer)))
     cogl_framebuffer_allocate (draw_buffer, NULL);
-  if (G_UNLIKELY (!read_buffer->allocated))
+  if (G_UNLIKELY (!cogl_framebuffer_is_allocated (read_buffer)))
     cogl_framebuffer_allocate (read_buffer, NULL);
 
   /* We handle buffer binding separately since the method depends on whether
@@ -622,15 +636,15 @@ delete_renderbuffers (CoglContext *ctx, GList *renderbuffers)
  * modify anything in
  */
 static gboolean
-try_creating_fbo (CoglContext *ctx,
-                  CoglTexture *texture,
-                  int texture_level,
-                  int texture_level_width,
-                  int texture_level_height,
-                  CoglTexture *depth_texture,
-                  CoglFramebufferConfig *config,
-                  CoglOffscreenAllocateFlags flags,
-                  CoglGLFramebuffer *gl_framebuffer)
+try_creating_fbo (CoglContext                 *ctx,
+                  CoglTexture                 *texture,
+                  int                          texture_level,
+                  int                          texture_level_width,
+                  int                          texture_level_height,
+                  CoglTexture                 *depth_texture,
+                  const CoglFramebufferConfig *config,
+                  CoglOffscreenAllocateFlags   flags,
+                  CoglGLFramebuffer           *gl_framebuffer)
 {
   GLuint tex_gl_handle;
   GLenum tex_gl_target;
@@ -739,10 +753,11 @@ gboolean
 _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen,
                              GError **error)
 {
-  CoglFramebuffer *fb = COGL_FRAMEBUFFER (offscreen);
-  CoglContext *ctx = fb->context;
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (offscreen);
+  CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
   CoglOffscreenAllocateFlags flags;
   CoglGLFramebuffer *gl_framebuffer = &offscreen->gl_framebuffer;
+  const CoglFramebufferConfig *config;
   int level_width;
   int level_height;
 
@@ -769,6 +784,8 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen,
   _cogl_texture_gl_flush_legacy_texobj_filters (offscreen->texture,
                                                 GL_NEAREST, GL_NEAREST);
 
+  config = cogl_framebuffer_get_config (framebuffer);
+
   if (((offscreen->create_flags & COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL) &&
        try_creating_fbo (ctx,
                          offscreen->texture,
@@ -776,7 +793,7 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen,
                          level_width,
                          level_height,
                          offscreen->depth_texture,
-                         &fb->config,
+                         config,
                          flags = 0,
                          gl_framebuffer)) ||
 
@@ -787,7 +804,7 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen,
                          level_width,
                          level_height,
                          offscreen->depth_texture,
-                         &fb->config,
+                         config,
                          flags = ctx->last_offscreen_allocate_flags,
                          gl_framebuffer)) ||
 
@@ -804,7 +821,7 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen,
                          level_width,
                          level_height,
                          offscreen->depth_texture,
-                         &fb->config,
+                         config,
                          flags = COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH_STENCIL,
                          gl_framebuffer)) ||
 
@@ -814,7 +831,7 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen,
                         level_width,
                         level_height,
                         offscreen->depth_texture,
-                        &fb->config,
+                        config,
                         flags = COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH |
                         COGL_OFFSCREEN_ALLOCATE_FLAG_STENCIL,
                         gl_framebuffer) ||
@@ -825,7 +842,7 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen,
                         level_width,
                         level_height,
                         offscreen->depth_texture,
-                        &fb->config,
+                        config,
                         flags = COGL_OFFSCREEN_ALLOCATE_FLAG_STENCIL,
                         gl_framebuffer) ||
 
@@ -835,7 +852,7 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen,
                         level_width,
                         level_height,
                         offscreen->depth_texture,
-                        &fb->config,
+                        config,
                         flags = COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH,
                         gl_framebuffer) ||
 
@@ -845,11 +862,12 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen,
                         level_width,
                         level_height,
                         offscreen->depth_texture,
-                        &fb->config,
+                        config,
                         flags = 0,
                         gl_framebuffer))
     {
-      fb->samples_per_pixel = gl_framebuffer->samples_per_pixel;
+      cogl_framebuffer_update_samples_per_pixel (framebuffer,
+                                                 gl_framebuffer->samples_per_pixel);
 
       if (!(offscreen->create_flags & COGL_OFFSCREEN_DISABLE_DEPTH_AND_STENCIL))
         {
@@ -878,7 +896,8 @@ _cogl_offscreen_gl_allocate (CoglOffscreen *offscreen,
 void
 _cogl_offscreen_gl_free (CoglOffscreen *offscreen)
 {
-  CoglContext *ctx = COGL_FRAMEBUFFER (offscreen)->context;
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (offscreen);
+  CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
 
   delete_renderbuffers (ctx, offscreen->gl_framebuffer.renderbuffers);
 
@@ -893,7 +912,7 @@ _cogl_framebuffer_gl_clear (CoglFramebuffer *framebuffer,
                             float blue,
                             float alpha)
 {
-  CoglContext *ctx = framebuffer->context;
+  CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
   GLbitfield gl_buffers = 0;
 
   if (buffers & COGL_BUFFER_BIT_COLOR)
@@ -904,13 +923,17 @@ _cogl_framebuffer_gl_clear (CoglFramebuffer *framebuffer,
 
   if (buffers & COGL_BUFFER_BIT_DEPTH)
     {
+      gboolean is_depth_writing_enabled;
+
       gl_buffers |= GL_DEPTH_BUFFER_BIT;
 
-      if (ctx->depth_writing_enabled_cache != framebuffer->depth_writing_enabled)
+      is_depth_writing_enabled =
+        cogl_framebuffer_get_depth_write_enabled (framebuffer);
+      if (ctx->depth_writing_enabled_cache != is_depth_writing_enabled)
         {
-          GE( ctx, glDepthMask (framebuffer->depth_writing_enabled));
+          GE( ctx, glDepthMask (is_depth_writing_enabled));
 
-          ctx->depth_writing_enabled_cache = framebuffer->depth_writing_enabled;
+          ctx->depth_writing_enabled_cache = is_depth_writing_enabled;
 
           /* Make sure the DepthMask is updated when the next primitive is drawn */
           ctx->current_pipeline_changes_since_flush |=
@@ -947,7 +970,7 @@ ensure_framebuffer_gl (CoglFramebuffer *framebuffer)
 static inline void
 _cogl_framebuffer_init_bits (CoglFramebuffer *framebuffer)
 {
-  CoglContext *ctx = framebuffer->context;
+  CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
   CoglFramebufferGl *framebuffer_gl;
 
   framebuffer_gl = ensure_framebuffer_gl (framebuffer);
@@ -963,11 +986,11 @@ _cogl_framebuffer_init_bits (CoglFramebuffer *framebuffer)
 
 #ifdef HAVE_COGL_GL
   if ((ctx->driver == COGL_DRIVER_GL3 &&
-       framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN) ||
+       cogl_is_onscreen (framebuffer)) ||
       (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS) &&
-       framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN))
+       cogl_is_offscreen (framebuffer)))
     {
-      gboolean is_offscreen = framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN;
+      gboolean is_offscreen = cogl_is_offscreen (framebuffer);
       const struct {
         GLenum attachment, pname;
         size_t offset;
@@ -1017,8 +1040,8 @@ _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) &&
-      framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN &&
-      framebuffer->internal_format == COGL_PIXEL_FORMAT_A_8)
+      cogl_is_offscreen (framebuffer) &&
+      cogl_framebuffer_get_internal_format (framebuffer) == COGL_PIXEL_FORMAT_A_8)
     {
       framebuffer_gl->bits.alpha = framebuffer_gl->bits.red;
       framebuffer_gl->bits.red = 0;
@@ -1027,9 +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,
-             framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN
-               ? "offscreen"
-               : "onscreen",
+             cogl_is_offscreen (framebuffer) ? "offscreen" : "onscreen",
              framebuffer_gl->bits.red,
              framebuffer_gl->bits.blue,
              framebuffer_gl->bits.green,
@@ -1057,27 +1078,27 @@ _cogl_framebuffer_gl_query_bits (CoglFramebuffer *framebuffer,
 void
 _cogl_framebuffer_gl_finish (CoglFramebuffer *framebuffer)
 {
-  GE (framebuffer->context, glFinish ());
+  GE (cogl_framebuffer_get_context (framebuffer), glFinish ());
 }
 
 void
 _cogl_framebuffer_gl_flush (CoglFramebuffer *framebuffer)
 {
-  GE (framebuffer->context, glFlush ());
+  GE (cogl_framebuffer_get_context (framebuffer), glFlush ());
 }
 
 void
 _cogl_framebuffer_gl_discard_buffers (CoglFramebuffer *framebuffer,
                                       unsigned long buffers)
 {
-  CoglContext *ctx = framebuffer->context;
+  CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
 
   if (ctx->glDiscardFramebuffer)
     {
       GLenum attachments[3];
       int i = 0;
 
-      if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN)
+      if (cogl_is_onscreen (framebuffer))
         {
           if (buffers & COGL_BUFFER_BIT_COLOR)
             attachments[i++] = GL_COLOR;
@@ -1116,7 +1137,7 @@ _cogl_framebuffer_gl_draw_attributes (CoglFramebuffer *framebuffer,
   _cogl_flush_attributes_state (framebuffer, pipeline, flags,
                                 attributes, n_attributes);
 
-  GE (framebuffer->context,
+  GE (cogl_framebuffer_get_context (framebuffer),
       glDrawArrays ((GLenum)mode, first_vertex, n_vertices));
 }
 
@@ -1180,7 +1201,7 @@ _cogl_framebuffer_gl_draw_indexed_attributes (CoglFramebuffer *framebuffer,
       break;
     }
 
-  GE (framebuffer->context,
+  GE (cogl_framebuffer_get_context (framebuffer),
       glDrawElements ((GLenum)mode,
                       n_vertices,
                       indices_gl_type,
@@ -1197,11 +1218,13 @@ _cogl_framebuffer_gl_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
                                               CoglBitmap *bitmap,
                                               GError **error)
 {
-  CoglContext *ctx = framebuffer->context;
+  CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
   int framebuffer_height = cogl_framebuffer_get_height (framebuffer);
   int width = cogl_bitmap_get_width (bitmap);
   int height = cogl_bitmap_get_height (bitmap);
   CoglPixelFormat format = cogl_bitmap_get_format (bitmap);
+  CoglPixelFormat internal_format =
+    cogl_framebuffer_get_internal_format (framebuffer);
   CoglPixelFormat required_format;
   GLenum gl_intformat;
   GLenum gl_format;
@@ -1281,8 +1304,10 @@ _cogl_framebuffer_gl_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
         }
 
       if (COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT (read_format))
-        read_format = ((read_format & ~COGL_PREMULT_BIT) |
-                       (framebuffer->internal_format & COGL_PREMULT_BIT));
+        {
+          read_format = ((read_format & ~COGL_PREMULT_BIT) |
+                         (internal_format & COGL_PREMULT_BIT));
+        }
 
       tmp_bmp = _cogl_bitmap_new_with_malloc_buffer (ctx,
                                                      width, height,
@@ -1336,7 +1361,7 @@ _cogl_framebuffer_gl_read_pixels_into_bitmap (CoglFramebuffer *framebuffer,
        * converted to the right format below */
       if (COGL_PIXEL_FORMAT_CAN_HAVE_PREMULT (format))
         bmp_format = ((format & ~COGL_PREMULT_BIT) |
-                      (framebuffer->internal_format & COGL_PREMULT_BIT));
+                      (internal_format & COGL_PREMULT_BIT));
       else
         bmp_format = format;
 
diff --git a/cogl/cogl/driver/gl/cogl-pipeline-opengl.c b/cogl/cogl/driver/gl/cogl-pipeline-opengl.c
index b99b74efea..bf3dbad9fe 100644
--- a/cogl/cogl/driver/gl/cogl-pipeline-opengl.c
+++ b/cogl/cogl/driver/gl/cogl-pipeline-opengl.c
@@ -259,7 +259,10 @@ flush_depth_state (CoglContext *ctx,
   gboolean depth_writing_enabled = depth_state->write_enabled;
 
   if (ctx->current_draw_buffer)
-    depth_writing_enabled &= ctx->current_draw_buffer->depth_writing_enabled;
+    {
+      depth_writing_enabled &=
+        cogl_framebuffer_get_depth_write_enabled (ctx->current_draw_buffer);
+    }
 
   if (ctx->depth_test_enabled_cache != depth_state->test_enabled)
     {
@@ -267,7 +270,7 @@ flush_depth_state (CoglContext *ctx,
         {
           GE (ctx, glEnable (GL_DEPTH_TEST));
           if (ctx->current_draw_buffer)
-            ctx->current_draw_buffer->depth_buffer_clear_needed = TRUE;
+            cogl_framebuffer_set_depth_buffer_clear_needed (ctx->current_draw_buffer);
         }
       else
         GE (ctx, glDisable (GL_DEPTH_TEST));
diff --git a/cogl/cogl/winsys/cogl-winsys-egl-private.h b/cogl/cogl/winsys/cogl-winsys-egl-private.h
index 8aea7c92bb..b004cb8728 100644
--- a/cogl/cogl/winsys/cogl-winsys-egl-private.h
+++ b/cogl/cogl/winsys/cogl-winsys-egl-private.h
@@ -87,9 +87,9 @@ typedef struct _CoglWinsysEGLVtable
   (* onscreen_deinit) (CoglOnscreen *onscreen);
 
   int
-  (* add_config_attributes) (CoglDisplay *display,
-                             CoglFramebufferConfig *config,
-                             EGLint *attributes);
+  (* add_config_attributes) (CoglDisplay                 *display,
+                             const CoglFramebufferConfig *config,
+                             EGLint                      *attributes);
   gboolean
   (* choose_config) (CoglDisplay *display,
                      EGLint *attributes,
diff --git a/cogl/cogl/winsys/cogl-winsys-egl-x11.c b/cogl/cogl/winsys/cogl-winsys-egl-x11.c
index aad6a12ca7..f298720388 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 (framebuffer->type != COGL_FRAMEBUFFER_TYPE_ONSCREEN)
+      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 (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN)
+  if (cogl_is_onscreen (framebuffer))
     {
       CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
       CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
@@ -319,9 +319,9 @@ error:
 }
 
 static int
-_cogl_winsys_egl_add_config_attributes (CoglDisplay *display,
-                                        CoglFramebufferConfig *config,
-                                        EGLint *attributes)
+_cogl_winsys_egl_add_config_attributes (CoglDisplay                 *display,
+                                        const CoglFramebufferConfig *config,
+                                        EGLint                      *attributes)
 {
   int i = 0;
 
@@ -413,7 +413,7 @@ _cogl_winsys_egl_onscreen_init (CoglOnscreen *onscreen,
                                 GError **error)
 {
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
-  CoglContext *context = framebuffer->context;
+  CoglContext *context = cogl_framebuffer_get_context (framebuffer);
   CoglDisplay *display = context->display;
   CoglRenderer *renderer = display->renderer;
   CoglRendererEGL *egl_renderer = renderer->winsys;
@@ -513,7 +513,7 @@ static void
 _cogl_winsys_egl_onscreen_deinit (CoglOnscreen *onscreen)
 {
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
-  CoglContext *context = framebuffer->context;
+  CoglContext *context = cogl_framebuffer_get_context (framebuffer);
   CoglRenderer *renderer = context->display->renderer;
   CoglXlibRenderer *xlib_renderer =
     _cogl_xlib_renderer_get_data (renderer);
@@ -544,7 +544,8 @@ static void
 _cogl_winsys_onscreen_set_visibility (CoglOnscreen *onscreen,
                                       gboolean visibility)
 {
-  CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  CoglContext *context = cogl_framebuffer_get_context (framebuffer);
   CoglRenderer *renderer = context->display->renderer;
   CoglXlibRenderer *xlib_renderer =
     _cogl_xlib_renderer_get_data (renderer);
@@ -562,7 +563,7 @@ _cogl_winsys_onscreen_set_resizable (CoglOnscreen *onscreen,
                                      gboolean resizable)
 {
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
-  CoglContext *context = framebuffer->context;
+  CoglContext *context = cogl_framebuffer_get_context (framebuffer);
   CoglXlibRenderer *xlib_renderer =
     _cogl_xlib_renderer_get_data (context->display->renderer);
   CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
diff --git a/cogl/cogl/winsys/cogl-winsys-egl.c b/cogl/cogl/winsys/cogl-winsys-egl.c
index 6aaac8ef87..6b56d21516 100644
--- a/cogl/cogl/winsys/cogl-winsys-egl.c
+++ b/cogl/cogl/winsys/cogl-winsys-egl.c
@@ -195,9 +195,9 @@ _cogl_winsys_renderer_connect (CoglRenderer *renderer,
 }
 
 static void
-egl_attributes_from_framebuffer_config (CoglDisplay *display,
-                                        CoglFramebufferConfig *config,
-                                        EGLint *attributes)
+egl_attributes_from_framebuffer_config (CoglDisplay                 *display,
+                                        const CoglFramebufferConfig *config,
+                                        EGLint                      *attributes)
 {
   CoglRenderer *renderer = display->renderer;
   CoglRendererEGL *egl_renderer = renderer->winsys;
@@ -548,11 +548,12 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
                             GError **error)
 {
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
-  CoglContext *context = framebuffer->context;
+  CoglContext *context = cogl_framebuffer_get_context (framebuffer);
   CoglDisplay *display = context->display;
   CoglDisplayEGL *egl_display = display->winsys;
   CoglRenderer *renderer = display->renderer;
   CoglRendererEGL *egl_renderer = renderer->winsys;
+  const CoglFramebufferConfig *config;
   EGLint attributes[MAX_EGL_CONFIG_ATTRIBS];
   EGLConfig egl_config;
   EGLint config_count = 0;
@@ -560,9 +561,8 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
 
   g_return_val_if_fail (egl_display->egl_context, FALSE);
 
-  egl_attributes_from_framebuffer_config (display,
-                                          &framebuffer->config,
-                                          attributes);
+  config = cogl_framebuffer_get_config (framebuffer);
+  egl_attributes_from_framebuffer_config (display, config, attributes);
 
   status = eglChooseConfig (egl_renderer->edpy,
                             attributes,
@@ -578,14 +578,14 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
 
   /* Update the real number of samples_per_pixel now that we have
    * found an egl_config... */
-  if (framebuffer->config.samples_per_pixel)
+  if (config->samples_per_pixel)
     {
       EGLint samples;
       status = eglGetConfigAttrib (egl_renderer->edpy,
                                    egl_config,
                                    EGL_SAMPLES, &samples);
       g_return_val_if_fail (status == EGL_TRUE, TRUE);
-      framebuffer->samples_per_pixel = samples;
+      cogl_framebuffer_update_samples_per_pixel (framebuffer, samples);
     }
 
   onscreen->winsys = g_slice_new0 (CoglOnscreenEGL);
@@ -606,7 +606,7 @@ static void
 _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
 {
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
-  CoglContext *context = framebuffer->context;
+  CoglContext *context = cogl_framebuffer_get_context (framebuffer);
   CoglDisplayEGL *egl_display = context->display->winsys;
   CoglRenderer *renderer = context->display->renderer;
   CoglRendererEGL *egl_renderer = renderer->winsys;
@@ -650,8 +650,8 @@ static gboolean
 bind_onscreen_with_context (CoglOnscreen *onscreen,
                             EGLContext egl_context)
 {
-  CoglFramebuffer *fb = COGL_FRAMEBUFFER (onscreen);
-  CoglContext *context = fb->context;
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  CoglContext *context = cogl_framebuffer_get_context (framebuffer);
   CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
 
   gboolean status = _cogl_winsys_egl_make_current (context->display,
@@ -672,8 +672,8 @@ bind_onscreen_with_context (CoglOnscreen *onscreen,
 static gboolean
 bind_onscreen (CoglOnscreen *onscreen)
 {
-  CoglFramebuffer *fb = COGL_FRAMEBUFFER (onscreen);
-  CoglContext *context = fb->context;
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  CoglContext *context = cogl_framebuffer_get_context (framebuffer);
   CoglDisplayEGL *egl_display = context->display->winsys;
 
   return bind_onscreen_with_context (onscreen, egl_display->egl_context);
@@ -692,7 +692,8 @@ _cogl_winsys_onscreen_bind (CoglOnscreen *onscreen)
 static int
 _cogl_winsys_onscreen_get_buffer_age (CoglOnscreen *onscreen)
 {
-  CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  CoglContext *context = cogl_framebuffer_get_context (framebuffer);
   CoglRenderer *renderer = context->display->renderer;
   CoglRendererEGL *egl_renderer = renderer->winsys;
   CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
@@ -729,11 +730,11 @@ _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
                                    int n_rectangles,
                                    CoglFrameInfo *info)
 {
-  CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  CoglContext *context = cogl_framebuffer_get_context (framebuffer);
   CoglRenderer *renderer = context->display->renderer;
   CoglRendererEGL *egl_renderer = renderer->winsys;
   CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
-  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
   int framebuffer_height  = cogl_framebuffer_get_height (framebuffer);
   int *rectangles = g_alloca (sizeof (int) * n_rectangles * 4);
   int i;
@@ -769,7 +770,8 @@ _cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
                                                 int n_rectangles,
                                                 CoglFrameInfo *info)
 {
-  CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  CoglContext *context = cogl_framebuffer_get_context (framebuffer);
   CoglRenderer *renderer = context->display->renderer;
   CoglRendererEGL *egl_renderer = renderer->winsys;
   CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
@@ -788,7 +790,7 @@ _cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
 
   if (n_rectangles && egl_renderer->pf_eglSwapBuffersWithDamage)
     {
-      CoglFramebuffer *fb = COGL_FRAMEBUFFER (onscreen);
+      CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
       size_t size = n_rectangles * sizeof (int) * 4;
       int *flipped = alloca (size);
       int i;
@@ -798,7 +800,9 @@ _cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
         {
           const int *rect = rectangles + 4 * i;
           int *flip_rect = flipped + 4 * i;
-          flip_rect[1] = fb->height - rect[1] - rect[3];
+
+          flip_rect[1] =
+            cogl_framebuffer_get_height (framebuffer) - rect[1] - rect[3];
         }
 
       if (egl_renderer->pf_eglSwapBuffersWithDamage (egl_renderer->edpy,
diff --git a/cogl/cogl/winsys/cogl-winsys-glx.c b/cogl/cogl/winsys/cogl-winsys-glx.c
index 00e70ade67..5bef8d3951 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 (framebuffer->type != COGL_FRAMEBUFFER_TYPE_ONSCREEN)
+      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 (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN)
+  if (cogl_is_onscreen (framebuffer))
     {
       CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
       CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
@@ -389,7 +389,8 @@ static void
 set_sync_pending (CoglOnscreen *onscreen)
 {
   CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
-  CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  CoglContext *context = cogl_framebuffer_get_context (framebuffer);
   CoglRenderer *renderer = context->display->renderer;
   CoglGLXRenderer *glx_renderer = renderer->winsys;
 
@@ -412,7 +413,8 @@ static void
 set_complete_pending (CoglOnscreen *onscreen)
 {
   CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
-  CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  CoglContext *context = cogl_framebuffer_get_context (framebuffer);
   CoglRenderer *renderer = context->display->renderer;
   CoglGLXRenderer *glx_renderer = renderer->winsys;
 
@@ -464,7 +466,7 @@ update_output (CoglOnscreen *onscreen)
 {
   CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
-  CoglContext *context = framebuffer->context;
+  CoglContext *context = cogl_framebuffer_get_context (framebuffer);
   CoglDisplay *display = context->display;
   CoglOutput *output;
   int width, height;
@@ -631,7 +633,7 @@ update_all_outputs (CoglRenderer *renderer)
     {
       CoglFramebuffer *framebuffer = l->data;
 
-      if (framebuffer->type != COGL_FRAMEBUFFER_TYPE_ONSCREEN)
+      if (!cogl_is_onscreen (framebuffer))
         continue;
 
       update_output (COGL_ONSCREEN (framebuffer));
@@ -855,9 +857,9 @@ update_winsys_features (CoglContext *context, GError **error)
 }
 
 static void
-glx_attributes_from_framebuffer_config (CoglDisplay *display,
-                                        CoglFramebufferConfig *config,
-                                        int *attributes)
+glx_attributes_from_framebuffer_config (CoglDisplay                 *display,
+                                        const CoglFramebufferConfig *config,
+                                        int                         *attributes)
 {
   CoglGLXRenderer *glx_renderer = display->renderer->winsys;
   int i = 0;
@@ -907,10 +909,10 @@ glx_attributes_from_framebuffer_config (CoglDisplay *display,
  * we could overload as an indication of error, so we have to return
  * an explicit boolean status. */
 static gboolean
-find_fbconfig (CoglDisplay *display,
-               CoglFramebufferConfig *config,
-               GLXFBConfig *config_ret,
-               GError **error)
+find_fbconfig (CoglDisplay                  *display,
+               const CoglFramebufferConfig  *config,
+               GLXFBConfig                  *config_ret,
+               GError                      **error)
 {
   CoglXlibRenderer *xlib_renderer =
     _cogl_xlib_renderer_get_data (display->renderer);
@@ -1235,7 +1237,7 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
                             GError **error)
 {
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
-  CoglContext *context = framebuffer->context;
+  CoglContext *context = cogl_framebuffer_get_context (framebuffer);
   CoglDisplay *display = context->display;
   CoglGLXDisplay *glx_display = display->winsys;
   CoglXlibRenderer *xlib_renderer =
@@ -1244,12 +1246,14 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
   Window xwin;
   CoglOnscreenXlib *xlib_onscreen;
   CoglOnscreenGLX *glx_onscreen;
+  const CoglFramebufferConfig *config;
   GLXFBConfig fbconfig;
   GError *fbconfig_error = NULL;
 
   g_return_val_if_fail (glx_display->glx_context, FALSE);
 
-  if (!find_fbconfig (display, &framebuffer->config,
+  config = cogl_framebuffer_get_config (framebuffer);
+  if (!find_fbconfig (display, config,
                       &fbconfig,
                       &fbconfig_error))
     {
@@ -1263,7 +1267,7 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
 
   /* Update the real number of samples_per_pixel now that we have
    * found an fbconfig... */
-  if (framebuffer->config.samples_per_pixel)
+  if (config->samples_per_pixel)
     {
       int samples;
       int status = glx_renderer->glXGetFBConfigAttrib (xlib_renderer->xdpy,
@@ -1271,7 +1275,7 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen,
                                                        GLX_SAMPLES,
                                                        &samples);
       g_return_val_if_fail (status == Success, TRUE);
-      framebuffer->samples_per_pixel = samples;
+      cogl_framebuffer_update_samples_per_pixel (framebuffer, samples);
     }
 
   /* FIXME: We need to explicitly Select for ConfigureNotify events.
@@ -1384,7 +1388,7 @@ static void
 _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
 {
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
-  CoglContext *context = framebuffer->context;
+  CoglContext *context = cogl_framebuffer_get_context (framebuffer);
   CoglContextGLX *glx_context = context->winsys;
   CoglGLXDisplay *glx_display = context->display->winsys;
   CoglXlibRenderer *xlib_renderer =
@@ -1455,7 +1459,8 @@ _cogl_winsys_onscreen_deinit (CoglOnscreen *onscreen)
 static void
 _cogl_winsys_onscreen_bind (CoglOnscreen *onscreen)
 {
-  CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  CoglContext *context = cogl_framebuffer_get_context (framebuffer);
   CoglContextGLX *glx_context = context->winsys;
   CoglGLXDisplay *glx_display = context->display->winsys;
   CoglXlibRenderer *xlib_renderer =
@@ -1526,7 +1531,7 @@ static void
 _cogl_winsys_wait_for_gpu (CoglOnscreen *onscreen)
 {
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
-  CoglContext *ctx = framebuffer->context;
+  CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
 
   ctx->glFinish ();
 }
@@ -1535,7 +1540,7 @@ static void
 _cogl_winsys_wait_for_vblank (CoglOnscreen *onscreen)
 {
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
-  CoglContext *ctx = framebuffer->context;
+  CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
   CoglGLXRenderer *glx_renderer;
   CoglXlibRenderer *xlib_renderer;
   CoglGLXDisplay *glx_display;
@@ -1598,7 +1603,7 @@ static int
 _cogl_winsys_onscreen_get_buffer_age (CoglOnscreen *onscreen)
 {
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
-  CoglContext *context = framebuffer->context;
+  CoglContext *context = cogl_framebuffer_get_context (framebuffer);
   CoglXlibRenderer *xlib_renderer = _cogl_xlib_renderer_get_data (context->display->renderer);
   CoglGLXRenderer *glx_renderer = context->display->renderer->winsys;
   CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
@@ -1635,7 +1640,7 @@ _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
                                    CoglFrameInfo *info)
 {
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
-  CoglContext *context = framebuffer->context;
+  CoglContext *context = cogl_framebuffer_get_context (framebuffer);
   CoglXlibRenderer *xlib_renderer =
     _cogl_xlib_renderer_get_data (context->display->renderer);
   CoglGLXRenderer *glx_renderer = context->display->renderer->winsys;
@@ -1842,7 +1847,7 @@ _cogl_winsys_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
                                                 CoglFrameInfo *info)
 {
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
-  CoglContext *context = framebuffer->context;
+  CoglContext *context = cogl_framebuffer_get_context (framebuffer);
   CoglXlibRenderer *xlib_renderer =
     _cogl_xlib_renderer_get_data (context->display->renderer);
   CoglGLXRenderer *glx_renderer = context->display->renderer->winsys;
@@ -1924,7 +1929,8 @@ static void
 _cogl_winsys_onscreen_set_visibility (CoglOnscreen *onscreen,
                                       gboolean visibility)
 {
-  CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  CoglContext *context = cogl_framebuffer_get_context (framebuffer);
   CoglXlibRenderer *xlib_renderer =
     _cogl_xlib_renderer_get_data (context->display->renderer);
   CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
@@ -1940,7 +1946,7 @@ _cogl_winsys_onscreen_set_resizable (CoglOnscreen *onscreen,
                                      gboolean resizable)
 {
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
-  CoglContext *context = framebuffer->context;
+  CoglContext *context = cogl_framebuffer_get_context (framebuffer);
   CoglXlibRenderer *xlib_renderer =
     _cogl_xlib_renderer_get_data (context->display->renderer);
   CoglOnscreenXlib *xlib_onscreen = onscreen->winsys;
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
index 87a690532b..68656e977d 100644
--- a/src/backends/native/meta-renderer-native.c
+++ b/src/backends/native/meta-renderer-native.c
@@ -807,9 +807,9 @@ fail:
 }
 
 static int
-meta_renderer_native_add_egl_config_attributes (CoglDisplay           *cogl_display,
-                                                CoglFramebufferConfig *config,
-                                                EGLint                *attributes)
+meta_renderer_native_add_egl_config_attributes (CoglDisplay                 *cogl_display,
+                                                const CoglFramebufferConfig *config,
+                                                EGLint                      *attributes)
 {
   CoglRendererEGL *cogl_renderer_egl = cogl_display->renderer->winsys;
   MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform;
@@ -1726,7 +1726,7 @@ copy_shared_framebuffer_cpu (CoglOnscreen                        *onscreen,
                              MetaRendererNativeGpuData           *renderer_gpu_data)
 {
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
-  CoglContext *cogl_context = framebuffer->context;
+  CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer);
   MetaDumbBuffer *dumb_fb;
   CoglBitmap *dumb_bitmap;
   CoglPixelFormat cogl_format;
@@ -1869,7 +1869,8 @@ ensure_crtc_modes (CoglOnscreen  *onscreen,
 {
   CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
   MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
-  CoglContext *cogl_context = COGL_FRAMEBUFFER (onscreen)->context;
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer);
   CoglRenderer *cogl_renderer = cogl_context->display->renderer;
   CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys;
   MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform;
@@ -1897,7 +1898,8 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen  *onscreen,
                                                int            n_rectangles,
                                                CoglFrameInfo *frame_info)
 {
-  CoglContext *cogl_context = COGL_FRAMEBUFFER (onscreen)->context;
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer);
   CoglDisplay *cogl_display = cogl_context_get_display (cogl_context);
   CoglRenderer *cogl_renderer = cogl_context->display->renderer;
   CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys;
@@ -2118,7 +2120,8 @@ meta_onscreen_native_direct_scanout (CoglOnscreen   *onscreen,
   CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
   MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
   MetaGpuKms *render_gpu = onscreen_native->render_gpu;
-  CoglContext *cogl_context = COGL_FRAMEBUFFER (onscreen)->context;
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer);
   CoglRenderer *cogl_renderer = cogl_context->display->renderer;
   CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys;
   MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform;
@@ -2217,7 +2220,7 @@ meta_renderer_native_create_surface_gbm (CoglOnscreen        *onscreen,
   MetaRendererNative *renderer_native = onscreen_native->renderer_native;
   MetaEgl *egl = meta_onscreen_native_get_egl (onscreen_native);
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
-  CoglContext *cogl_context = framebuffer->context;
+  CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer);
   CoglDisplay *cogl_display = cogl_context->display;
   CoglDisplayEGL *cogl_display_egl = cogl_display->winsys;
   CoglRenderer *cogl_renderer = cogl_display->renderer;
@@ -2305,7 +2308,7 @@ meta_renderer_native_create_surface_egl_device (CoglOnscreen  *onscreen,
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
   CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
   MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
-  CoglContext *cogl_context = framebuffer->context;
+  CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer);
   CoglDisplay *cogl_display = cogl_context->display;
   CoglDisplayEGL *cogl_display_egl = cogl_display->winsys;
   CoglRenderer *cogl_renderer = cogl_display->renderer;
@@ -2538,7 +2541,7 @@ meta_renderer_native_init_onscreen (CoglOnscreen *onscreen,
                                     GError      **error)
 {
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
-  CoglContext *cogl_context = framebuffer->context;
+  CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer);
   CoglDisplay *cogl_display = cogl_context->display;
   CoglDisplayEGL *cogl_display_egl = cogl_display->winsys;
   CoglOnscreenEGL *onscreen_egl;
@@ -2644,7 +2647,7 @@ destroy_egl_surface (CoglOnscreen *onscreen)
       MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
       MetaEgl *egl = meta_onscreen_native_get_egl (onscreen_native);
       CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
-      CoglContext *cogl_context = framebuffer->context;
+      CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer);
       CoglRenderer *cogl_renderer = cogl_context->display->renderer;
       CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys;
 
@@ -2660,7 +2663,7 @@ static void
 meta_renderer_native_release_onscreen (CoglOnscreen *onscreen)
 {
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
-  CoglContext *cogl_context = framebuffer->context;
+  CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer);
   CoglDisplay *cogl_display = cogl_context_get_display (cogl_context);
   CoglDisplayEGL *cogl_display_egl = cogl_display->winsys;
   CoglOnscreenEGL *onscreen_egl = onscreen->winsys;


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