[cogl/wip/rib/master-next: 29/36] framebuffer: split out CoglOnscreen code



commit cfc779271e4ddcf817c68795afcbb84f8f43f651
Author: Robert Bragg <robert linux intel com>
Date:   Thu Oct 13 21:31:04 2011 +0100

    framebuffer: split out CoglOnscreen code
    
    This factors out the CoglOnscreen code from cogl-framebuffer.c so we now
    have cogl-onscreen.c, cogl-onscreen.h and cogl-onscreen-private.h.
    Notably some of the functions pulled out are currently namespaced as
    cogl_framebuffer but we know we are planning on renaming them to be in
    the cogl_onscreen namespace; such as cogl_framebuffer_swap_buffers().

 cogl/Makefile.am                                |    2 +
 cogl/cogl-clutter.c                             |    1 +
 cogl/cogl-context.c                             |    1 +
 cogl/cogl-framebuffer-private.h                 |   42 +--
 cogl/cogl-framebuffer.c                         |  338 +----------------------
 cogl/cogl-framebuffer.h                         |  217 +--------------
 cogl/cogl-onscreen-private.h                    |   63 ++++
 cogl/cogl-onscreen-template-private.h           |    1 +
 cogl/cogl-onscreen.c                            |  344 +++++++++++++++++++++++
 cogl/cogl-onscreen.h                            |  258 +++++++++++++++++
 cogl/cogl-pipeline-opengl.c                     |    1 +
 cogl/cogl.h                                     |    1 +
 cogl/winsys/cogl-winsys-egl.c                   |    1 +
 cogl/winsys/cogl-winsys-glx.c                   |    1 +
 cogl/winsys/cogl-winsys-private.h               |    2 +-
 doc/reference/cogl-2.0-experimental/Makefile.am |    1 +
 doc/reference/cogl/Makefile.am                  |    1 +
 17 files changed, 699 insertions(+), 576 deletions(-)
---
diff --git a/cogl/Makefile.am b/cogl/Makefile.am
index 7e3e943..2d844cf 100644
--- a/cogl/Makefile.am
+++ b/cogl/Makefile.am
@@ -88,6 +88,7 @@ cogl_public_h = \
 	$(srcdir)/cogl-primitive.h 		\
 	$(srcdir)/cogl-clip-state.h		\
 	$(srcdir)/cogl-framebuffer.h		\
+	$(srcdir)/cogl-onscreen.h		\
 	$(srcdir)/cogl-clutter.h       		\
 	$(srcdir)/cogl.h			\
 	$(NULL)
@@ -305,6 +306,7 @@ cogl_sources_c = \
 	$(srcdir)/cogl-journal.c			\
 	$(srcdir)/cogl-framebuffer-private.h		\
 	$(srcdir)/cogl-framebuffer.c 			\
+	$(srcdir)/cogl-onscreen.c 			\
 	$(srcdir)/cogl-profile.h 			\
 	$(srcdir)/cogl-profile.c 			\
 	$(srcdir)/cogl-flags.h				\
diff --git a/cogl/cogl-clutter.c b/cogl/cogl-clutter.c
index aaf0281..fca6e82 100644
--- a/cogl/cogl-clutter.c
+++ b/cogl/cogl-clutter.c
@@ -37,6 +37,7 @@
 #include "cogl-winsys-private.h"
 #include "cogl-winsys-stub-private.h"
 #include "cogl-framebuffer-private.h"
+#include "cogl-onscreen-private.h"
 
 gboolean
 cogl_clutter_check_extension (const char *name, const char *ext)
diff --git a/cogl/cogl-context.c b/cogl/cogl-context.c
index cd09cbc..bb70e13 100644
--- a/cogl/cogl-context.c
+++ b/cogl/cogl-context.c
@@ -41,6 +41,7 @@
 #include "cogl-pipeline-private.h"
 #include "cogl-pipeline-opengl-private.h"
 #include "cogl-framebuffer-private.h"
+#include "cogl-onscreen-private.h"
 #include "cogl2-path.h"
 
 #include <string.h>
diff --git a/cogl/cogl-framebuffer-private.h b/cogl/cogl-framebuffer-private.h
index a6c5b6e..e5922c7 100644
--- a/cogl/cogl-framebuffer-private.h
+++ b/cogl/cogl-framebuffer-private.h
@@ -28,6 +28,7 @@
 #include "cogl-matrix-stack.h"
 #include "cogl-clip-state-private.h"
 #include "cogl-journal-private.h"
+#include "cogl-winsys-private.h"
 
 #ifdef COGL_HAS_XLIB_SUPPORT
 #include <X11/Xlib.h>
@@ -38,10 +39,6 @@
 #include <GL/glxext.h>
 #endif
 
