cogl-framebuffer: Separate the draw and read buffer

The current framebuffer is now internally separated so that there can
be a different draw and read buffer. This is required to use the
GL_EXT_framebuffer_blit extension. The current draw and read buffers
are stored as a pair in a single stack so that pushing the draw and
read buffer is done simultaneously with the new
_cogl_push_framebuffers internal function. Calling
cogl_pop_framebuffer will restore both the draw and read buffer to the
previous state. The public cogl_push_framebuffer function is layered
on top of the new function so that it just pushes the same buffer for
both drawing and reading.

When flushing the framebuffer state, the cogl_framebuffer_flush_state
function now tackes a pointer to both the draw and the read
buffer. Anywhere that was just flushing the state for the current
framebuffer with _cogl_get_framebuffer now needs to call both
_cogl_get_draw_buffer and _cogl_get_read_buffer.
This commit is contained in:
Neil Roberts 2011-02-02 14:23:53 +00:00
parent 4d6754ed0f
commit a067e7a16b
11 changed files with 264 additions and 121 deletions

View File

@ -480,7 +480,7 @@ enable_gl_state (CoglDrawFlags flags,
CoglAttribute **attributes,
ValidateLayerState *state)
{
CoglFramebuffer *framebuffer = _cogl_get_framebuffer ();
CoglFramebuffer *framebuffer = _cogl_get_draw_buffer ();
int i;
#ifdef MAY_HAVE_PROGRAMABLE_GL
GLuint generic_index = 0;
@ -1060,7 +1060,7 @@ flush_state (CoglDrawFlags flags,
{
if (!(flags & COGL_DRAW_SKIP_JOURNAL_FLUSH))
{
CoglFramebuffer *framebuffer = _cogl_get_framebuffer ();
CoglFramebuffer *framebuffer = _cogl_get_draw_buffer ();
_cogl_journal_flush (framebuffer->journal, framebuffer);
}
@ -1080,7 +1080,9 @@ flush_state (CoglDrawFlags flags,
* stack can cause some drawing which would change the array
* pointers. */
if (!(flags & COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH))
_cogl_framebuffer_flush_state (_cogl_get_framebuffer (), 0);
_cogl_framebuffer_flush_state (_cogl_get_draw_buffer (),
_cogl_get_read_buffer (),
0);
}
/* This can be called directly by the CoglJournal to draw attributes

View File

@ -77,7 +77,7 @@ set_clip_plane (GLint plane_num,
GLdouble plane[4];
#endif
GLfloat angle;
CoglFramebuffer *framebuffer = _cogl_get_framebuffer ();
CoglFramebuffer *framebuffer = _cogl_get_draw_buffer ();
CoglMatrixStack *modelview_stack =
_cogl_framebuffer_get_modelview_stack (framebuffer);
CoglMatrixStack *projection_stack =
@ -131,7 +131,7 @@ set_clip_planes (float x_1,
float x_2,
float y_2)
{
CoglFramebuffer *framebuffer = _cogl_get_framebuffer ();
CoglFramebuffer *framebuffer = _cogl_get_draw_buffer ();
CoglMatrixStack *modelview_stack =
_cogl_framebuffer_get_modelview_stack (framebuffer);
CoglMatrix modelview_matrix;
@ -192,7 +192,7 @@ add_stencil_clip_rectangle (float x_1,
float y_2,
gboolean first)
{
CoglFramebuffer *framebuffer = _cogl_get_framebuffer ();
CoglFramebuffer *framebuffer = _cogl_get_draw_buffer ();
CoglMatrixStack *modelview_stack =
_cogl_framebuffer_get_modelview_stack (framebuffer);
CoglMatrixStack *projection_stack =
@ -586,7 +586,7 @@ _cogl_clip_stack_flush (CoglClipStack *stack)
ctx->current_clip_stack = _cogl_clip_stack_ref (stack);
modelview_stack =
_cogl_framebuffer_get_modelview_stack (_cogl_get_framebuffer ());
_cogl_framebuffer_get_modelview_stack (_cogl_get_draw_buffer ());
has_clip_planes = cogl_features_available (COGL_FEATURE_FOUR_CLIP_PLANES);
@ -617,7 +617,7 @@ _cogl_clip_stack_flush (CoglClipStack *stack)
scissor_x0 = scissor_y0 = scissor_x1 = scissor_y1 = scissor_y_start = 0;
else
{
CoglFramebuffer *framebuffer = _cogl_get_framebuffer ();
CoglFramebuffer *framebuffer = _cogl_get_draw_buffer ();
/* We store the entry coordinates in Cogl coordinate space
* but OpenGL requires the window origin to be the bottom

View File

@ -51,7 +51,7 @@ cogl_clip_push_window_rectangle (int x_offset,
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
framebuffer = _cogl_get_framebuffer ();
framebuffer = _cogl_get_draw_buffer ();
clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
clip_state->stacks->data =
@ -82,7 +82,7 @@ cogl_clip_push_rectangle (float x_1,
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
framebuffer = _cogl_get_framebuffer ();
framebuffer = _cogl_get_draw_buffer ();
clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
cogl_get_modelview_matrix (&modelview_matrix);
@ -115,7 +115,7 @@ cogl_clip_push_from_path_preserve (void)
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
framebuffer = _cogl_get_framebuffer ();
framebuffer = _cogl_get_draw_buffer ();
clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
cogl_get_modelview_matrix (&modelview_matrix);
@ -151,7 +151,7 @@ cogl_clip_pop (void)
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
framebuffer = _cogl_get_framebuffer ();
framebuffer = _cogl_get_draw_buffer ();
clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
_cogl_clip_pop_real (clip_state);
@ -169,7 +169,7 @@ _cogl_clip_state_flush (CoglClipState *clip_state)
void
cogl_clip_ensure (void)
{
CoglFramebuffer *framebuffer = _cogl_get_framebuffer ();
CoglFramebuffer *framebuffer = _cogl_get_draw_buffer ();
CoglClipState *clip_state;
clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
@ -195,7 +195,7 @@ cogl_clip_stack_save (void)
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
framebuffer = _cogl_get_framebuffer ();
framebuffer = _cogl_get_draw_buffer ();
clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
_cogl_clip_stack_save_real (clip_state);
@ -225,7 +225,7 @@ cogl_clip_stack_restore (void)
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
framebuffer = _cogl_get_framebuffer ();
framebuffer = _cogl_get_draw_buffer ();
clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
_cogl_clip_stack_restore_real (clip_state);

View File

@ -236,14 +236,18 @@ typedef enum _CoglFramebufferFlushFlags
} CoglFramebufferFlushFlags;
void
_cogl_framebuffer_flush_state (CoglFramebuffer *framebuffer,
_cogl_framebuffer_flush_state (CoglFramebuffer *draw_buffer,
CoglFramebuffer *read_buffer,
CoglFramebufferFlushFlags flags);
CoglHandle
_cogl_onscreen_new (void);
CoglFramebuffer *
_cogl_get_framebuffer (void);
_cogl_get_draw_buffer (void);
CoglFramebuffer *
_cogl_get_read_buffer (void);
GSList *
_cogl_create_framebuffer_stack (void);
@ -269,5 +273,20 @@ _cogl_offscreen_new_to_texture_full (CoglHandle texhandle,
CoglOffscreenFlags create_flags,
unsigned int level);
/*
* _cogl_push_framebuffers:
* @draw_buffer: A pointer to the buffer used for drawing
* @read_buffer: A pointer to the buffer used for reading back pixels
*
* Redirects drawing and reading to the specified framebuffers as in
* cogl_push_framebuffer() except that it allows the draw and read
* buffer to be different. The buffers are pushed as a pair so that
* they can later both be restored with a single call to
* cogl_pop_framebuffer().
*/
void
_cogl_push_framebuffers (CoglFramebuffer *draw_buffer,
CoglFramebuffer *read_buffer);
#endif /* __COGL_FRAMEBUFFER_PRIVATE_H */

View File

@ -99,6 +99,12 @@
#ifndef GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE
#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217
#endif
#ifndef GL_READ_FRAMEBUFFER
#define GL_READ_FRAMEBUFFER 0x8CA8
#endif
#ifndef GL_DRAW_FRAMEBUFFER
#define GL_DRAW_FRAMEBUFFER 0x8CA9
#endif
typedef enum {
_TRY_DEPTH_STENCIL = 1L<<0,
@ -106,6 +112,12 @@ typedef enum {
_TRY_STENCIL = 1L<<2
} TryFBOFlags;
typedef struct _CoglFramebufferStackEntry
{
CoglFramebuffer *draw_buffer;
CoglFramebuffer *read_buffer;
} CoglFramebufferStackEntry;
static void _cogl_framebuffer_free (CoglFramebuffer *framebuffer);
static void _cogl_onscreen_free (CoglOnscreen *onscreen);
static void _cogl_offscreen_free (CoglOffscreen *offscreen);
@ -364,7 +376,7 @@ _cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer,
/* NB: _cogl_framebuffer_flush_state may disrupt various state (such
* as the pipeline state) when flushing the clip stack, so should
* always be done first when preparing to draw. */
_cogl_framebuffer_flush_state (framebuffer, 0);
_cogl_framebuffer_flush_state (framebuffer, framebuffer, 0);
_cogl_clear4f (buffers, red, green, blue, alpha);;
@ -505,7 +517,7 @@ _cogl_framebuffer_set_viewport (CoglFramebuffer *framebuffer,
framebuffer->viewport_width = width;
framebuffer->viewport_height = height;
if (_cogl_get_framebuffer () == framebuffer)
if (_cogl_get_draw_buffer () == framebuffer)
ctx->dirty_gl_viewport = TRUE;
}
@ -988,12 +1000,27 @@ _cogl_onscreen_clutter_backend_set_size (int width, int height)
ctx->dirty_gl_viewport = 1;
}
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;
return g_slist_prepend (stack, COGL_INVALID_HANDLE);
entry = create_stack_entry (COGL_INVALID_HANDLE, COGL_INVALID_HANDLE);
return g_slist_prepend (stack, entry);
}
void
@ -1003,11 +1030,19 @@ _cogl_free_framebuffer_stack (GSList *stack)
for (l = stack; l != NULL; l = l->next)
{
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (l->data);
if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN)
_cogl_offscreen_free (COGL_OFFSCREEN (framebuffer));
CoglFramebufferStackEntry *entry = l->data;
if (entry->draw_buffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN)
_cogl_offscreen_free (COGL_OFFSCREEN (entry->draw_buffer));
else
_cogl_onscreen_free (COGL_ONSCREEN (framebuffer));
_cogl_onscreen_free (COGL_ONSCREEN (entry->draw_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));
g_slice_free (CoglFramebufferStackEntry, entry);
}
g_slist_free (stack);
}
@ -1016,42 +1051,55 @@ _cogl_free_framebuffer_stack (GSList *stack)
* 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_framebuffer_real (CoglFramebuffer *framebuffer)
_cogl_set_framebuffers_real (CoglFramebuffer *draw_buffer,
CoglFramebuffer *read_buffer)
{
CoglFramebuffer **entry;
CoglFramebufferStackEntry *entry;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
entry = (CoglFramebuffer **)&ctx->framebuffer_stack->data;
entry = ctx->framebuffer_stack->data;
ctx->dirty_bound_framebuffer = 1;
ctx->dirty_gl_viewport = 1;
if (framebuffer)
cogl_object_ref (framebuffer);
if (*entry)
cogl_object_unref (*entry);
if (draw_buffer)
cogl_object_ref (draw_buffer);
if (entry->draw_buffer)
cogl_object_unref (entry->draw_buffer);
*entry = framebuffer;
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;
/* We've effectively just switched the current modelview and
* projection matrix stacks and clip state so we need to dirty
* them to ensure they get flushed for the next batch of geometry
* we flush */
_cogl_matrix_stack_dirty (framebuffer->modelview_stack);
_cogl_matrix_stack_dirty (framebuffer->projection_stack);
_cogl_matrix_stack_dirty (draw_buffer->modelview_stack);
_cogl_matrix_stack_dirty (draw_buffer->projection_stack);
_cogl_clip_stack_dirty ();
}
void
cogl_set_framebuffer (CoglFramebuffer *framebuffer)
static void
_cogl_set_framebuffers (CoglFramebuffer *draw_buffer,
CoglFramebuffer *read_buffer)
{
CoglFramebuffer *current;
CoglFramebuffer *current_draw_buffer;
CoglFramebuffer *current_read_buffer;
g_return_if_fail (_cogl_is_framebuffer (framebuffer));
g_return_if_fail (_cogl_is_framebuffer (draw_buffer));
g_return_if_fail (_cogl_is_framebuffer (read_buffer));
current = _cogl_get_framebuffer ();
if (current != framebuffer)
current_draw_buffer = _cogl_get_draw_buffer ();
current_read_buffer = _cogl_get_read_buffer ();
if (current_draw_buffer != draw_buffer ||
current_read_buffer != read_buffer)
{
/* XXX: eventually we want to remove this implicit journal flush
* so we can log into the journal beyond framebuffer changes to
@ -1059,12 +1107,20 @@ cogl_set_framebuffer (CoglFramebuffer *framebuffer)
* mid-scene renders to textures. Current will be NULL when the
* framebuffer stack is first created so we need to guard
* against that here */
if (current)
_cogl_framebuffer_flush_journal (current);
_cogl_set_framebuffer_real (framebuffer);
if (current_draw_buffer)
_cogl_framebuffer_flush_journal (current_draw_buffer);
if (current_read_buffer)
_cogl_framebuffer_flush_journal (current_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)
@ -1074,48 +1130,83 @@ cogl_set_draw_buffer (CoglBufferTarget target, CoglHandle handle)
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_framebuffer (void)
_cogl_get_draw_buffer (void)
{
CoglFramebufferStackEntry *entry;
_COGL_GET_CONTEXT (ctx, NULL);
g_assert (ctx->framebuffer_stack);
return ctx->framebuffer_stack->data;
entry = ctx->framebuffer_stack->data;
return entry->draw_buffer;
}
CoglFramebuffer *
_cogl_get_read_buffer (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)
{
CoglFramebuffer *old_draw_buffer, *old_read_buffer;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
g_return_if_fail (_cogl_is_framebuffer (draw_buffer));
g_return_if_fail (_cogl_is_framebuffer (read_buffer));
g_assert (ctx->framebuffer_stack);
/* 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_object_ref (_cogl_get_draw_buffer ());
old_read_buffer = cogl_object_ref (_cogl_get_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_GET_CONTEXT (ctx, NO_RETVAL);
g_return_if_fail (_cogl_is_framebuffer (buffer));
g_assert (ctx->framebuffer_stack);
/* Copy the top of the stack so that when we call cogl_set_framebuffer
it will still know what the old framebuffer was */
ctx->framebuffer_stack =
g_slist_prepend (ctx->framebuffer_stack,
cogl_object_ref (_cogl_get_framebuffer ()));
cogl_set_framebuffer (buffer);
_cogl_push_framebuffers (buffer, buffer);
}
/* XXX: deprecated API */
void
cogl_push_draw_buffer (void)
{
cogl_push_framebuffer (_cogl_get_framebuffer ());
cogl_push_framebuffer (_cogl_get_draw_buffer ());
}
void
cogl_pop_framebuffer (void)
{
CoglFramebuffer *to_pop;
CoglFramebuffer *to_restore;
CoglFramebufferStackEntry *to_pop;
CoglFramebufferStackEntry *to_restore;
gboolean changed = FALSE;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -1125,16 +1216,23 @@ cogl_pop_framebuffer (void)
to_pop = ctx->framebuffer_stack->data;
to_restore = ctx->framebuffer_stack->next->data;
if (to_pop != to_restore)
if (to_pop->draw_buffer != to_restore->draw_buffer ||
to_pop->read_buffer != to_restore->read_buffer)
{
/* XXX: eventually we want to remove this implicit journal flush
* so we can log into the journal beyond framebuffer changes to
* support batching scenes that depend on the results of
* mid-scene renders to textures. */
_cogl_framebuffer_flush_journal (to_pop);
_cogl_framebuffer_flush_journal (to_pop->draw_buffer);
_cogl_framebuffer_flush_journal (to_pop->read_buffer);
changed = TRUE;
}
cogl_object_unref (to_pop);
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);
@ -1142,8 +1240,9 @@ cogl_pop_framebuffer (void)
/* If the framebuffer has changed as a result of popping the top
* then re-assert the current buffer so as to dirty state as
* necessary. */
if (to_pop != to_restore)
_cogl_set_framebuffer_real (to_restore);
if (changed)
_cogl_set_framebuffers_real (to_restore->draw_buffer,
to_restore->read_buffer);
}
/* XXX: deprecated API */
@ -1153,8 +1252,21 @@ cogl_pop_draw_buffer (void)
cogl_pop_framebuffer ();
}
static void
bind_gl_framebuffer (GLenum target, CoglFramebuffer *framebuffer)
{
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN)
GE (glBindFramebuffer (target,
COGL_OFFSCREEN (framebuffer)->fbo_handle));
else
GE (glBindFramebuffer (target, 0));
}
void
_cogl_framebuffer_flush_state (CoglFramebuffer *framebuffer,
_cogl_framebuffer_flush_state (CoglFramebuffer *draw_buffer,
CoglFramebuffer *read_buffer,
CoglFramebufferFlushFlags flags)
{
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -1162,13 +1274,15 @@ _cogl_framebuffer_flush_state (CoglFramebuffer *framebuffer,
if (cogl_features_available (COGL_FEATURE_OFFSCREEN) &&
ctx->dirty_bound_framebuffer)
{
if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN)
{
GE (glBindFramebuffer (GL_FRAMEBUFFER,
COGL_OFFSCREEN (framebuffer)->fbo_handle));
}
if (!cogl_features_available (COGL_FEATURE_OFFSCREEN_BLIT) ||
draw_buffer == read_buffer)
bind_gl_framebuffer (GL_FRAMEBUFFER, draw_buffer);
else
GE (glBindFramebuffer (GL_FRAMEBUFFER, 0));
{
bind_gl_framebuffer (GL_DRAW_FRAMEBUFFER, draw_buffer);
bind_gl_framebuffer (GL_READ_FRAMEBUFFER, read_buffer);
}
ctx->dirty_bound_framebuffer = FALSE;
}
@ -1181,41 +1295,42 @@ _cogl_framebuffer_flush_state (CoglFramebuffer *framebuffer,
* left, while Cogl defines them to be top left.
* NB: We render upside down to offscreen framebuffers so we don't
* need to convert the y offset in this case. */
if (cogl_is_offscreen (framebuffer))
gl_viewport_y = framebuffer->viewport_y;
if (cogl_is_offscreen (draw_buffer))
gl_viewport_y = draw_buffer->viewport_y;
else
gl_viewport_y = framebuffer->height -
(framebuffer->viewport_y + framebuffer->viewport_height);
gl_viewport_y = draw_buffer->height -
(draw_buffer->viewport_y + draw_buffer->viewport_height);
COGL_NOTE (OPENGL, "Calling glViewport(%d, %d, %d, %d)",
framebuffer->viewport_x,
draw_buffer->viewport_x,
gl_viewport_y,
framebuffer->viewport_width,
framebuffer->viewport_height);
draw_buffer->viewport_width,
draw_buffer->viewport_height);
GE (glViewport (framebuffer->viewport_x,
GE (glViewport (draw_buffer->viewport_x,
gl_viewport_y,
framebuffer->viewport_width,
framebuffer->viewport_height));
draw_buffer->viewport_width,
draw_buffer->viewport_height));
ctx->dirty_gl_viewport = FALSE;
}
/* since we might have changed the framebuffer, we should initialize
* the bits; this is a no-op if they have already been initialized
*/
_cogl_framebuffer_init_bits (framebuffer);
_cogl_framebuffer_init_bits (draw_buffer);
_cogl_framebuffer_init_bits (read_buffer);
/* XXX: Flushing clip state may trash the modelview and projection
* matrices so we must do it before flushing the matrices...
*/
if (!(flags & COGL_FRAMEBUFFER_FLUSH_SKIP_CLIP_STATE))
_cogl_clip_state_flush (&framebuffer->clip_state);
_cogl_clip_state_flush (&draw_buffer->clip_state);
if (!(flags & COGL_FRAMEBUFFER_FLUSH_SKIP_MODELVIEW))
_cogl_matrix_stack_flush_to_gl (framebuffer->modelview_stack,
_cogl_matrix_stack_flush_to_gl (draw_buffer->modelview_stack,
COGL_MATRIX_MODELVIEW);
_cogl_matrix_stack_flush_to_gl (framebuffer->projection_stack,
_cogl_matrix_stack_flush_to_gl (draw_buffer->projection_stack,
COGL_MATRIX_PROJECTION);
}

View File

@ -1312,6 +1312,7 @@ _cogl_journal_flush (CoglJournal *journal,
/* NB: the journal deals with flushing the modelview stack and clip
state manually */
_cogl_framebuffer_flush_state (framebuffer,
framebuffer,
COGL_FRAMEBUFFER_FLUSH_SKIP_MODELVIEW |
COGL_FRAMEBUFFER_FLUSH_SKIP_CLIP_STATE);
@ -1518,7 +1519,7 @@ _cogl_journal_log_quad (CoglJournal *journal,
entry->pipeline = _cogl_pipeline_journal_ref (source);
clip_stack = _cogl_framebuffer_get_clip_stack (_cogl_get_framebuffer ());
clip_stack = _cogl_framebuffer_get_clip_stack (_cogl_get_draw_buffer ());
entry->clip_stack = _cogl_clip_stack_ref (clip_stack);
if (G_UNLIKELY (source != pipeline))
@ -1528,7 +1529,7 @@ _cogl_journal_log_quad (CoglJournal *journal,
_cogl_pipeline_foreach_layer_internal (pipeline,
add_framebuffer_deps_cb,
_cogl_get_framebuffer ());
_cogl_get_draw_buffer ());
/* XXX: It doesn't feel very nice that in this case we just assume
* that the journal is associated with the current framebuffer. I
@ -1536,7 +1537,7 @@ _cogl_journal_log_quad (CoglJournal *journal,
* the reason we don't have that currently is that it would
* introduce a circular reference. */
if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_DISABLE_BATCHING)))
_cogl_framebuffer_flush_journal (_cogl_get_framebuffer ());
_cogl_framebuffer_flush_journal (_cogl_get_draw_buffer ());
COGL_TIMER_STOP (_cogl_uprof_context, log_timer);
}
@ -1587,7 +1588,7 @@ entry_to_screen_polygon (const CoglJournalEntry *entry,
4 /* n_points */);
projection_stack =
_cogl_framebuffer_get_projection_stack (_cogl_get_framebuffer ());
_cogl_framebuffer_get_projection_stack (_cogl_get_draw_buffer ());
_cogl_matrix_stack_get (projection_stack, &projection);
cogl_matrix_project_points (&projection,
@ -1599,7 +1600,7 @@ entry_to_screen_polygon (const CoglJournalEntry *entry,
poly, /* points_out */
4 /* n_points */);
_cogl_framebuffer_get_viewport4fv (_cogl_get_framebuffer (),
_cogl_framebuffer_get_viewport4fv (_cogl_get_draw_buffer (),
viewport);
/* Scale from OpenGL normalized device coordinates (ranging from -1 to 1)

View File

@ -434,7 +434,7 @@ _cogl_matrix_stack_prepare_for_flush (CoglMatrixStack *stack,
* always render upside down to offscreen buffers.
*/
if (mode == COGL_MATRIX_PROJECTION &&
cogl_is_offscreen (_cogl_get_framebuffer ()))
cogl_is_offscreen (_cogl_get_draw_buffer ()))
{
CoglMatrix flipped_projection;
CoglMatrix *projection =

View File

@ -78,7 +78,7 @@ log_quad_sub_textures_cb (CoglHandle texture_handle,
void *user_data)
{
TextureSlicedQuadState *state = user_data;
CoglFramebuffer *framebuffer = _cogl_get_framebuffer ();
CoglFramebuffer *framebuffer = _cogl_get_draw_buffer ();
CoglHandle texture_override;
float quad_coords[4];
@ -542,7 +542,7 @@ _cogl_multitexture_quad_single_primitive (const float *position,
if (state.override_pipeline)
pipeline = state.override_pipeline;
framebuffer = _cogl_get_framebuffer ();
framebuffer = _cogl_get_draw_buffer ();
_cogl_journal_log_quad (framebuffer->journal,
position,
pipeline,

View File

@ -1048,7 +1048,7 @@ _cogl_texture_draw_and_read (CoglHandle handle,
bpp = _cogl_get_format_bpp (COGL_PIXEL_FORMAT_RGBA_8888);
framebuffer = _cogl_get_framebuffer ();
framebuffer = _cogl_get_draw_buffer ();
/* Viewport needs to have some size and be inside the window for this */
_cogl_framebuffer_get_viewport4fv (framebuffer, viewport);
if (viewport[0] < 0 || viewport[1] < 0 ||

View File

@ -151,7 +151,7 @@ cogl_check_extension (const char *name, const char *ext)
void
cogl_clear (const CoglColor *color, unsigned long buffers)
{
_cogl_framebuffer_clear (_cogl_get_framebuffer (), buffers, color);
_cogl_framebuffer_clear (_cogl_get_draw_buffer (), buffers, color);
}
static gboolean
@ -282,7 +282,7 @@ cogl_set_backface_culling_enabled (gboolean setting)
return;
/* Currently the journal can't track changes to backface culling state... */
_cogl_framebuffer_flush_journal (_cogl_get_framebuffer ());
_cogl_framebuffer_flush_journal (_cogl_get_draw_buffer ());
ctx->enable_backface_culling = setting;
}
@ -311,7 +311,7 @@ _cogl_flush_face_winding (void)
* all offscreen rendering is done upside down resulting in reversed winding
* for all triangles.
*/
if (cogl_is_offscreen (_cogl_get_framebuffer ()))
if (cogl_is_offscreen (_cogl_get_draw_buffer ()))
winding = COGL_FRONT_WINDING_CLOCKWISE;
else
winding = COGL_FRONT_WINDING_COUNTER_CLOCKWISE;
@ -360,7 +360,7 @@ cogl_set_viewport (int x,
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
framebuffer = _cogl_get_framebuffer ();
framebuffer = _cogl_get_draw_buffer ();
_cogl_framebuffer_set_viewport (framebuffer,
x,
@ -415,7 +415,7 @@ cogl_get_viewport (float v[4])
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
framebuffer = _cogl_get_framebuffer ();
framebuffer = _cogl_get_draw_buffer ();
_cogl_framebuffer_get_viewport4fv (framebuffer, viewport);
for (i = 0; i < 4; i++)
@ -430,7 +430,7 @@ cogl_get_bitmasks (int *red,
{
CoglFramebuffer *framebuffer;
framebuffer = _cogl_get_framebuffer ();
framebuffer = _cogl_get_draw_buffer ();
if (red)
*red = _cogl_framebuffer_get_red_bits (framebuffer);
@ -497,7 +497,7 @@ _cogl_read_pixels_with_rowstride (int x,
guint8 *pixels,
int rowstride)
{
CoglFramebuffer *framebuffer = _cogl_get_framebuffer ();
CoglFramebuffer *framebuffer = _cogl_get_read_buffer ();
int framebuffer_height;
int bpp;
CoglBitmap *bmp;
@ -537,7 +537,9 @@ _cogl_read_pixels_with_rowstride (int x,
*/
cogl_flush ();
_cogl_framebuffer_flush_state (framebuffer, 0);
_cogl_framebuffer_flush_state (_cogl_get_draw_buffer (),
framebuffer,
0);
framebuffer_height = _cogl_framebuffer_get_height (framebuffer);
@ -706,7 +708,9 @@ cogl_begin_gl (void)
* NB: _cogl_framebuffer_flush_state may disrupt various state (such
* as the pipeline state) when flushing the clip stack, so should
* always be done first when preparing to draw. */
_cogl_framebuffer_flush_state (_cogl_get_framebuffer (), 0);
_cogl_framebuffer_flush_state (_cogl_get_draw_buffer (),
_cogl_get_read_buffer (),
0);
/* Setup the state for the current pipeline */
@ -762,7 +766,7 @@ void
cogl_push_matrix (void)
{
CoglMatrixStack *modelview_stack =
_cogl_framebuffer_get_modelview_stack (_cogl_get_framebuffer ());
_cogl_framebuffer_get_modelview_stack (_cogl_get_draw_buffer ());
_cogl_matrix_stack_push (modelview_stack);
}
@ -770,7 +774,7 @@ void
cogl_pop_matrix (void)
{
CoglMatrixStack *modelview_stack =
_cogl_framebuffer_get_modelview_stack (_cogl_get_framebuffer ());
_cogl_framebuffer_get_modelview_stack (_cogl_get_draw_buffer ());
_cogl_matrix_stack_pop (modelview_stack);
}
@ -778,7 +782,7 @@ void
cogl_scale (float x, float y, float z)
{
CoglMatrixStack *modelview_stack =
_cogl_framebuffer_get_modelview_stack (_cogl_get_framebuffer ());
_cogl_framebuffer_get_modelview_stack (_cogl_get_draw_buffer ());
_cogl_matrix_stack_scale (modelview_stack, x, y, z);
}
@ -786,7 +790,7 @@ void
cogl_translate (float x, float y, float z)
{
CoglMatrixStack *modelview_stack =
_cogl_framebuffer_get_modelview_stack (_cogl_get_framebuffer ());
_cogl_framebuffer_get_modelview_stack (_cogl_get_draw_buffer ());
_cogl_matrix_stack_translate (modelview_stack, x, y, z);
}
@ -794,7 +798,7 @@ void
cogl_rotate (float angle, float x, float y, float z)
{
CoglMatrixStack *modelview_stack =
_cogl_framebuffer_get_modelview_stack (_cogl_get_framebuffer ());
_cogl_framebuffer_get_modelview_stack (_cogl_get_draw_buffer ());
_cogl_matrix_stack_rotate (modelview_stack, angle, x, y, z);
}
@ -802,7 +806,7 @@ void
cogl_transform (const CoglMatrix *matrix)
{
CoglMatrixStack *modelview_stack =
_cogl_framebuffer_get_modelview_stack (_cogl_get_framebuffer ());
_cogl_framebuffer_get_modelview_stack (_cogl_get_draw_buffer ());
_cogl_matrix_stack_multiply (modelview_stack, matrix);
}
@ -831,7 +835,7 @@ cogl_frustum (float left,
float z_far)
{
CoglMatrixStack *projection_stack =
_cogl_framebuffer_get_projection_stack (_cogl_get_framebuffer ());
_cogl_framebuffer_get_projection_stack (_cogl_get_draw_buffer ());
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -856,7 +860,7 @@ cogl_ortho (float left,
{
CoglMatrix ortho;
CoglMatrixStack *projection_stack =
_cogl_framebuffer_get_projection_stack (_cogl_get_framebuffer ());
_cogl_framebuffer_get_projection_stack (_cogl_get_draw_buffer ());
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -869,7 +873,7 @@ void
cogl_get_modelview_matrix (CoglMatrix *matrix)
{
CoglMatrixStack *modelview_stack =
_cogl_framebuffer_get_modelview_stack (_cogl_get_framebuffer ());
_cogl_framebuffer_get_modelview_stack (_cogl_get_draw_buffer ());
_cogl_matrix_stack_get (modelview_stack, matrix);
_COGL_MATRIX_DEBUG_PRINT (matrix);
}
@ -878,7 +882,7 @@ void
cogl_set_modelview_matrix (CoglMatrix *matrix)
{
CoglMatrixStack *modelview_stack =
_cogl_framebuffer_get_modelview_stack (_cogl_get_framebuffer ());
_cogl_framebuffer_get_modelview_stack (_cogl_get_draw_buffer ());
_cogl_matrix_stack_set (modelview_stack, matrix);
_COGL_MATRIX_DEBUG_PRINT (matrix);
}
@ -887,7 +891,7 @@ void
cogl_get_projection_matrix (CoglMatrix *matrix)
{
CoglMatrixStack *projection_stack =
_cogl_framebuffer_get_projection_stack (_cogl_get_framebuffer ());
_cogl_framebuffer_get_projection_stack (_cogl_get_draw_buffer ());
_cogl_matrix_stack_get (projection_stack, matrix);
_COGL_MATRIX_DEBUG_PRINT (matrix);
}
@ -896,7 +900,7 @@ void
cogl_set_projection_matrix (CoglMatrix *matrix)
{
CoglMatrixStack *projection_stack =
_cogl_framebuffer_get_projection_stack (_cogl_get_framebuffer ());
_cogl_framebuffer_get_projection_stack (_cogl_get_draw_buffer ());
_cogl_matrix_stack_set (projection_stack, matrix);
/* FIXME: Update the inverse projection matrix!! Presumably use
@ -909,7 +913,7 @@ _cogl_get_clip_state (void)
{
CoglFramebuffer *framebuffer;
framebuffer = _cogl_get_framebuffer ();
framebuffer = _cogl_get_draw_buffer ();
return _cogl_framebuffer_get_clip_state (framebuffer);
}
@ -1119,5 +1123,5 @@ _cogl_swap_buffers_notify (void)
{
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
_cogl_framebuffer_swap_notify (_cogl_get_framebuffer ());
_cogl_framebuffer_swap_notify (_cogl_get_draw_buffer ());
}

View File

@ -355,7 +355,7 @@ _cogl_add_path_to_stencil_buffer (CoglPath *path,
gboolean need_clear)
{
CoglPathData *data = path->data;
CoglFramebuffer *framebuffer = _cogl_get_framebuffer ();
CoglFramebuffer *framebuffer = _cogl_get_draw_buffer ();
CoglMatrixStack *modelview_stack =
_cogl_framebuffer_get_modelview_stack (framebuffer);
CoglMatrixStack *projection_stack =
@ -466,14 +466,16 @@ cogl2_path_fill (CoglPath *path)
if (path->data->path_nodes->len == 0)
return;
framebuffer = _cogl_get_framebuffer ();
framebuffer = _cogl_get_draw_buffer ();
_cogl_framebuffer_flush_journal (framebuffer);
/* NB: _cogl_framebuffer_flush_state may disrupt various state (such
* as the pipeline state) when flushing the clip stack, so should
* always be done first when preparing to draw. */
_cogl_framebuffer_flush_state (framebuffer, 0);
_cogl_framebuffer_flush_state (framebuffer,
_cogl_get_read_buffer (),
0);
_cogl_path_fill_nodes (path);
}