From 1932892b9819686f5b61540025e3a60786549d64 Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Thu, 2 Jan 2014 03:33:03 +0000 Subject: [PATCH] framebuffer: move fb stack under cogl/deprecated/ This moves the framebuffer stack apis out of cogl-framebuffer.c into cogl/deprecated/cogl-framebuffer-deprecated.c so cogl-framebuffer.c is more in-line with the master branch to ease cherry picking patches. Reviewed-by: Neil Roberts --- cogl/cogl-context.c | 2 + cogl/cogl-framebuffer.c | 252 ----------------- cogl/cogl1-context.h | 198 -------------- cogl/deprecated/cogl-framebuffer-deprecated.c | 255 +++++++++++++++++- cogl/deprecated/cogl-framebuffer-deprecated.h | 199 ++++++++++++++ 5 files changed, 455 insertions(+), 451 deletions(-) diff --git a/cogl/cogl-context.c b/cogl/cogl-context.c index 026df1ced..75cfdb308 100644 --- a/cogl/cogl-context.c +++ b/cogl/cogl-context.c @@ -50,6 +50,8 @@ #include "cogl-config-private.h" #include "cogl-error-private.h" +#include "cogl/deprecated/cogl-framebuffer-deprecated.h" + #include #include diff --git a/cogl/cogl-framebuffer.c b/cogl/cogl-framebuffer.c index ef80edf96..cb55dbe3a 100644 --- a/cogl/cogl-framebuffer.c +++ b/cogl/cogl-framebuffer.c @@ -50,12 +50,6 @@ #include "cogl-error-private.h" #include "cogl-texture-gl-private.h" -typedef struct _CoglFramebufferStackEntry -{ - CoglFramebuffer *draw_buffer; - CoglFramebuffer *read_buffer; -} CoglFramebufferStackEntry; - extern CoglObjectClass _cogl_onscreen_class; #ifdef COGL_ENABLE_DEBUG @@ -801,252 +795,6 @@ cogl_framebuffer_allocate (CoglFramebuffer *framebuffer, return TRUE; } -static CoglFramebufferStackEntry * -create_stack_entry (CoglFramebuffer *draw_buffer, - CoglFramebuffer *read_buffer) -{ - CoglFramebufferStackEntry *entry = g_slice_new (CoglFramebufferStackEntry); - - entry->draw_buffer = draw_buffer; - entry->read_buffer = read_buffer; - - return entry; -} - -GSList * -_cogl_create_framebuffer_stack (void) -{ - CoglFramebufferStackEntry *entry; - GSList *stack = NULL; - - entry = create_stack_entry (NULL, NULL); - - return g_slist_prepend (stack, entry); -} - -void -_cogl_free_framebuffer_stack (GSList *stack) -{ - GSList *l; - - for (l = stack; l != NULL; l = l->next) - { - CoglFramebufferStackEntry *entry = l->data; - - if (entry->draw_buffer) - cogl_object_unref (entry->draw_buffer); - - if (entry->read_buffer) - cogl_object_unref (entry->draw_buffer); - - g_slice_free (CoglFramebufferStackEntry, entry); - } - g_slist_free (stack); -} - -static void -notify_buffers_changed (CoglFramebuffer *old_draw_buffer, - CoglFramebuffer *new_draw_buffer, - CoglFramebuffer *old_read_buffer, - CoglFramebuffer *new_read_buffer) -{ - /* XXX: To support the deprecated cogl_set_draw_buffer API we keep - * track of the last onscreen framebuffer that was set so that it - * can be restored if the COGL_WINDOW_BUFFER enum is used. A - * reference isn't taken to the framebuffer because otherwise we - * would have a circular reference between the context and the - * framebuffer. Instead the pointer is set to NULL in - * _cogl_onscreen_free as a kind of a cheap weak reference */ - if (new_draw_buffer && - new_draw_buffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN) - new_draw_buffer->context->window_buffer = new_draw_buffer; -} - -/* Set the current framebuffer without checking if it's already the - * current framebuffer. This is used by cogl_pop_framebuffer while - * the top of the stack is currently not up to date. */ -static void -_cogl_set_framebuffers_real (CoglFramebuffer *draw_buffer, - CoglFramebuffer *read_buffer) -{ - CoglFramebufferStackEntry *entry; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - _COGL_RETURN_IF_FAIL (ctx != NULL); - _COGL_RETURN_IF_FAIL (draw_buffer && read_buffer ? - draw_buffer->context == read_buffer->context : TRUE); - - entry = ctx->framebuffer_stack->data; - - notify_buffers_changed (entry->draw_buffer, - draw_buffer, - entry->read_buffer, - read_buffer); - - if (draw_buffer) - cogl_object_ref (draw_buffer); - if (entry->draw_buffer) - cogl_object_unref (entry->draw_buffer); - - if (read_buffer) - cogl_object_ref (read_buffer); - if (entry->read_buffer) - cogl_object_unref (entry->read_buffer); - - entry->draw_buffer = draw_buffer; - entry->read_buffer = read_buffer; -} - -static void -_cogl_set_framebuffers (CoglFramebuffer *draw_buffer, - CoglFramebuffer *read_buffer) -{ - CoglFramebuffer *current_draw_buffer; - CoglFramebuffer *current_read_buffer; - - _COGL_RETURN_IF_FAIL (cogl_is_framebuffer (draw_buffer)); - _COGL_RETURN_IF_FAIL (cogl_is_framebuffer (read_buffer)); - - current_draw_buffer = cogl_get_draw_framebuffer (); - current_read_buffer = _cogl_get_read_framebuffer (); - - if (current_draw_buffer != draw_buffer || - current_read_buffer != read_buffer) - _cogl_set_framebuffers_real (draw_buffer, read_buffer); -} - -void -cogl_set_framebuffer (CoglFramebuffer *framebuffer) -{ - _cogl_set_framebuffers (framebuffer, framebuffer); -} - -/* XXX: deprecated API */ -void -cogl_set_draw_buffer (CoglBufferTarget target, CoglHandle handle) -{ - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - if (target == COGL_WINDOW_BUFFER) - handle = ctx->window_buffer; - - /* This is deprecated public API. The public API doesn't currently - really expose the concept of separate draw and read buffers so - for the time being this actually just sets both buffers */ - cogl_set_framebuffer (handle); -} - -CoglFramebuffer * -cogl_get_draw_framebuffer (void) -{ - CoglFramebufferStackEntry *entry; - - _COGL_GET_CONTEXT (ctx, NULL); - - g_assert (ctx->framebuffer_stack); - - entry = ctx->framebuffer_stack->data; - - return entry->draw_buffer; -} - -CoglFramebuffer * -_cogl_get_read_framebuffer (void) -{ - CoglFramebufferStackEntry *entry; - - _COGL_GET_CONTEXT (ctx, NULL); - - g_assert (ctx->framebuffer_stack); - - entry = ctx->framebuffer_stack->data; - - return entry->read_buffer; -} - -void -_cogl_push_framebuffers (CoglFramebuffer *draw_buffer, - CoglFramebuffer *read_buffer) -{ - CoglContext *ctx; - CoglFramebuffer *old_draw_buffer, *old_read_buffer; - - _COGL_RETURN_IF_FAIL (cogl_is_framebuffer (draw_buffer)); - _COGL_RETURN_IF_FAIL (cogl_is_framebuffer (read_buffer)); - - ctx = draw_buffer->context; - _COGL_RETURN_IF_FAIL (ctx != NULL); - _COGL_RETURN_IF_FAIL (draw_buffer->context == read_buffer->context); - - _COGL_RETURN_IF_FAIL (ctx->framebuffer_stack != NULL); - - /* Copy the top of the stack so that when we call cogl_set_framebuffer - it will still know what the old framebuffer was */ - old_draw_buffer = cogl_get_draw_framebuffer (); - if (old_draw_buffer) - cogl_object_ref (old_draw_buffer); - old_read_buffer = _cogl_get_read_framebuffer (); - if (old_read_buffer) - cogl_object_ref (old_read_buffer); - ctx->framebuffer_stack = - g_slist_prepend (ctx->framebuffer_stack, - create_stack_entry (old_draw_buffer, - old_read_buffer)); - - _cogl_set_framebuffers (draw_buffer, read_buffer); -} - -void -cogl_push_framebuffer (CoglFramebuffer *buffer) -{ - _cogl_push_framebuffers (buffer, buffer); -} - -/* XXX: deprecated API */ -void -cogl_push_draw_buffer (void) -{ - cogl_push_framebuffer (cogl_get_draw_framebuffer ()); -} - -void -cogl_pop_framebuffer (void) -{ - CoglFramebufferStackEntry *to_pop; - CoglFramebufferStackEntry *to_restore; - - _COGL_GET_CONTEXT (ctx, NO_RETVAL); - - g_assert (ctx->framebuffer_stack != NULL); - g_assert (ctx->framebuffer_stack->next != NULL); - - to_pop = ctx->framebuffer_stack->data; - to_restore = ctx->framebuffer_stack->next->data; - - if (to_pop->draw_buffer != to_restore->draw_buffer || - to_pop->read_buffer != to_restore->read_buffer) - notify_buffers_changed (to_pop->draw_buffer, - to_restore->draw_buffer, - to_pop->read_buffer, - to_restore->read_buffer); - - cogl_object_unref (to_pop->draw_buffer); - cogl_object_unref (to_pop->read_buffer); - g_slice_free (CoglFramebufferStackEntry, to_pop); - - ctx->framebuffer_stack = - g_slist_delete_link (ctx->framebuffer_stack, - ctx->framebuffer_stack); -} - -/* XXX: deprecated API */ -void -cogl_pop_draw_buffer (void) -{ - cogl_pop_framebuffer (); -} - static unsigned long _cogl_framebuffer_compare_viewport_state (CoglFramebuffer *a, CoglFramebuffer *b) diff --git a/cogl/cogl1-context.h b/cogl/cogl1-context.h index 53c9783ae..754dfb948 100644 --- a/cogl/cogl1-context.h +++ b/cogl/cogl1-context.h @@ -731,204 +731,6 @@ COGL_DEPRECATED_IN_1_16 void cogl_set_source_texture (CoglTexture *texture); -/** - * cogl_set_framebuffer: - * @buffer: A #CoglFramebuffer object, either onscreen or offscreen. - * - * This redirects all subsequent drawing to the specified framebuffer. This can - * either be an offscreen buffer created with cogl_offscreen_new_to_texture () - * or in the future it may be an onscreen framebuffers too. - * - * Since: 1.2 - * Deprecated: 1.16: The latest drawing apis take explicit - * #CoglFramebuffer arguments so this stack of - * framebuffers shouldn't be used anymore. - */ -COGL_DEPRECATED_IN_1_16 -void -cogl_set_framebuffer (CoglFramebuffer *buffer); - -/** - * cogl_push_framebuffer: - * @buffer: A #CoglFramebuffer object, either onscreen or offscreen. - * - * Redirects all subsequent drawing to the specified framebuffer. This can - * either be an offscreen buffer created with cogl_offscreen_new_to_texture () - * or in the future it may be an onscreen framebuffer too. - * - * You should understand that a framebuffer owns the following state: - * - * The projection matrix - * The modelview matrix stack - * The viewport - * The clip stack - * - * So these items will automatically be saved and restored when you - * push and pop between different framebuffers. - * - * Also remember a newly allocated framebuffer will have an identity matrix for - * the projection and modelview matrices which gives you a coordinate space - * like OpenGL with (-1, -1) corresponding to the top left of the viewport, - * (1, 1) corresponding to the bottom right and +z coming out towards the - * viewer. - * - * If you want to set up a coordinate space like Clutter does with (0, 0) - * corresponding to the top left and (framebuffer_width, framebuffer_height) - * corresponding to the bottom right you can do so like this: - * - * |[ - * static void - * setup_viewport (unsigned int width, - * unsigned int height, - * float fovy, - * float aspect, - * float z_near, - * float z_far) - * { - * float z_camera; - * CoglMatrix projection_matrix; - * CoglMatrix mv_matrix; - * - * cogl_set_viewport (0, 0, width, height); - * cogl_perspective (fovy, aspect, z_near, z_far); - * - * cogl_get_projection_matrix (&projection_matrix); - * z_camera = 0.5 * projection_matrix.xx; - * - * cogl_matrix_init_identity (&mv_matrix); - * cogl_matrix_translate (&mv_matrix, -0.5f, -0.5f, -z_camera); - * cogl_matrix_scale (&mv_matrix, 1.0f / width, -1.0f / height, 1.0f / width); - * cogl_matrix_translate (&mv_matrix, 0.0f, -1.0 * height, 0.0f); - * cogl_set_modelview_matrix (&mv_matrix); - * } - * - * static void - * my_init_framebuffer (ClutterStage *stage, - * CoglFramebuffer *framebuffer, - * unsigned int framebuffer_width, - * unsigned int framebuffer_height) - * { - * ClutterPerspective perspective; - * - * clutter_stage_get_perspective (stage, &perspective); - * - * cogl_push_framebuffer (framebuffer); - * setup_viewport (framebuffer_width, - * framebuffer_height, - * perspective.fovy, - * perspective.aspect, - * perspective.z_near, - * perspective.z_far); - * } - * ]| - * - * The previous framebuffer can be restored by calling cogl_pop_framebuffer() - * - * Since: 1.2 - * Deprecated: 1.16: The latest drawing apis take explicit - * #CoglFramebuffer arguments so this stack of - * framebuffers shouldn't be used anymore. - */ -COGL_DEPRECATED_IN_1_16 -void -cogl_push_framebuffer (CoglFramebuffer *buffer); - -/** - * cogl_pop_framebuffer: - * - * Restores the framebuffer that was previously at the top of the stack. - * All subsequent drawing will be redirected to this framebuffer. - * - * Since: 1.2 - * Deprecated: 1.16: The latest drawing apis take explicit - * #CoglFramebuffer arguments so this stack of - * framebuffers shouldn't be used anymore. - */ -COGL_DEPRECATED_IN_1_16 -void -cogl_pop_framebuffer (void); - -/** - * cogl_set_draw_buffer: - * @target: A #CoglBufferTarget that specifies what kind of framebuffer you - * are setting as the render target. - * @offscreen: If you are setting a framebuffer of type COGL_OFFSCREEN_BUFFER - * then this is a CoglHandle for the offscreen buffer. - * - * Redirects all subsequent drawing to the specified framebuffer. This - * can either be an offscreen buffer created with - * cogl_offscreen_new_to_texture () or you can revert to your original - * on screen window buffer. - * - * Deprecated: 1.16: The latest drawing apis take explicit - * #CoglFramebuffer arguments so this stack of - * framebuffers shouldn't be used anymore. - */ -COGL_DEPRECATED_IN_1_16 -void -cogl_set_draw_buffer (CoglBufferTarget target, - CoglHandle offscreen); - -/** - * cogl_push_draw_buffer: - * - * Save cogl_set_draw_buffer() state. - * - * Deprecated: 1.16: The latest drawing apis take explicit - * #CoglFramebuffer arguments so this stack of - * framebuffers shouldn't be used anymore. - */ -COGL_DEPRECATED_IN_1_16 -void -cogl_push_draw_buffer (void); - -/** - * cogl_pop_draw_buffer: - * - * Restore cogl_set_draw_buffer() state. - * - * Deprecated: 1.16: The latest drawing apis take explicit - * #CoglFramebuffer arguments so this stack of - * framebuffers shouldn't be used anymore. - */ -COGL_DEPRECATED_IN_1_16 -void -cogl_pop_draw_buffer (void); - -/** - * cogl_read_pixels: - * @x: The window x position to start reading from - * @y: The window y position to start reading from - * @width: The width of the rectangle you want to read - * @height: The height of the rectangle you want to read - * @source: Identifies which auxillary buffer you want to read - * (only COGL_READ_PIXELS_COLOR_BUFFER supported currently) - * @format: The pixel format you want the result in - * (only COGL_PIXEL_FORMAT_RGBA_8888 supported currently) - * @pixels: The location to write the pixel data. - * - * This reads a rectangle of pixels from the current framebuffer where - * position (0, 0) is the top left. The pixel at (x, y) is the first - * read, and the data is returned with a rowstride of (width * 4). - * - * Currently Cogl assumes that the framebuffer is in a premultiplied - * format so if @format is non-premultiplied it will convert it. To - * read the pixel values without any conversion you should either - * specify a format that doesn't use an alpha channel or use one of - * the formats ending in PRE. - * - * Deprecated: 1.16: Use cogl_framebuffer_read_pixels() instead - */ -COGL_DEPRECATED_IN_1_16_FOR (cogl_framebuffer_read_pixels) -void -cogl_read_pixels (int x, - int y, - int width, - int height, - CoglReadPixelsFlags source, - CoglPixelFormat format, - uint8_t *pixels); - /** * cogl_flush: * diff --git a/cogl/deprecated/cogl-framebuffer-deprecated.c b/cogl/deprecated/cogl-framebuffer-deprecated.c index dc099d97d..fe314eee9 100644 --- a/cogl/deprecated/cogl-framebuffer-deprecated.c +++ b/cogl/deprecated/cogl-framebuffer-deprecated.c @@ -25,12 +25,265 @@ #include #include "cogl-types.h" +#include "cogl-context-private.h" #include "cogl-framebuffer-private.h" #include "cogl-framebuffer-deprecated.h" +typedef struct _CoglFramebufferStackEntry +{ + CoglFramebuffer *draw_buffer; + CoglFramebuffer *read_buffer; +} CoglFramebufferStackEntry; + + +static CoglFramebufferStackEntry * +create_stack_entry (CoglFramebuffer *draw_buffer, + CoglFramebuffer *read_buffer) +{ + CoglFramebufferStackEntry *entry = g_slice_new (CoglFramebufferStackEntry); + + entry->draw_buffer = draw_buffer; + entry->read_buffer = read_buffer; + + return entry; +} + +GSList * +_cogl_create_framebuffer_stack (void) +{ + CoglFramebufferStackEntry *entry; + GSList *stack = NULL; + + entry = create_stack_entry (NULL, NULL); + + return g_slist_prepend (stack, entry); +} + +void +_cogl_free_framebuffer_stack (GSList *stack) +{ + GSList *l; + + for (l = stack; l != NULL; l = l->next) + { + CoglFramebufferStackEntry *entry = l->data; + + if (entry->draw_buffer) + cogl_object_unref (entry->draw_buffer); + + if (entry->read_buffer) + cogl_object_unref (entry->draw_buffer); + + g_slice_free (CoglFramebufferStackEntry, entry); + } + g_slist_free (stack); +} + +static void +notify_buffers_changed (CoglFramebuffer *old_draw_buffer, + CoglFramebuffer *new_draw_buffer, + CoglFramebuffer *old_read_buffer, + CoglFramebuffer *new_read_buffer) +{ + /* XXX: To support the deprecated cogl_set_draw_buffer API we keep + * track of the last onscreen framebuffer that was set so that it + * can be restored if the COGL_WINDOW_BUFFER enum is used. A + * reference isn't taken to the framebuffer because otherwise we + * would have a circular reference between the context and the + * framebuffer. Instead the pointer is set to NULL in + * _cogl_onscreen_free as a kind of a cheap weak reference */ + if (new_draw_buffer && + new_draw_buffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN) + new_draw_buffer->context->window_buffer = new_draw_buffer; +} + +/* Set the current framebuffer without checking if it's already the + * current framebuffer. This is used by cogl_pop_framebuffer while + * the top of the stack is currently not up to date. */ +static void +_cogl_set_framebuffers_real (CoglFramebuffer *draw_buffer, + CoglFramebuffer *read_buffer) +{ + CoglFramebufferStackEntry *entry; + + _COGL_GET_CONTEXT (ctx, NO_RETVAL); + + _COGL_RETURN_IF_FAIL (ctx != NULL); + _COGL_RETURN_IF_FAIL (draw_buffer && read_buffer ? + draw_buffer->context == read_buffer->context : TRUE); + + entry = ctx->framebuffer_stack->data; + + notify_buffers_changed (entry->draw_buffer, + draw_buffer, + entry->read_buffer, + read_buffer); + + if (draw_buffer) + cogl_object_ref (draw_buffer); + if (entry->draw_buffer) + cogl_object_unref (entry->draw_buffer); + + if (read_buffer) + cogl_object_ref (read_buffer); + if (entry->read_buffer) + cogl_object_unref (entry->read_buffer); + + entry->draw_buffer = draw_buffer; + entry->read_buffer = read_buffer; +} + +static void +_cogl_set_framebuffers (CoglFramebuffer *draw_buffer, + CoglFramebuffer *read_buffer) +{ + CoglFramebuffer *current_draw_buffer; + CoglFramebuffer *current_read_buffer; + + _COGL_RETURN_IF_FAIL (cogl_is_framebuffer (draw_buffer)); + _COGL_RETURN_IF_FAIL (cogl_is_framebuffer (read_buffer)); + + current_draw_buffer = cogl_get_draw_framebuffer (); + current_read_buffer = _cogl_get_read_framebuffer (); + + if (current_draw_buffer != draw_buffer || + current_read_buffer != read_buffer) + _cogl_set_framebuffers_real (draw_buffer, read_buffer); +} + +void +cogl_set_framebuffer (CoglFramebuffer *framebuffer) +{ + _cogl_set_framebuffers (framebuffer, framebuffer); +} + +/* XXX: deprecated API */ +void +cogl_set_draw_buffer (CoglBufferTarget target, CoglHandle handle) +{ + _COGL_GET_CONTEXT (ctx, NO_RETVAL); + + if (target == COGL_WINDOW_BUFFER) + handle = ctx->window_buffer; + + /* This is deprecated public API. The public API doesn't currently + really expose the concept of separate draw and read buffers so + for the time being this actually just sets both buffers */ + cogl_set_framebuffer (handle); +} + +CoglFramebuffer * +cogl_get_draw_framebuffer (void) +{ + CoglFramebufferStackEntry *entry; + + _COGL_GET_CONTEXT (ctx, NULL); + + g_assert (ctx->framebuffer_stack); + + entry = ctx->framebuffer_stack->data; + + return entry->draw_buffer; +} + +CoglFramebuffer * +_cogl_get_read_framebuffer (void) +{ + CoglFramebufferStackEntry *entry; + + _COGL_GET_CONTEXT (ctx, NULL); + + g_assert (ctx->framebuffer_stack); + + entry = ctx->framebuffer_stack->data; + + return entry->read_buffer; +} + +void +_cogl_push_framebuffers (CoglFramebuffer *draw_buffer, + CoglFramebuffer *read_buffer) +{ + CoglContext *ctx; + CoglFramebuffer *old_draw_buffer, *old_read_buffer; + + _COGL_RETURN_IF_FAIL (cogl_is_framebuffer (draw_buffer)); + _COGL_RETURN_IF_FAIL (cogl_is_framebuffer (read_buffer)); + + ctx = draw_buffer->context; + _COGL_RETURN_IF_FAIL (ctx != NULL); + _COGL_RETURN_IF_FAIL (draw_buffer->context == read_buffer->context); + + _COGL_RETURN_IF_FAIL (ctx->framebuffer_stack != NULL); + + /* Copy the top of the stack so that when we call cogl_set_framebuffer + it will still know what the old framebuffer was */ + old_draw_buffer = cogl_get_draw_framebuffer (); + if (old_draw_buffer) + cogl_object_ref (old_draw_buffer); + old_read_buffer = _cogl_get_read_framebuffer (); + if (old_read_buffer) + cogl_object_ref (old_read_buffer); + ctx->framebuffer_stack = + g_slist_prepend (ctx->framebuffer_stack, + create_stack_entry (old_draw_buffer, + old_read_buffer)); + + _cogl_set_framebuffers (draw_buffer, read_buffer); +} + +void +cogl_push_framebuffer (CoglFramebuffer *buffer) +{ + _cogl_push_framebuffers (buffer, buffer); +} + +/* XXX: deprecated API */ +void +cogl_push_draw_buffer (void) +{ + cogl_push_framebuffer (cogl_get_draw_framebuffer ()); +} + +void +cogl_pop_framebuffer (void) +{ + CoglFramebufferStackEntry *to_pop; + CoglFramebufferStackEntry *to_restore; + + _COGL_GET_CONTEXT (ctx, NO_RETVAL); + + g_assert (ctx->framebuffer_stack != NULL); + g_assert (ctx->framebuffer_stack->next != NULL); + + to_pop = ctx->framebuffer_stack->data; + to_restore = ctx->framebuffer_stack->next->data; + + if (to_pop->draw_buffer != to_restore->draw_buffer || + to_pop->read_buffer != to_restore->read_buffer) + notify_buffers_changed (to_pop->draw_buffer, + to_restore->draw_buffer, + to_pop->read_buffer, + to_restore->read_buffer); + + cogl_object_unref (to_pop->draw_buffer); + cogl_object_unref (to_pop->read_buffer); + g_slice_free (CoglFramebufferStackEntry, to_pop); + + ctx->framebuffer_stack = + g_slist_delete_link (ctx->framebuffer_stack, + ctx->framebuffer_stack); +} + +/* XXX: deprecated API */ +void +cogl_pop_draw_buffer (void) +{ + cogl_pop_framebuffer (); +} + CoglPixelFormat cogl_framebuffer_get_color_format (CoglFramebuffer *framebuffer) { return framebuffer->internal_format; } - diff --git a/cogl/deprecated/cogl-framebuffer-deprecated.h b/cogl/deprecated/cogl-framebuffer-deprecated.h index 92962bd33..eccfecbb2 100644 --- a/cogl/deprecated/cogl-framebuffer-deprecated.h +++ b/cogl/deprecated/cogl-framebuffer-deprecated.h @@ -27,6 +27,205 @@ #include +/** + * cogl_set_framebuffer: + * @buffer: A #CoglFramebuffer object, either onscreen or offscreen. + * + * This redirects all subsequent drawing to the specified framebuffer. This can + * either be an offscreen buffer created with cogl_offscreen_new_to_texture () + * or in the future it may be an onscreen framebuffers too. + * + * Since: 1.2 + * Deprecated: 1.16: The latest drawing apis take explicit + * #CoglFramebuffer arguments so this stack of + * framebuffers shouldn't be used anymore. + */ +COGL_DEPRECATED_IN_1_16 +void +cogl_set_framebuffer (CoglFramebuffer *buffer); + +/** + * cogl_push_framebuffer: + * @buffer: A #CoglFramebuffer object, either onscreen or offscreen. + * + * Redirects all subsequent drawing to the specified framebuffer. This can + * either be an offscreen buffer created with cogl_offscreen_new_to_texture () + * or in the future it may be an onscreen framebuffer too. + * + * You should understand that a framebuffer owns the following state: + * + * The projection matrix + * The modelview matrix stack + * The viewport + * The clip stack + * + * So these items will automatically be saved and restored when you + * push and pop between different framebuffers. + * + * Also remember a newly allocated framebuffer will have an identity matrix for + * the projection and modelview matrices which gives you a coordinate space + * like OpenGL with (-1, -1) corresponding to the top left of the viewport, + * (1, 1) corresponding to the bottom right and +z coming out towards the + * viewer. + * + * If you want to set up a coordinate space like Clutter does with (0, 0) + * corresponding to the top left and (framebuffer_width, framebuffer_height) + * corresponding to the bottom right you can do so like this: + * + * |[ + * static void + * setup_viewport (unsigned int width, + * unsigned int height, + * float fovy, + * float aspect, + * float z_near, + * float z_far) + * { + * float z_camera; + * CoglMatrix projection_matrix; + * CoglMatrix mv_matrix; + * + * cogl_set_viewport (0, 0, width, height); + * cogl_perspective (fovy, aspect, z_near, z_far); + * + * cogl_get_projection_matrix (&projection_matrix); + * z_camera = 0.5 * projection_matrix.xx; + * + * cogl_matrix_init_identity (&mv_matrix); + * cogl_matrix_translate (&mv_matrix, -0.5f, -0.5f, -z_camera); + * cogl_matrix_scale (&mv_matrix, 1.0f / width, -1.0f / height, 1.0f / width); + * cogl_matrix_translate (&mv_matrix, 0.0f, -1.0 * height, 0.0f); + * cogl_set_modelview_matrix (&mv_matrix); + * } + * + * static void + * my_init_framebuffer (ClutterStage *stage, + * CoglFramebuffer *framebuffer, + * unsigned int framebuffer_width, + * unsigned int framebuffer_height) + * { + * ClutterPerspective perspective; + * + * clutter_stage_get_perspective (stage, &perspective); + * + * cogl_push_framebuffer (framebuffer); + * setup_viewport (framebuffer_width, + * framebuffer_height, + * perspective.fovy, + * perspective.aspect, + * perspective.z_near, + * perspective.z_far); + * } + * ]| + * + * The previous framebuffer can be restored by calling cogl_pop_framebuffer() + * + * Since: 1.2 + * Deprecated: 1.16: The latest drawing apis take explicit + * #CoglFramebuffer arguments so this stack of + * framebuffers shouldn't be used anymore. + */ +COGL_DEPRECATED_IN_1_16 +void +cogl_push_framebuffer (CoglFramebuffer *buffer); + +/** + * cogl_pop_framebuffer: + * + * Restores the framebuffer that was previously at the top of the stack. + * All subsequent drawing will be redirected to this framebuffer. + * + * Since: 1.2 + * Deprecated: 1.16: The latest drawing apis take explicit + * #CoglFramebuffer arguments so this stack of + * framebuffers shouldn't be used anymore. + */ +COGL_DEPRECATED_IN_1_16 +void +cogl_pop_framebuffer (void); + +/** + * cogl_set_draw_buffer: + * @target: A #CoglBufferTarget that specifies what kind of framebuffer you + * are setting as the render target. + * @offscreen: If you are setting a framebuffer of type COGL_OFFSCREEN_BUFFER + * then this is a CoglHandle for the offscreen buffer. + * + * Redirects all subsequent drawing to the specified framebuffer. This + * can either be an offscreen buffer created with + * cogl_offscreen_new_to_texture () or you can revert to your original + * on screen window buffer. + * + * Deprecated: 1.16: The latest drawing apis take explicit + * #CoglFramebuffer arguments so this stack of + * framebuffers shouldn't be used anymore. + */ +COGL_DEPRECATED_IN_1_16 +void +cogl_set_draw_buffer (CoglBufferTarget target, + CoglHandle offscreen); + +/** + * cogl_push_draw_buffer: + * + * Save cogl_set_draw_buffer() state. + * + * Deprecated: 1.16: The latest drawing apis take explicit + * #CoglFramebuffer arguments so this stack of + * framebuffers shouldn't be used anymore. + */ +COGL_DEPRECATED_IN_1_16 +void +cogl_push_draw_buffer (void); + +/** + * cogl_pop_draw_buffer: + * + * Restore cogl_set_draw_buffer() state. + * + * Deprecated: 1.16: The latest drawing apis take explicit + * #CoglFramebuffer arguments so this stack of + * framebuffers shouldn't be used anymore. + */ +COGL_DEPRECATED_IN_1_16 +void +cogl_pop_draw_buffer (void); + +/** + * cogl_read_pixels: + * @x: The window x position to start reading from + * @y: The window y position to start reading from + * @width: The width of the rectangle you want to read + * @height: The height of the rectangle you want to read + * @source: Identifies which auxillary buffer you want to read + * (only COGL_READ_PIXELS_COLOR_BUFFER supported currently) + * @format: The pixel format you want the result in + * (only COGL_PIXEL_FORMAT_RGBA_8888 supported currently) + * @pixels: The location to write the pixel data. + * + * This reads a rectangle of pixels from the current framebuffer where + * position (0, 0) is the top left. The pixel at (x, y) is the first + * read, and the data is returned with a rowstride of (width * 4). + * + * Currently Cogl assumes that the framebuffer is in a premultiplied + * format so if @format is non-premultiplied it will convert it. To + * read the pixel values without any conversion you should either + * specify a format that doesn't use an alpha channel or use one of + * the formats ending in PRE. + * + * Deprecated: 1.16: Use cogl_framebuffer_read_pixels() instead + */ +COGL_DEPRECATED_IN_1_16_FOR (cogl_framebuffer_read_pixels) +void +cogl_read_pixels (int x, + int y, + int width, + int height, + CoglReadPixelsFlags source, + CoglPixelFormat format, + uint8_t *pixels); + + /* XXX: Since this api was marked unstable, maybe we can just * remove this api if we can't find anyone is using it. */ /**