-#ifdef COGL_HAS_WIN32_SUPPORT
-#include <windows.h>
-#endif
-
 typedef enum _CoglFramebufferType {
   COGL_FRAMEBUFFER_TYPE_ONSCREEN,
   COGL_FRAMEBUFFER_TYPE_OFFSCREEN
@@ -145,31 +142,18 @@ typedef struct _CoglOffscreen
 
 #define COGL_OFFSCREEN(X) ((CoglOffscreen *)(X))
 
-struct _CoglOnscreen
-{
-  CoglFramebuffer  _parent;
-
-#ifdef COGL_HAS_X11_SUPPORT
-  guint32 foreign_xid;
-  CoglOnscreenX11MaskCallback foreign_update_mask_callback;
-  void *foreign_update_mask_data;
-#endif
-
-#ifdef COGL_HAS_WIN32_SUPPORT
-  HWND foreign_hwnd;
-#endif
-
-  gboolean swap_throttled;
-
-  void *winsys;
-};
-
 void
-_cogl_framebuffer_state_init (void);
+_cogl_framebuffer_init (CoglFramebuffer *framebuffer,
+                        CoglContext *ctx,
+                        CoglFramebufferType type,
+                        CoglPixelFormat format,
+                        int width,
+                        int height);
 
-void
-_cogl_framebuffer_winsys_update_size (CoglFramebuffer *framebuffer,
-                                      int width, int height);
+void _cogl_framebuffer_free (CoglFramebuffer *framebuffer);
+
+const CoglWinsysVtable *
+_cogl_framebuffer_get_winsys (CoglFramebuffer *framebuffer);
 
 void
 _cogl_framebuffer_clear_without_flush4f (CoglFramebuffer *framebuffer,
@@ -354,8 +338,4 @@ _cogl_blit_framebuffer (unsigned int src_x,
                         unsigned int width,
                         unsigned int height);
 
-CoglOnscreen *
-_cogl_onscreen_new (void);
-
 #endif /* __COGL_FRAMEBUFFER_PRIVATE_H */
-
diff --git a/cogl/cogl-framebuffer.c b/cogl/cogl-framebuffer.c
index a09176f..c35fdd1 100644
--- a/cogl/cogl-framebuffer.c
+++ b/cogl/cogl-framebuffer.c
@@ -31,7 +31,6 @@
 #include "cogl-context-private.h"
 #include "cogl-display-private.h"
 #include "cogl-renderer-private.h"
-#include "cogl-handle.h"
 #include "cogl-object-private.h"
 #include "cogl-util.h"
 #include "cogl-texture-private.h"
@@ -106,11 +105,10 @@ typedef struct _CoglFramebufferStackEntry
   CoglFramebuffer *read_buffer;
 } CoglFramebufferStackEntry;
 
-static void _cogl_framebuffer_free (CoglFramebuffer *framebuffer);
-static void _cogl_onscreen_free (CoglOnscreen *onscreen);
+extern GQuark _cogl_object_onscreen_get_type (void);
+
 static void _cogl_offscreen_free (CoglOffscreen *offscreen);
 
-COGL_OBJECT_INTERNAL_DEFINE (Onscreen, onscreen);
 COGL_OBJECT_DEFINE (Offscreen, offscreen);
 COGL_OBJECT_DEFINE_DEPRECATED_REF_COUNTING (offscreen);
 
@@ -129,16 +127,16 @@ cogl_framebuffer_error_quark (void)
 gboolean
 _cogl_is_framebuffer (void *object)
 {
-  CoglHandleObject *obj = object;
+  CoglObject *obj = object;
 
   if (obj == NULL)
     return FALSE;
 
-  return obj->klass->type == _cogl_handle_onscreen_get_type ()
-    || obj->klass->type == _cogl_handle_offscreen_get_type ();
+  return obj->klass->type == _cogl_object_onscreen_get_type ()
+    || obj->klass->type == _cogl_object_offscreen_get_type ();
 }
 
-static void
+void
 _cogl_framebuffer_init (CoglFramebuffer *framebuffer,
                         CoglContext *ctx,
                         CoglFramebufferType type,
@@ -225,7 +223,7 @@ _cogl_framebuffer_free (CoglFramebuffer *framebuffer)
   cogl_object_unref (ctx);
 }
 
-static const CoglWinsysVtable *
+const CoglWinsysVtable *
 _cogl_framebuffer_get_winsys (CoglFramebuffer *framebuffer)
 {
   return framebuffer->context->display->renderer->winsys_vtable;
@@ -788,76 +786,6 @@ _cogl_offscreen_free (CoglOffscreen *offscreen)
   g_free (offscreen);
 }
 
-static void
-_cogl_onscreen_init_from_template (CoglOnscreen *onscreen,
-                                   CoglOnscreenTemplate *onscreen_template)
-{
-  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
-
-  framebuffer->config = onscreen_template->config;
-  cogl_object_ref (framebuffer->config.swap_chain);
-}
-
-/* XXX: While we still have backend in Clutter we need a dummy object
- * to represent the CoglOnscreen framebuffer that the backend
- * creates... */
-CoglOnscreen *
-_cogl_onscreen_new (void)
-{
-  CoglOnscreen *onscreen = g_new0 (CoglOnscreen, 1);
-
-  _COGL_GET_CONTEXT (ctx, NULL);
-
-  _cogl_framebuffer_init (COGL_FRAMEBUFFER (onscreen),
-                          ctx,
-                          COGL_FRAMEBUFFER_TYPE_ONSCREEN,
-                          COGL_PIXEL_FORMAT_RGBA_8888_PRE,
-                          0x1eadbeef, /* width */
-                          0x1eadbeef); /* height */
-  /* NB: make sure to pass positive width/height numbers here
-   * because otherwise we'll hit input validation assertions!*/
-
-  _cogl_onscreen_init_from_template (onscreen, ctx->display->onscreen_template);
-
-  COGL_FRAMEBUFFER (onscreen)->allocated = TRUE;
-
-  /* XXX: Note we don't initialize onscreen->winsys in this case. */
-
-  return _cogl_onscreen_object_new (onscreen);
-}
-
-CoglOnscreen *
-cogl_onscreen_new (CoglContext *ctx, int width, int height)
-{
-  CoglOnscreen *onscreen;
-
-  /* FIXME: We are assuming onscreen buffers will always be
-     premultiplied so we'll set the premult flag on the bitmap
-     format. This will usually be correct because the result of the
-     default blending operations for Cogl ends up with premultiplied
-     data in the framebuffer. However it is possible for the
-     framebuffer to be in whatever format depending on what
-     CoglPipeline is used to render to it. Eventually we may want to
-     add a way for an application to inform Cogl that the framebuffer
-     is not premultiplied in case it is being used for some special
-     purpose. */
-
-  onscreen = g_new0 (CoglOnscreen, 1);
-  _cogl_framebuffer_init (COGL_FRAMEBUFFER (onscreen),
-                          ctx,
-                          COGL_FRAMEBUFFER_TYPE_ONSCREEN,
-                          COGL_PIXEL_FORMAT_RGBA_8888_PRE,
-                          width, /* width */
-                          height); /* height */
-
-  _cogl_onscreen_init_from_template (onscreen, ctx->display->onscreen_template);
-
-  /* FIXME: This should be configurable via the template too */
-  onscreen->swap_throttled = TRUE;
-
-  return _cogl_onscreen_object_new (onscreen);
-}
-
 static gboolean
 try_creating_fbo (CoglOffscreen *offscreen,
                   TryFBOFlags flags)
@@ -1099,38 +1027,6 @@ cogl_framebuffer_allocate (CoglFramebuffer *framebuffer,
   return TRUE;
 }
 
-static void
-_cogl_onscreen_free (CoglOnscreen *onscreen)
-{
-  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
-  const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
-
-  winsys->onscreen_deinit (onscreen);
-  g_return_if_fail (onscreen->winsys == NULL);
-
-  /* Chain up to parent */
-  _cogl_framebuffer_free (framebuffer);
-
-  g_free (onscreen);
-}
-
-void
-_cogl_framebuffer_winsys_update_size (CoglFramebuffer *framebuffer,
-                                      int width, int height)
-{
-  CoglContext *ctx = framebuffer->context;
-
-  if (framebuffer->width == width && framebuffer->height == height)
-    return;
-
-  framebuffer->width = width;
-  framebuffer->height = height;
-
-  /* We'll need to recalculate the GL viewport state derived
-   * from the Cogl viewport */
-  ctx->dirty_gl_viewport = 1;
-}
-
 static CoglFramebufferStackEntry *
 create_stack_entry (CoglFramebuffer *draw_buffer,
                     CoglFramebuffer *read_buffer)
@@ -1164,20 +1060,10 @@ _cogl_free_framebuffer_stack (GSList *stack)
       CoglFramebufferStackEntry *entry = l->data;
 
       if (entry->draw_buffer)
-        {
-          if (entry->draw_buffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN)
-            _cogl_offscreen_free (COGL_OFFSCREEN (entry->draw_buffer));
-          else
-            _cogl_onscreen_free (COGL_ONSCREEN (entry->draw_buffer));
-        }
+        cogl_object_unref (entry->draw_buffer);
 
       if (entry->read_buffer)
-        {
-          if (entry->read_buffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN)
-            _cogl_offscreen_free (COGL_OFFSCREEN (entry->read_buffer));
-          else
-            _cogl_onscreen_free (COGL_ONSCREEN (entry->read_buffer));
-        }
+        cogl_object_unref (entry->draw_buffer);
 
       g_slice_free (CoglFramebufferStackEntry, entry);
     }
@@ -1861,214 +1747,8 @@ cogl_framebuffer_discard_buffers (CoglFramebuffer *framebuffer,
 }
 
 void
