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 <neil@linux.intel.com>
This commit is contained in:
@ -25,12 +25,265 @@
|
||||
#include <config.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user