From 79719347c879f675de92f1fe097de1c4b5f71116 Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Thu, 13 Oct 2011 21:31:04 +0100 Subject: [PATCH] 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(). Reviewed-by: Neil Roberts --- 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 +- cogl/winsys/cogl-winsys-wgl.c | 1 + .../cogl-2.0-experimental/Makefile.am | 1 + doc/reference/cogl/Makefile.am | 1 + 18 files changed, 700 insertions(+), 576 deletions(-) create mode 100644 cogl/cogl-onscreen-private.h create mode 100644 cogl/cogl-onscreen.c create mode 100644 cogl/cogl-onscreen.h diff --git a/cogl/Makefile.am b/cogl/Makefile.am index 7e3e943f7..2d844cf0f 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 aaf02817a..fca6e82fd 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 ebedd4431..953e4b97f 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 diff --git a/cogl/cogl-framebuffer-private.h b/cogl/cogl-framebuffer-private.h index 9d8bdb1f1..a6f8e1643 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 @@ -38,10 +39,6 @@ #include #endif -#ifdef COGL_HAS_WIN32_SUPPORT -#include -#endif - typedef enum _CoglFramebufferType { COGL_FRAMEBUFFER_TYPE_ONSCREEN, COGL_FRAMEBUFFER_TYPE_OFFSCREEN @@ -139,31 +136,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, @@ -348,8 +332,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 8c47b593e..968c3f8f5 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); } @@ -1860,215 +1746,9 @@ cogl_framebuffer_discard_buffers (CoglFramebuffer *framebuffer, _cogl_framebuffer_discard_buffers_real (framebuffer, buffers); } -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 e168e6d04..48f888e4b 100644 --- a/cogl/cogl-framebuffer.h +++ b/cogl/cogl-framebuffer.h @@ -28,6 +28,8 @@ #ifndef __COGL_FRAMEBUFFER_H #define __COGL_FRAMEBUFFER_H +#include + #include #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. - * - * 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. - * - * 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. - * - * 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. - * - * 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 000000000..be789a53d --- /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 . + * + * + */ + +#ifndef __COGL_ONSCREEN_PRIVATE_H +#define __COGL_ONSCREEN_PRIVATE_H + +#include "cogl-framebuffer-private.h" + +#include + +#ifdef COGL_HAS_WIN32_SUPPORT +#include +#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 212787978..b080b57d2 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 000000000..52ee784ab --- /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 . + * + * + */ + +#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 000000000..8a9d64aed --- /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 + * . + * + * + * + * Authors: + * Robert Bragg + */ + +#if !defined(__COGL_H_INSIDE__) && !defined(CLUTTER_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __COGL_ONSCREEN_H +#define __COGL_ONSCREEN_H + +#include +#include +#include + +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. + * + * 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. + * + * 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. + * + * 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. + * + * 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 361364e9b..cc9ca1b6e 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 892103933..336736065 100644 --- a/cogl/cogl.h +++ b/cogl/cogl.h @@ -93,6 +93,7 @@ typedef struct _CoglFramebuffer CoglFramebuffer; #include #include #include +#include #ifdef COGL_HAS_XLIB #include #include diff --git a/cogl/winsys/cogl-winsys-egl.c b/cogl/winsys/cogl-winsys-egl.c index dfefbcd44..e2e74bde3 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 86be11dda..10422e791 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 diff --git a/cogl/winsys/cogl-winsys-private.h b/cogl/winsys/cogl-winsys-private.h index dbc409775..16317b7ba 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/cogl/winsys/cogl-winsys-wgl.c b/cogl/winsys/cogl-winsys-wgl.c index a90ab996d..9e120024e 100644 --- a/cogl/winsys/cogl-winsys-wgl.c +++ b/cogl/winsys/cogl-winsys-wgl.c @@ -35,6 +35,7 @@ #include "cogl-winsys-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-display-private.h" diff --git a/doc/reference/cogl-2.0-experimental/Makefile.am b/doc/reference/cogl-2.0-experimental/Makefile.am index e34e89b97..417deb332 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 fb5dd3f3c..8c5d71034 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 \