-cogl_framebuffer_swap_buffers (CoglFramebuffer *framebuffer)
-{
-  const CoglWinsysVtable *winsys;
-
-  g_return_if_fail  (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN);
-
-  /* FIXME: we shouldn't need to flush *all* journals here! */
-  cogl_flush ();
-  winsys = _cogl_framebuffer_get_winsys (framebuffer);
-  winsys->onscreen_swap_buffers (COGL_ONSCREEN (framebuffer));
-  cogl_framebuffer_discard_buffers (framebuffer,
-                                    COGL_BUFFER_BIT_COLOR |
-                                    COGL_BUFFER_BIT_DEPTH |
-                                    COGL_BUFFER_BIT_STENCIL);
-}
-
-void
-cogl_framebuffer_swap_region (CoglFramebuffer *framebuffer,
-                              const int *rectangles,
-                              int n_rectangles)
-{
-  const CoglWinsysVtable *winsys;
-
-  g_return_if_fail  (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN);
-
-  /* FIXME: we shouldn't need to flush *all* journals here! */
-  cogl_flush ();
-
-  winsys = _cogl_framebuffer_get_winsys (framebuffer);
-
-  /* This should only be called if the winsys advertises
-     COGL_WINSYS_FEATURE_SWAP_REGION */
-  g_return_if_fail (winsys->onscreen_swap_region != NULL);
-
-  winsys->onscreen_swap_region (COGL_ONSCREEN (framebuffer),
-                                rectangles,
-                                n_rectangles);
-
-  cogl_framebuffer_discard_buffers (framebuffer,
-                                    COGL_BUFFER_BIT_COLOR |
-                                    COGL_BUFFER_BIT_DEPTH |
-                                    COGL_BUFFER_BIT_STENCIL);
-}
-
-#ifdef COGL_HAS_X11_SUPPORT
-void
-cogl_x11_onscreen_set_foreign_window_xid (CoglOnscreen *onscreen,
-                                          guint32 xid,
-                                          CoglOnscreenX11MaskCallback update,
-                                          void *user_data)
-{
-  /* We don't wan't applications to get away with being lazy here and not
-   * passing an update callback... */
-  g_return_if_fail (update);
-
-  onscreen->foreign_xid = xid;
-  onscreen->foreign_update_mask_callback = update;
-  onscreen->foreign_update_mask_data = user_data;
-}
-
-guint32
-cogl_x11_onscreen_get_window_xid (CoglOnscreen *onscreen)
-{
-  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
-
-  if (onscreen->foreign_xid)
-    return onscreen->foreign_xid;
-  else
-    {
-      const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
-
-      /* This should only be called for x11 onscreens */
-      g_return_val_if_fail (winsys->onscreen_x11_get_window_xid != NULL, 0);
-
-      return winsys->onscreen_x11_get_window_xid (onscreen);
-    }
-}
-
-guint32
-cogl_x11_onscreen_get_visual_xid (CoglOnscreen *onscreen)
-{
-  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
-  const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
-  XVisualInfo *visinfo;
-  guint32 id;
-
-  /* This should only be called for xlib based onscreens */
-  g_return_val_if_fail (winsys->xlib_get_visual_info != NULL, 0);
-
-  visinfo = winsys->xlib_get_visual_info ();
-  id = (guint32)visinfo->visualid;
-
-  XFree (visinfo);
-  return id;
-}
-#endif /* COGL_HAS_X11_SUPPORT */
-
-#ifdef COGL_HAS_WIN32_SUPPORT
-
-void
-cogl_win32_onscreen_set_foreign_window (CoglOnscreen *onscreen,
-                                        HWND hwnd)
-{
-  onscreen->foreign_hwnd = hwnd;
-}
-
-HWND
-cogl_win32_onscreen_get_window (CoglOnscreen *onscreen)
-{
-  if (onscreen->foreign_hwnd)
-    return onscreen->foreign_hwnd;
-  else
-    {
-      CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
-      const CoglWinsysVtable *winsys =
-        _cogl_framebuffer_get_winsys (framebuffer);
-
-      /* This should only be called for win32 onscreens */
-      g_return_val_if_fail (winsys->onscreen_win32_get_window != NULL, 0);
-
-      return winsys->onscreen_win32_get_window (onscreen);
-    }
-}
-
-#endif /* COGL_HAS_WIN32_SUPPORT */
-
-unsigned int
-cogl_framebuffer_add_swap_buffers_callback (CoglFramebuffer *framebuffer,
-                                            CoglSwapBuffersNotify callback,
-                                            void *user_data)
-{
-  CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
-  const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
-
-  /* Should this just be cogl_onscreen API instead? */
-  g_return_val_if_fail (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN, 0);
-
-  /* This should only be called when
-     COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT is advertised */
-  g_return_val_if_fail (winsys->onscreen_add_swap_buffers_callback != NULL, 0);
-
-  return winsys->onscreen_add_swap_buffers_callback (onscreen,
-                                                     callback,
-                                                     user_data);
-}
-
-void
-cogl_framebuffer_remove_swap_buffers_callback (CoglFramebuffer *framebuffer,
-                                               unsigned int id)
-{
-  CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
-  const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
-
-  /* This should only be called when
-     COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT is advertised */
-  g_return_if_fail (winsys->onscreen_remove_swap_buffers_callback != NULL);
-
-  winsys->onscreen_remove_swap_buffers_callback (onscreen, id);
-}
-
-void
 cogl_framebuffer_finish (CoglFramebuffer *framebuffer)
 {
   _cogl_framebuffer_flush_journal (framebuffer);
   GE (framebuffer->context, glFinish ());
 }
-
-void
-cogl_onscreen_set_swap_throttled (CoglOnscreen *onscreen,
-                                  gboolean throttled)
-{
-  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
-  onscreen->swap_throttled = throttled;
-  if (framebuffer->allocated)
-    {
-      const CoglWinsysVtable *winsys =
-        _cogl_framebuffer_get_winsys (framebuffer);
-      winsys->onscreen_update_swap_throttled (onscreen);
-    }
-}
-
-void
-cogl_onscreen_show (CoglOnscreen *onscreen)
-{
-  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
-  const CoglWinsysVtable *winsys;
-
-  if (!framebuffer->allocated)
-    {
-      if (!cogl_framebuffer_allocate (framebuffer, NULL))
-        return;
-    }
-
-  winsys = _cogl_framebuffer_get_winsys (framebuffer);
-  if (winsys->onscreen_set_visibility)
-    winsys->onscreen_set_visibility (onscreen, TRUE);
-}
-
-void
-cogl_onscreen_hide (CoglOnscreen *onscreen)
-{
-  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
-
-  if (framebuffer->allocated)
-    {
-      const CoglWinsysVtable *winsys =
-        _cogl_framebuffer_get_winsys (framebuffer);
-      if (winsys->onscreen_set_visibility)
-        winsys->onscreen_set_visibility (onscreen, FALSE);
-    }
-}
diff --git a/cogl/cogl-framebuffer.h b/cogl/cogl-framebuffer.h
index d63ef15..87ae65f 100644
--- a/cogl/cogl-framebuffer.h
+++ b/cogl/cogl-framebuffer.h
@@ -28,6 +28,8 @@
 #ifndef __COGL_FRAMEBUFFER_H
 #define __COGL_FRAMEBUFFER_H
 
+#include <cogl/cogl.h>
+
 #include <glib.h>
 
 #ifdef COGL_HAS_WIN32_SUPPORT
@@ -498,69 +500,6 @@ void
 cogl_framebuffer_discard_buffers (CoglFramebuffer *framebuffer,
                                   unsigned long buffers);
 
-/* XXX: Actually should this be renamed too cogl_onscreen_swap_buffers()? */
-#define cogl_framebuffer_swap_buffers cogl_framebuffer_swap_buffers_EXP
-/**
- * cogl_framebuffer_swap_buffers:
- * @framebuffer: A #CoglFramebuffer
- *
- * Swaps the current back buffer being rendered too, to the front for display.
- *
- * This function also implicitly discards the contents of the color, depth and
- * stencil buffers as if cogl_framebuffer_discard_buffers() were used. The
- * significance of the discard is that you should not expect to be able to
- * start a new frame that incrementally builds on the contents of the previous
- * frame.
- *
- * Since: 1.8
- * Stability: unstable
- */
-void
-cogl_framebuffer_swap_buffers (CoglFramebuffer *framebuffer);
-
-#define cogl_framebuffer_swap_region cogl_framebuffer_swap_region_EXP
-/**
- * cogl_framebuffer_swap_region:
- * @framebuffer: A #CoglFramebuffer
- * @rectangles: An array of integer 4-tuples representing rectangles as
- *              (x, y, width, height) tuples.
- * @n_rectangles: The number of 4-tuples to be read from @rectangles
- *
- * Swaps a region of the back buffer being rendered too, to the front for
- * display.  @rectangles represents the region as array of @n_rectangles each
- * defined by 4 sequential (x, y, width, height) integers.
- *
- * This function also implicitly discards the contents of the color, depth and
- * stencil buffers as if cogl_framebuffer_discard_buffers() were used. The
- * significance of the discard is that you should not expect to be able to
- * start a new frame that incrementally builds on the contents of the previous
- * frame.
- *
- * Since: 1.8
- * Stability: unstable
- */
-void
-cogl_framebuffer_swap_region (CoglFramebuffer *framebuffer,
-                              const int *rectangles,
-                              int n_rectangles);
-
-
-typedef void (*CoglSwapBuffersNotify) (CoglFramebuffer *framebuffer,
-                                       void *user_data);
-
-#define cogl_framebuffer_add_swap_buffers_callback \
-  cogl_framebuffer_add_swap_buffers_callback_EXP
-unsigned int
-cogl_framebuffer_add_swap_buffers_callback (CoglFramebuffer *framebuffer,
-                                            CoglSwapBuffersNotify callback,
-                                            void *user_data);
-
-#define cogl_framebuffer_remove_swap_buffers_callback \
-  cogl_framebuffer_remove_swap_buffers_callback_EXP
-void
-cogl_framebuffer_remove_swap_buffers_callback (CoglFramebuffer *framebuffer,
-                                               unsigned int id);
-
 /**
  * cogl_framebuffer_finish:
  * @framebuffer: A #CoglFramebuffer pointer
@@ -581,158 +520,6 @@ cogl_framebuffer_remove_swap_buffers_callback (CoglFramebuffer *framebuffer,
 void
 cogl_framebuffer_finish (CoglFramebuffer *framebuffer);
 
-typedef struct _CoglOnscreen CoglOnscreen;
-#define COGL_ONSCREEN(X) ((CoglOnscreen *)(X))
-
-CoglOnscreen *
-cogl_onscreen_new (CoglContext *context, int width, int height);
-
-#ifdef COGL_HAS_X11
-typedef void (*CoglOnscreenX11MaskCallback) (CoglOnscreen *onscreen,
-                                             guint32 event_mask,
-                                             void *user_data);
-
-/**
- * cogl_x11_onscreen_set_foreign_window_xid:
- * @onscreen: The unallocated framebuffer to associated with an X
- *            window.
- * @xid: The XID of an existing X window
- * @update: A callback that notifies of updates to what Cogl requires
- *          to be in the core X protocol event mask.
- *
- * Ideally we would recommend that you let Cogl be responsible for
- * creating any X window required to back an onscreen framebuffer but
- * if you really need to target a window created manually this
- * function can be called before @onscreen has been allocated to set a
- * foreign XID for your existing X window.
- *
- * Since Cogl needs, for example, to track changes to the size of an X
- * window it requires that certain events be selected for via the core
- * X protocol. This requirement may also be changed asynchronously so
- * you must pass in an @update callback to inform you of Cogl's
- * required event mask.
- *
- * For example if you are using Xlib you could use this API roughly
- * as follows:
- * [{
- * static void
- * my_update_cogl_x11_event_mask (CoglOnscreen *onscreen,
- *                                guint32 event_mask,
- *                                void *user_data)
- * {
- *   XSetWindowAttributes attrs;
- *   MyData *data = user_data;
- *   attrs.event_mask = event_mask | data->my_event_mask;
- *   XChangeWindowAttributes (data->xdpy,
- *                            data->xwin,
- *                            CWEventMask,
- *                            &attrs);
- * }
- *
- * {
- *   *snip*
- *   cogl_x11_onscreen_set_foreign_window_xid (onscreen,
- *                                             data->xwin,
- *                                             my_update_cogl_x11_event_mask,
- *                                             data);
- *   *snip*
- * }
- * }]
- *
- * Since: 2.0
- * Stability: Unstable
- */
-#define cogl_x11_onscreen_set_foreign_window_xid \
-  cogl_x11_onscreen_set_foreign_window_xid_EXP
-void
-cogl_x11_onscreen_set_foreign_window_xid (CoglOnscreen *onscreen,
-                                          guint32 xid,
-                                          CoglOnscreenX11MaskCallback update,
-                                          void *user_data);
-
-#define cogl_x11_onscreen_get_window_xid cogl_x11_onscreen_get_window_xid_EXP
-guint32
-cogl_x11_onscreen_get_window_xid (CoglOnscreen *onscreen);
-
-#define cogl_x11_onscreen_get_visual_xid cogl_x11_onscreen_get_visual_xid_EXP
-guint32
-cogl_x11_onscreen_get_visual_xid (CoglOnscreen *onscreen);
-#endif /* COGL_HAS_X11 */
-
-#ifdef COGL_HAS_WIN32_SUPPORT
-#define cogl_win32_onscreen_set_foreign_window \
-  cogl_win32_onscreen_set_foreign_window_EXP
-void
-cogl_win32_onscreen_set_foreign_window (CoglOnscreen *onscreen,
-                                        HWND hwnd);
-
-#define cogl_win32_onscreen_get_window cogl_win32_onscreen_get_window_EXP
-HWND
-cogl_win32_onscreen_get_window (CoglOnscreen *onscreen);
-#endif /* COGL_HAS_WIN32_SUPPORT */
-
-#if defined (COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT)
-struct wl_surface *
-cogl_wayland_onscreen_get_surface (CoglOnscreen *onscreen);
-#endif /* COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT */
-
-#define cogl_onscreen_set_swap_throttled cogl_onscreen_set_swap_throttled_EXP
-void
-cogl_onscreen_set_swap_throttled (CoglOnscreen *onscreen,
-                                  gboolean throttled);
-
-/**
- * cogl_onscreen_show:
- * @onscreen: The onscreen framebuffer to make visible
- *
- * This requests to make @onscreen visible to the user.
- *
- * Actually the precise semantics of this function depend on the
- * window system currently in use, and if you don't have a
- * multi-windowining system this function may in-fact do nothing.
- *
- * This function will implicitly allocate the given @onscreen
- * framebuffer before showing it if it hasn't already been allocated.
- *
- * <note>Since Cogl doesn't explicitly track the visibility status of
- * onscreen framebuffers it wont try to avoid redundant window system
- * requests e.g. to show an already visible window. This also means
- * that it's acceptable to alternatively use native APIs to show and
- * hide windows without confusing Cogl.</note>
- *
- * Since: 2.0
- * Stability: Unstable
- */
-#define cogl_onscreen_show cogl_onscreen_show_EXP
-void
-cogl_onscreen_show (CoglOnscreen *onscreen);
-
-/**
- * cogl_onscreen_hide:
- * @onscreen: The onscreen framebuffer to make invisible
- *
- * This requests to make @onscreen invisible to the user.
- *
- * Actually the precise semantics of this function depend on the
- * window system currently in use, and if you don't have a
- * multi-windowining system this function may in-fact do nothing.
- *
- * This function does not implicitly allocate the given @onscreen
- * framebuffer before hiding it.
- *
- * <note>Since Cogl doesn't explicitly track the visibility status of
- * onscreen framebuffers it wont try to avoid redundant window system
- * requests e.g. to show an already visible window. This also means
- * that it's acceptable to alternatively use native APIs to show and
- * hide windows without confusing Cogl.</note>
- *
- * Since: 2.0
- * Stability: Unstable
- */
-#define cogl_onscreen_hide cogl_onscreen_hide_EXP
-void
-cogl_onscreen_hide (CoglOnscreen *onscreen);
-
 #define cogl_get_draw_framebuffer cogl_get_draw_framebuffer_EXP
 CoglFramebuffer *
 cogl_get_draw_framebuffer (void);
diff --git a/cogl/cogl-onscreen-private.h b/cogl/cogl-onscreen-private.h
new file mode 100644
index 0000000..be789a5
--- /dev/null
+++ b/cogl/cogl-onscreen-private.h
@@ -0,0 +1,63 @@
+/*
+ * Cogl
+ *
+ * An object oriented GL/GLES Abstraction/Utility Layer
+ *
+ * Copyright (C) 2011 Intel Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ */
+
+#ifndef __COGL_ONSCREEN_PRIVATE_H
+#define __COGL_ONSCREEN_PRIVATE_H
+
+#include "cogl-framebuffer-private.h"
+
+#include <glib.h>
+
+#ifdef COGL_HAS_WIN32_SUPPORT
+#include <windows.h>
+#endif
+
+struct _CoglOnscreen
+{
+  CoglFramebuffer  _parent;
+
+#ifdef COGL_HAS_X11_SUPPORT
+  guint32 foreign_xid;
+  CoglOnscreenX11MaskCallback foreign_update_mask_callback;
+  void *foreign_update_mask_data;
+#endif
+
+#ifdef COGL_HAS_WIN32_SUPPORT
+  HWND foreign_hwnd;
+#endif
+
+  gboolean swap_throttled;
+
+  void *winsys;
+};
+CoglOnscreen *
+_cogl_onscreen_new (void);
+
+void
+_cogl_framebuffer_winsys_update_size (CoglFramebuffer *framebuffer,
+                                      int width, int height);
+
+GQuark
+_cogl_object_onscreen_get_type (void);
+
+#endif /* __COGL_ONSCREEN_PRIVATE_H */
diff --git a/cogl/cogl-onscreen-template-private.h b/cogl/cogl-onscreen-template-private.h
index 2127879..b080b57 100644
--- a/cogl/cogl-onscreen-template-private.h
+++ b/cogl/cogl-onscreen-template-private.h
@@ -26,6 +26,7 @@
 
 #include "cogl-object-private.h"
 #include "cogl-swap-chain.h"
+#include "cogl-framebuffer-private.h"
 
 struct _CoglOnscreenTemplate
 {
diff --git a/cogl/cogl-onscreen.c b/cogl/cogl-onscreen.c
new file mode 100644
index 0000000..52ee784
--- /dev/null
+++ b/cogl/cogl-onscreen.c
@@ -0,0 +1,344 @@
+/*
+ * Cogl
+ *
+ * An object oriented GL/GLES Abstraction/Utility Layer
+ *
+ * Copyright (C) 2011 Intel Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "cogl-onscreen-private.h"
+#include "cogl-framebuffer-private.h"
+#include "cogl-onscreen-template-private.h"
+#include "cogl-context-private.h"
+#include "cogl-object-private.h"
+
+static void _cogl_onscreen_free (CoglOnscreen *onscreen);
+
+COGL_OBJECT_INTERNAL_DEFINE (Onscreen, onscreen);
+
+static void
+_cogl_onscreen_init_from_template (CoglOnscreen *onscreen,
+                                   CoglOnscreenTemplate *onscreen_template)
+{
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+
+  framebuffer->config = onscreen_template->config;
+  cogl_object_ref (framebuffer->config.swap_chain);
+}
+
+/* XXX: While we still have backend in Clutter we need a dummy object
+ * to represent the CoglOnscreen framebuffer that the backend
+ * creates... */
+CoglOnscreen *
+_cogl_onscreen_new (void)
+{
+  CoglOnscreen *onscreen = g_new0 (CoglOnscreen, 1);
+
+  _COGL_GET_CONTEXT (ctx, NULL);
+
+  _cogl_framebuffer_init (COGL_FRAMEBUFFER (onscreen),
+                          ctx,
+                          COGL_FRAMEBUFFER_TYPE_ONSCREEN,
+                          COGL_PIXEL_FORMAT_RGBA_8888_PRE,
+                          0x1eadbeef, /* width */
+                          0x1eadbeef); /* height */
+  /* NB: make sure to pass positive width/height numbers here
+   * because otherwise we'll hit input validation assertions!*/
+
+  _cogl_onscreen_init_from_template (onscreen, ctx->display->onscreen_template);
+
+  COGL_FRAMEBUFFER (onscreen)->allocated = TRUE;
+
+  /* XXX: Note we don't initialize onscreen->winsys in this case. */
+
+  return _cogl_onscreen_object_new (onscreen);
+}
+
+CoglOnscreen *
+cogl_onscreen_new (CoglContext *ctx, int width, int height)
+{
+  CoglOnscreen *onscreen;
+
+  /* FIXME: We are assuming onscreen buffers will always be
+     premultiplied so we'll set the premult flag on the bitmap
+     format. This will usually be correct because the result of the
+     default blending operations for Cogl ends up with premultiplied
+     data in the framebuffer. However it is possible for the
+     framebuffer to be in whatever format depending on what
+     CoglPipeline is used to render to it. Eventually we may want to
+     add a way for an application to inform Cogl that the framebuffer
+     is not premultiplied in case it is being used for some special
+     purpose. */
+
+  onscreen = g_new0 (CoglOnscreen, 1);
+  _cogl_framebuffer_init (COGL_FRAMEBUFFER (onscreen),
+                          ctx,
+                          COGL_FRAMEBUFFER_TYPE_ONSCREEN,
+                          COGL_PIXEL_FORMAT_RGBA_8888_PRE,
+                          width, /* width */
+                          height); /* height */
+
+  _cogl_onscreen_init_from_template (onscreen, ctx->display->onscreen_template);
+
+  /* FIXME: This should be configurable via the template too */
+  onscreen->swap_throttled = TRUE;
+
+  return _cogl_onscreen_object_new (onscreen);
+}
+
+static void
+_cogl_onscreen_free (CoglOnscreen *onscreen)
+{
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
+
+  winsys->onscreen_deinit (onscreen);
+  g_return_if_fail (onscreen->winsys == NULL);
+
+  /* Chain up to parent */
+  _cogl_framebuffer_free (framebuffer);
+
+  g_free (onscreen);
+}
+
+void
+cogl_framebuffer_swap_buffers (CoglFramebuffer *framebuffer)
+{
+  const CoglWinsysVtable *winsys;
+
+  g_return_if_fail  (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN);
+
+  /* FIXME: we shouldn't need to flush *all* journals here! */
+  cogl_flush ();
+  winsys = _cogl_framebuffer_get_winsys (framebuffer);
+  winsys->onscreen_swap_buffers (COGL_ONSCREEN (framebuffer));
+  cogl_framebuffer_discard_buffers (framebuffer,
+                                    COGL_BUFFER_BIT_COLOR |
+                                    COGL_BUFFER_BIT_DEPTH |
+                                    COGL_BUFFER_BIT_STENCIL);
+}
+
+void
+cogl_framebuffer_swap_region (CoglFramebuffer *framebuffer,
+                              const int *rectangles,
+                              int n_rectangles)
+{
+  const CoglWinsysVtable *winsys;
+
+  g_return_if_fail  (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN);
+
+  /* FIXME: we shouldn't need to flush *all* journals here! */
+  cogl_flush ();
+
+  winsys = _cogl_framebuffer_get_winsys (framebuffer);
+
+  /* This should only be called if the winsys advertises
+     COGL_WINSYS_FEATURE_SWAP_REGION */
+  g_return_if_fail (winsys->onscreen_swap_region != NULL);
+
+  winsys->onscreen_swap_region (COGL_ONSCREEN (framebuffer),
+                                rectangles,
+                                n_rectangles);
+
+  cogl_framebuffer_discard_buffers (framebuffer,
+                                    COGL_BUFFER_BIT_COLOR |
+                                    COGL_BUFFER_BIT_DEPTH |
+                                    COGL_BUFFER_BIT_STENCIL);
+}
+
+#ifdef COGL_HAS_X11_SUPPORT
+void
+cogl_x11_onscreen_set_foreign_window_xid (CoglOnscreen *onscreen,
+                                          guint32 xid,
+                                          CoglOnscreenX11MaskCallback update,
+                                          void *user_data)
+{
+  /* We don't wan't applications to get away with being lazy here and not
+   * passing an update callback... */
+  g_return_if_fail (update);
+
+  onscreen->foreign_xid = xid;
+  onscreen->foreign_update_mask_callback = update;
+  onscreen->foreign_update_mask_data = user_data;
+}
+
+guint32
+cogl_x11_onscreen_get_window_xid (CoglOnscreen *onscreen)
+{
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+
+  if (onscreen->foreign_xid)
+    return onscreen->foreign_xid;
+  else
+    {
+      const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
+
+      /* This should only be called for x11 onscreens */
+      g_return_val_if_fail (winsys->onscreen_x11_get_window_xid != NULL, 0);
+
+      return winsys->onscreen_x11_get_window_xid (onscreen);
+    }
+}
+
+guint32
+cogl_x11_onscreen_get_visual_xid (CoglOnscreen *onscreen)
+{
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
+  XVisualInfo *visinfo;
+  guint32 id;
+
+  /* This should only be called for xlib based onscreens */
+  g_return_val_if_fail (winsys->xlib_get_visual_info != NULL, 0);
+
+  visinfo = winsys->xlib_get_visual_info ();
+  id = (guint32)visinfo->visualid;
+
+  XFree (visinfo);
+  return id;
+}
+#endif /* COGL_HAS_X11_SUPPORT */
+
+#ifdef COGL_HAS_WIN32_SUPPORT
+
+void
+cogl_win32_onscreen_set_foreign_window (CoglOnscreen *onscreen,
+                                        HWND hwnd)
+{
+  onscreen->foreign_hwnd = hwnd;
+}
+
+HWND
+cogl_win32_onscreen_get_window (CoglOnscreen *onscreen)
+{
+  if (onscreen->foreign_hwnd)
+    return onscreen->foreign_hwnd;
+  else
+    {
+      CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+      const CoglWinsysVtable *winsys =
+        _cogl_framebuffer_get_winsys (framebuffer);
+
+      /* This should only be called for win32 onscreens */
+      g_return_val_if_fail (winsys->onscreen_win32_get_window != NULL, 0);
+
+      return winsys->onscreen_win32_get_window (onscreen);
+    }
+}
+
+#endif /* COGL_HAS_WIN32_SUPPORT */
+
+unsigned int
+cogl_framebuffer_add_swap_buffers_callback (CoglFramebuffer *framebuffer,
+                                            CoglSwapBuffersNotify callback,
+                                            void *user_data)
+{
+  CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
+  const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
+
+  /* Should this just be cogl_onscreen API instead? */
+  g_return_val_if_fail (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN, 0);
+
+  /* This should only be called when
+     COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT is advertised */
+  g_return_val_if_fail (winsys->onscreen_add_swap_buffers_callback != NULL, 0);
+
+  return winsys->onscreen_add_swap_buffers_callback (onscreen,
+                                                     callback,
+                                                     user_data);
+}
+
+void
+cogl_framebuffer_remove_swap_buffers_callback (CoglFramebuffer *framebuffer,
+                                               unsigned int id)
+{
+  CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
+  const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
+
+  /* This should only be called when
+     COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT is advertised */
+  g_return_if_fail (winsys->onscreen_remove_swap_buffers_callback != NULL);
+
+  winsys->onscreen_remove_swap_buffers_callback (onscreen, id);
+}
+
+void
+cogl_onscreen_set_swap_throttled (CoglOnscreen *onscreen,
+                                  gboolean throttled)
+{
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  onscreen->swap_throttled = throttled;
+  if (framebuffer->allocated)
+    {
+      const CoglWinsysVtable *winsys =
+        _cogl_framebuffer_get_winsys (framebuffer);
+      winsys->onscreen_update_swap_throttled (onscreen);
+    }
+}
+
+void
+cogl_onscreen_show (CoglOnscreen *onscreen)
+{
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+  const CoglWinsysVtable *winsys;
+
+  if (!framebuffer->allocated)
+    {
+      if (!cogl_framebuffer_allocate (framebuffer, NULL))
+        return;
+    }
+
+  winsys = _cogl_framebuffer_get_winsys (framebuffer);
+  if (winsys->onscreen_set_visibility)
+    winsys->onscreen_set_visibility (onscreen, TRUE);
+}
+
+void
+cogl_onscreen_hide (CoglOnscreen *onscreen)
+{
+  CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
+
+  if (framebuffer->allocated)
+    {
+      const CoglWinsysVtable *winsys =
+        _cogl_framebuffer_get_winsys (framebuffer);
+      if (winsys->onscreen_set_visibility)
+        winsys->onscreen_set_visibility (onscreen, FALSE);
+    }
+}
+
+void
+_cogl_framebuffer_winsys_update_size (CoglFramebuffer *framebuffer,
+                                      int width, int height)
+{
+  CoglContext *ctx = framebuffer->context;
+
+  if (framebuffer->width == width && framebuffer->height == height)
+    return;
+
+  framebuffer->width = width;
+  framebuffer->height = height;
+
+  /* We'll need to recalculate the GL viewport state derived
+   * from the Cogl viewport */
+  ctx->dirty_gl_viewport = 1;
+}
diff --git a/cogl/cogl-onscreen.h b/cogl/cogl-onscreen.h
new file mode 100644
index 0000000..8a9d64a
--- /dev/null
+++ b/cogl/cogl-onscreen.h
@@ -0,0 +1,258 @@
+/*
+ * Cogl
+ *
+ * An object oriented GL/GLES Abstraction/Utility Layer
+ *
+ * Copyright (C) 2011 Intel Corporation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ *
+ *
+ * Authors:
+ *   Robert Bragg <robert linux intel com>
+ */
+
+#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
+#error "Only <cogl/cogl.h> can be included directly."
+#endif
+
+#ifndef __COGL_ONSCREEN_H
+#define __COGL_ONSCREEN_H
+
+#include <cogl/cogl-context.h>
+#include <cogl/cogl-framebuffer.h>
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct _CoglOnscreen CoglOnscreen;
+#define COGL_ONSCREEN(X) ((CoglOnscreen *)(X))
+
+CoglOnscreen *
+cogl_onscreen_new (CoglContext *context, int width, int height);
+
+#ifdef COGL_HAS_X11
+typedef void (*CoglOnscreenX11MaskCallback) (CoglOnscreen *onscreen,
+                                             guint32 event_mask,
+                                             void *user_data);
+
+/**
+ * cogl_x11_onscreen_set_foreign_window_xid:
+ * @onscreen: The unallocated framebuffer to associated with an X
+ *            window.
+ * @xid: The XID of an existing X window
+ * @update: A callback that notifies of updates to what Cogl requires
+ *          to be in the core X protocol event mask.
+ *
+ * Ideally we would recommend that you let Cogl be responsible for
+ * creating any X window required to back an onscreen framebuffer but
+ * if you really need to target a window created manually this
+ * function can be called before @onscreen has been allocated to set a
+ * foreign XID for your existing X window.
+ *
+ * Since Cogl needs, for example, to track changes to the size of an X
+ * window it requires that certain events be selected for via the core
+ * X protocol. This requirement may also be changed asynchronously so
+ * you must pass in an @update callback to inform you of Cogl's
+ * required event mask.
+ *
+ * For example if you are using Xlib you could use this API roughly
+ * as follows:
+ * [{
+ * static void
+ * my_update_cogl_x11_event_mask (CoglOnscreen *onscreen,
+ *                                guint32 event_mask,
+ *                                void *user_data)
+ * {
+ *   XSetWindowAttributes attrs;
+ *   MyData *data = user_data;
+ *   attrs.event_mask = event_mask | data->my_event_mask;
+ *   XChangeWindowAttributes (data->xdpy,
+ *                            data->xwin,
+ *                            CWEventMask,
+ *                            &attrs);
+ * }
+ *
+ * {
+ *   *snip*
+ *   cogl_x11_onscreen_set_foreign_window_xid (onscreen,
+ *                                             data->xwin,
+ *                                             my_update_cogl_x11_event_mask,
+ *                                             data);
+ *   *snip*
+ * }
+ * }]
+ *
+ * Since: 2.0
+ * Stability: Unstable
+ */
+#define cogl_x11_onscreen_set_foreign_window_xid \
+  cogl_x11_onscreen_set_foreign_window_xid_EXP
+void
+cogl_x11_onscreen_set_foreign_window_xid (CoglOnscreen *onscreen,
+                                          guint32 xid,
+                                          CoglOnscreenX11MaskCallback update,
+                                          void *user_data);
+
+#define cogl_x11_onscreen_get_window_xid cogl_x11_onscreen_get_window_xid_EXP
+guint32
+cogl_x11_onscreen_get_window_xid (CoglOnscreen *onscreen);
+
+#define cogl_x11_onscreen_get_visual_xid cogl_x11_onscreen_get_visual_xid_EXP
+guint32
+cogl_x11_onscreen_get_visual_xid (CoglOnscreen *onscreen);
+#endif /* COGL_HAS_X11 */
+
+#ifdef COGL_HAS_WIN32_SUPPORT
+#define cogl_win32_onscreen_set_foreign_window \
+  cogl_win32_onscreen_set_foreign_window_EXP
+void
+cogl_win32_onscreen_set_foreign_window (CoglOnscreen *onscreen,
+                                        HWND hwnd);
+
+#define cogl_win32_onscreen_get_window cogl_win32_onscreen_get_window_EXP
+HWND
+cogl_win32_onscreen_get_window (CoglOnscreen *onscreen);
+#endif /* COGL_HAS_WIN32_SUPPORT */
+
+#if defined (COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT)
+struct wl_surface *
+cogl_wayland_onscreen_get_surface (CoglOnscreen *onscreen);
+#endif /* COGL_HAS_EGL_PLATFORM_WAYLAND_SUPPORT */
+
+#define cogl_onscreen_set_swap_throttled cogl_onscreen_set_swap_throttled_EXP
+void
+cogl_onscreen_set_swap_throttled (CoglOnscreen *onscreen,
+                                  gboolean throttled);
+
+/**
+ * cogl_onscreen_show:
+ * @onscreen: The onscreen framebuffer to make visible
+ *
+ * This requests to make @onscreen visible to the user.
+ *
+ * Actually the precise semantics of this function depend on the
+ * window system currently in use, and if you don't have a
+ * multi-windowining system this function may in-fact do nothing.
+ *
+ * This function will implicitly allocate the given @onscreen
+ * framebuffer before showing it if it hasn't already been allocated.
+ *
+ * <note>Since Cogl doesn't explicitly track the visibility status of
+ * onscreen framebuffers it wont try to avoid redundant window system
+ * requests e.g. to show an already visible window. This also means
+ * that it's acceptable to alternatively use native APIs to show and
+ * hide windows without confusing Cogl.</note>
+ *
+ * Since: 2.0
+ * Stability: Unstable
+ */
+#define cogl_onscreen_show cogl_onscreen_show_EXP
+void
+cogl_onscreen_show (CoglOnscreen *onscreen);
+
+/**
+ * cogl_onscreen_hide:
+ * @onscreen: The onscreen framebuffer to make invisible
+ *
+ * This requests to make @onscreen invisible to the user.
+ *
+ * Actually the precise semantics of this function depend on the
+ * window system currently in use, and if you don't have a
+ * multi-windowining system this function may in-fact do nothing.
+ *
+ * This function does not implicitly allocate the given @onscreen
+ * framebuffer before hiding it.
+ *
+ * <note>Since Cogl doesn't explicitly track the visibility status of
+ * onscreen framebuffers it wont try to avoid redundant window system
+ * requests e.g. to show an already visible window. This also means
+ * that it's acceptable to alternatively use native APIs to show and
+ * hide windows without confusing Cogl.</note>
+ *
+ * Since: 2.0
+ * Stability: Unstable
+ */
+#define cogl_onscreen_hide cogl_onscreen_hide_EXP
+void
+cogl_onscreen_hide (CoglOnscreen *onscreen);
+
+/* XXX: Actually should this be renamed too cogl_onscreen_swap_buffers()? */
+#define cogl_framebuffer_swap_buffers cogl_framebuffer_swap_buffers_EXP
+/**
+ * cogl_framebuffer_swap_buffers:
+ * @framebuffer: A #CoglFramebuffer
+ *
+ * Swaps the current back buffer being rendered too, to the front for display.
+ *
+ * This function also implicitly discards the contents of the color, depth and
+ * stencil buffers as if cogl_framebuffer_discard_buffers() were used. The
+ * significance of the discard is that you should not expect to be able to
+ * start a new frame that incrementally builds on the contents of the previous
+ * frame.
+ *
+ * Since: 1.8
+ * Stability: unstable
+ */
+void
+cogl_framebuffer_swap_buffers (CoglFramebuffer *framebuffer);
+
+#define cogl_framebuffer_swap_region cogl_framebuffer_swap_region_EXP
+/**
+ * cogl_framebuffer_swap_region:
+ * @framebuffer: A #CoglFramebuffer
+ * @rectangles: An array of integer 4-tuples representing rectangles as
+ *              (x, y, width, height) tuples.
+ * @n_rectangles: The number of 4-tuples to be read from @rectangles
+ *
+ * Swaps a region of the back buffer being rendered too, to the front for
+ * display.  @rectangles represents the region as array of @n_rectangles each
+ * defined by 4 sequential (x, y, width, height) integers.
+ *
+ * This function also implicitly discards the contents of the color, depth and
+ * stencil buffers as if cogl_framebuffer_discard_buffers() were used. The
+ * significance of the discard is that you should not expect to be able to
+ * start a new frame that incrementally builds on the contents of the previous
+ * frame.
+ *
+ * Since: 1.8
+ * Stability: unstable
+ */
+void
+cogl_framebuffer_swap_region (CoglFramebuffer *framebuffer,
+                              const int *rectangles,
+                              int n_rectangles);
+
+
+typedef void (*CoglSwapBuffersNotify) (CoglFramebuffer *framebuffer,
+                                       void *user_data);
+
+#define cogl_framebuffer_add_swap_buffers_callback \
+  cogl_framebuffer_add_swap_buffers_callback_EXP
+unsigned int
+cogl_framebuffer_add_swap_buffers_callback (CoglFramebuffer *framebuffer,
+                                            CoglSwapBuffersNotify callback,
+                                            void *user_data);
+
+#define cogl_framebuffer_remove_swap_buffers_callback \
+  cogl_framebuffer_remove_swap_buffers_callback_EXP
+void
+cogl_framebuffer_remove_swap_buffers_callback (CoglFramebuffer *framebuffer,
+                                               unsigned int id);
+
+G_END_DECLS
+
+#endif /* __COGL_ONSCREEN_H */
diff --git a/cogl/cogl-pipeline-opengl.c b/cogl/cogl-pipeline-opengl.c
index 361364e..cc9ca1b 100644
--- a/cogl/cogl-pipeline-opengl.c
+++ b/cogl/cogl-pipeline-opengl.c
@@ -36,6 +36,7 @@
 #include "cogl-pipeline-private.h"
 #include "cogl-context-private.h"
 #include "cogl-texture-private.h"
+#include "cogl-framebuffer-private.h"
 
 /* This is needed to set the color attribute on GLES2 */
 #ifdef HAVE_COGL_GLES2
diff --git a/cogl/cogl.h b/cogl/cogl.h
index ecca354..e78719d 100644
--- a/cogl/cogl.h
+++ b/cogl/cogl.h
@@ -93,6 +93,7 @@ typedef struct _CoglFramebuffer CoglFramebuffer;
 #include <cogl/cogl-pipeline-state.h>
 #include <cogl/cogl-pipeline-layer-state.h>
 #include <cogl/cogl-framebuffer.h>
+#include <cogl/cogl-onscreen.h>
 #ifdef COGL_HAS_XLIB
 #include <cogl/cogl-xlib.h>
 #include <cogl/cogl-xlib-renderer.h>
diff --git a/cogl/winsys/cogl-winsys-egl.c b/cogl/winsys/cogl-winsys-egl.c
index 5bdbc01..bdaa418 100644
--- a/cogl/winsys/cogl-winsys-egl.c
+++ b/cogl/winsys/cogl-winsys-egl.c
@@ -35,6 +35,7 @@
 #include "cogl-feature-private.h"
 #include "cogl-context-private.h"
 #include "cogl-framebuffer.h"
+#include "cogl-onscreen-private.h"
 #include "cogl-swap-chain-private.h"
 #include "cogl-renderer-private.h"
 #include "cogl-onscreen-template-private.h"
diff --git a/cogl/winsys/cogl-winsys-glx.c b/cogl/winsys/cogl-winsys-glx.c
index 104120f..a38117b 100644
--- a/cogl/winsys/cogl-winsys-glx.c
+++ b/cogl/winsys/cogl-winsys-glx.c
@@ -45,6 +45,7 @@
 #include "cogl-texture-rectangle-private.h"
 #include "cogl-pipeline-opengl-private.h"
 #include "cogl-framebuffer-private.h"
+#include "cogl-onscreen-private.h"
 #include "cogl-swap-chain-private.h"
 
 #include <stdlib.h>
diff --git a/cogl/winsys/cogl-winsys-private.h b/cogl/winsys/cogl-winsys-private.h
index dbc4097..16317b7 100644
--- a/cogl/winsys/cogl-winsys-private.h
+++ b/cogl/winsys/cogl-winsys-private.h
@@ -25,8 +25,8 @@
 #define __COGL_WINSYS_PRIVATE_H
 
 #include "cogl-renderer.h"
+#include "cogl-onscreen.h"
 
-#include "cogl-framebuffer-private.h"
 #ifdef COGL_HAS_XLIB_SUPPORT
 #include "cogl-texture-pixmap-x11-private.h"
 #endif
diff --git a/doc/reference/cogl-2.0-experimental/Makefile.am b/doc/reference/cogl-2.0-experimental/Makefile.am
index e34e89b..417deb3 100644
--- a/doc/reference/cogl-2.0-experimental/Makefile.am
+++ b/doc/reference/cogl-2.0-experimental/Makefile.am
@@ -59,6 +59,7 @@ IGNORE_HFILES=\
 	cogl-color-private.h			\
 	cogl-feature-private.h			\
 	cogl-framebuffer-private.h		\
+	cogl-onscreen-private.h			\
 	cogl-gtype-private.h			\
 	cogl-index-array-private.h		\
 	cogl-indices-private.h			\
diff --git a/doc/reference/cogl/Makefile.am b/doc/reference/cogl/Makefile.am
index fb5dd3f..8c5d710 100644
--- a/doc/reference/cogl/Makefile.am
+++ b/doc/reference/cogl/Makefile.am
@@ -59,6 +59,7 @@ IGNORE_HFILES=\
 	cogl-color-private.h			\
 	cogl-feature-private.h			\
 	cogl-framebuffer-private.h		\
+	cogl-onscreen-private.h			\
 	cogl-gtype-private.h			\
 	cogl-index-buffer-private.h		\
 	cogl-indices-private.h			\



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